@onjmin/koe 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/converter/frq.ts","../src/converter/pitch.ts","../src/converter/pack.ts","../src/converter/parse-oto.ts","../src/converter/wav.ts","../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js","../src/converter/zip.ts","../src/koe.ts","../src/engine/voice-bank.ts","../src/engine/index.ts","../src/engine/worldline.ts","../src/oto/frames.ts","../src/oto/estimate.ts","../src/oto/kana.ts","../src/oto/generate.ts","../src/oto/write.ts","../src/utautts/assets.ts","../src/utautts/hts.ts","../src/utautts/openjtalk_features.ts","../src/utautts/prosody_rules.ts","../src/utautts/UtauTTSAdapter.ts"],"sourcesContent":["/**\r\n * UTAU `.frq` frequency-analysis files (FREQ0003). The same format OpenUtau\r\n * reads: an 8-byte header, hop size, the average fundamental frequency of the\r\n * whole recording, then a per-frame f0 / amplitude curve.\r\n *\r\n * Layout:\r\n * char[8] \"FREQ0003\"\r\n * int32 hopSize ← in ORIGINAL WAV samples\r\n * float64 averageF0 ← whole-file average in Hz\r\n * byte[16] (blank)\r\n * int32 length\r\n * { float64 f0, float64 amp } × length\r\n */\r\n\r\nconst HEADER_SIZE = 40;\r\n\r\nexport interface FrqData {\r\n\t/** Analysis hop in samples of the ORIGINAL wav (not the 48 kHz conversion) */\r\n\thopSize: number;\r\n\t/** Whole-file average f0 in Hz, as stored in the header */\r\n\taverageF0: number;\r\n\t/** Per-frame f0 in Hz — 0 where the analyser found no clear pitch */\r\n\tf0: Float64Array;\r\n\t/** Per-frame amplitude, parallel to {@link f0} */\r\n\tamp: Float64Array;\r\n}\r\n\r\n/** Parse a `.frq` file, including the per-frame curve. Null if not FREQ0003. */\r\nexport function parseFrq(buffer: ArrayBuffer): FrqData | null {\r\n\tif (buffer.byteLength < HEADER_SIZE) return null;\r\n\tconst view = new DataView(buffer);\r\n\r\n\tlet header = \"\";\r\n\tfor (let i = 0; i < 8; i++) header += String.fromCharCode(view.getUint8(i));\r\n\tif (header !== \"FREQ0003\") return null;\r\n\r\n\tconst hopSize = view.getInt32(8, true);\r\n\tconst averageF0 = view.getFloat64(12, true); // little-endian\r\n\tconst declared = view.getInt32(36, true);\r\n\t// Trust the file's actual size over the declared count — truncated frq files\r\n\t// are common enough that reading past the buffer must not throw.\r\n\tconst available = Math.floor((buffer.byteLength - HEADER_SIZE) / 16);\r\n\tconst length = Math.max(0, Math.min(declared, available));\r\n\r\n\tconst f0 = new Float64Array(length);\r\n\tconst amp = new Float64Array(length);\r\n\tfor (let i = 0; i < length; i++) {\r\n\t\tconst p = HEADER_SIZE + i * 16;\r\n\t\tf0[i] = view.getFloat64(p, true);\r\n\t\tamp[i] = view.getFloat64(p + 8, true);\r\n\t}\r\n\r\n\treturn {\r\n\t\thopSize: hopSize > 0 ? hopSize : 256,\r\n\t\taverageF0: Number.isFinite(averageF0) && averageF0 > 0 ? averageF0 : 0,\r\n\t\tf0,\r\n\t\tamp,\r\n\t};\r\n}\r\n\r\n/**\r\n * Average f0 over the voiced frames covering a time span of the recording.\r\n *\r\n * The header's whole-file average includes leading silence and unvoiced\r\n * consonants, so it can sit well away from the pitch actually sounding in the\r\n * region a note is built from. Playback resamples the whole phoneme by one\r\n * scalar ratio, so an inaccurate value both detunes the note and makes two\r\n * crossfading notes drift apart in phase across the overlap — a 1% error at\r\n * 233 Hz drifts ~25° over a 30 ms overlap and ~84° over 100 ms.\r\n *\r\n * @param startMs / endMs span within the ORIGINAL recording, in milliseconds\r\n * @param sourceRate sample rate of the original WAV the frq describes\r\n * @returns Hz, or 0 when the span holds no voiced frames\r\n */\r\nexport function frqAverageF0InRange(\r\n\tfrq: FrqData,\r\n\tstartMs: number,\r\n\tendMs: number,\r\n\tsourceRate: number,\r\n): number {\r\n\tif (!(sourceRate > 0) || frq.f0.length === 0) return 0;\r\n\tconst perFrameMs = (frq.hopSize / sourceRate) * 1000;\r\n\tif (!(perFrameMs > 0)) return 0;\r\n\r\n\tconst first = Math.max(0, Math.floor(startMs / perFrameMs));\r\n\tconst last = Math.min(frq.f0.length - 1, Math.ceil(endMs / perFrameMs));\r\n\r\n\t// Amplitude-weighted so quiet fringe frames (a decaying tail, a breath)\r\n\t// don't pull the average away from the body of the vowel.\r\n\tlet num = 0;\r\n\tlet den = 0;\r\n\tfor (let i = first; i <= last; i++) {\r\n\t\tconst hz = frq.f0[i];\r\n\t\tif (!(hz > 0)) continue; // unvoiced / undetected\r\n\t\tconst w = frq.amp[i] > 0 ? frq.amp[i] : 1;\r\n\t\tnum += hz * w;\r\n\t\tden += w;\r\n\t}\r\n\treturn den > 0 ? num / den : 0;\r\n}\r\n\r\n/** Whole-file average f0 in Hz from a `.frq` file, or null. */\r\nexport function parseFrqAverageF0(buffer: ArrayBuffer): number | null {\r\n\tconst frq = parseFrq(buffer);\r\n\treturn frq && frq.averageF0 > 0 ? frq.averageF0 : null;\r\n}\r\n\r\n/** Map a WAV filename to its sibling frq filename: \"あ.wav\" → \"あ_wav.frq\". */\r\nexport function frqFileName(wavName: string): string {\r\n\tconst dot = wavName.lastIndexOf(\".\");\r\n\tconst base = dot >= 0 ? wavName.slice(0, dot) : wavName;\r\n\tconst ext = dot >= 0 ? wavName.slice(dot + 1) : \"wav\";\r\n\treturn `${base}_${ext}.frq`;\r\n}\r\n","const SAMPLE_RATE = 48000;\n\nconst NAME_SEMITONE: Record<string, number> = {\n\tc: 0,\n\td: 2,\n\te: 4,\n\tf: 5,\n\tg: 7,\n\ta: 9,\n\tb: 11,\n};\n\n/** Parse a note name like \"E4\", \"G#4\", \"Db5\" → frequency in Hz (null if invalid). */\nexport function noteNameToHz(name: string): number | null {\n\tconst m = /^([A-Ga-g])([#b]?)(-?\\d+)$/.exec(name);\n\tif (!m) return null;\n\tlet semi = NAME_SEMITONE[m[1].toLowerCase()];\n\tif (m[2] === \"#\") semi++;\n\telse if (m[2] === \"b\") semi--;\n\tconst midi = (parseInt(m[3], 10) + 1) * 12 + semi;\n\treturn 440 * 2 ** ((midi - 69) / 12);\n}\n\n/** Recorded pitch encoded in a multi-pitch alias suffix: \"a い_E4\" → 329.63 Hz. */\nexport function pitchFromAliasSuffix(alias: string): number | null {\n\tconst m = /_([A-Ga-g][#b]?-?\\d+)$/.exec(alias);\n\treturn m ? noteNameToHz(m[1]) : null;\n}\n\n/**\n * Estimate the fundamental frequency (Hz) of a voiced region by normalized\n * autocorrelation. Returns 0 when no clear pitch is found (unvoiced consonant,\n * silence, or a region too short to analyse).\n *\n * The signal is decimated to a lower analysis rate for speed; f0 below ~700 Hz\n * is well within the resulting Nyquist limit. A parabolic interpolation around\n * the best lag gives sub-sample (sub-semitone) accuracy.\n */\nexport function detectF0(pcm: Int16Array, start: number, end: number): number {\n\tconst DECIM = 4;\n\tconst sr = SAMPLE_RATE / DECIM; // 12 kHz analysis rate\n\tconst minLag = Math.floor(sr / 700); // highest f0 we look for\n\tconst maxLag = Math.floor(sr / 70); // lowest f0 we look for\n\n\tconst outLen = Math.floor((end - start) / DECIM);\n\tif (outLen < maxLag + 2) return 0;\n\tconst win = Math.min(outLen, 1500); // up to ~0.125 s of vowel\n\n\t// Decimate (box-average) + remove DC, and build a prefix sum of squares so\n\t// each lag's window energy is O(1).\n\tconst buf = new Float32Array(win);\n\tlet mean = 0;\n\tfor (let i = 0; i < win; i++) {\n\t\tlet s = 0;\n\t\tconst base = start + i * DECIM;\n\t\tfor (let j = 0; j < DECIM; j++) s += pcm[base + j];\n\t\tbuf[i] = s;\n\t\tmean += s;\n\t}\n\tmean /= win;\n\n\tconst sq = new Float64Array(win + 1);\n\tfor (let i = 0; i < win; i++) {\n\t\tbuf[i] -= mean;\n\t\tsq[i + 1] = sq[i] + buf[i] * buf[i];\n\t}\n\tif (sq[win] < 1) return 0; // effectively silent\n\n\t// Normalized autocorrelation: 2·r(lag) / (E[0..n] + E[lag..lag+n]) ∈ [-1, 1].\n\tconst norm = (lag: number): number => {\n\t\tconst n = win - lag;\n\t\tlet r = 0;\n\t\tfor (let i = 0; i < n; i++) r += buf[i] * buf[i + lag];\n\t\tconst e = sq[n] + (sq[lag + n] - sq[lag]);\n\t\treturn e > 0 ? (2 * r) / e : 0;\n\t};\n\n\tlet bestLag = -1;\n\tlet best = 0;\n\tfor (let lag = minLag; lag <= maxLag; lag++) {\n\t\tconst v = norm(lag);\n\t\tif (v > best) {\n\t\t\tbest = v;\n\t\t\tbestLag = lag;\n\t\t}\n\t}\n\tif (bestLag < 1 || best < 0.4) return 0; // unvoiced / no clear period\n\n\t// Parabolic interpolation around the peak\n\tconst y0 = norm(bestLag - 1);\n\tconst y1 = best;\n\tconst y2 = norm(bestLag + 1);\n\tconst denom = y0 - 2 * y1 + y2;\n\tconst shift = denom !== 0 ? (0.5 * (y0 - y2)) / denom : 0;\n\n\treturn sr / (bestLag + shift);\n}\n","import type { Manifest, PhonemeEntry } from \"../types.js\";\r\nimport type { OtoEntry } from \"./parse-oto.js\";\r\nimport { detectF0 } from \"./pitch.js\";\r\n\r\nconst TARGET_RATE = 48000;\r\n\r\nfunction msToSamples(ms: number): number {\r\n\treturn Math.round((ms / 1000) * TARGET_RATE);\r\n}\r\n\r\nconst clamp = (v: number, lo: number, hi: number) =>\r\n\tMath.max(lo, Math.min(hi, v));\r\n\r\nexport interface PackInput {\r\n\toto: OtoEntry;\r\n\t/** Full PCM of the source WAV (48kHz / 16bit / mono) */\r\n\tpcm: Int16Array;\r\n\t/** Known recorded pitch in Hz (e.g. from the .frq file). 0/undefined → auto-detect. */\r\n\trecordedPitch?: number;\r\n}\r\n\r\nexport interface PackOutput {\r\n\tmanifest: Manifest;\r\n\t/** Raw PCM blob — Int16 / 48kHz / mono */\r\n\tbin: ArrayBuffer;\r\n}\r\n\r\nexport interface TrimmedPhoneme {\r\n\t/** PCM trimmed to the oto region [offset, cutoff] */\r\n\tpcm: Int16Array;\r\n\t/** Manifest params relative to the trimmed start (sample 0 = oto offset) */\r\n\tentry: Omit<PhonemeEntry, \"offset\">;\r\n}\r\n\r\n/**\r\n * Resolve an oto entry's usable region within the full 48 kHz PCM.\r\n *\r\n * Shared with the converter CLI, which needs the same bounds to look up the\r\n * region's local f0 in a `.frq` curve.\r\n */\r\nexport function otoRegion(\r\n\tpcmLength: number,\r\n\toto: OtoEntry,\r\n): { start: number; end: number } {\r\n\tconst start = clamp(msToSamples(oto.offset), 0, pcmLength);\r\n\tconst end =\r\n\t\toto.cutoff < 0\r\n\t\t\t? clamp(start + msToSamples(-oto.cutoff), start, pcmLength)\r\n\t\t\t: clamp(pcmLength - msToSamples(oto.cutoff), start, pcmLength);\r\n\treturn { start, end };\r\n}\r\n\r\n/**\r\n * Remove the DC offset from a phoneme slice, returning an independent copy.\r\n *\r\n * A sample sitting off-centre cannot be crossfaded cleanly no matter how well\r\n * the phase is aligned: the two constant offsets simply add, so the seam gets a\r\n * step in its mean. Centring each phoneme at pack time is the only place this\r\n * can be fixed cheaply, and it is a precondition for the playback-side phase\r\n * alignment to actually deliver a flat crossfade.\r\n *\r\n * The copy is required as well as convenient — several oto entries routinely\r\n * point into the same source WAV, so the slices must not share storage.\r\n */\r\nfunction centerSlice(slice: Int16Array): Int16Array {\r\n\tconst out = new Int16Array(slice.length);\r\n\tif (slice.length === 0) return out;\r\n\r\n\tlet sum = 0;\r\n\tfor (let i = 0; i < slice.length; i++) sum += slice[i];\r\n\tconst dc = Math.round(sum / slice.length);\r\n\r\n\tfor (let i = 0; i < slice.length; i++) {\r\n\t\tout[i] = clamp(slice[i] - dc, -32768, 32767);\r\n\t}\r\n\treturn out;\r\n}\r\n\r\n/**\r\n * Cut the full WAV PCM down to its usable oto region and recompute parameters\r\n * relative to the trimmed start.\r\n *\r\n * UTAU oto.ini values are all in ms and measured from `offset` (the left blank),\r\n * except `cutoff` (right blank):\r\n * - cutoff >= 0 : measured from the END of the file\r\n * - cutoff < 0 : region length from offset = |cutoff|\r\n *\r\n * After trimming, sample 0 == oto offset, so pre/overlap/consonant carry over\r\n * unchanged (just converted to samples), and the slice length is the region end.\r\n */\r\nexport function trimToOto(\r\n\tpcm: Int16Array,\r\n\toto: OtoEntry,\r\n\trecordedPitch = 0,\r\n): TrimmedPhoneme {\r\n\tconst { start, end } = otoRegion(pcm.length, oto);\r\n\r\n\t// Centre the slice: the stored PCM is what playback crossfades, so the DC\r\n\t// offset has to go before it is written to voice.bin.\r\n\tconst slice = centerSlice(pcm.subarray(start, end));\r\n\tconst length = slice.length;\r\n\r\n\tconst pre = clamp(msToSamples(oto.pre), 0, length);\r\n\tconst overlap = clamp(msToSamples(oto.overlap), 0, length);\r\n\tconst consonant = clamp(msToSamples(oto.consonant), 0, length);\r\n\r\n\t// Prefer the known recorded pitch (from the .frq file or alias suffix); only\r\n\t// fall back to autocorrelation on the sustained vowel when none is available.\r\n\tconst pitch =\r\n\t\trecordedPitch > 0\r\n\t\t\t? recordedPitch\r\n\t\t\t: detectF0(\r\n\t\t\t\t\tslice,\r\n\t\t\t\t\tMath.min(Math.max(pre, consonant), Math.max(0, length - 1)),\r\n\t\t\t\t\tlength,\r\n\t\t\t\t);\r\n\r\n\treturn {\r\n\t\tpcm: slice,\r\n\t\tentry: { length, pre, overlap, consonant, pitch },\r\n\t};\r\n}\r\n\r\n/**\r\n * Pack phonemes into voice.bin + manifest.json.\r\n * Each phoneme is trimmed to its oto region and DC-centred first.\r\n * Duplicate aliases are silently overwritten by the later entry.\r\n */\r\nexport function pack(inputs: PackInput[], referencePitch = 220): PackOutput {\r\n\tconst phonemes: Record<string, PhonemeEntry> = {};\r\n\tconst chunks: Int16Array[] = [];\r\n\tlet byteOffset = 0;\r\n\r\n\tfor (const { oto, pcm, recordedPitch } of inputs) {\r\n\t\tconst { pcm: slice, entry } = trimToOto(pcm, oto, recordedPitch);\r\n\t\tif (slice.length === 0) continue;\r\n\r\n\t\tphonemes[oto.alias] = { offset: byteOffset, ...entry };\r\n\t\tbyteOffset += slice.byteLength;\r\n\t\tchunks.push(slice);\r\n\t}\r\n\r\n\tconst bin = new ArrayBuffer(byteOffset);\r\n\tconst view = new Uint8Array(bin);\r\n\tlet pos = 0;\r\n\tfor (const chunk of chunks) {\r\n\t\tview.set(\r\n\t\t\tnew Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength),\r\n\t\t\tpos,\r\n\t\t);\r\n\t\tpos += chunk.byteLength;\r\n\t}\r\n\r\n\tconst manifest: Manifest = {\r\n\t\tsampleRate: 48000,\r\n\t\treferencePitch,\r\n\t\tphonemes,\r\n\t};\r\n\r\n\treturn { manifest, bin };\r\n}\r\n","export interface OtoEntry {\n\t/** Source WAV filename */\n\twav: string;\n\t/** Phoneme alias */\n\talias: string;\n\t/** Left blank — offset from WAV start (ms) */\n\toffset: number;\n\t/** Consonant portion end from offset (ms) */\n\tconsonant: number;\n\t/** Right blank — negative = from WAV end, positive = from offset (ms) */\n\tcutoff: number;\n\t/** Preutterance from offset (ms) */\n\tpre: number;\n\t/** Overlap / crossfade region (ms) */\n\toverlap: number;\n}\n\n/**\n * Parse oto.ini content (already decoded to UTF-8 string).\n * Silently skips malformed lines.\n */\nexport function parseOto(content: string): OtoEntry[] {\n\tconst entries: OtoEntry[] = [];\n\n\tfor (const raw of content.split(/\\r?\\n/)) {\n\t\tconst line = raw.trim();\n\t\tif (!line || line.startsWith(\"#\")) continue;\n\n\t\tconst eq = line.indexOf(\"=\");\n\t\tif (eq === -1) continue;\n\n\t\tconst wav = line.slice(0, eq).trim();\n\t\tconst parts = line.slice(eq + 1).split(\",\");\n\t\tif (parts.length < 6) continue;\n\n\t\tconst [alias, offsetStr, consonantStr, cutoffStr, preStr, overlapStr] =\n\t\t\tparts;\n\t\t// Empty alias → use filename without extension (UTAU spec default)\n\t\tconst aliasStr = alias.trim() || wav.replace(/\\.[^.]+$/, \"\");\n\t\tconst entry: OtoEntry = {\n\t\t\twav,\n\t\t\talias: aliasStr,\n\t\t\toffset: parseFloat(offsetStr) || 0,\n\t\t\tconsonant: parseFloat(consonantStr) || 0,\n\t\t\tcutoff: parseFloat(cutoffStr) || 0,\n\t\t\tpre: parseFloat(preStr) || 0,\n\t\t\toverlap: parseFloat(overlapStr) || 0,\n\t\t};\n\n\t\tif (!entry.alias) continue;\n\t\tentries.push(entry);\n\t}\n\n\treturn entries;\n}\n","export interface WavData {\r\n\tsampleRate: number;\r\n\tchannels: number;\r\n\t/** Normalized samples in [-1, 1], interleaved if multi-channel */\r\n\tsamples: Float32Array;\r\n}\r\n\r\n/** Parse a WAV file from an ArrayBuffer. Supports PCM 8/16/24-bit and IEEE float 32-bit. */\r\nexport function parseWav(buf: ArrayBuffer): WavData {\r\n\tconst view = new DataView(buf);\r\n\r\n\tconst riff = readFourCC(view, 0);\r\n\tif (riff !== \"RIFF\") throw new Error(`Not a RIFF file (got \"${riff}\")`);\r\n\r\n\tlet sampleRate = 0;\r\n\tlet channels = 0;\r\n\tlet bitsPerSample = 0;\r\n\tlet audioFormat = 1;\r\n\tlet dataOffset = 0;\r\n\tlet dataLength = 0;\r\n\r\n\tlet pos = 12;\r\n\twhile (pos < view.byteLength - 8) {\r\n\t\tconst id = readFourCC(view, pos);\r\n\t\tconst size = view.getUint32(pos + 4, true);\r\n\t\tpos += 8;\r\n\r\n\t\tif (id === \"fmt \") {\r\n\t\t\taudioFormat = view.getUint16(pos, true);\r\n\t\t\tchannels = view.getUint16(pos + 2, true);\r\n\t\t\tsampleRate = view.getUint32(pos + 4, true);\r\n\t\t\tbitsPerSample = view.getUint16(pos + 14, true);\r\n\t\t\t// WAVE_FORMAT_EXTENSIBLE: the real format code is the first 2 bytes of\r\n\t\t\t// the SubFormat GUID in the extension.\r\n\t\t\tif (audioFormat === 0xfffe && size >= 40) {\r\n\t\t\t\taudioFormat = view.getUint16(pos + 24, true);\r\n\t\t\t}\r\n\t\t} else if (id === \"data\") {\r\n\t\t\tdataOffset = pos;\r\n\t\t\t// Clamp to the actual file size — a corrupt chunk header could otherwise\r\n\t\t\t// send sample reads past the end of the buffer.\r\n\t\t\tdataLength = Math.min(size, view.byteLength - pos);\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tpos += size + (size & 1);\r\n\t}\r\n\r\n\tif (!dataOffset) throw new Error(\"WAV has no data chunk\");\r\n\tif (!channels || !sampleRate) throw new Error(\"WAV fmt chunk missing\");\r\n\r\n\t// Reject anything the sample loop below cannot decode — falling through\r\n\t// would silently produce all-zero (silent) audio.\r\n\tconst supported =\r\n\t\t(audioFormat === 3 && bitsPerSample === 32) ||\r\n\t\t(audioFormat === 1 &&\r\n\t\t\t(bitsPerSample === 8 || bitsPerSample === 16 || bitsPerSample === 24));\r\n\tif (!supported) {\r\n\t\tthrow new Error(\r\n\t\t\t`Unsupported WAV format ${audioFormat} / ${bitsPerSample}-bit (need PCM 8/16/24-bit or IEEE float 32-bit)`,\r\n\t\t);\r\n\t}\r\n\r\n\tconst bytesPerSample = bitsPerSample >> 3;\r\n\tconst totalSamples = Math.floor(dataLength / bytesPerSample);\r\n\tconst samples = new Float32Array(totalSamples);\r\n\r\n\tfor (let i = 0; i < totalSamples; i++) {\r\n\t\tconst p = dataOffset + i * bytesPerSample;\r\n\t\tif (audioFormat === 3) {\r\n\t\t\tsamples[i] = view.getFloat32(p, true);\r\n\t\t} else if (bitsPerSample === 8) {\r\n\t\t\tsamples[i] = (view.getUint8(p) - 128) / 128;\r\n\t\t} else if (bitsPerSample === 16) {\r\n\t\t\tsamples[i] = view.getInt16(p, true) / 32768;\r\n\t\t} else if (bitsPerSample === 24) {\r\n\t\t\tconst lo = view.getUint8(p) | (view.getUint8(p + 1) << 8);\r\n\t\t\tlet hi = view.getUint8(p + 2);\r\n\t\t\tif (hi & 0x80) hi = hi | 0xffffff00;\r\n\t\t\tsamples[i] = ((hi << 16) | lo) / 8388608;\r\n\t\t}\r\n\t}\r\n\r\n\treturn { sampleRate, channels, samples };\r\n}\r\n\r\n/** Mix down to mono by averaging all channels. */\r\nexport function toMono(wav: WavData): WavData {\r\n\tif (wav.channels === 1) return wav;\r\n\tconst len = wav.samples.length / wav.channels;\r\n\tconst out = new Float32Array(len);\r\n\tfor (let i = 0; i < len; i++) {\r\n\t\tlet sum = 0;\r\n\t\tfor (let c = 0; c < wav.channels; c++)\r\n\t\t\tsum += wav.samples[i * wav.channels + c];\r\n\t\tout[i] = sum / wav.channels;\r\n\t}\r\n\treturn { sampleRate: wav.sampleRate, channels: 1, samples: out };\r\n}\r\n\r\n/** Linear interpolation resample to targetRate. Expects mono input. */\r\nexport function resample(wav: WavData, targetRate: number): WavData {\r\n\tif (wav.sampleRate === targetRate) return wav;\r\n\tconst ratio = wav.sampleRate / targetRate;\r\n\tconst outLen = Math.floor(wav.samples.length / ratio);\r\n\tconst out = new Float32Array(outLen);\r\n\tconst src = wav.samples;\r\n\tfor (let i = 0; i < outLen; i++) {\r\n\t\tconst x = i * ratio;\r\n\t\tconst xi = Math.floor(x);\r\n\t\tconst frac = x - xi;\r\n\t\tout[i] = (src[xi] ?? 0) + ((src[xi + 1] ?? 0) - (src[xi] ?? 0)) * frac;\r\n\t}\r\n\treturn { sampleRate: targetRate, channels: 1, samples: out };\r\n}\r\n\r\n/** Convert Float32 [-1,1] samples to Int16 PCM. */\r\nexport function toInt16(samples: Float32Array): Int16Array {\r\n\tconst out = new Int16Array(samples.length);\r\n\tfor (let i = 0; i < samples.length; i++) {\r\n\t\tout[i] = Math.round(Math.max(-1, Math.min(1, samples[i])) * 32767);\r\n\t}\r\n\treturn out;\r\n}\r\n\r\n/**\r\n * Decode a WAV to 48kHz/16bit/mono Int16 PCM, reporting the source sample rate.\r\n *\r\n * The rate is needed to index a sibling `.frq` file, whose analysis hop is\r\n * counted in ORIGINAL samples — see {@link frqAverageF0InRange}.\r\n *\r\n * Note this does not touch amplitude: peak levels are carried through\r\n * unchanged, so a bank's own relative loudness between phonemes is preserved\r\n * (UTAU's engine instead normalises each region to −6 dBFS, which is why its\r\n * イ/エ段 and 語尾 samples come out louder than recorded).\r\n */\r\nexport function readWavPcm48k(buf: ArrayBuffer): {\r\n\tpcm: Int16Array;\r\n\tsourceRate: number;\r\n} {\r\n\tconst wav = parseWav(buf);\r\n\tconst mono = toMono(wav);\r\n\tconst resampled = resample(mono, 48000);\r\n\treturn { pcm: toInt16(resampled.samples), sourceRate: wav.sampleRate };\r\n}\r\n\r\n/**\r\n * Convert a WAV to 48kHz/16bit/mono Int16 PCM.\r\n *\r\n * @deprecated Misnomer — this never normalised amplitude. Use\r\n * {@link readWavPcm48k}, which also reports the source sample rate.\r\n */\r\nexport function normalizePcm(buf: ArrayBuffer): Int16Array {\r\n\treturn readWavPcm48k(buf).pcm;\r\n}\r\n\r\nfunction readFourCC(view: DataView, pos: number): string {\r\n\treturn String.fromCharCode(\r\n\t\tview.getUint8(pos),\r\n\t\tview.getUint8(pos + 1),\r\n\t\tview.getUint8(pos + 2),\r\n\t\tview.getUint8(pos + 3),\r\n\t);\r\n}\r\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Some of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + ';addEventListener(\"error\",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})'\n ], { type: 'text/javascript' }))));\n w.onmessage = function (e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err = new Error(ed[0]);\n err['code'] = ed[1];\n err.stack = ed[2];\n cb(err, null);\n }\n else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new i32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return { b: b, r: r };\n};\nvar _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i) {\n if (cd[i])\n ++l[cd[i] - 1];\n }\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 1; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i) {\n if (cd[i]) {\n co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);\n }\n }\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p + 7) / 8) | 0; };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n return new u8(v.subarray(s, e));\n};\n/**\n * Codes for errors generated within this library\n */\nexport var FlateErrorCode = {\n UnexpectedEOF: 0,\n InvalidBlockType: 1,\n InvalidLengthLiteral: 2,\n InvalidDistance: 3,\n StreamFinished: 4,\n NoStreamHandler: 5,\n InvalidHeader: 6,\n NoCallback: 7,\n InvalidUTF8: 8,\n ExtraFieldTooLong: 9,\n InvalidDate: 10,\n FilenameTooLong: 11,\n StreamFinishing: 12,\n InvalidZipData: 13,\n UnknownCompressionMethod: 14\n};\n// error codes\nvar ec = [\n 'unexpected EOF',\n 'invalid block type',\n 'invalid length/literal',\n 'invalid distance',\n 'stream finished',\n 'no stream handler',\n , // determined by compression function\n 'no callback',\n 'invalid UTF-8 data',\n 'extra field too long',\n 'date not in range 1980-2099',\n 'filename too long',\n 'stream finishing',\n 'invalid zip data'\n // determined by unknown compression method\n];\n;\nvar err = function (ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, st, buf, dict) {\n // source length dict length\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n // have to estimate size\n var resize = noBuf || st.i != 2;\n // no state\n var noSt = st.i;\n // Assumes roughly 33% compression ratio average\n if (noBuf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n // ensure size\n if (resize)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (;; lpos = pos) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n // don't reallocate for streams or user buffers\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n d[o + 2] |= v >> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return { t: et, l: 0 };\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return { t: v, l: 1 };\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return { t: new u8(tr), l: mbt };\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return { c: cl.subarray(0, cli), n: s };\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;\n var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;\n var _c = lc(dlt), lclt = _c.c, nlc = _c.n;\n var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n ++lcfreq[lclt[i] & 31];\n for (var i = 0; i < lcdt.length; ++i)\n ++lcfreq[lcdt[i] & 31];\n var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];\n if (bs >= 0 && flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n var sym = syms[i];\n if (sym > 255) {\n var len = (sym >> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (sym >> 23) & 31), p += fleb[len];\n var dst = sym & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[sym]), p += ll[sym];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, st) {\n var s = st.z || dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var lst = st.l;\n var pos = (st.r || 0) & 7;\n if (lvl) {\n if (pos)\n w[0] = st.r >> 3;\n var opt = deo[lvl - 1];\n var n = opt >> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new i32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx blkpos\n var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;\n for (; i + 2 < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768 previous index mod\n var imod = i & 32767, pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = i - dif + j & 32767;\n var pti = prev[ti];\n var cd = ti - pti & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += imod - pimod & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one int32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n for (i = Math.max(i, wi); i < s; ++i) {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n if (!lst) {\n st.r = (pos & 7) | w[(pos / 8) | 0] << 3;\n // shft(pos) now 1 less if pos & 7 != 0\n pos -= 7;\n st.h = head, st.p = prev, st.i = i, st.w = wi;\n }\n }\n else {\n for (var i = st.w || 0; i < s + lst; i += 65535) {\n // end\n var e = i + 65535;\n if (e >= s) {\n // write final block\n w[(pos / 8) | 0] = lst;\n e = s;\n }\n pos = wfblk(w, pos + 1, dat.subarray(i, e));\n }\n st.i = s;\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new Int32Array(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && -306674912) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = -1;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return ~c; }\n };\n};\n// Adler32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length | 0;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 2655, l);\n for (; i < e; ++i)\n m += n += d[i];\n n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);\n }\n a = n, b = m;\n },\n d: function () {\n a %= 65521, b %= 65521;\n return (a & 255) << 24 | (a & 0xFF00) << 8 | (b & 255) << 8 | (b >> 8);\n }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n if (!st) {\n st = { l: 1 };\n if (opt.dictionary) {\n var dict = opt.dictionary.subarray(-32768);\n var newDat = new u8(dict.length + dat.length);\n newDat.set(dict);\n newDat.set(dat, dict.length);\n dat = newDat;\n st.w = dict.length;\n }\n }\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? (st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20) : (12 + opt.mem), pre, post, st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\\s+/g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return fnStr;\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n fnStr = wcln(fns[i], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td = mrg({}, ch[id].e);\n return wk(ch[id].c + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt]; };\nvar bDflt = function () { return [u8, u16, i32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zls]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get opts\nvar gopt = function (o) { return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n}; };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) {\n if (ev.data[0]) {\n strm.push(ev.data[0], ev.data[1]);\n postMessage([ev.data[0].length]);\n }\n else\n strm.flush(ev.data[1]);\n };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id, flush, ext) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else if (!Array.isArray(dat))\n ext(dat);\n else if (dat.length == 1) {\n strm.queuedSize -= dat[0];\n if (strm.ondrain)\n strm.ondrain(dat[0]);\n }\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.queuedSize = 0;\n strm.push = function (d, f) {\n if (!strm.ondata)\n err(5);\n if (t)\n strm.ondata(err(4, 0, 1), null, !!f);\n strm.queuedSize += d.length;\n // can fail for cross-realm Uint8Array, but ok - only a small performance penalty\n w.postMessage([d, t = f], d.buffer instanceof ArrayBuffer ? [d.buffer] : []);\n };\n strm.terminate = function () { w.terminate(); };\n if (flush) {\n strm.flush = function (sync) { w.postMessage([0, sync]); };\n }\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; };\n// read 8 bytes\nvar b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, 'invalid gzip data');\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + (o.filename ? o.filename.length + 1 : 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (o.dictionary && 32);\n c[1] |= 31 - ((c[0] << 8) | c[1]) % 31;\n if (o.dictionary) {\n var h = adler();\n h.p(o.dictionary);\n wbytes(c, 2, h.d());\n }\n};\n// zlib start\nvar zls = function (d, dict) {\n if ((d[0] & 15) != 8 || (d[0] >> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n err(6, 'invalid zlib data');\n if ((d[1] >> 5 & 1) == +!dict)\n err(6, 'invalid zlib data: ' + (d[1] & 32 ? 'need' : 'unexpected') + ' dictionary');\n return (d[1] >> 3 & 4) + 2;\n};\nfunction StrmOpt(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n this.s = { l: 0, i: 32768, w: 32768, z: 32768 };\n // Buffer length must always be 0 mod 32768 for index calculations to be correct when modifying head and prev\n // 98304 = 32768 (lookback) + 65536 (common chunk size)\n this.b = new u8(98304);\n if (this.o.dictionary) {\n var dict = this.o.dictionary.subarray(-32768);\n this.b.set(dict, 32768 - dict.length);\n this.s.i = 32768 - dict.length;\n }\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, this.s), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n var endLen = chunk.length + this.s.z;\n if (endLen > this.b.length) {\n if (endLen > 2 * this.b.length - 32768) {\n var newBuf = new u8(endLen & -32768);\n newBuf.set(this.b.subarray(0, this.s.z));\n this.b = newBuf;\n }\n var split = this.b.length - this.s.z;\n this.b.set(chunk.subarray(0, split), this.s.z);\n this.s.z = this.b.length;\n this.p(this.b, false);\n this.b.set(this.b.subarray(-32768));\n this.b.set(chunk.subarray(split), 32768);\n this.s.z = chunk.length - split + 32768;\n this.s.i = 32766, this.s.w = 32768;\n }\n else {\n this.b.set(chunk, this.s.z);\n this.s.z += chunk.length;\n }\n this.s.l = final & 1;\n if (this.s.z > this.s.w + 8191 || final) {\n this.p(this.b, final || false);\n this.s.w = this.s.i, this.s.i -= 2;\n }\n if (final) {\n // cleanup unneeded buffers/state to reduce memory usage\n this.s = this.o = {};\n this.b = et;\n }\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * deflated output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible. A separate DEFLATE stream may be concatenated\n * with the current output after a sync flush.\n */\n Deflate.prototype.flush = function (sync) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n this.p(this.b, false);\n this.s.w = this.s.i, this.s.i -= 2;\n // could technically skip writing the type-0 block for (this.s.r & 7) == 0,\n // but the deterministic trailer (00 00 FF FF) is useful in some situations\n if (sync) {\n var c = new u8(6);\n c[0] = this.s.r >> 3;\n // write empty, non-final type-0 block\n var ep = wfblk(c, this.s.r, et);\n this.s.r = 0;\n this.ondata(c.subarray(0, ep >> 3), false);\n }\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6, 1);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n return dopt(data, opts || {}, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n function Inflate(opts, cb) {\n // no StrmOpt here to avoid adding to workerizer\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate.prototype.e = function (c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate.prototype.c = function (final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n function AsyncInflate(opts, cb) {\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Inflate(ev.data);\n onmessage = astrm(strm);\n }, 7, 0);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gopt(ev.data[1]))); }, 1, cb);\n}\nexport function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n this.l += chunk.length;\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, this.s);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * GZIPped output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Gzip.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8, 1);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (!opts)\n opts = {};\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming single or multi-member GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n function Gunzip(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n }\n else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, 0);\n // process concatenated GZIP\n if (this.s.f && !this.s.l) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n else if (final) {\n Inflate.prototype.c.call(this, final);\n }\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming single or multi-member GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n function AsyncGunzip(opts, cb) {\n var _this = this;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gunzip(ev.data);\n strm.onmember = function (offset) { return postMessage(offset); };\n onmessage = astrm(strm);\n }, 9, 0, function (offset) { return _this.onmember && _this.onmember(offset); });\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0], ev.data[1])); }, 3, cb);\n}\nexport function gunzipSync(data, opts) {\n var st = gzs(data);\n if (st + 8 > data.length)\n err(6, 'invalid gzip data');\n return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && (this.o.dictionary ? 6 : 2), f && 4, this.s);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * zlibbed output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Zlib.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10, 1);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (!opts)\n opts = {};\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, opts.dictionary ? 6 : 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n function Unzlib(opts, cb) {\n Inflate.call(this, opts, cb);\n this.v = opts && opts.dictionary ? 2 : 1;\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 6 && !final)\n return;\n this.p = this.p.subarray(zls(this.p, this.v - 1)), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n err(6, 'invalid zlib data');\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n function AsyncUnzlib(opts, cb) {\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Unzlib(ev.data);\n onmessage = astrm(strm);\n }, 11, 0);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gopt(ev.data[1]))); }, 5, cb);\n}\nexport function unzlibSync(data, opts) {\n return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n function Decompress(opts, cb) {\n this.o = StrmOpt.call(this, opts, cb) || {};\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n }\n // init substream\n // overriden by AsyncDecompress\n Decompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (dat, final) {\n _this.ondata(dat, final);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(this.o)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(this.o)\n : new this.Z(this.o);\n this.i();\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n function AsyncDecompress(opts, cb) {\n Decompress.call(this, opts, cb);\n this.queuedSize = 0;\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n }\n AsyncDecompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (err, dat, final) {\n _this.ondata(err, dat, final);\n };\n this.s.ondrain = function (size) {\n _this.queuedSize -= size;\n if (_this.ondrain)\n _this.ondrain(size);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n this.queuedSize += chunk.length;\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param opts The decompression options\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, opts) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, opts)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, opts)\n : unzlibSync(data, opts);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k, op = o;\n if (Array.isArray(val))\n op = mrg(o, val[1]), val = val[0];\n if (ArrayBuffer.isView(val))\n t[n] = [val, op];\n else {\n t[n += '/'] = [new u8(0), op];\n fltn(val, n, t, o);\n }\n }\n};\n// text encoder\nvar te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();\n// text decoder\nvar td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();\n// text decoder stream\nvar tds = 0;\ntry {\n td.decode(et, { stream: true });\n tds = 1;\n}\ncatch (e) { }\n// decode UTF8\nvar dutf8 = function (d) {\n for (var r = '', i = 0;;) {\n var c = d[i++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i + eb > d.length)\n return { s: r, r: slc(d, i - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63));\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63));\n }\n};\n/**\n * Streaming UTF-8 decoding\n */\nvar DecodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is decoded\n */\n function DecodeUTF8(cb) {\n this.ondata = cb;\n if (tds)\n this.t = new TextDecoder();\n else\n this.p = et;\n }\n /**\n * Pushes a chunk to be decoded from UTF-8 binary\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n DecodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n final = !!final;\n if (this.t) {\n this.ondata(this.t.decode(chunk, { stream: true }), final);\n if (final) {\n if (this.t.decode().length)\n err(8);\n this.t = null;\n }\n return;\n }\n if (!this.p)\n err(4);\n var dat = new u8(this.p.length + chunk.length);\n dat.set(this.p);\n dat.set(chunk, this.p.length);\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (final) {\n if (r.length)\n err(8);\n this.p = null;\n }\n else\n this.p = r;\n this.ondata(s, final);\n };\n return DecodeUTF8;\n}());\nexport { DecodeUTF8 };\n/**\n * Streaming UTF-8 encoding\n */\nvar EncodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is encoded\n */\n function EncodeUTF8(cb) {\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be encoded to UTF-8\n * @param chunk The string data to push\n * @param final Whether this is the last chunk\n */\n EncodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.ondata(strToU8(chunk), this.d = final || false);\n };\n return EncodeUTF8;\n}());\nexport { EncodeUTF8 };\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n if (latin1) {\n var ar_1 = new u8(str.length);\n for (var i = 0; i < str.length; ++i)\n ar_1[i] = str.charCodeAt(i);\n return ar_1;\n }\n if (te)\n return te.encode(str);\n var l = str.length;\n var ar = new u8(str.length + (str.length >> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n if (latin1) {\n var r = '';\n for (var i = 0; i < dat.length; i += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));\n return r;\n }\n else if (td) {\n return td.decode(dat);\n }\n else {\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (r.length)\n err(8);\n return s;\n }\n}\n;\n// deflate bit flag\nvar dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; };\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];\n};\n// read zip64 header sizes\nvar z64hs = function (d, b, l, z, sc, su, off) {\n var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;\n var nf = nsc + nsu + noff;\n if (z && nf) {\n for (; b + 4 < e; b += 4 + b2(d, b + 2)) {\n if (b2(d, b) == 1) {\n return [\n nsc ? b8(d, b + 4 + 8 * nsu) : sc,\n nsu ? b8(d, b + 4) : su,\n noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,\n 1\n ];\n }\n }\n // z == 2 for unknown whether or not zip64\n if (z < 2)\n err(13);\n }\n return [sc, su, off, 0];\n};\n// extra field length\nvar exfl = function (ex) {\n var le = 0;\n if (ex) {\n for (var k in ex) {\n var l = ex[k].length;\n if (l > 65535)\n err(9);\n le += l + 4;\n }\n }\n return le;\n};\n// write zip header\nvar wzh = function (d, b, f, fn, u, c, ce, co) {\n var fl = fn.length, ex = f.extra, col = co && co.length;\n var exl = exfl(ex);\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b++] = 20, d[b++] = f.os;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (f.flag << 1) | (c < 0 && 8), d[b++] = u && 8;\n d[b++] = f.compression & 255, d[b++] = f.compression >> 8;\n var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n err(10);\n wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >> 1)), b += 4;\n if (c != -1) {\n wbytes(d, b, f.crc);\n wbytes(d, b + 4, c < 0 ? -c - 2 : c);\n wbytes(d, b + 8, f.size);\n }\n wbytes(d, b + 12, fl);\n wbytes(d, b + 14, exl), b += 16;\n if (ce != null) {\n wbytes(d, b, col);\n wbytes(d, b + 6, f.attrs);\n wbytes(d, b + 10, ce), b += 14;\n }\n d.set(fn, b);\n b += fl;\n if (exl) {\n for (var k in ex) {\n var exf = ex[k], l = exf.length;\n wbytes(d, b, +k);\n wbytes(d, b + 2, l);\n d.set(exf, b + 4), b += 4 + l;\n }\n }\n if (col)\n d.set(co, b), b += col;\n return b;\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\n/**\n * A pass-through stream to keep data uncompressed in a ZIP archive.\n */\nvar ZipPassThrough = /*#__PURE__*/ (function () {\n /**\n * Creates a pass-through stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n */\n function ZipPassThrough(filename) {\n this.filename = filename;\n this.c = crc();\n this.size = 0;\n this.compression = 0;\n }\n /**\n * Processes a chunk and pushes to the output stream. You can override this\n * method in a subclass for custom behavior, but by default this passes\n * the data through. You must call this.ondata(err, chunk, final) at some\n * point in this method.\n * @param chunk The chunk to process\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.process = function (chunk, final) {\n this.ondata(null, chunk, final);\n };\n /**\n * Pushes a chunk to be added. If you are subclassing this with a custom\n * compression algorithm, note that you must push data from the source\n * file only, pre-compression.\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n this.c.p(chunk);\n this.size += chunk.length;\n if (final)\n this.crc = this.c.d();\n // we shouldn't really do this cast, but properly handling ArrayBufferLike\n // makes the API unergonomic with Buffer\n this.process(chunk, final || false);\n };\n return ZipPassThrough;\n}());\nexport { ZipPassThrough };\n// I don't extend because TypeScript extension adds 1kB of runtime bloat\n/**\n * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate\n * for better performance\n */\nvar ZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function ZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new Deflate(opts, function (dat, final) {\n _this.ondata(null, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n }\n ZipDeflate.prototype.process = function (chunk, final) {\n try {\n this.d.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return ZipDeflate;\n}());\nexport { ZipDeflate };\n/**\n * Asynchronous streaming DEFLATE compression for ZIP archives\n */\nvar AsyncZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function AsyncZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new AsyncDeflate(opts, function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n this.terminate = this.d.terminate;\n }\n AsyncZipDeflate.prototype.process = function (chunk, final) {\n this.d.push(chunk, final);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return AsyncZipDeflate;\n}());\nexport { AsyncZipDeflate };\n// TODO: Better tree shaking\n/**\n * A zippable archive to which files can incrementally be added\n */\nvar Zip = /*#__PURE__*/ (function () {\n /**\n * Creates an empty ZIP archive to which files can be added\n * @param cb The callback to call whenever data for the generated ZIP archive\n * is available\n */\n function Zip(cb) {\n this.ondata = cb;\n this.u = [];\n this.d = 1;\n }\n /**\n * Adds a file to the ZIP archive\n * @param file The file stream to add\n */\n Zip.prototype.add = function (file) {\n var _this = this;\n if (!this.ondata)\n err(5);\n // finishing or finished\n if (this.d & 2)\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false);\n else {\n var f = strToU8(file.filename), fl_1 = f.length;\n var com = file.comment, o = com && strToU8(com);\n var u = fl_1 != file.filename.length || (o && (com.length != o.length));\n var hl_1 = fl_1 + exfl(file.extra) + 30;\n if (fl_1 > 65535)\n this.ondata(err(11, 0, 1), null, false);\n var header = new u8(hl_1);\n wzh(header, 0, file, f, u, -1);\n var chks_1 = [header];\n var pAll_1 = function () {\n for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) {\n var chk = chks_2[_i];\n _this.ondata(null, chk, false);\n }\n chks_1 = [];\n };\n var tr_1 = this.d;\n this.d = 0;\n var ind_1 = this.u.length;\n var uf_1 = mrg(file, {\n f: f,\n u: u,\n o: o,\n t: function () {\n if (file.terminate)\n file.terminate();\n },\n r: function () {\n pAll_1();\n if (tr_1) {\n var nxt = _this.u[ind_1 + 1];\n if (nxt)\n nxt.r();\n else\n _this.d = 1;\n }\n tr_1 = 1;\n }\n });\n var cl_1 = 0;\n file.ondata = function (err, dat, final) {\n if (err) {\n _this.ondata(err, dat, final);\n _this.terminate();\n }\n else {\n cl_1 += dat.length;\n chks_1.push(dat);\n if (final) {\n var dd = new u8(16);\n wbytes(dd, 0, 0x8074B50);\n wbytes(dd, 4, file.crc);\n wbytes(dd, 8, cl_1);\n wbytes(dd, 12, file.size);\n chks_1.push(dd);\n uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size;\n if (tr_1)\n uf_1.r();\n tr_1 = 1;\n }\n else if (tr_1)\n pAll_1();\n }\n };\n this.u.push(uf_1);\n }\n };\n /**\n * Ends the process of adding files and prepares to emit the final chunks.\n * This *must* be called after adding all desired files for the resulting\n * ZIP file to work properly.\n */\n Zip.prototype.end = function () {\n var _this = this;\n if (this.d & 2) {\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true);\n return;\n }\n if (this.d)\n this.e();\n else\n this.u.push({\n r: function () {\n if (!(_this.d & 1))\n return;\n _this.u.splice(-1, 1);\n _this.e();\n },\n t: function () { }\n });\n this.d = 3;\n };\n Zip.prototype.e = function () {\n var bt = 0, l = 0, tl = 0;\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0);\n }\n var out = new u8(tl + 22);\n for (var _b = 0, _c = this.u; _b < _c.length; _b++) {\n var f = _c[_b];\n wzh(out, bt, f, f.f, f.u, -f.c - 2, l, f.o);\n bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b;\n }\n wzf(out, bt, this.u.length, tl, l);\n this.ondata(null, out, true);\n this.d = 2;\n };\n /**\n * A method to terminate any internal workers used by the stream. Subsequent\n * calls to add() will fail.\n */\n Zip.prototype.terminate = function () {\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n f.t();\n }\n this.d = 2;\n };\n return Zip;\n}());\nexport { Zip };\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n var l = f.c.length;\n wzh(out, tot, f, f.f, f.u, l);\n var badd = 30 + f.f.length + exfl(f.extra);\n var loc = tot + badd;\n out.set(f.c, loc);\n wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l;\n }\n catch (e) {\n return cbd(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cbd(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), size = file.length;\n c.p(file);\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n var compression = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n var l = d.length;\n files[i] = mrg(p, {\n size: size,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n compression: compression\n });\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n if (!--lft)\n cbf();\n }\n };\n if (s > 65535)\n cbl(err(11, 0, 1), null);\n if (!compression)\n cbl(null, file);\n else if (size < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (!opts)\n opts = {};\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var compression = p.level == 0 ? 0 : 8;\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n if (s > 65535)\n err(11);\n var d = compression ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push(mrg(p, {\n size: file.length,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n o: o,\n compression: compression\n }));\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f, f.f, f.u, f.c.length);\n var badd = 30 + f.f.length + exfl(f.extra);\n out.set(f.c, f.o + badd);\n wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Streaming pass-through decompression for ZIP archives\n */\nvar UnzipPassThrough = /*#__PURE__*/ (function () {\n function UnzipPassThrough() {\n }\n UnzipPassThrough.prototype.push = function (chunk, final) {\n // same as ZipPassThrough: cast to retain Buffer ergonomics\n this.ondata(null, chunk, final);\n };\n UnzipPassThrough.compression = 0;\n return UnzipPassThrough;\n}());\nexport { UnzipPassThrough };\n/**\n * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for\n * better performance.\n */\nvar UnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function UnzipInflate() {\n var _this = this;\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n UnzipInflate.prototype.push = function (chunk, final) {\n try {\n this.i.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n UnzipInflate.compression = 8;\n return UnzipInflate;\n}());\nexport { UnzipInflate };\n/**\n * Asynchronous streaming DEFLATE decompression for ZIP archives\n */\nvar AsyncUnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function AsyncUnzipInflate(_, sz) {\n var _this = this;\n if (sz < 320000) {\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n else {\n this.i = new AsyncInflate(function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.terminate = this.i.terminate;\n }\n }\n AsyncUnzipInflate.prototype.push = function (chunk, final) {\n if (this.i.terminate)\n chunk = slc(chunk, 0);\n this.i.push(chunk, final);\n };\n AsyncUnzipInflate.compression = 8;\n return AsyncUnzipInflate;\n}());\nexport { AsyncUnzipInflate };\n/**\n * A ZIP archive decompression stream that emits files as they are discovered\n */\nvar Unzip = /*#__PURE__*/ (function () {\n /**\n * Creates a ZIP decompression stream\n * @param cb The callback to call whenever a file in the ZIP archive is found\n */\n function Unzip(cb) {\n this.onfile = cb;\n this.k = [];\n this.o = {\n 0: UnzipPassThrough\n };\n this.p = et;\n }\n /**\n * Pushes a chunk to be unzipped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzip.prototype.push = function (chunk, final) {\n var _this = this;\n if (!this.onfile)\n err(5);\n if (!this.p)\n err(4);\n if (this.c > 0) {\n var len = Math.min(this.c, chunk.length);\n var toAdd = chunk.subarray(0, len);\n this.c -= len;\n if (this.d)\n this.d.push(toAdd, !this.c);\n else\n this.k[0].push(toAdd);\n chunk = chunk.subarray(len);\n if (chunk.length)\n return this.push(chunk, final);\n }\n else {\n var f = 0, i = 0, is = void 0, buf = void 0;\n if (!this.p.length)\n buf = chunk;\n else if (!chunk.length)\n buf = this.p;\n else {\n buf = new u8(this.p.length + chunk.length);\n buf.set(this.p), buf.set(chunk, this.p.length);\n }\n var l = buf.length, oc = this.c, add = oc && this.d;\n var _loop_2 = function () {\n var sig = b4(buf, i);\n if (sig == 0x4034B50) {\n f = 1, is = i;\n this_1.d = null;\n this_1.c = 0;\n var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);\n if (l > i + 30 + fnl + es) {\n var chks_3 = [];\n this_1.k.unshift(chks_3);\n f = 2;\n var lsc = b4(buf, i + 18), lsu = b4(buf, i + 22);\n var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);\n var _a = z64hs(buf, i, es, 2, lsc, lsu, 0), sc_1 = _a[0], su_1 = _a[1], z64 = _a[3];\n if (dd)\n sc_1 = -1 - z64;\n i += es;\n this_1.c = sc_1;\n var d_1;\n var file_1 = {\n name: fn_1,\n compression: cmp_1,\n start: function () {\n if (!file_1.ondata)\n err(5);\n if (!sc_1)\n file_1.ondata(null, et, true);\n else {\n var ctr = _this.o[cmp_1];\n if (!ctr)\n file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false);\n d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);\n d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); };\n for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {\n var dat = chks_4[_i];\n d_1.push(dat, false);\n }\n if (_this.k[0] == chks_3 && _this.c)\n _this.d = d_1;\n else\n d_1.push(et, true);\n }\n },\n terminate: function () {\n if (d_1 && d_1.terminate)\n d_1.terminate();\n }\n };\n if (sc_1 >= 0)\n file_1.size = sc_1, file_1.originalSize = su_1;\n this_1.onfile(file_1);\n }\n return \"break\";\n }\n else if (oc) {\n if (sig == 0x8074B50) {\n is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;\n return \"break\";\n }\n else if (sig == 0x2014B50) {\n is = i -= 4, f = 3, this_1.c = 0;\n return \"break\";\n }\n }\n };\n var this_1 = this;\n for (; i < l - 4; ++i) {\n var state_1 = _loop_2();\n if (state_1 === \"break\")\n break;\n }\n this.p = et;\n if (oc < 0) {\n var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i);\n if (add)\n add.push(dat, !!f);\n else\n this.k[+(f == 2)].push(dat);\n }\n if (f & 2)\n return this.push(buf.subarray(i), final);\n this.p = buf.subarray(i);\n }\n if (final) {\n if (this.c)\n err(13);\n this.p = null;\n }\n };\n /**\n * Registers a decoder with the stream, allowing for files compressed with\n * the compression type provided to be expanded correctly\n * @param decoder The decoder constructor\n */\n Unzip.prototype.register = function (decoder) {\n this.o[decoder.compression] = decoder;\n };\n return Unzip;\n}());\nexport { Unzip };\nvar mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); };\nexport function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n // Synchronously decompress under 512KB, or barely-compressed data\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl(err(14, 'unknown compression type ' + c_1, 1), null);\n }\n else\n cbl(null, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_3(i);\n }\n }\n else\n cbd(null, {});\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @param opts The ZIP extraction options\n * @returns The decompressed files\n */\nexport function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, 'unknown compression type ' + c_2);\n }\n }\n return files;\n}\n","import { unzipSync, zipSync } from \"fflate\";\n\n/** Minimal file-like handle so zip entries can stand in for `File` objects. */\nexport interface ZipFile {\n\tarrayBuffer(): Promise<ArrayBuffer>;\n}\n\n/**\n * Extracts a zip archive into a flat path → file map, mirroring the shape of\n * `webkitdirectory` file lists so the converter can treat both sources the same.\n *\n * Many UTAU voicebank zips are packed on Windows without the UTF-8 flag, so\n * entry names are Shift_JIS bytes. fflate decodes those as latin1 (1 byte =\n * 1 code point) rather than mangling them, so we can losslessly recover the\n * original bytes and re-decode with the right encoding per entry.\n */\nexport function unzipToFileMap(\n\tdata: ArrayBuffer,\n): Promise<Record<string, ZipFile>> {\n\tconst bytes = new Uint8Array(data);\n\tconst unzipped = unzipSync(bytes);\n\tconst isUtf8ByIndex = readUtf8Flags(bytes);\n\tconst sjisDecoder = new TextDecoder(\"shift_jis\");\n\n\tconst fileMap: Record<string, ZipFile> = {};\n\tObject.keys(unzipped).forEach((rawName, i) => {\n\t\tconst fileBytes = unzipped[rawName];\n\t\tconst name = isUtf8ByIndex[i]\n\t\t\t? rawName\n\t\t\t: sjisDecoder.decode(Uint8Array.from(rawName, (c) => c.charCodeAt(0)));\n\t\tconst path = name.replace(/\\\\/g, \"/\");\n\t\tif (path.endsWith(\"/\")) return; // directory entry\n\t\tfileMap[path] = {\n\t\t\tarrayBuffer: () =>\n\t\t\t\tPromise.resolve(\n\t\t\t\t\tfileBytes.buffer.slice(\n\t\t\t\t\t\tfileBytes.byteOffset,\n\t\t\t\t\t\tfileBytes.byteOffset + fileBytes.byteLength,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t};\n\t});\n\treturn Promise.resolve(fileMap);\n}\n\n/** Walks the central directory to read the UTF-8 language flag (bit 11) of each entry, in order. */\nfunction readUtf8Flags(buf: Uint8Array): boolean[] {\n\tconst view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n\n\tlet eocd = -1;\n\tconst maxBack = Math.min(buf.length, 65557); // 22 + max comment length\n\tfor (let i = buf.length - 22; i >= buf.length - maxBack && i >= 0; i--) {\n\t\tif (view.getUint32(i, true) === 0x06054b50) {\n\t\t\teocd = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (eocd < 0) return [];\n\n\tconst entryCount = view.getUint16(eocd + 10, true);\n\tlet cdOffset = view.getUint32(eocd + 16, true);\n\n\tconst flags: boolean[] = [];\n\tfor (let i = 0; i < entryCount; i++) {\n\t\tif (view.getUint32(cdOffset, true) !== 0x02014b50) break;\n\t\tconst flag = view.getUint16(cdOffset + 8, true);\n\t\tconst nameLen = view.getUint16(cdOffset + 28, true);\n\t\tconst extraLen = view.getUint16(cdOffset + 30, true);\n\t\tconst commentLen = view.getUint16(cdOffset + 32, true);\n\t\tflags.push((flag & 0x800) !== 0);\n\t\tcdOffset += 46 + nameLen + extraLen + commentLen;\n\t}\n\treturn flags;\n}\n\n/**\n * Pack a path → bytes map into a zip Blob.\n *\n * Entry names are written as UTF-8 with the language flag set, which is what\n * every current unzip tool reads — including Windows Explorer, so a bank whose\n * folders are named in Japanese comes back out intact.\n */\nexport function zipFiles(files: Record<string, Uint8Array>): Blob {\n\tconst packed = zipSync(files, { level: 6 });\n\tconst bytes = new Uint8Array(packed.length);\n\tbytes.set(packed);\n\treturn new Blob([bytes], { type: \"application/zip\" });\n}\n","import type { Manifest } from \"./types.js\";\n\n/** Magic number 'KOE\\0' (stored big-endian as 0x4B 0x4F 0x45 0x00). */\nconst MAGIC = 0x4b4f4500;\n\n/**\n * Koe Archive Format (.koe)\n * [4B] magic 'KOE\\0' (big-endian)\n * [4B] JSON length (little-endian)\n * [N ] manifest JSON (UTF-8)\n * [M ] raw PCM (Int16 / 48kHz / mono); phoneme offsets are relative to here\n */\nexport function packKoe(manifest: Manifest, pcmParts: BlobPart[]): Blob {\n\tconst json = new TextEncoder().encode(JSON.stringify(manifest));\n\tconst header = new ArrayBuffer(8);\n\tconst view = new DataView(header);\n\tview.setUint32(0, MAGIC, false); // magic, big-endian\n\tview.setUint32(4, json.byteLength, true); // json length, little-endian\n\treturn new Blob([header, json, ...pcmParts]);\n}\n\n/** Read the 8-byte header → JSON length. Throws on bad magic. */\nexport function parseKoeHeader(headerBytes: ArrayBuffer): {\n\tjsonLength: number;\n} {\n\tconst view = new DataView(headerBytes);\n\tif (view.byteLength < 8 || view.getUint32(0, false) !== MAGIC) {\n\t\tthrow new Error(\"Not a .koe file (bad magic)\");\n\t}\n\treturn { jsonLength: view.getUint32(4, true) };\n}\n\n/** Byte offset where PCM data begins, given the JSON length. */\nexport const pcmBase = (jsonLength: number): number => 8 + jsonLength;\n","import { parseKoeHeader, pcmBase } from \"../koe.js\";\nimport type { Manifest } from \"../types.js\";\n\n/**\n * Supplies raw bytes from the PCM section of a .koe archive on demand.\n * - BlobVoiceSource: slices an in-memory Blob / File (no full-buffer copy)\n * - RangeVoiceSource: HTTP Range requests against a URL (mobile-friendly)\n * `base` is the byte offset where PCM data starts (8 + jsonLength).\n */\ninterface VoiceSource {\n\treadBytes(offset: number, length: number): Promise<ArrayBuffer>;\n}\n\n/** Hard ceiling on a single phoneme's PCM size (~10.5 MB / ~55s at 48kHz). */\nconst MAX_PHONEME_SAMPLES = 5_242_880;\n/** Hard ceiling on the manifest JSON header itself. */\nconst MAX_JSON_LENGTH = 50 * 1024 * 1024;\n\nclass BlobVoiceSource implements VoiceSource {\n\tconstructor(\n\t\tprivate blob: Blob,\n\t\tprivate base: number,\n\t) {}\n\treadBytes(offset: number, length: number): Promise<ArrayBuffer> {\n\t\tconst start = this.base + offset;\n\t\treturn this.blob.slice(start, start + length).arrayBuffer();\n\t}\n}\n\nclass RangeVoiceSource implements VoiceSource {\n\tconstructor(\n\t\tprivate url: string,\n\t\tprivate base: number,\n\t) {}\n\tasync readBytes(offset: number, length: number): Promise<ArrayBuffer> {\n\t\tconst start = this.base + offset;\n\t\treturn rangeFetch(this.url, start, length);\n\t}\n}\n\nasync function rangeFetch(\n\turl: string,\n\tstart: number,\n\tlength: number,\n): Promise<ArrayBuffer> {\n\tconst res = await fetch(url, {\n\t\theaders: { Range: `bytes=${start}-${start + length - 1}` },\n\t\tcredentials: \"omit\", // never leak cookies / auth to a MML-supplied URL\n\t});\n\t// A server that ignores Range and returns 200 with the full file would\n\t// blow past the requested size and exhaust memory; only accept 206.\n\tif (res.status !== 206) {\n\t\tthrow new Error(\n\t\t\t`.koe fetch failed: expected 206 Partial Content, got ${res.status}`,\n\t\t);\n\t}\n\treturn readCapped(res, length);\n}\n\n/**\n * Read a response body without trusting its declared size: a server can answer\n * 206 yet still stream an oversized body. Abort as soon as the read exceeds\n * the requested byte count, before buffering the excess.\n */\nasync function readCapped(res: Response, length: number): Promise<ArrayBuffer> {\n\tconst reader = res.body?.getReader();\n\tif (!reader) {\n\t\tconst buf = await res.arrayBuffer();\n\t\tif (buf.byteLength > length) {\n\t\t\tthrow new Error(\n\t\t\t\t`.koe fetch failed: response exceeds requested ${length} bytes`,\n\t\t\t);\n\t\t}\n\t\treturn buf;\n\t}\n\tconst out = new Uint8Array(length);\n\tlet received = 0;\n\tfor (;;) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tif (received + value.byteLength > length) {\n\t\t\tawait reader.cancel();\n\t\t\tthrow new Error(\n\t\t\t\t`.koe fetch failed: response exceeds requested ${length} bytes`,\n\t\t\t);\n\t\t}\n\t\tout.set(value, received);\n\t\treceived += value.byteLength;\n\t}\n\treturn received === length ? out.buffer : out.buffer.slice(0, received);\n}\n\nfunction validateJsonLength(jsonLength: number): void {\n\tif (\n\t\t!Number.isInteger(jsonLength) ||\n\t\tjsonLength < 0 ||\n\t\tjsonLength > MAX_JSON_LENGTH\n\t) {\n\t\tthrow new Error(`manifest JSON length out of bounds: ${jsonLength}`);\n\t}\n}\n\nfunction parseManifest(json: ArrayBuffer): Manifest {\n\tconst manifest = JSON.parse(new TextDecoder().decode(json)) as Manifest;\n\tif (\n\t\t!manifest ||\n\t\ttypeof manifest !== \"object\" ||\n\t\ttypeof manifest.phonemes !== \"object\" ||\n\t\tmanifest.phonemes === null\n\t) {\n\t\tthrow new Error(\"invalid manifest: missing phonemes table\");\n\t}\n\treturn manifest;\n}\n\n/**\n * Read-only access to a .koe voice bank: its manifest plus per-phoneme PCM,\n * fetched on demand (Blob slice or HTTP Range). The full bank is never held in\n * memory.\n *\n * Pure data — no AudioContext, no AudioWorklet, no DOM. Use this when you only\n * need the source samples (e.g. to feed the {@link Worldline} renderer or any\n * other vocoder). {@link KoeEngine} builds its concatenative playback on top of\n * this same class.\n *\n * const bank = await VoiceBank.load(koeBlobOrUrl);\n * const pcm = await bank.getPcm('a'); // Float64 [-1, 1]\n */\nexport class VoiceBank {\n\tprivate constructor(\n\t\t/** The voice bank manifest (sample rate, reference pitch, phoneme table). */\n\t\treadonly manifest: Manifest,\n\t\tprivate source: VoiceSource,\n\t) {}\n\n\t/**\n\t * Parse a .koe archive header + manifest and bind a lazy PCM source.\n\t * @param koe a Blob/File of the .koe archive, or a URL (served with Range support)\n\t */\n\tstatic async load(koe: Blob | string): Promise<VoiceBank> {\n\t\ttry {\n\t\t\tif (typeof koe === \"string\") {\n\t\t\t\t// Range requests on blob: URLs are not portable (Firefox/Safari answer\n\t\t\t\t// 200); the data already lives in memory, so read it back as a Blob.\n\t\t\t\tif (/^blob:/i.test(koe)) {\n\t\t\t\t\tconst res = await fetch(koe);\n\t\t\t\t\tif (!res.ok) {\n\t\t\t\t\t\tthrow new Error(`blob: URL fetch failed: ${res.status}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn await VoiceBank.fromBlob(await res.blob());\n\t\t\t\t}\n\t\t\t\tif (!/^https?:/i.test(koe)) {\n\t\t\t\t\tthrow new Error(`unsupported URL protocol: ${koe}`);\n\t\t\t\t}\n\t\t\t\tconst header = await rangeFetch(koe, 0, 8);\n\t\t\t\tconst { jsonLength } = parseKoeHeader(header);\n\t\t\t\tvalidateJsonLength(jsonLength);\n\t\t\t\tconst json = await rangeFetch(koe, 8, jsonLength);\n\t\t\t\tconst manifest = parseManifest(json);\n\t\t\t\treturn new VoiceBank(\n\t\t\t\t\tmanifest,\n\t\t\t\t\tnew RangeVoiceSource(koe, pcmBase(jsonLength)),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn await VoiceBank.fromBlob(koe);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to load .koe voice bank: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate static async fromBlob(koe: Blob): Promise<VoiceBank> {\n\t\tconst header = await koe.slice(0, 8).arrayBuffer();\n\t\tconst { jsonLength } = parseKoeHeader(header);\n\t\tvalidateJsonLength(jsonLength);\n\t\tconst json = await koe.slice(8, 8 + jsonLength).arrayBuffer();\n\t\tconst manifest = parseManifest(json);\n\t\treturn new VoiceBank(\n\t\t\tmanifest,\n\t\t\tnew BlobVoiceSource(koe, pcmBase(jsonLength)),\n\t\t);\n\t}\n\n\t/** True if the bank contains a phoneme under this alias. */\n\thas(phoneme: string): boolean {\n\t\t// Own-property check: a plain [phoneme] access would also match inherited\n\t\t// Object.prototype keys like \"toString\" / \"constructor\".\n\t\treturn Object.hasOwn(this.manifest.phonemes, phoneme);\n\t}\n\n\t/**\n\t * Raw Int16 PCM bytes (48 kHz / mono) for a phoneme, or null if unknown.\n\t * The returned ArrayBuffer is freshly allocated and safe to transfer to a\n\t * worker / AudioWorklet.\n\t */\n\tasync readPcmBytes(phoneme: string): Promise<ArrayBuffer | null> {\n\t\tif (!Object.hasOwn(this.manifest.phonemes, phoneme)) return null;\n\t\tconst entry = this.manifest.phonemes[phoneme];\n\t\tif (\n\t\t\t!Number.isInteger(entry.offset) ||\n\t\t\t!Number.isInteger(entry.length) ||\n\t\t\tentry.offset < 0 ||\n\t\t\tentry.length < 0 ||\n\t\t\tentry.length > MAX_PHONEME_SAMPLES\n\t\t) {\n\t\t\tthrow new Error(`manifest entry out of bounds for phoneme: ${phoneme}`);\n\t\t}\n\t\treturn this.source.readBytes(entry.offset, entry.length * 2); // Int16 = 2 bytes/sample\n\t}\n\n\t/**\n\t * A phoneme's PCM as a Float64Array normalised to [-1, 1], or null if unknown.\n\t * Intended for external analysis / resynthesis such as the WORLD vocoder.\n\t */\n\tasync getPcm(phoneme: string): Promise<Float64Array | null> {\n\t\tconst buf = await this.readPcmBytes(phoneme);\n\t\tif (!buf) return null;\n\t\t// A truncated read (Blob clamped at EOF) can yield an odd byte count,\n\t\t// which the Int16Array(buffer) constructor rejects — floor to whole samples.\n\t\tconst int16 = new Int16Array(buf, 0, Math.floor(buf.byteLength / 2));\n\t\tconst f64 = new Float64Array(int16.length);\n\t\tfor (let i = 0; i < int16.length; i++) f64[i] = int16[i] / 32768;\n\t\treturn f64;\n\t}\n}\n","import type { Manifest, NoteEvent } from \"../types.js\";\r\nimport { VoiceBank } from \"./voice-bank.js\";\r\n\r\nexport type { NoteEvent };\r\n\r\nexport interface KoeEngineOptions {\r\n\t/** URL to koe-worklet.js. Defaults to './koe-worklet.js'. */\r\n\tworkletUrl?: string;\r\n}\r\n\r\nexport interface PlayOptions {\r\n\t/**\r\n\t * Play the first note's lead-in (its consonant / preutterance region) instead\r\n\t * of skipping straight to the vowel.\r\n\t *\r\n\t * Every note but the first gets its lead-in from the crossfade with the note\r\n\t * before it. The first note has no predecessor, so the lead-in has to come\r\n\t * from somewhere: with `leadIn` the phrase starts one preutterance EARLIER\r\n\t * relative to its beats, and {@link KoeEngine.play} returns that offset in\r\n\t * samples so a sequencer can schedule around it. Left off (the default), the\r\n\t * first note keeps its beat exactly but opens on its vowel, dropping the\r\n\t * consonant.\r\n\t */\r\n\tleadIn?: boolean;\r\n}\r\n\r\n/**\r\n * Main-thread API for the koe concatenative synthesis engine.\r\n *\r\n * Loads a single .koe archive. The full voice bank is never held in memory:\r\n * phonemes are fetched on demand (via {@link VoiceBank}) and cached in the\r\n * audio thread.\r\n *\r\n * const engine = new KoeEngine();\r\n * await engine.load(koeBlobOrUrl);\r\n * await engine.play([{ phoneme: 'a', pitch: 440, duration: 48000 }]);\r\n *\r\n * For analysis / resynthesis (e.g. {@link Worldline}) you usually only need the\r\n * raw samples — use {@link VoiceBank} directly instead, which needs no\r\n * AudioContext or worklet.\r\n */\r\nexport class KoeEngine {\r\n\tprivate ctx: AudioContext;\r\n\tprivate workletUrl: string;\r\n\tprivate node: AudioWorkletNode | null = null;\r\n\tprivate bank: VoiceBank | null = null;\r\n\tprivate delivered = new Set<string>();\r\n\tprivate pending = new Map<string, Promise<void>>();\r\n\r\n\tconstructor(options: KoeEngineOptions = {}) {\r\n\t\tthis.ctx = new AudioContext({ sampleRate: 48000 });\r\n\t\tthis.workletUrl = options.workletUrl ?? \"./koe-worklet.js\";\r\n\t}\r\n\r\n\tget audioContext(): AudioContext {\r\n\t\treturn this.ctx;\r\n\t}\r\n\r\n\tget manifest(): Manifest | null {\r\n\t\treturn this.bank?.manifest ?? null;\r\n\t}\r\n\r\n\t/** The underlying voice bank (manifest + on-demand PCM), or null before load(). */\r\n\tget voiceBank(): VoiceBank | null {\r\n\t\treturn this.bank;\r\n\t}\r\n\r\n\t/**\r\n\t * Register the worklet and bind a .koe voice bank.\r\n\t * @param koe a Blob/File of the .koe archive, or a URL (served with Range support)\r\n\t */\r\n\tasync load(koe: Blob | string): Promise<void> {\r\n\t\tawait this.ctx.audioWorklet.addModule(this.workletUrl);\r\n\r\n\t\t// Re-loading: tear down the previous node, or both would keep playing.\r\n\t\tthis.node?.disconnect();\r\n\t\tthis.node = null;\r\n\r\n\t\tthis.bank = await VoiceBank.load(koe);\r\n\t\tthis.delivered.clear();\r\n\t\tthis.pending.clear();\r\n\r\n\t\tthis.node = new AudioWorkletNode(this.ctx, \"koe-processor\", {\r\n\t\t\tnumberOfInputs: 0,\r\n\t\t\tnumberOfOutputs: 1,\r\n\t\t\toutputChannelCount: [1],\r\n\t\t});\r\n\t\tthis.node.port.postMessage({ type: \"init\", manifest: this.bank.manifest });\r\n\t\tthis.node.connect(this.ctx.destination);\r\n\r\n\t\tconsole.log(\r\n\t\t\t\"[koe] ready —\",\r\n\t\t\tObject.keys(this.bank.manifest.phonemes).length,\r\n\t\t\t\"phonemes (on-demand)\",\r\n\t\t);\r\n\t}\r\n\r\n\t/** Fetch one phoneme's PCM and deliver it to the worklet (deduped, cached). */\r\n\tprivate ensurePhoneme(name: string): Promise<void> {\r\n\t\tif (this.delivered.has(name)) return Promise.resolve();\r\n\t\tconst existing = this.pending.get(name);\r\n\t\tif (existing) return existing;\r\n\t\tif (!this.bank || !this.node) return Promise.resolve();\r\n\r\n\t\tconst load = this.bank\r\n\t\t\t.readPcmBytes(name)\r\n\t\t\t.then((buf) => {\r\n\t\t\t\tif (!buf || !this.node) return;\r\n\t\t\t\tthis.node.port.postMessage({ type: \"phoneme\", name, buffer: buf }, [\r\n\t\t\t\t\tbuf,\r\n\t\t\t\t]);\r\n\t\t\t\tthis.delivered.add(name);\r\n\t\t\t})\r\n\t\t\t.finally(() => {\r\n\t\t\t\t// Always clear pending — a failed fetch must stay retryable, or the\r\n\t\t\t\t// rejected promise would poison every later play() of this phoneme.\r\n\t\t\t\tthis.pending.delete(name);\r\n\t\t\t});\r\n\r\n\t\tthis.pending.set(name, load);\r\n\t\treturn load;\r\n\t}\r\n\r\n\t/**\r\n\t * Stop current playback, preload the phonemes for `notes`, then queue them.\r\n\t *\r\n\t * @returns the lead-in offset in samples — how far the first note's audio\r\n\t * starts ahead of its beat. 0 unless {@link PlayOptions.leadIn}.\r\n\t */\r\n\tasync play(notes: NoteEvent[], options: PlayOptions = {}): Promise<number> {\r\n\t\tif (!this.node) throw new Error(\"KoeEngine: call load() before play()\");\r\n\t\tthis.node.port.postMessage({ type: \"stop\" });\r\n\t\tconst names = [...new Set(notes.map((n) => n.phoneme))].filter(Boolean);\r\n\t\tawait Promise.all(names.map((n) => this.ensurePhoneme(n)));\r\n\t\tconst leadIn = options.leadIn === true;\r\n\t\tthis.node.port.postMessage({ type: \"play\", notes, leadIn });\r\n\t\treturn leadIn ? this.leadInSamples(notes) : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Output samples the first note's lead-in occupies ahead of its beat —\r\n\t * mirrors what the worklet does with `leadIn`, so callers can compensate.\r\n\t */\r\n\tprivate leadInSamples(notes: NoteEvent[]): number {\r\n\t\tconst first = notes[0];\r\n\t\tconst m = this.bank?.manifest;\r\n\t\tif (!first || !m || first.phoneme === \"\") return 0;\r\n\t\tconst entry = Object.hasOwn(m.phonemes, first.phoneme)\r\n\t\t\t? m.phonemes[first.phoneme]\r\n\t\t\t: undefined;\r\n\t\tif (!entry || entry.length <= 0) return 0;\r\n\t\tconst recorded = entry.pitch || m.referencePitch || first.pitch || 1;\r\n\t\tconst stepRate = first.pitch / recorded;\r\n\t\treturn stepRate > 0 ? entry.pre / stepRate : 0;\r\n\t}\r\n\r\n\t/** Stop playback and clear the queue. */\r\n\tstop(): void {\r\n\t\tthis.node?.port.postMessage({ type: \"stop\" });\r\n\t}\r\n\r\n\t/** Resume the AudioContext if suspended (e.g. after autoplay block). */\r\n\tasync resume(): Promise<void> {\r\n\t\tif (this.ctx.state === \"suspended\") await this.ctx.resume();\r\n\t}\r\n\r\n\t/**\r\n\t * Tear down the worklet node and close the AudioContext, releasing the audio\r\n\t * hardware. The engine cannot be reused afterwards — create a new one.\r\n\t */\r\n\tasync dispose(): Promise<void> {\r\n\t\tthis.node?.disconnect();\r\n\t\tthis.node = null;\r\n\t\tthis.bank = null;\r\n\t\tthis.delivered.clear();\r\n\t\tthis.pending.clear();\r\n\t\tif (this.ctx.state !== \"closed\") await this.ctx.close();\r\n\t}\r\n\r\n\t/**\r\n\t * Read a phoneme's raw PCM and return it as a Float64Array normalised to\r\n\t * [-1, 1]. Convenience that forwards to the underlying {@link VoiceBank}.\r\n\t * Intended for external analysis such as the WORLD vocoder.\r\n\t */\r\n\tasync getPcm(phoneme: string): Promise<Float64Array | null> {\r\n\t\treturn this.bank?.getPcm(phoneme) ?? null;\r\n\t}\r\n}\r\n","import type { PhonemeEntry } from \"../types.js\";\n\n/** Output sample rate of the worldline synthesizer. */\nexport const WORLDLINE_SAMPLE_RATE = 48000;\n\n/**\n * WORLD needs roughly 85 ms of audio for stable F0 analysis. Phonemes with\n * fewer samples than this are rejected (renderNote returns null).\n */\nexport const MIN_WORLDLINE_SAMPLES = 4096;\n\n/** SynthRequest struct layout — 120 bytes, WASM32. */\nconst SYNTH_REQ_SIZE = 120;\n/** Frame period hardcoded in worldline's phrase_synth.cpp. */\nconst WL_FRAME_MS = 10;\n\n/**\n * The subset of the Emscripten module surface that we call. worldline.js is an\n * MODULARIZE=1 / EXPORT_NAME=WorldlineModule build of OpenUtau's worldline.\n */\ninterface WorldlineWasm {\n\t_PhraseSynthNew(): number;\n\t_PhraseSynthDelete(ps: number): void;\n\t_PhraseSynthAddRequest(\n\t\tps: number,\n\t\treq: number,\n\t\tposMs: number,\n\t\tskipMs: number,\n\t\tlengthMs: number,\n\t\tfadeInMs: number,\n\t\tfadeOutMs: number,\n\t\tflag: number,\n\t): void;\n\t_PhraseSynthSetCurves(\n\t\tps: number,\n\t\tf0: number,\n\t\tgender: number,\n\t\ttension: number,\n\t\tbreathiness: number,\n\t\tvoicing: number,\n\t\tlength: number,\n\t\tframeMs: number,\n\t): void;\n\t_PhraseSynthSynth(ps: number, yPtrPtr: number, flag: number): number;\n\t_malloc(size: number): number;\n\t_free(ptr: number): void;\n\tsetValue(ptr: number, value: number, type: string): void;\n\tgetValue(ptr: number, type: string): number;\n\tHEAPF32: Float32Array;\n\tHEAPF64: Float64Array;\n}\n\ntype WorldlineFactory = (opts?: {\n\tlocateFile?: (path: string) => string;\n}) => Promise<WorldlineWasm>;\n\ndeclare global {\n\t// Injected by worldline.js when loaded as a classic <script> or via importScripts.\n\t// eslint-disable-next-line no-var\n\tvar WorldlineModule: WorldlineFactory | undefined;\n\t// Present in classic Web Workers (used to load worldline.js off the main thread).\n\t// eslint-disable-next-line no-var\n\tvar importScripts: ((...urls: string[]) => void) | undefined;\n}\n\nexport interface WorldlineLoadOptions {\n\t/**\n\t * URL of `worldline.js` (the Emscripten loader). The matching\n\t * `worldline.wasm` must sit next to it — it is resolved relative to this URL.\n\t *\n\t * When consuming koe from npm + a CDN this is typically e.g.\n\t * `https://cdn.jsdelivr.net/npm/@onjmin/koe/dist/world/worldline.js`, or your\n\t * own hosted copy of `dist/world/`.\n\t */\n\tscriptUrl: string;\n}\n\n/**\n * A per-frame expression value: either a flat constant for the whole note, or\n * a function evaluated once per 10ms WORLD frame for a custom curve (vibrato,\n * portamento, scoop-in, humanize jitter, hand-drawn automation, …).\n *\n * `tMs` is elapsed time from the start of the rendered buffer (0 = includes\n * the `preMs` lead-in), `totalMs` is the full rendered length (`preMs +\n * durationMs`). Callers own all curve shaping — worldline itself has no\n * opinion on what \"vibrato\" or \"scoop\" means, it just samples whatever\n * function you give it once per frame.\n */\nexport type CurveInput = number | ((tMs: number, totalMs: number) => number);\n\nconst sampleCurve = (\n\tinput: number,\n\tcurve: CurveInput,\n\ttotalMs: number,\n): number => (typeof curve === \"function\" ? curve(input, totalMs) : curve);\n\n/**\n * One sample placed on a phrase timeline (mirrors worldline's\n * `PhraseSynth::AddRequest` + the UTAU `SynthRequest` fields that matter for\n * speech). All times are ms.\n */\nexport interface PhraseUnit {\n\tpcm: Float64Array;\n\t/** Where the (offset-trimmed) sample head is placed on the phrase timeline. */\n\tposMs: number;\n\t/** Leading part of the resampled sample to skip before `posMs`. */\n\tskipMs: number;\n\t/** How much of the resampled sample is used from `posMs`. */\n\tlengthMs: number;\n\tfadeInMs: number;\n\tfadeOutMs: number;\n\t/** Fixed (unstretched) consonant region of the sample. */\n\tconsonantMs: number;\n\t/** Trim from the sample tail; defaults to two WORLD frames. */\n\tcutMs?: number;\n\t/**\n\t * UTAU \"required length\": the resampler stretches the sample to this total\n\t * length (consonant kept, vowel stretched). Defaults to `lengthMs`. UtauTTS\n\t * rounds it up to 50 ms steps so the vowel loop has slack for the release.\n\t */\n\trequiredLengthMs?: number;\n\t/** UTAU volume, 100 = unity. */\n\tvolume?: number;\n\t/**\n\t * MIDI note the resampler targets before the F0 curve is applied. Pick the\n\t * note closest to the sample's own pitch to keep the formant shift minimal.\n\t */\n\ttone?: number;\n}\n\nexport interface RenderPhraseParams {\n\tunits: PhraseUnit[];\n\tpitch: CurveInput;\n\tgender?: CurveInput;\n\ttension?: CurveInput;\n\tbreathiness?: CurveInput;\n\tvoicing?: CurveInput;\n\ttempo?: number;\n}\n\nexport interface RenderNoteParams {\n\t/**\n\t * Source phoneme PCM normalised to [-1, 1] (e.g. from\n\t * `VoiceBank.getPcm()` / `KoeEngine.getPcm()`).\n\t */\n\tpcm: Float64Array;\n\t/**\n\t * Target output pitch in Hz. Pass a function for vibrato, portamento,\n\t * scoop-in, pitch-drift humanize, etc. — it is sampled once per 10ms frame.\n\t */\n\tpitch: CurveInput;\n\t/** Sustain / vowel duration in ms (the lead-in below is rendered on top). */\n\tdurationMs: number;\n\t/** Preutterance / lead-in in ms — convert from {@link PhonemeEntry.pre}. */\n\tpreMs: number;\n\t/** Consonant length in ms — convert from {@link PhonemeEntry.consonant}. */\n\tconsonantMs: number;\n\t/** Reference tempo in BPM for worldline's internal timing. Default 120. */\n\ttempo?: number;\n\t/**\n\t * Formant/gender shift, 0-1. 0.5 (default) = unmodified. Below 0.5 skews\n\t * toward a lower/thicker formant (older, huskier); above 0.5 toward a\n\t * higher/thinner one (younger, brighter) — pitch itself is unaffected.\n\t */\n\tgender?: CurveInput;\n\t/**\n\t * Tension, 0-1. 0.5 (default) = neutral. Higher = tighter/more strained\n\t * (\"こぶし\"-style push); lower = more relaxed/breathy-adjacent.\n\t */\n\ttension?: CurveInput;\n\t/** Breathiness, 0-1. 0.5 (default) = neutral. Higher = airier/whispered. */\n\tbreathiness?: CurveInput;\n\t/**\n\t * Voicing ratio, 0-1. 1.0 (default) = fully voiced. Lower blends toward an\n\t * unvoiced/falsetto-adjacent texture.\n\t */\n\tvoicing?: CurveInput;\n}\n\n/** Convert a sample count at 48 kHz to milliseconds. */\nexport const samplesToMs = (samples: number): number =>\n\t(samples / WORLDLINE_SAMPLE_RATE) * 1000;\n\n/**\n * Derive {@link RenderNoteParams} lead-in / consonant fields from a manifest\n * entry, so callers don't repeat the sample→ms conversion.\n *\n * const params = { pcm, pitch, durationMs, ...leadInFromEntry(entry) };\n */\nexport function leadInFromEntry(entry: PhonemeEntry): {\n\tpreMs: number;\n\tconsonantMs: number;\n} {\n\treturn {\n\t\tpreMs: samplesToMs(entry.pre || 0),\n\t\tconsonantMs: samplesToMs(entry.consonant || 0),\n\t};\n}\n\n// Cache module factories by script URL so repeated loads share one WASM instance.\nconst moduleCache = new Map<string, Promise<WorldlineWasm>>();\n\nfunction injectScript(src: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst existing = document.querySelector<HTMLScriptElement>(\n\t\t\t`script[data-koe-worldline=\"${src}\"]`,\n\t\t);\n\t\tif (existing) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tconst s = document.createElement(\"script\");\n\t\ts.src = src;\n\t\ts.dataset.koeWorldline = src;\n\t\ts.onload = () => resolve();\n\t\ts.onerror = () => reject(new Error(`worldline: failed to load ${src}`));\n\t\tdocument.head.appendChild(s);\n\t});\n}\n\nfunction loadWasm(scriptUrl: string): Promise<WorldlineWasm> {\n\tconst cached = moduleCache.get(scriptUrl);\n\tif (cached) return cached;\n\n\tconst baseUrl = scriptUrl.slice(0, scriptUrl.lastIndexOf(\"/\") + 1);\n\tconst instantiate = (): Promise<WorldlineWasm> => {\n\t\tconst factory = globalThis.WorldlineModule;\n\t\tif (!factory)\n\t\t\tthrow new Error(\n\t\t\t\t\"worldline: WorldlineModule global was not defined by the script\",\n\t\t\t);\n\t\t// locateFile resolves worldline.wasm next to the script; fetch works in both\n\t\t// the DOM and Web Workers, so the WASM instantiates the same way off-thread.\n\t\treturn factory({ locateFile: (f: string) => baseUrl + f });\n\t};\n\n\tlet promise: Promise<WorldlineWasm>;\n\tif (typeof document !== \"undefined\") {\n\t\t// Main thread / DOM: load worldline.js via a <script> tag.\n\t\tpromise = injectScript(scriptUrl).then(instantiate);\n\t} else if (typeof globalThis.importScripts === \"function\") {\n\t\t// Classic Web Worker: importScripts runs worldline.js synchronously in the\n\t\t// worker's global scope, defining globalThis.WorldlineModule. This lets the\n\t\t// heavy WORLD synthesis run off the main thread.\n\t\tpromise = Promise.resolve().then(() => {\n\t\t\t(globalThis.importScripts as (...urls: string[]) => void)(scriptUrl);\n\t\t\treturn instantiate();\n\t\t});\n\t} else {\n\t\treturn Promise.reject(\n\t\t\tnew Error(\n\t\t\t\t\"Worldline.load requires a DOM or a classic Web Worker (importScripts) to load worldline.js\",\n\t\t\t),\n\t\t);\n\t}\n\tmoduleCache.set(scriptUrl, promise);\n\treturn promise;\n}\n\n/**\n * High-quality WORLD-vocoder note renderer (OpenUtau's worldline via WASM).\n *\n * Pure synthesis: PCM in → PCM out. No AudioContext, no scheduling — the caller\n * owns playback (schedule the returned buffer on its own timeline). Pair it with\n * {@link VoiceBank} for the source samples:\n *\n * const bank = await VoiceBank.load(koeUrl);\n * const wl = await Worldline.load({ scriptUrl: '.../world/worldline.js' });\n *\n * const entry = bank.manifest.phonemes[alias];\n * const pcm = await bank.getPcm(alias);\n * const audio = wl.renderNote({\n * pcm, pitch: 440, durationMs: 500, ...leadInFromEntry(entry),\n * });\n * // audio: Float32 @ 48 kHz, layout [lead-in/consonant ≈ preMs][vowel ≈ durationMs]\n */\nexport class Worldline {\n\treadonly sampleRate = WORLDLINE_SAMPLE_RATE;\n\n\tprivate constructor(private wasm: WorldlineWasm) {}\n\n\t/**\n\t * Load + instantiate the worldline WASM module (deduped per scriptUrl).\n\t *\n\t * Works on the main thread (loads via `<script>`) and inside a classic Web\n\t * Worker (loads via `importScripts`), so the heavy synthesis can run\n\t * off-thread. The matching `worldline.wasm` is fetched next to scriptUrl.\n\t */\n\tstatic async load(options: WorldlineLoadOptions): Promise<Worldline> {\n\t\treturn new Worldline(await loadWasm(options.scriptUrl));\n\t}\n\n\t/**\n\t * Render one note to Float32 PCM at 48 kHz.\n\t *\n\t * The output buffer is laid out as [lead-in/consonant ≈ preMs][vowel ≈\n\t * durationMs], rendered from sample offset 0 (no leading silence). The vowel\n\t * onset (the \"beat\") sits at ≈ preMs into the buffer, so a sequencer should\n\t * place the buffer at `beatTime − preMs` and may trim/crossfade the lead-in.\n\t *\n\t * No internal crossfade is applied — apply fades externally.\n\t *\n\t * @returns Float32 PCM, or null when `pcm` is shorter than\n\t * {@link MIN_WORLDLINE_SAMPLES} (too short for stable F0 analysis).\n\t */\n\n\trenderPhrase(params: RenderPhraseParams): Float32Array | null {\n\t\tconst {\n\t\t\tunits,\n\t\t\tpitch,\n\t\t\tgender = 0.5,\n\t\t\ttension = 0.5,\n\t\t\tbreathiness = 0.5,\n\t\t\tvoicing = 1.0,\n\t\t\ttempo = 120,\n\t\t} = params;\n\t\tif (units.length === 0) return null;\n\n\t\tconst WL = this.wasm;\n\t\tconst FS = WORLDLINE_SAMPLE_RATE;\n\n\t\t// Calculate total duration from the last unit's posMs + lengthMs\n\t\tlet totalMs = 0;\n\t\tfor (const u of units) {\n\t\t\tconst endMs = u.posMs + u.lengthMs;\n\t\t\tif (endMs > totalMs) totalMs = endMs;\n\t\t}\n\n\t\tconst ps = WL._PhraseSynthNew();\n\t\tif (!ps) return null;\n\n\t\tconst pointersToFree: number[] = [];\n\n\t\tfor (const u of units) {\n\t\t\tif (!u.pcm || u.pcm.length < MIN_WORLDLINE_SAMPLES) continue;\n\n\t\t\tconst reqPtr = WL._malloc(SYNTH_REQ_SIZE);\n\t\t\tif (!reqPtr) continue;\n\t\t\tpointersToFree.push(reqPtr);\n\n\t\t\tconst samplePtr = WL._malloc(u.pcm.length * 8);\n\t\t\tif (!samplePtr) continue;\n\t\t\tpointersToFree.push(samplePtr);\n\n\t\t\tWL.HEAPF64.set(u.pcm, samplePtr >> 3);\n\n\t\t\tconst sv = (off: number, val: number, type: string) =>\n\t\t\t\tWL.setValue(reqPtr + off, val, type);\n\t\t\tsv(0, FS, \"i32\");\n\t\t\tsv(4, u.pcm.length, \"i32\");\n\t\t\tsv(8, samplePtr, \"*\");\n\t\t\tsv(12, 0, \"i32\");\n\t\t\tsv(16, 0, \"*\");\n\t\t\t// The F0 curve set below overrides per-frame pitch; the tone only seeds\n\t\t\t// the resampler, so default to A4 unless the caller knows the sample pitch.\n\t\t\tsv(20, u.tone ?? 69, \"i32\");\n\t\t\tsv(24, 100.0, \"double\");\n\t\t\tsv(32, 0.0, \"double\");\n\t\t\tsv(40, u.requiredLengthMs ?? u.lengthMs, \"double\");\n\t\t\tsv(48, u.consonantMs, \"double\");\n\t\t\tconst cutMs = u.cutMs ?? WL_FRAME_MS * 2;\n\t\t\tsv(56, cutMs, \"double\");\n\t\t\tsv(64, u.volume ?? 100.0, \"double\");\n\t\t\tsv(72, 0.0, \"double\");\n\t\t\tsv(80, tempo, \"double\");\n\t\t\tsv(88, 0, \"i32\");\n\t\t\tsv(92, 0, \"*\");\n\t\t\tsv(96, 0, \"i32\");\n\t\t\tsv(100, 0, \"i32\");\n\t\t\tsv(104, 100, \"i32\");\n\t\t\tsv(108, 0, \"i32\");\n\t\t\tsv(112, 0, \"i32\");\n\t\t\tsv(116, 100, \"i32\");\n\n\t\t\tWL._PhraseSynthAddRequest(\n\t\t\t\tps,\n\t\t\t\treqPtr,\n\t\t\t\tu.posMs,\n\t\t\t\tu.skipMs,\n\t\t\t\tu.lengthMs,\n\t\t\t\tu.fadeInMs,\n\t\t\t\tu.fadeOutMs,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\n\t\ttotalMs += WL_FRAME_MS * 2;\n\t\tconst nFrames = Math.ceil(totalMs / WL_FRAME_MS) + 4;\n\t\tconst f0Arr = new Float64Array(nFrames);\n\t\tconst gArr = new Float64Array(nFrames);\n\t\tconst tArr = new Float64Array(nFrames);\n\t\tconst bArr = new Float64Array(nFrames);\n\t\tconst vArr = new Float64Array(nFrames);\n\n\t\tfor (let i = 0; i < nFrames; i++) {\n\t\t\tconst tMs = i * WL_FRAME_MS;\n\t\t\tf0Arr[i] = sampleCurve(tMs, pitch, totalMs);\n\t\t\tgArr[i] = sampleCurve(tMs, gender, totalMs);\n\t\t\ttArr[i] = sampleCurve(tMs, tension, totalMs);\n\t\t\tbArr[i] = sampleCurve(tMs, breathiness, totalMs);\n\t\t\tvArr[i] = sampleCurve(tMs, voicing, totalMs);\n\t\t}\n\n\t\tconst f0Ptr = WL._malloc(nFrames * 8);\n\t\tconst gPtr = WL._malloc(nFrames * 8);\n\t\tconst tPtr = WL._malloc(nFrames * 8);\n\t\tconst bPtr = WL._malloc(nFrames * 8);\n\t\tconst vPtr = WL._malloc(nFrames * 8);\n\n\t\tif (f0Ptr && gPtr && tPtr && bPtr && vPtr) {\n\t\t\tWL.HEAPF64.set(f0Arr, f0Ptr >> 3);\n\t\t\tWL.HEAPF64.set(gArr, gPtr >> 3);\n\t\t\tWL.HEAPF64.set(tArr, tPtr >> 3);\n\t\t\tWL.HEAPF64.set(bArr, bPtr >> 3);\n\t\t\tWL.HEAPF64.set(vArr, vPtr >> 3);\n\t\t\tWL._PhraseSynthSetCurves(\n\t\t\t\tps,\n\t\t\t\tf0Ptr,\n\t\t\t\tgPtr,\n\t\t\t\ttPtr,\n\t\t\t\tbPtr,\n\t\t\t\tvPtr,\n\t\t\t\tnFrames,\n\t\t\t\tWL_FRAME_MS,\n\t\t\t);\n\t\t}\n\n\t\tif (f0Ptr) WL._free(f0Ptr);\n\t\tif (gPtr) WL._free(gPtr);\n\t\tif (tPtr) WL._free(tPtr);\n\t\tif (bPtr) WL._free(bPtr);\n\t\tif (vPtr) WL._free(vPtr);\n\n\t\tconst yPtrPtr = WL._malloc(4);\n\t\tlet audio = null;\n\t\tif (yPtrPtr) {\n\t\t\tconst outLen = WL._PhraseSynthSynth(ps, yPtrPtr, 0);\n\t\t\tconst yPtr = WL.getValue(yPtrPtr, \"*\");\n\t\t\tif (outLen > 0 && yPtr) {\n\t\t\t\taudio = new Float32Array(WL.HEAPF32.buffer, yPtr, outLen).slice();\n\t\t\t\tWL._free(yPtr);\n\t\t\t}\n\t\t\tWL._free(yPtrPtr);\n\t\t}\n\n\t\tfor (const ptr of pointersToFree) {\n\t\t\tWL._free(ptr);\n\t\t}\n\t\tWL._PhraseSynthDelete(ps);\n\n\t\treturn audio;\n\t}\n\n\trenderNote(params: RenderNoteParams): Float32Array | null {\n\t\tconst {\n\t\t\tpcm,\n\t\t\tpitch,\n\t\t\tdurationMs,\n\t\t\tpreMs,\n\t\t\tconsonantMs,\n\t\t\ttempo = 120,\n\t\t\tgender = 0.5,\n\t\t\ttension = 0.5,\n\t\t\tbreathiness = 0.5,\n\t\t\tvoicing = 1.0,\n\t\t} = params;\n\t\tif (!pcm || pcm.length < MIN_WORLDLINE_SAMPLES) return null;\n\n\t\tconst WL = this.wasm;\n\t\tconst FS = WORLDLINE_SAMPLE_RATE;\n\t\t// Representative pitch for the resampler's target note — the midpoint of\n\t\t// the vowel sustain when pitch is a curve, otherwise the flat value.\n\t\tconst basePitch = sampleCurve(\n\t\t\tpreMs + durationMs / 2,\n\t\t\tpitch,\n\t\t\tpreMs + durationMs,\n\t\t);\n\t\tconst midiNote = Math.round(69 + 12 * Math.log2(basePitch / 440));\n\t\tconst posMs = 0; // no leading silence\n\t\tconst reqLen = preMs + durationMs; // render lead-in/consonant + vowel\n\n\t\t// cut_off must trim at least ~2 frames off the tail. PhraseSynth::AddRequest\n\t\t// computes the trim frame count as ceil(in_length_ms)/frame_ms, but\n\t\t// PyinEstimator yields floor(N/nhop)−1 frames — one fewer. With cut_off=0 the\n\t\t// requested frame count exceeds f0_.size() and Model::Trim's f0_.erase() runs\n\t\t// past end(), causing \"memory access out of bounds\". Trimming 2 frames keeps\n\t\t// it within bounds.\n\t\tconst cutMs = WL_FRAME_MS * 2;\n\n\t\tconst ps = WL._PhraseSynthNew();\n\t\tif (!ps) return null;\n\t\tconst reqPtr = WL._malloc(SYNTH_REQ_SIZE);\n\t\tif (!reqPtr) {\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tconst samplePtr = WL._malloc(pcm.length * 8);\n\t\tif (!samplePtr) {\n\t\t\tWL._free(reqPtr);\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tWL.HEAPF64.set(pcm, samplePtr >> 3);\n\n\t\tconst sv = (off: number, val: number, type: string) =>\n\t\t\tWL.setValue(reqPtr + off, val, type);\n\t\tsv(0, FS, \"i32\");\n\t\tsv(4, pcm.length, \"i32\");\n\t\tsv(8, samplePtr, \"*\");\n\t\tsv(12, 0, \"i32\");\n\t\tsv(16, 0, \"*\");\n\t\tsv(20, midiNote, \"i32\");\n\t\tsv(24, 100.0, \"double\");\n\t\tsv(32, 0.0, \"double\");\n\t\tsv(40, reqLen, \"double\");\n\t\tsv(48, consonantMs, \"double\");\n\t\tsv(56, cutMs, \"double\");\n\t\tsv(64, 100.0, \"double\");\n\t\tsv(72, 0.0, \"double\");\n\t\tsv(80, tempo, \"double\");\n\t\tsv(88, 0, \"i32\");\n\t\tsv(92, 0, \"*\");\n\t\tsv(96, 0, \"i32\");\n\t\tsv(100, 0, \"i32\");\n\t\tsv(104, 100, \"i32\");\n\t\tsv(108, 0, \"i32\");\n\t\tsv(112, 0, \"i32\");\n\t\tsv(116, 100, \"i32\");\n\n\t\t// skip/fadeIn/fadeOut all 0 — crossfade is handled externally.\n\t\tWL._PhraseSynthAddRequest(ps, reqPtr, posMs, 0.0, reqLen, 0.0, 0.0, 0);\n\t\tWL._free(samplePtr);\n\t\tWL._free(reqPtr);\n\n\t\tconst totalMs = posMs + reqLen + WL_FRAME_MS * 2;\n\t\tconst nFrames = Math.ceil(totalMs / WL_FRAME_MS) + 4;\n\t\t// Sample each curve once per 10ms frame. Plain numbers short-circuit to a\n\t\t// flat fill (same cost as before); functions get evaluated per-frame so\n\t\t// callers can draw vibrato, portamento, scoop-in, humanize jitter, etc.\n\t\tconst f0Arr = new Float64Array(nFrames);\n\t\tconst gArr = new Float64Array(nFrames);\n\t\tconst tArr = new Float64Array(nFrames);\n\t\tconst bArr = new Float64Array(nFrames);\n\t\tconst vArr = new Float64Array(nFrames);\n\t\tfor (let i = 0; i < nFrames; i++) {\n\t\t\tconst tMs = i * WL_FRAME_MS;\n\t\t\tf0Arr[i] = sampleCurve(tMs, pitch, totalMs);\n\t\t\tgArr[i] = sampleCurve(tMs, gender, totalMs);\n\t\t\ttArr[i] = sampleCurve(tMs, tension, totalMs);\n\t\t\tbArr[i] = sampleCurve(tMs, breathiness, totalMs);\n\t\t\tvArr[i] = sampleCurve(tMs, voicing, totalMs);\n\t\t}\n\n\t\tconst f0Ptr = WL._malloc(nFrames * 8);\n\t\tconst gPtr = WL._malloc(nFrames * 8);\n\t\tconst tPtr = WL._malloc(nFrames * 8);\n\t\tconst bPtr = WL._malloc(nFrames * 8);\n\t\tconst vPtr = WL._malloc(nFrames * 8);\n\t\tif (!f0Ptr || !gPtr || !tPtr || !bPtr || !vPtr) {\n\t\t\tif (f0Ptr) WL._free(f0Ptr);\n\t\t\tif (gPtr) WL._free(gPtr);\n\t\t\tif (tPtr) WL._free(tPtr);\n\t\t\tif (bPtr) WL._free(bPtr);\n\t\t\tif (vPtr) WL._free(vPtr);\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tWL.HEAPF64.set(f0Arr, f0Ptr >> 3);\n\t\tWL.HEAPF64.set(gArr, gPtr >> 3);\n\t\tWL.HEAPF64.set(tArr, tPtr >> 3);\n\t\tWL.HEAPF64.set(bArr, bPtr >> 3);\n\t\tWL.HEAPF64.set(vArr, vPtr >> 3);\n\t\tWL._PhraseSynthSetCurves(\n\t\t\tps,\n\t\t\tf0Ptr,\n\t\t\tgPtr,\n\t\t\ttPtr,\n\t\t\tbPtr,\n\t\t\tvPtr,\n\t\t\tnFrames,\n\t\t\tWL_FRAME_MS,\n\t\t);\n\t\tWL._free(f0Ptr);\n\t\tWL._free(gPtr);\n\t\tWL._free(tPtr);\n\t\tWL._free(bPtr);\n\t\tWL._free(vPtr);\n\n\t\tconst yPtrPtr = WL._malloc(4);\n\t\tif (!yPtrPtr) {\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tconst outLen = WL._PhraseSynthSynth(ps, yPtrPtr, 0);\n\t\tconst yPtr = WL.getValue(yPtrPtr, \"*\");\n\t\tconst audio =\n\t\t\toutLen > 0 && yPtr\n\t\t\t\t? new Float32Array(WL.HEAPF32.buffer, yPtr, outLen).slice()\n\t\t\t\t: null;\n\t\t// The wrapper allocates *y with `new float[]` for the caller to release;\n\t\t// Emscripten's operator new is malloc-backed, so _free reclaims it.\n\t\tif (yPtr) WL._free(yPtr);\n\t\tWL._free(yPtrPtr);\n\t\tWL._PhraseSynthDelete(ps);\n\t\treturn audio;\n\t}\n}\n","/**\n * Frame-level acoustic features used to locate mora boundaries.\n *\n * Everything downstream reasons in *frames* at a fixed 2 ms hop, so a frame\n * index doubles as a millisecond timestamp once multiplied by {@link HOP_MS}.\n * The analysis runs at 16 kHz regardless of the source rate: that is well past\n * the 4–8 kHz band where fricative noise lives, and keeps a 512-point FFT to\n * 32 ms — short enough to see a plosive burst, long enough to resolve F1.\n */\n\nimport { parseWav, resample, toMono, type WavData } from \"../converter/wav.js\";\n\n/** Analysis rate. */\nexport const RATE = 16000;\n/** Hop between frames, in milliseconds. */\nexport const HOP_MS = 2;\n\nconst HOP = (RATE * HOP_MS) / 1000; // 32 samples\nconst FFT_SIZE = 512; // 32 ms window\nconst BINS = FFT_SIZE / 2;\n/** Pitch analysis runs on a ×2 decimation of the 16 kHz signal. */\nconst PITCH_DECIM = 2;\nconst PITCH_RATE = RATE / PITCH_DECIM; // 8 kHz\nconst PITCH_WIN = 512; // 64 ms — at least 4 periods at 70 Hz\nconst MIN_F0 = 70;\nconst MAX_F0 = 600;\n\nexport interface Frames {\n\t/** Number of frames. */\n\tn: number;\n\t/** Source duration in milliseconds. */\n\tdurationMs: number;\n\t/** Short-time level in dBFS, −120 for digital silence. */\n\trmsDb: Float32Array;\n\t/** {@link rmsDb} smoothed over ~30 ms, for threshold crossings. */\n\tsmoothDb: Float32Array;\n\t/** Normalised autocorrelation peak, 0–1. Above ~0.5 reads as voiced. */\n\tvoiced: Float32Array;\n\t/** Share of spectral energy above 4 kHz — high for /s/, /sh/, /ch/. */\n\thighRatio: Float32Array;\n\t/** Level of the >4 kHz band alone, in dB. Frication shows here first. */\n\thighDb: Float32Array;\n\t/** Noise floor of {@link highDb}, in dB. */\n\thighFloorDb: number;\n\t/** Positive spectral flux, normalised so its own median is 1. */\n\tflux: Float32Array;\n\t/** Median f0 of the voiced portion, in Hz (0 when nothing is voiced). */\n\tf0: number;\n\t/** Noise floor in dBFS, estimated from the quietest tenth of the file. */\n\tfloorDb: number;\n\t/**\n\t * Level of the quietest 50 ms in the file — a true noise floor, unlike\n\t * {@link floorDb}, which a short recording's own voice can drag upwards.\n\t * Used to trace an attack back past the point where it is merely audible.\n\t */\n\tquietDb: number;\n\t/** Loudest smoothed frame, in dBFS. */\n\tpeakDb: number;\n}\n\n/**\n * Offset from a frame's first sample to the middle of its analysis window.\n *\n * Every feature a frame carries describes the whole window, so the event it\n * reports actually happened around the window's centre. Ignoring that biases\n * every boundary half a window early — 16 ms here, which is large enough to\n * shift a preutterance audibly.\n */\nconst WINDOW_CENTRE_MS = (FFT_SIZE / 2 / RATE) * 1000;\n\n/** Convert a *duration* in milliseconds to a count of frames. */\nexport function msToFrame(ms: number): number {\n\treturn Math.round(ms / HOP_MS);\n}\n\n/** Convert a *duration* in frames to milliseconds. */\nexport function framesToMs(frames: number): number {\n\treturn frames * HOP_MS;\n}\n\n/** Convert a frame *index* to the time in the signal that it describes. */\nexport function frameTimeMs(frame: number): number {\n\treturn frame * HOP_MS + WINDOW_CENTRE_MS;\n}\n\n/** In-place iterative radix-2 FFT over split real/imaginary arrays. */\nfunction fft(re: Float32Array, im: Float32Array): void {\n\tconst n = re.length;\n\tfor (let i = 1, j = 0; i < n; i++) {\n\t\tlet bit = n >> 1;\n\t\tfor (; j & bit; bit >>= 1) j ^= bit;\n\t\tj ^= bit;\n\t\tif (i < j) {\n\t\t\t[re[i], re[j]] = [re[j], re[i]];\n\t\t\t[im[i], im[j]] = [im[j], im[i]];\n\t\t}\n\t}\n\tfor (let len = 2; len <= n; len <<= 1) {\n\t\tconst ang = (-2 * Math.PI) / len;\n\t\tconst wRe = Math.cos(ang);\n\t\tconst wIm = Math.sin(ang);\n\t\tfor (let i = 0; i < n; i += len) {\n\t\t\tlet curRe = 1;\n\t\t\tlet curIm = 0;\n\t\t\tfor (let k = 0; k < len >> 1; k++) {\n\t\t\t\tconst aRe = re[i + k];\n\t\t\t\tconst aIm = im[i + k];\n\t\t\t\tconst bRe =\n\t\t\t\t\tre[i + k + (len >> 1)] * curRe - im[i + k + (len >> 1)] * curIm;\n\t\t\t\tconst bIm =\n\t\t\t\t\tre[i + k + (len >> 1)] * curIm + im[i + k + (len >> 1)] * curRe;\n\t\t\t\tre[i + k] = aRe + bRe;\n\t\t\t\tim[i + k] = aIm + bIm;\n\t\t\t\tre[i + k + (len >> 1)] = aRe - bRe;\n\t\t\t\tim[i + k + (len >> 1)] = aIm - bIm;\n\t\t\t\tconst nextRe = curRe * wRe - curIm * wIm;\n\t\t\t\tcurIm = curRe * wIm + curIm * wRe;\n\t\t\t\tcurRe = nextRe;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Noise floor: the level of the quietest 50 ms in the file.\n *\n * A low percentile is the obvious estimator and the wrong one — a short,\n * quietly recorded mora can be more than 90 % voice, which drags a tenth-\n * percentile \"floor\" up into the consonant and hides the attack entirely.\n */\nfunction quietestWindow(db: Float32Array): number {\n\tconst averaged = smooth(db, Math.round(50 / HOP_MS));\n\tlet min = Infinity;\n\tfor (let i = 0; i < averaged.length; i++) {\n\t\tif (averaged[i] < min) min = averaged[i];\n\t}\n\treturn Number.isFinite(min) ? min : -120;\n}\n\nfunction percentile(values: Float32Array, p: number): number {\n\tconst sorted = Float32Array.from(values).sort();\n\tconst i = Math.min(\n\t\tsorted.length - 1,\n\t\tMath.max(0, Math.round(p * (sorted.length - 1))),\n\t);\n\treturn sorted[i];\n}\n\n/**\n * Normalised cross-correlation of `buf` at `lag`, over `win` samples from\n * `at`. Returns a value in [-1, 1]; 1 means perfectly periodic at that lag.\n */\nfunction ncc(buf: Float32Array, at: number, win: number, lag: number): number {\n\tlet r = 0;\n\tlet e0 = 0;\n\tlet e1 = 0;\n\tfor (let i = 0; i < win; i++) {\n\t\tconst a = buf[at + i];\n\t\tconst b = buf[at + i + lag];\n\t\tr += a * b;\n\t\te0 += a * a;\n\t\te1 += b * b;\n\t}\n\tconst denom = Math.sqrt(e0 * e1);\n\treturn denom > 1e-12 ? r / denom : 0;\n}\n\n/** Extract every feature the mora estimator needs from one mono signal. */\nexport function analyze(wav: WavData): Frames {\n\tconst mono = resample(toMono(wav), RATE);\n\tconst x = mono.samples;\n\tconst n = Math.max(1, Math.floor((x.length - FFT_SIZE) / HOP) + 1);\n\n\tconst rmsDb = new Float32Array(n);\n\tconst highRatio = new Float32Array(n);\n\tconst highDb = new Float32Array(n);\n\tconst flux = new Float32Array(n);\n\tconst voiced = new Float32Array(n);\n\n\tconst window = new Float32Array(FFT_SIZE);\n\tfor (let i = 0; i < FFT_SIZE; i++) {\n\t\twindow[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / FFT_SIZE);\n\t}\n\n\tconst re = new Float32Array(FFT_SIZE);\n\tconst im = new Float32Array(FFT_SIZE);\n\tconst mag = new Float32Array(BINS);\n\tconst prevMag = new Float32Array(BINS);\n\t// 4 kHz is the boundary between \"voice\" and \"sibilant hiss\" at this rate.\n\tconst highBin = Math.floor((4000 / (RATE / 2)) * BINS);\n\n\tfor (let t = 0; t < n; t++) {\n\t\tconst off = t * HOP;\n\t\tlet energy = 0;\n\t\tfor (let i = 0; i < FFT_SIZE; i++) {\n\t\t\tconst s = x[off + i] ?? 0;\n\t\t\tenergy += s * s;\n\t\t\tre[i] = s * window[i];\n\t\t\tim[i] = 0;\n\t\t}\n\t\trmsDb[t] = 10 * Math.log10(energy / FFT_SIZE + 1e-12);\n\n\t\tfft(re, im);\n\n\t\tlet lowSum = 0;\n\t\tlet highSum = 0;\n\t\tlet fluxSum = 0;\n\t\tfor (let b = 1; b < BINS; b++) {\n\t\t\tconst m = Math.sqrt(re[b] * re[b] + im[b] * im[b]);\n\t\t\tmag[b] = m;\n\t\t\tif (b < highBin) lowSum += m;\n\t\t\telse highSum += m;\n\t\t\t// Log-domain flux: a doubling counts the same whether the frame is\n\t\t\t// loud or quiet, so a consonant release inside a soft passage still\n\t\t\t// registers as an onset.\n\t\t\tconst d = Math.log10(m + 1e-6) - Math.log10(prevMag[b] + 1e-6);\n\t\t\tif (d > 0) fluxSum += d;\n\t\t}\n\t\tprevMag.set(mag);\n\t\thighRatio[t] = highSum / (lowSum + highSum + 1e-12);\n\t\thighDb[t] = 20 * Math.log10(highSum / BINS + 1e-9);\n\t\tflux[t] = t === 0 ? 0 : fluxSum;\n\t}\n\n\tconst smoothDb = smooth(rmsDb, Math.round(30 / HOP_MS));\n\tconst smoothHighDb = smooth(highDb, Math.round(20 / HOP_MS));\n\tconst highFloorDb = quietestWindow(smoothHighDb);\n\tconst floorDb = percentile(smoothDb, 0.1);\n\tconst quietDb = quietestWindow(smoothDb);\n\tlet peakDb = -120;\n\tfor (let t = 0; t < n; t++) if (smoothDb[t] > peakDb) peakDb = smoothDb[t];\n\n\t// --- pitch ---------------------------------------------------------------\n\t// Decimate for speed, then find the file's own f0 once and track only a\n\t// narrow lag band around it. A full search per frame would dominate runtime\n\t// and, on a single sustained note, buy nothing.\n\tconst pitchBuf = new Float32Array(Math.floor(x.length / PITCH_DECIM));\n\tfor (let i = 0; i < pitchBuf.length; i++) {\n\t\tpitchBuf[i] = (x[i * PITCH_DECIM] + x[i * PITCH_DECIM + 1]) * 0.5;\n\t}\n\tconst minLag = Math.floor(PITCH_RATE / MAX_F0);\n\tconst maxLag = Math.floor(PITCH_RATE / MIN_F0);\n\n\tconst loud: number[] = [];\n\tfor (let t = 0; t < n; t++) {\n\t\tif (smoothDb[t] > peakDb - 10) loud.push(t);\n\t}\n\tconst lags: number[] = [];\n\tconst step = Math.max(1, Math.floor(loud.length / 24));\n\tfor (let k = 0; k < loud.length; k += step) {\n\t\tconst at = Math.floor((loud[k] * HOP) / PITCH_DECIM);\n\t\tif (at + PITCH_WIN + maxLag >= pitchBuf.length) continue;\n\t\tlet best = 0;\n\t\tlet bestLag = 0;\n\t\tfor (let lag = minLag; lag <= maxLag; lag++) {\n\t\t\tconst v = ncc(pitchBuf, at, PITCH_WIN, lag);\n\t\t\tif (v > best) {\n\t\t\t\tbest = v;\n\t\t\t\tbestLag = lag;\n\t\t\t}\n\t\t}\n\t\tif (best > 0.5 && bestLag > 0) lags.push(bestLag);\n\t}\n\tlags.sort((a, b) => a - b);\n\tconst centreLag = lags.length ? lags[lags.length >> 1] : 0;\n\tconst f0 = centreLag ? PITCH_RATE / centreLag : 0;\n\n\tif (centreLag) {\n\t\tconst lo = Math.max(minLag, Math.floor(centreLag / 1.7));\n\t\tconst hi = Math.min(maxLag, Math.ceil(centreLag * 1.7));\n\t\tfor (let t = 0; t < n; t++) {\n\t\t\t// Silence is never voiced, and skipping it keeps the inner loop off\n\t\t\t// the long tails of room tone that bracket every recording.\n\t\t\tif (smoothDb[t] < floorDb + 6) continue;\n\t\t\tconst at = Math.floor((t * HOP) / PITCH_DECIM);\n\t\t\tif (at + PITCH_WIN + hi >= pitchBuf.length) continue;\n\t\t\tlet best = 0;\n\t\t\tfor (let lag = lo; lag <= hi; lag++) {\n\t\t\t\tconst v = ncc(pitchBuf, at, PITCH_WIN, lag);\n\t\t\t\tif (v > best) best = v;\n\t\t\t}\n\t\t\tvoiced[t] = best;\n\t\t}\n\t}\n\n\t// Normalise flux by its own median so thresholds are scale-free.\n\tconst medianFlux = percentile(flux, 0.5) || 1;\n\tfor (let t = 0; t < n; t++) flux[t] /= medianFlux;\n\n\treturn {\n\t\tn,\n\t\tdurationMs: (x.length / RATE) * 1000,\n\t\trmsDb,\n\t\tsmoothDb,\n\t\tvoiced,\n\t\thighRatio,\n\t\thighDb: smoothHighDb,\n\t\thighFloorDb,\n\t\tflux: smooth(flux, 3),\n\t\tf0,\n\t\tfloorDb,\n\t\tquietDb,\n\t\tpeakDb,\n\t};\n}\n\n/** Centred moving average over `width` frames, with shrinking edge windows. */\nexport function smooth(src: Float32Array, width: number): Float32Array {\n\tif (width <= 1) return Float32Array.from(src);\n\tconst prefix = new Float64Array(src.length + 1);\n\tfor (let i = 0; i < src.length; i++) prefix[i + 1] = prefix[i] + src[i];\n\n\tconst out = new Float32Array(src.length);\n\tconst half = width >> 1;\n\tfor (let i = 0; i < src.length; i++) {\n\t\tconst lo = Math.max(0, i - half);\n\t\tconst hi = Math.min(src.length, i + half + 1);\n\t\tout[i] = (prefix[hi] - prefix[lo]) / (hi - lo);\n\t}\n\treturn out;\n}\n\n/** Convenience wrapper: decode a WAV buffer and analyse it. */\nexport function analyzeWav(buf: ArrayBuffer): Frames {\n\treturn analyze(parseWav(buf));\n}\n","/**\n * Parameter estimation for oto.ini entries.\n *\n * The rules encoded here follow the UTAU音源制作wiki's 原音設定 articles\n * (https://w.atwiki.jp/vbmaker/pages/17.html and its 単独音 / 連続音 sequels):\n *\n * - オフセット sits just before the consonant, keeping a little room so the\n * attack is never clipped.\n * - 先行発声 marks where the *vowel* begins — the voicing onset for a voiceless\n * consonant, the release for a nasal or a flap, the midpoint of the glide for\n * や/わ行.\n * - 子音部 runs from the offset through the vowel's onset until the spectrum\n * settles, so a long note stretches only steady-state vowel.\n * - オーバーラップ is ~20 ms for さ/な/ま/ら行, ~30 ms for や/わ行, and goes\n * *negative* for 破裂音 to reproduce the silent closure of か/た/ぱ行.\n * - 右ブランク lands just before the note starts to decay.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\nimport {\n\ttype Frames,\n\tframesToMs,\n\tframeTimeMs,\n\tHOP_MS,\n\tmsToFrame,\n\tsmooth,\n} from \"./frames.js\";\nimport type { ConsonantClass, Syllable } from \"./kana.js\";\n\n/** Per-class settings derived from the wiki's 原音設定解説. */\ninterface Articulation {\n\t/**\n\t * Longest consonant kept ahead of the vowel. The wiki warns that a 先行発声\n\t * past ~100 ms reads as a staccato \"溜め\"; sibilants are the exception, and\n\t * routinely run longer in hand-tuned banks.\n\t */\n\tmaxConsonantMs: number;\n\t/** Silence kept before the consonant so the attack is not clipped. */\n\tleadInMs: number;\n\t/**\n\t * オーバーラップ as a fraction of the preutterance.\n\t *\n\t * The wiki gives absolutes — 20 ms for さ/な/ま/ら行, 30 ms for や/わ行,\n\t * \"下限は15ミリ秒、上限は先行発声と同じ値くらい\" — but a fraction expresses the\n\t * same rule while scaling with how long the consonant actually came out. The\n\t * ratios below are what the reference banks work out to: roughly 0.6 of the\n\t * preutterance for sonorants, 0.3 for the obstruents whose noise should not\n\t * bleed into the previous note.\n\t */\n\toverlapRatio: number;\n\t/** Overrides {@link overlapRatio} when the class wants a fixed value. */\n\tfixedOverlapMs?: number;\n\t/** True when the vocal folds are already running during the consonant. */\n\tvoicedConsonant: boolean;\n\t/** True when the consonant is noise, and so begins in the >4 kHz band. */\n\tfricationOnset: boolean;\n}\n\nconst ARTICULATION: Record<ConsonantClass, Articulation> = {\n\tvowel: {\n\t\tmaxConsonantMs: 40,\n\t\tleadInMs: 3,\n\t\toverlapRatio: 0,\n\t\tfixedOverlapMs: 20,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tnasalN: {\n\t\tmaxConsonantMs: 40,\n\t\tleadInMs: 3,\n\t\toverlapRatio: 0,\n\t\tfixedOverlapMs: 20,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tnasal: {\n\t\tmaxConsonantMs: 110,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tliquid: {\n\t\tmaxConsonantMs: 80,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tsemivowel: {\n\t\tmaxConsonantMs: 75,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tfricativeVoiceless: {\n\t\tmaxConsonantMs: 140,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.3,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: true,\n\t},\n\tfricativeVoiced: {\n\t\tmaxConsonantMs: 130,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.4,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: true,\n\t},\n\taffricate: {\n\t\tmaxConsonantMs: 120,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.3,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: true,\n\t},\n\tplosiveVoiceless: {\n\t\tmaxConsonantMs: 90,\n\t\tleadInMs: 8,\n\t\toverlapRatio: 0,\n\t\t// か/た/ぱ行 need a gap, not a crossfade: the wiki asks for a negative\n\t\t// overlap so the closure that precedes the burst survives synthesis.\n\t\tfixedOverlapMs: -10,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: false,\n\t},\n\tplosiveVoiced: {\n\t\tmaxConsonantMs: 90,\n\t\tleadInMs: 8,\n\t\toverlapRatio: 0.55,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n};\n\n/** Overlap never goes below this, nor above the preutterance. */\nconst MIN_OVERLAP_MS = 12;\nconst MAX_OVERLAP_MS = 40;\n\n/** Periodicity above which a frame counts as voiced. */\nconst VOICED_THRESHOLD = 0.55;\n/** A voiced run shorter than this is a glitch, not the start of a vowel. */\nconst VOICED_RUN_MS = 24;\n/** な/ま/ら行 always hold their consonant at least this long before releasing. */\nconst MIN_VOICED_CONSONANT_MS = 22;\n/**\n * Frames added to a within-phrase onset before it is taken as the vowel start.\n *\n * The onset track peaks while the transition is still happening; the note\n * belongs where the new vowel has arrived, which the reference banks put\n * consistently later.\n */\nconst SEQUENCE_ONSET_BIAS = 12; // 24 ms\n\n/** Ceiling on a 連続音 entry's 先行発声, in milliseconds. */\nconst MAX_SEQUENCE_PRE_MS = 250;\n/** dB below the note's peak at which it counts as having started to decay. */\nconst DECAY_DROP_DB = 4;\n/** Margin left between the end of the usable region and the note's release. */\nconst RELEASE_GUARD_FRAMES = 10; // 20 ms\n\nfunction clamp(v: number, lo: number, hi: number): number {\n\treturn Math.min(hi, Math.max(lo, v));\n}\n\n/** How far above the noise floor a frame has to sit to count as sound. */\nconst SOUND_OVER_FLOOR_DB = 8;\n/** Ceiling on that threshold, relative to the loudest frame. */\nconst SOUND_UNDER_PEAK_DB = 15;\n/** dB the level must still be dropping over 6 ms for the attack to continue. */\nconst ATTACK_SLOPE_DB = 1;\n/** Share of energy above 4 kHz that marks a frame as frication. */\nconst FRICATION_HIGH_RATIO = 0.45;\n/**\n * Frication has to sit within this much of the loudest frame to count.\n *\n * Not a distance above the noise floor: on a recording cropped so tightly that\n * the /s/ *is* the quietest thing in the file, there is no floor to measure\n * against, and the loudest frame is the only stable reference.\n */\nconst FRICATION_UNDER_PEAK_DB = 30;\n\n/** Level above which a frame is \"sound\" rather than room tone. */\nfunction soundThreshold(f: Frames): number {\n\treturn Math.min(\n\t\tMath.max(f.floorDb + SOUND_OVER_FLOOR_DB, f.peakDb - 34),\n\t\tf.peakDb - SOUND_UNDER_PEAK_DB,\n\t);\n}\n\n/** First frame in [from, to) whose smoothed level clears the sound threshold. */\nexport function findSoundStart(f: Frames, from: number, to: number): number {\n\tconst th = soundThreshold(f);\n\tfor (let t = Math.max(0, from); t < Math.min(f.n, to); t++) {\n\t\tif (f.smoothDb[t] >= th) return t;\n\t}\n\treturn Math.max(0, from);\n}\n\n/** Last frame in (from, to] still above the sound threshold. */\nexport function findSoundEnd(f: Frames, from: number, to: number): number {\n\tconst th = soundThreshold(f);\n\tfor (let t = Math.min(f.n, to) - 1; t > from; t--) {\n\t\tif (f.smoothDb[t] >= th) return t;\n\t}\n\treturn Math.min(f.n - 1, to);\n}\n\n/**\n * Where the consonant itself begins.\n *\n * Broadband level finds most attacks, but /s/ and /sh/ start as quiet hiss that\n * barely moves the meter while dominating the band above 4 kHz. Watching that\n * band as well is what stops さ行 from being set up as if the vowel's own\n * aspiration were the consonant.\n */\nexport function findConsonantStart(\n\tf: Frames,\n\tfrom: number,\n\tto: number,\n\tfrication: boolean,\n): number {\n\tconst lo = Math.max(0, from);\n\tlet start = findSoundStart(f, from, to);\n\n\tif (frication) {\n\t\t// /s/ and /sh/ can be 20 dB down on the vowel and still be unmistakable,\n\t\t// because almost all of what little energy they have sits above 4 kHz.\n\t\t// A ratio test catches that where an absolute level never would — and on\n\t\t// a tightly cropped recording there is no quiet high band to compare to.\n\t\tconst level = f.peakDb - FRICATION_UNDER_PEAK_DB;\n\t\tconst absolute = f.highFloorDb + 8;\n\t\tfor (let t = lo; t < start; t++) {\n\t\t\tconst byRatio =\n\t\t\t\tf.highRatio[t] >= FRICATION_HIGH_RATIO && f.smoothDb[t] >= level;\n\t\t\tif (byRatio || f.highDb[t] >= absolute) {\n\t\t\t\tstart = t;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// The threshold above says \"this is clearly the mora\"; the attack itself\n\t// begins earlier. Walk back while the level is still falling — /h/ and /f/\n\t// ramp in over tens of milliseconds without ever being loud or sibilant, and\n\t// a ramp is the one thing that distinguishes them from room tone, which is\n\t// flat. Stop where the curve levels off, or where it reaches the floor.\n\tconst foot = f.quietDb + 6;\n\tconst k = Math.max(1, msToFrame(6));\n\twhile (start > lo) {\n\t\tconst back = Math.max(lo, start - k);\n\t\tconst stillFalling =\n\t\t\tf.smoothDb[start] - f.smoothDb[back] >= ATTACK_SLOPE_DB;\n\t\tif (!stillFalling && f.smoothDb[start - 1] <= foot) break;\n\t\tstart--;\n\t}\n\treturn start;\n}\n\n/**\n * First frame of a sustained voiced run in [from, to). This is the vowel onset\n * for か/さ/た/は/ぱ行, whose consonants carry no voicing of their own.\n */\nexport function findVoiceOnset(f: Frames, from: number, to: number): number {\n\tconst need = Math.ceil(VOICED_RUN_MS / HOP_MS);\n\tconst hi = Math.min(f.n, to);\n\tfor (let t = Math.max(0, from); t < hi; t++) {\n\t\tif (f.voiced[t] < VOICED_THRESHOLD) continue;\n\t\tlet run = 0;\n\t\twhile (t + run < hi && f.voiced[t + run] >= VOICED_THRESHOLD) run++;\n\t\tif (run >= need) return t;\n\t\tt += run;\n\t}\n\treturn -1;\n}\n\n/**\n * Where a *voiced* consonant hands over to its vowel.\n *\n * な/ま行 release into the vowel with a step up in level; ら行 flaps do the\n * same over a few milliseconds; ざ行 lose their high-frequency noise; や/わ行\n * glide, and the wiki asks for the midpoint of that glide. All four show up as\n * a peak in the same combined measure — a local rise in level plus spectral\n * change — so one search covers them.\n */\nfunction findVoicedRelease(f: Frames, from: number, to: number): number {\n\tconst lo = Math.max(1, from);\n\tconst hi = Math.min(f.n - 1, to);\n\tif (hi <= lo) return lo;\n\n\tconst k = Math.max(1, msToFrame(10));\n\tlet best = lo;\n\tlet bestScore = -Infinity;\n\tfor (let t = lo; t < hi; t++) {\n\t\tconst rise =\n\t\t\tf.smoothDb[Math.min(f.n - 1, t + k)] - f.smoothDb[Math.max(0, t - k)];\n\t\t// Losing sibilance is as much a vowel onset as gaining loudness: ざ行 and\n\t\t// じゃ行 arrive by shedding their noise band, not by getting louder.\n\t\tconst deSibilance =\n\t\t\t(f.highRatio[Math.max(0, t - k)] -\n\t\t\t\tf.highRatio[Math.min(f.n - 1, t + k)]) *\n\t\t\t30;\n\t\tconst score = rise + deSibilance + f.flux[t];\n\t\tif (score > bestScore) {\n\t\t\tbestScore = score;\n\t\t\tbest = t;\n\t\t}\n\t}\n\treturn best;\n}\n\n/**\n * End of the transition into the vowel: the point past which the spectrum\n * stops moving, which is where 子音部/固定範囲 may stop.\n */\nfunction findVowelStable(f: Frames, vowelOnset: number, limit: number): number {\n\tconst minMs = 45;\n\tconst maxMs = 110;\n\tconst from = vowelOnset + msToFrame(minMs);\n\tconst to = Math.min(limit, vowelOnset + msToFrame(maxMs));\n\tif (to <= from) return Math.min(limit, vowelOnset + msToFrame(minMs));\n\n\tconst calm = smooth(f.flux, Math.max(1, msToFrame(12)));\n\tconst need = Math.ceil(20 / HOP_MS);\n\tfor (let t = from; t < to - need; t++) {\n\t\tlet steady = true;\n\t\tfor (let k = 0; k < need; k++) {\n\t\t\tif (calm[t + k] > 1.05) {\n\t\t\t\tsteady = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (steady) return t;\n\t}\n\treturn to;\n}\n\n/**\n * Where the note starts to fall away. Walking forward from the loudest frame\n * keeps a slow vibrato dip from being mistaken for the release.\n */\nfunction findDecayStart(f: Frames, from: number, soundEnd: number): number {\n\tlet peak = from;\n\tfor (let t = from; t <= soundEnd; t++) {\n\t\tif (f.smoothDb[t] > f.smoothDb[peak]) peak = t;\n\t}\n\t// A shallow threshold on purpose: hand-set banks stop the 右ブランク while the\n\t// note is still strong, well before the tail has run out.\n\tconst th = f.smoothDb[peak] - DECAY_DROP_DB;\n\tconst need = Math.ceil(24 / HOP_MS);\n\tfor (let t = peak; t <= soundEnd - need; t++) {\n\t\tlet falling = true;\n\t\tfor (let k = 0; k < need; k++) {\n\t\t\tif (f.smoothDb[t + k] >= th) {\n\t\t\t\tfalling = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Back off a little further: 右ブランク should stop *before* the decay, so\n\t\t// nothing inside the stretched region is already fading.\n\t\tif (falling) return Math.max(from, t - RELEASE_GUARD_FRAMES);\n\t}\n\t// No clear release in range — the note runs to the end of what we can hear,\n\t// so keep the same margin off that instead.\n\treturn Math.max(from, soundEnd - RELEASE_GUARD_FRAMES);\n}\n\n/** True when a が/だ/ば行 mora prevoices — a low \"ん\"-like hum before the burst. */\nfunction hasPrevoicing(\n\tf: Frames,\n\tconsStart: number,\n\tvowelOnset: number,\n): boolean {\n\tif (vowelOnset - consStart < msToFrame(25)) return false;\n\tlet voicedFrames = 0;\n\tfor (let t = consStart; t < vowelOnset; t++) {\n\t\tif (f.voiced[t] >= VOICED_THRESHOLD) voicedFrames++;\n\t}\n\treturn voicedFrames >= (vowelOnset - consStart) * 0.6;\n}\n\n/** Frame positions the oto parameters are built from. */\nexport interface MoraPosition {\n\t/** Frame where the consonant (or vowel, if there is none) begins. */\n\tconsStart: number;\n\t/** Frame where the vowel begins — the 先行発声 anchor. */\n\tvowelOnset: number;\n\t/** Frame past which the vowel is steady. */\n\tstable: number;\n\t/** True when a voiced stop prevoiced into its burst. */\n\tprevoiced: boolean;\n}\n\n/**\n * Locate one mora inside `[from, to)`, given what consonant it starts with.\n */\nexport function locateMora(\n\tf: Frames,\n\tcls: ConsonantClass,\n\tfrom: number,\n\tto: number,\n): MoraPosition {\n\tconst art = ARTICULATION[cls];\n\tconst consStart = findConsonantStart(f, from, to, art.fricationOnset);\n\tconst searchEnd = Math.min(\n\t\tto,\n\t\tconsStart + msToFrame(art.maxConsonantMs + 60),\n\t);\n\n\tlet vowelOnset: number;\n\tif (!art.voicedConsonant) {\n\t\t// Voiceless consonant: the vowel is exactly where the folds start.\n\t\tconst v = findVoiceOnset(f, consStart, searchEnd);\n\t\tvowelOnset = v >= 0 ? v : consStart + msToFrame(30);\n\t} else if (cls === \"vowel\" || cls === \"nasalN\") {\n\t\tconst v = findVoiceOnset(f, consStart, searchEnd);\n\t\tvowelOnset = v >= 0 ? v : consStart;\n\t} else {\n\t\tconst voiceStart = findVoiceOnset(f, consStart, searchEnd);\n\t\tconst base = voiceStart >= 0 ? voiceStart : consStart;\n\t\t// な/ま行 hold their nasal for a good 30–80 ms before releasing, so the\n\t\t// search has to start past the voicing onset — otherwise the onset itself\n\t\t// is the strongest thing in the window and wins.\n\t\tvowelOnset = findVoicedRelease(\n\t\t\tf,\n\t\t\tbase + msToFrame(MIN_VOICED_CONSONANT_MS),\n\t\t\tMath.min(to, base + msToFrame(art.maxConsonantMs)),\n\t\t);\n\t}\n\tvowelOnset = clamp(vowelOnset, consStart, Math.max(consStart, to - 1));\n\n\treturn {\n\t\tconsStart,\n\t\tvowelOnset,\n\t\tstable: findVowelStable(f, vowelOnset, to),\n\t\tprevoiced:\n\t\t\tcls === \"plosiveVoiced\" && hasPrevoicing(f, consStart, vowelOnset),\n\t};\n}\n\n/** Round to the 0.001 ms oto.ini files conventionally carry. */\nfunction round(ms: number): number {\n\treturn Math.round(ms * 1000) / 1000;\n}\n\n/**\n * Turn frame positions into the five oto.ini numbers.\n *\n * `endFrame` is where the usable region stops; 右ブランク is always written in\n * its negative form (relative to the offset), which stays correct no matter how\n * much silence trails the file.\n */\nfunction buildEntry(\n\twav: string,\n\talias: string,\n\tf: Frames,\n\tcls: ConsonantClass,\n\tpos: MoraPosition,\n\tendFrame: number,\n): OtoEntry {\n\tconst art = ARTICULATION[cls];\n\n\t// Offset: leave a little air before the attack, but never let the consonant\n\t// run longer than the class allows.\n\tlet offsetMs = frameTimeMs(pos.consStart) - art.leadInMs;\n\tconst vowelMs = frameTimeMs(pos.vowelOnset);\n\toffsetMs = Math.max(offsetMs, vowelMs - art.maxConsonantMs);\n\toffsetMs = clamp(offsetMs, 0, Math.max(0, vowelMs - 1));\n\n\tconst pre = Math.max(1, vowelMs - offsetMs);\n\n\tlet overlap: number;\n\tif (art.fixedOverlapMs !== undefined) {\n\t\t// Bare vowels have no consonant to hide a crossfade in, so the wiki lets\n\t\t// the overlap run past the (tiny) preutterance; plosives take their\n\t\t// negative closure gap. Neither scales with anything measured.\n\t\toverlap = art.fixedOverlapMs;\n\t} else {\n\t\t// \"下限はどの発音であっても早くて15ミリ秒程度、上限は先行発声と同じ値くらい\"\n\t\toverlap = clamp(\n\t\t\tart.overlapRatio * pre,\n\t\t\tMath.min(MIN_OVERLAP_MS, pre),\n\t\t\tMath.min(MAX_OVERLAP_MS, pre),\n\t\t);\n\t}\n\n\t// 子音部: through the vowel onset and on until the vowel is steady, so only\n\t// steady-state vowel ever gets stretched.\n\tconst consonant = Math.max(\n\t\tpre + 10,\n\t\tMath.abs(overlap) + 10,\n\t\tframeTimeMs(pos.stable) - offsetMs,\n\t);\n\n\t// Keep at least a little stretchable vowel past the fixed region.\n\tconst endMs = Math.max(frameTimeMs(endFrame), offsetMs + consonant + 30);\n\tconst cutoff = -(Math.min(endMs, f.durationMs) - offsetMs);\n\n\treturn {\n\t\twav,\n\t\talias,\n\t\toffset: round(offsetMs),\n\t\tconsonant: round(consonant),\n\t\tcutoff: round(cutoff),\n\t\tpre: round(pre),\n\t\toverlap: round(overlap),\n\t};\n}\n\n/**\n * 単独音: one mora per file, one entry per alias.\n *\n * `aliases` lets a caller emit the usual family for a file — the bare kana plus\n * a `- か` head variant — all sharing the same measurements.\n */\nexport function estimateSolo(\n\twav: string,\n\tf: Frames,\n\tsyl: Syllable,\n\taliases: string[],\n): OtoEntry[] {\n\tconst soundStart = findSoundStart(f, 0, f.n);\n\tconst soundEnd = findSoundEnd(f, soundStart, f.n);\n\tconst pos = locateMora(f, syl.cls, 0, soundEnd);\n\tconst end = findDecayStart(f, pos.stable, soundEnd);\n\treturn aliases.map((alias) => buildEntry(wav, alias, f, syl.cls, pos, end));\n}\n\n/**\n * A 母音結合 entry (`* あ`): a mid-phrase vowel taken from the steady part of\n * the note, with the long symmetric crossfade those aliases are used with.\n */\nexport function estimateVowelJoin(\n\twav: string,\n\tf: Frames,\n\tsyl: Syllable,\n\talias: string,\n): OtoEntry | null {\n\tconst soundStart = findSoundStart(f, 0, f.n);\n\tconst soundEnd = findSoundEnd(f, soundStart, f.n);\n\tconst pos = locateMora(f, syl.cls, 0, soundEnd);\n\tconst end = findDecayStart(f, pos.stable, soundEnd);\n\n\t// The wiki's values for 母音結合: 先行発声 50, オーバーラップ twice that, and\n\t// a 固定範囲 just past the crossfade. They only work if the note is long\n\t// enough to hold them.\n\tconst pre = 50;\n\tconst overlap = 100;\n\tconst consonant = 110;\n\t// The entry begins exactly where the vowel settled: everything a 母音結合\n\t// alias plays is steady-state, with the preutterance sitting inside it.\n\tconst offsetMs = frameTimeMs(pos.stable);\n\tconst endMs = frameTimeMs(end);\n\tif (offsetMs < 0 || endMs - offsetMs < consonant + 40) return null;\n\n\treturn {\n\t\twav,\n\t\talias,\n\t\toffset: round(offsetMs),\n\t\tconsonant,\n\t\tcutoff: round(-(endMs - offsetMs)),\n\t\tpre,\n\t\toverlap,\n\t};\n}\n\n/** A 連続音 recording's rhythmic grid. */\nexport interface Grid {\n\t/** Frame of the first mora's onset. */\n\tstart: number;\n\t/** Frames between successive moras. */\n\tinterval: number;\n\t/** Per-mora onset frames, snapped to the strongest nearby transition. */\n\tonsets: number[];\n}\n\n/** How far a snapped onset may pull away from the fitted tempo line. */\nconst GRID_SNAP_WEIGHT = 0.6;\n\n/** Least-squares line through (index, value) pairs. */\nfunction fitLine(values: readonly number[]): {\n\tintercept: number;\n\tslope: number;\n} {\n\tconst n = values.length;\n\tif (n < 2) return { intercept: values[0] ?? 0, slope: 0 };\n\tlet sx = 0;\n\tlet sy = 0;\n\tlet sxx = 0;\n\tlet sxy = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tsx += i;\n\t\tsy += values[i];\n\t\tsxx += i * i;\n\t\tsxy += i * values[i];\n\t}\n\tconst denom = n * sxx - sx * sx;\n\tconst slope = denom !== 0 ? (n * sxy - sx * sy) / denom : 0;\n\treturn { intercept: (sy - slope * sx) / n, slope };\n}\n\n/** Combined onset strength: spectral change plus a local rise in level. */\nfunction onsetStrength(f: Frames): Float32Array {\n\tconst k = Math.max(1, msToFrame(12));\n\tconst out = new Float32Array(f.n);\n\tfor (let t = 0; t < f.n; t++) {\n\t\tconst rise =\n\t\t\tf.smoothDb[Math.min(f.n - 1, t + k)] - f.smoothDb[Math.max(0, t - k)];\n\t\tout[t] = f.flux[t] + Math.max(0, rise) / 3;\n\t}\n\treturn smooth(out, Math.max(1, msToFrame(8)));\n}\n\n/**\n * Fit `count` evenly spaced moras to the recording.\n *\n * 連続音 lists are sung to a guide BGM, so the moras land on a metronomic grid —\n * which is exactly why the wiki treats 連続音 oto as something you *generate*\n * and then touch up. Fitting a global tempo first, and only then snapping each\n * mora to the nearest real transition, keeps one mis-detected onset from\n * dragging the rest of the file out of alignment.\n */\nexport function detectGrid(f: Frames, count: number): Grid | null {\n\tif (count < 1) return null;\n\tconst strength = onsetStrength(f);\n\tconst uttStart = findSoundStart(f, 0, f.n);\n\tconst uttEnd = findSoundEnd(f, uttStart, f.n);\n\tconst span = uttEnd - uttStart;\n\tif (span < msToFrame(80)) return null;\n\n\tif (count === 1) {\n\t\treturn { start: uttStart, interval: span, onsets: [uttStart] };\n\t}\n\n\tconst candidates = intervalCandidates(\n\t\tstrength,\n\t\tuttStart,\n\t\tuttEnd,\n\t\tspan / count,\n\t);\n\tconst best = { score: -Infinity, start: uttStart, interval: span / count };\n\tconst search = (requireFit: boolean): void => {\n\t\tfor (const candidate of candidates) {\n\t\t\tfor (\n\t\t\t\tlet iv = candidate * 0.85;\n\t\t\t\tiv <= candidate * 1.18;\n\t\t\t\tiv += candidate * 0.02\n\t\t\t) {\n\t\t\t\t// Every grid point looks for its onset in a window of the same width,\n\t\t\t\t// so one sliding-window maximum serves the whole phase sweep.\n\t\t\t\tconst near = windowArgMax(strength, Math.round(iv * 0.22));\n\t\t\t\tconst tol = iv * 0.22;\n\t\t\t\tconst hardEnd = uttEnd + iv * 0.4;\n\t\t\t\tfor (\n\t\t\t\t\tlet phase = uttStart - iv * 0.25;\n\t\t\t\t\tphase <= uttStart + iv * 0.5;\n\t\t\t\t\tphase += 1\n\t\t\t\t) {\n\t\t\t\t\tif (requireFit && phase + (count - 1) * iv > hardEnd) break;\n\t\t\t\t\tlet total = 0;\n\t\t\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\t\t\tconst centre = phase + i * iv;\n\t\t\t\t\t\tconst at = near[clamp(Math.round(centre), 0, f.n - 1)];\n\t\t\t\t\t\ttotal += strength[at] - Math.abs(at - centre) / tol;\n\t\t\t\t\t}\n\t\t\t\t\tif (total > best.score) {\n\t\t\t\t\t\tbest.score = total;\n\t\t\t\t\t\tbest.start = phase;\n\t\t\t\t\t\tbest.interval = iv;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Normally every mora has to fit inside the utterance. When none of the\n\t// candidate tempos can manage that — a phrase sung faster at the end, or an\n\t// utterance whose tail the threshold clipped — a grid that overruns is still\n\t// far better than no entries at all for the file.\n\tsearch(true);\n\tif (!Number.isFinite(best.score)) search(false);\n\tif (!Number.isFinite(best.score)) return null;\n\n\tconst near = windowArgMax(strength, Math.round(best.interval * 0.25));\n\tconst snapped: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tsnapped.push(\n\t\t\tnear[clamp(Math.round(best.start + i * best.interval), 0, f.n - 1)],\n\t\t);\n\t}\n\n\t// Refit the tempo to where the onsets actually landed, then pull each one\n\t// back toward that line. A vowel-to-vowel join has no attack to lock onto and\n\t// its peak wanders; the singer's own timing does not.\n\tconst { intercept, slope } = fitLine(snapped);\n\tconst onsets: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst fitted = intercept + slope * i;\n\t\tconst blended = Math.round(\n\t\t\tfitted + (snapped[i] - fitted) * GRID_SNAP_WEIGHT,\n\t\t);\n\t\tonsets.push(i > 0 ? Math.max(blended, onsets[i - 1] + 4) : blended);\n\t}\n\n\treturn {\n\t\tstart: onsets[0],\n\t\tinterval: slope > 0 ? slope : best.interval,\n\t\tonsets,\n\t};\n}\n\n/**\n * For every index, the index of the largest value within ±`half` of it.\n * A monotonic deque keeps this linear regardless of the window width.\n */\nfunction windowArgMax(src: Float32Array, half: number): Int32Array {\n\tconst n = src.length;\n\tconst out = new Int32Array(n);\n\tconst deque = new Int32Array(n);\n\tlet head = 0;\n\tlet tail = 0;\n\tlet next = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst limit = Math.min(n - 1, i + half);\n\t\twhile (next <= limit) {\n\t\t\twhile (tail > head && src[deque[tail - 1]] <= src[next]) tail--;\n\t\t\tdeque[tail++] = next++;\n\t\t}\n\t\twhile (deque[head] < i - half) head++;\n\t\tout[i] = deque[head];\n\t}\n\treturn out;\n}\n\n/**\n * Plausible mora intervals, in frames.\n *\n * Dividing the utterance by the mora count only works when the recording stops\n * shortly after the last mora; plenty of lists hold the final vowel for a\n * second or more, which inflates the estimate past any sane tempo. Auto-\n * correlating the onset track measures the beat directly instead, and its\n * *shortest* strong peak is the beat rather than a multiple of it.\n */\nfunction intervalCandidates(\n\tstrength: Float32Array,\n\tfrom: number,\n\tto: number,\n\tfromSpan: number,\n): number[] {\n\tconst lo = msToFrame(180);\n\tconst hi = Math.min(msToFrame(1300), Math.floor((to - from) / 2));\n\tconst out: number[] = [];\n\tif (hi > lo) {\n\t\tlet mean = 0;\n\t\tfor (let t = from; t < to; t++) mean += strength[t];\n\t\tmean /= Math.max(1, to - from);\n\n\t\tconst r = new Float64Array(hi + 1);\n\t\tlet peak = 0;\n\t\tfor (let lag = lo; lag <= hi; lag++) {\n\t\t\tlet sum = 0;\n\t\t\tlet n = 0;\n\t\t\tfor (let t = from; t + lag < to; t++, n++) {\n\t\t\t\tsum += (strength[t] - mean) * (strength[t + lag] - mean);\n\t\t\t}\n\t\t\tr[lag] = n > 0 ? sum / n : 0;\n\t\t\tif (r[lag] > peak) peak = r[lag];\n\t\t}\n\t\tif (peak > 0) {\n\t\t\tfor (let lag = lo + 1; lag < hi; lag++) {\n\t\t\t\tif (r[lag] < peak * 0.7) continue;\n\t\t\t\tif (r[lag] < r[lag - 1] || r[lag] < r[lag + 1]) continue;\n\t\t\t\tout.push(lag);\n\t\t\t\tif (out.length >= 2) break;\n\t\t\t}\n\t\t}\n\t}\n\tout.push(fromSpan);\n\n\t// Every peak's halves and thirds go in too. A list where every other mora is\n\t// a weak ん correlates most strongly at *two* moras, and nothing but trying\n\t// the sub-multiple tells the two apart — the grid score then picks.\n\tconst withSubmultiples: number[] = [];\n\tconst seen = new Set<number>();\n\tconst shortest = msToFrame(150);\n\tfor (const c of out) {\n\t\tfor (const divisor of [1, 2, 3]) {\n\t\t\tconst key = Math.round(c / divisor);\n\t\t\tif (key < shortest || seen.has(key)) continue;\n\t\t\tseen.add(key);\n\t\t\twithSubmultiples.push(key);\n\t\t}\n\t}\n\t// An utterance too short for even one plausible interval still has to yield\n\t// a grid; the caller has moras to place either way.\n\tif (withSubmultiples.length === 0) withSubmultiples.push(shortest);\n\treturn withSubmultiples;\n}\n\n/**\n * Where a mora's vowel starts *inside* a phrase, where nothing is silent.\n *\n * A voiceless consonant still cuts the voicing, so the vowel begins when the\n * folds come back. Everything else — a vowel following a vowel, a nasal, a\n * glide — never stops phonating, and its boundary is the transition itself,\n * which is what the grid already snapped to.\n */\nfunction sequenceVowelOnset(\n\tf: Frames,\n\tcls: ConsonantClass,\n\tonset: number,\n\tnext: number,\n): number {\n\tif (ARTICULATION[cls].voicedConsonant) return onset + SEQUENCE_ONSET_BIAS;\n\n\tconst lo = Math.max(0, onset - msToFrame(100));\n\tconst hi = Math.min(next, onset + msToFrame(150));\n\tlet quietest = onset;\n\tfor (let t = lo; t < hi; t++) {\n\t\tif (f.voiced[t] < f.voiced[quietest]) quietest = t;\n\t}\n\tif (f.voiced[quietest] >= VOICED_THRESHOLD) return onset;\n\n\tconst resumed = findVoiceOnset(\n\t\tf,\n\t\tquietest,\n\t\tMath.min(next, hi + msToFrame(80)),\n\t);\n\treturn resumed >= 0 ? resumed : onset;\n}\n\n/**\n * 連続音: every mora in the file gets an entry, aliased against the vowel it\n * follows (`a か`), with the first written as a phrase head (`- あ`).\n *\n * The template — 先行発声 at half the mora interval, オーバーラップ at a third of\n * that, 固定範囲 half again as long, 右ブランク two thirds of an interval past the\n * note — is the one the established 連続音 banks ship, and it survives a mora\n * whose consonant is longer than average because half an interval is far more\n * room than any Japanese onset needs.\n */\nexport function estimateSequence(\n\twav: string,\n\tf: Frames,\n\tsyllables: Syllable[],\n\topts: { suffix?: string; prefix?: string; trailingRest?: boolean } = {},\n): OtoEntry[] {\n\tconst grid = detectGrid(f, syllables.length);\n\tif (!grid) return [];\n\n\tconst intervalMs = framesToMs(grid.interval);\n\t// Half an interval, but never more than 250 ms — which is both what every\n\t// reference bank writes and far more room than any Japanese onset needs.\n\tconst pre = clamp(intervalMs / 2, 60, MAX_SEQUENCE_PRE_MS);\n\tconst overlap = round(pre / 3);\n\tconst consonant = round(pre * 1.5);\n\tconst suffix = opts.suffix ?? \"\";\n\t// A head marker describes how the phrase *starts*, so it belongs on the\n\t// phrase-head alias and nowhere else.\n\tconst prefix = opts.prefix ?? \"\";\n\n\tconst entries: OtoEntry[] = [];\n\tfor (let i = 0; i < syllables.length; i++) {\n\t\tconst syl = syllables[i];\n\t\tconst onset = grid.onsets[i];\n\t\tconst next =\n\t\t\ti + 1 < syllables.length\n\t\t\t\t? grid.onsets[i + 1]\n\t\t\t\t: findSoundEnd(f, onset, f.n);\n\n\t\tlet vowelFrame: number;\n\t\tif (i === 0) {\n\t\t\t// The phrase head is the one mora with real silence in front of it, so\n\t\t\t// it can be measured the same way a 単独音 file is.\n\t\t\tvowelFrame = locateMora(f, syl.cls, 0, next).vowelOnset;\n\t\t} else {\n\t\t\tvowelFrame = sequenceVowelOnset(f, syl.cls, onset, next);\n\t\t}\n\n\t\tconst noteMs = frameTimeMs(vowelFrame);\n\t\tconst offsetMs = clamp(noteMs - pre, 0, Math.max(0, noteMs - 1));\n\t\tconst actualPre = noteMs - offsetMs;\n\t\t// 右ブランク reaches two thirds of an interval past the note, so each mora's\n\t\t// tail is still there for the next one to cross-fade into.\n\t\tconst endMs = Math.min(f.durationMs, noteMs + (intervalMs * 2) / 3);\n\n\t\tconst alias =\n\t\t\ti === 0\n\t\t\t\t? `- ${prefix}${syl.kana}${suffix}`\n\t\t\t\t: `${syllables[i - 1].vowel} ${syl.kana}${suffix}`;\n\n\t\tentries.push({\n\t\t\twav,\n\t\t\talias,\n\t\t\toffset: round(offsetMs),\n\t\t\tconsonant: Math.max(round(consonant), round(actualPre + 20)),\n\t\t\tcutoff: round(-Math.max(endMs - offsetMs, consonant + 40)),\n\t\t\tpre: round(actualPre),\n\t\t\toverlap: i === 0 ? 0 : Math.min(overlap, round(actualPre)),\n\t\t});\n\t}\n\n\tif (opts.trailingRest && syllables.length > 0) {\n\t\tconst last = syllables[syllables.length - 1];\n\t\tconst lastOnset = grid.onsets[syllables.length - 1];\n\t\tconst soundEnd = findSoundEnd(f, lastOnset, f.n);\n\t\tconst decay = findDecayStart(f, lastOnset, soundEnd);\n\t\tconst noteMs = frameTimeMs(decay);\n\t\tconst offsetMs = clamp(noteMs - pre, 0, Math.max(0, noteMs - 1));\n\t\tconst actualPre = noteMs - offsetMs;\n\t\tentries.push({\n\t\t\twav,\n\t\t\talias: `${last.vowel} R${suffix}`,\n\t\t\toffset: round(offsetMs),\n\t\t\tconsonant: round(consonant),\n\t\t\tcutoff: round(\n\t\t\t\t-(Math.min(f.durationMs, frameTimeMs(soundEnd)) - offsetMs),\n\t\t\t),\n\t\t\tpre: round(actualPre),\n\t\t\toverlap: Math.min(overlap, round(actualPre)),\n\t\t});\n\t}\n\n\treturn entries;\n}\n","/**\n * Kana → phoneme tables for oto.ini generation.\n *\n * A UTAU recording's filename *is* its phonetic transcript: `か.wav` holds one\n * mora, `_ああいあうえあ.wav` holds seven. Everything the estimator does — where\n * to look for the vowel, how wide to make the crossfade, whether the overlap\n * goes negative — follows from which consonant a mora starts with, so the kana\n * has to be resolved into (consonant, vowel) before any audio is touched.\n */\n\n/**\n * Articulation class of a mora's initial consonant. The estimator branches on\n * this to pick where the preutterance lands and what overlap the mora gets;\n * see `ARTICULATION` in `estimate.ts`.\n */\nexport type ConsonantClass =\n\t/** あ/い/う/え/お — no consonant at all. */\n\t| \"vowel\"\n\t/** ん — a syllabic nasal that is its own nucleus. */\n\t| \"nasalN\"\n\t/** な/ま行 — voiced throughout, vowel starts at the nasal release. */\n\t| \"nasal\"\n\t/** ら行 — a flap: brief closure, then the vowel. */\n\t| \"liquid\"\n\t/** や/わ行 and vowel glides (いぇ, うぉ) — barely a consonant at all. */\n\t| \"semivowel\"\n\t/** さ/は行 — voiceless noise, so voicing onset *is* the vowel onset. */\n\t| \"fricativeVoiceless\"\n\t/** ざ行, ヴ — voiced noise. */\n\t| \"fricativeVoiced\"\n\t/** つ/ち — a stop released into friction; behaves like a plosive. */\n\t| \"affricate\"\n\t/** か/た/ぱ行 — a silent closure precedes the burst. */\n\t| \"plosiveVoiceless\"\n\t/** が/だ/ば行 — may prevoice through the closure. */\n\t| \"plosiveVoiced\";\n\nexport interface Syllable {\n\t/** The kana as written, e.g. \"きゃ\". Used verbatim in the alias. */\n\tkana: string;\n\t/** Romanised onset, e.g. \"ky\". Empty for bare vowels and ん. */\n\tconsonant: string;\n\t/** Romanised nucleus: a/i/u/e/o, or \"n\" for ん. */\n\tvowel: string;\n\tcls: ConsonantClass;\n}\n\nconst CLASS_OF: Record<string, ConsonantClass> = {\n\t\"\": \"vowel\",\n\tk: \"plosiveVoiceless\",\n\tky: \"plosiveVoiceless\",\n\tt: \"plosiveVoiceless\",\n\tty: \"plosiveVoiceless\",\n\tp: \"plosiveVoiceless\",\n\tpy: \"plosiveVoiceless\",\n\tg: \"plosiveVoiced\",\n\tgy: \"plosiveVoiced\",\n\td: \"plosiveVoiced\",\n\tdy: \"plosiveVoiced\",\n\tb: \"plosiveVoiced\",\n\tby: \"plosiveVoiced\",\n\ts: \"fricativeVoiceless\",\n\tsh: \"fricativeVoiceless\",\n\th: \"fricativeVoiceless\",\n\thy: \"fricativeVoiceless\",\n\tf: \"fricativeVoiceless\",\n\tz: \"fricativeVoiced\",\n\tj: \"fricativeVoiced\",\n\tv: \"fricativeVoiced\",\n\tts: \"affricate\",\n\tch: \"affricate\",\n\tn: \"nasal\",\n\tny: \"nasal\",\n\tm: \"nasal\",\n\tmy: \"nasal\",\n\tr: \"liquid\",\n\try: \"liquid\",\n\ty: \"semivowel\",\n\tw: \"semivowel\",\n};\n\n/**\n * kana → \"consonant vowel\". A space-separated pair keeps the table readable;\n * a leading space means \"no consonant\".\n */\nconst KANA: Record<string, string> = {\n\tあ: \" a\",\n\tい: \" i\",\n\tう: \" u\",\n\tえ: \" e\",\n\tお: \" o\",\n\tん: \" n\",\n\tか: \"k a\",\n\tき: \"k i\",\n\tく: \"k u\",\n\tけ: \"k e\",\n\tこ: \"k o\",\n\tが: \"g a\",\n\tぎ: \"g i\",\n\tぐ: \"g u\",\n\tげ: \"g e\",\n\tご: \"g o\",\n\tさ: \"s a\",\n\tし: \"sh i\",\n\tす: \"s u\",\n\tせ: \"s e\",\n\tそ: \"s o\",\n\tざ: \"z a\",\n\tじ: \"j i\",\n\tず: \"z u\",\n\tぜ: \"z e\",\n\tぞ: \"z o\",\n\tた: \"t a\",\n\tち: \"ch i\",\n\tつ: \"ts u\",\n\tて: \"t e\",\n\tと: \"t o\",\n\tだ: \"d a\",\n\tぢ: \"j i\",\n\tづ: \"z u\",\n\tで: \"d e\",\n\tど: \"d o\",\n\tな: \"n a\",\n\tに: \"n i\",\n\tぬ: \"n u\",\n\tね: \"n e\",\n\tの: \"n o\",\n\tは: \"h a\",\n\tひ: \"h i\",\n\tふ: \"f u\",\n\tへ: \"h e\",\n\tほ: \"h o\",\n\tば: \"b a\",\n\tび: \"b i\",\n\tぶ: \"b u\",\n\tべ: \"b e\",\n\tぼ: \"b o\",\n\tぱ: \"p a\",\n\tぴ: \"p i\",\n\tぷ: \"p u\",\n\tぺ: \"p e\",\n\tぽ: \"p o\",\n\tま: \"m a\",\n\tみ: \"m i\",\n\tむ: \"m u\",\n\tめ: \"m e\",\n\tも: \"m o\",\n\tや: \"y a\",\n\tゆ: \"y u\",\n\tよ: \"y o\",\n\tら: \"r a\",\n\tり: \"r i\",\n\tる: \"r u\",\n\tれ: \"r e\",\n\tろ: \"r o\",\n\tわ: \"w a\",\n\tゐ: \"w i\",\n\tゑ: \"w e\",\n\tを: \"w o\",\n\tゔ: \"v u\",\n};\n\n/** Small kana that can only appear as the second half of a digraph. */\nconst SMALL: Record<string, string> = {\n\tぁ: \"a\",\n\tぃ: \"i\",\n\tぅ: \"u\",\n\tぇ: \"e\",\n\tぉ: \"o\",\n\tゃ: \"a\",\n\tゅ: \"u\",\n\tょ: \"o\",\n\tゎ: \"a\",\n};\n\n/** Digraphs whose onset is not simply \"base consonant + y\". */\nconst DIGRAPH: Record<string, string> = {\n\tしゃ: \"sh a\",\n\tしゅ: \"sh u\",\n\tしょ: \"sh o\",\n\tしぇ: \"sh e\",\n\tじゃ: \"j a\",\n\tじゅ: \"j u\",\n\tじょ: \"j o\",\n\tじぇ: \"j e\",\n\tちゃ: \"ch a\",\n\tちゅ: \"ch u\",\n\tちょ: \"ch o\",\n\tちぇ: \"ch e\",\n\tぢゃ: \"j a\",\n\tぢゅ: \"j u\",\n\tぢょ: \"j o\",\n\tつぁ: \"ts a\",\n\tつぃ: \"ts i\",\n\tつぇ: \"ts e\",\n\tつぉ: \"ts o\",\n\tてぃ: \"t i\",\n\tてゃ: \"ty a\",\n\tてゅ: \"ty u\",\n\tてょ: \"ty o\",\n\tでぃ: \"d i\",\n\tでゃ: \"dy a\",\n\tでゅ: \"dy u\",\n\tでょ: \"dy o\",\n\tとぅ: \"t u\",\n\tどぅ: \"d u\",\n\tふぁ: \"f a\",\n\tふぃ: \"f i\",\n\tふぇ: \"f e\",\n\tふぉ: \"f o\",\n\tふゅ: \"f u\",\n\tゔぁ: \"v a\",\n\tゔぃ: \"v i\",\n\tゔぇ: \"v e\",\n\tゔぉ: \"v o\",\n\tゔゅ: \"v u\",\n\tくぁ: \"k a\",\n\tくぃ: \"k i\",\n\tくぇ: \"k e\",\n\tくぉ: \"k o\",\n\tぐぁ: \"g a\",\n\tぐぃ: \"g i\",\n\tぐぇ: \"g e\",\n\tぐぉ: \"g o\",\n\tすぃ: \"s i\",\n\tずぃ: \"z i\",\n};\n\n/**\n * Katakana → hiragana, so ヴァ and ゔぁ resolve identically. Only the kana\n * block is folded; ー and everything else is left alone for the caller to\n * reject.\n */\nexport function toHiragana(s: string): string {\n\tlet out = \"\";\n\tfor (const ch of s) {\n\t\tconst c = ch.codePointAt(0) ?? 0;\n\t\t// Katakana ァ(30A1)–ヶ(30F6) map onto hiragana ぁ(3041)–ゖ(3096).\n\t\tout += c >= 0x30a1 && c <= 0x30f6 ? String.fromCodePoint(c - 0x60) : ch;\n\t}\n\treturn out;\n}\n\nfunction make(kana: string, pair: string): Syllable {\n\tconst sp = pair.indexOf(\" \");\n\tconst consonant = pair.slice(0, sp);\n\tconst vowel = pair.slice(sp + 1);\n\treturn { kana, consonant, vowel, cls: CLASS_OF[consonant] ?? \"vowel\" };\n}\n\n/**\n * Resolve one kana or digraph starting at `i`, returning the syllable and how\n * many characters it consumed — or null if the text is not kana we know.\n */\nfunction readSyllable(\n\tsrc: string,\n\thira: string,\n\ti: number,\n): { syl: Syllable; len: number } | null {\n\tconst two = hira.slice(i, i + 2);\n\tif (two.length === 2) {\n\t\tconst explicit = DIGRAPH[two];\n\t\tif (explicit) return { syl: make(src.slice(i, i + 2), explicit), len: 2 };\n\n\t\tconst small = SMALL[two[1]];\n\t\tconst base = KANA[two[0]];\n\t\tif (small && base) {\n\t\t\tconst sp = base.indexOf(\" \");\n\t\t\tconst baseConsonant = base.slice(0, sp);\n\t\t\tconst baseVowel = base.slice(sp + 1);\n\t\t\t// きゃ = k + i + a → a palatalised \"ky\" onset.\n\t\t\tif (baseVowel === \"i\" && CLASS_OF[`${baseConsonant}y`]) {\n\t\t\t\tconst pair = `${baseConsonant}y ${small}`;\n\t\t\t\treturn { syl: make(src.slice(i, i + 2), pair), len: 2 };\n\t\t\t}\n\t\t\t// いぇ / うぉ — a bare vowel gliding into another is a semivowel.\n\t\t\tif (!baseConsonant) {\n\t\t\t\tconst glide = baseVowel === \"i\" ? \"y\" : baseVowel === \"u\" ? \"w\" : \"\";\n\t\t\t\tconst syl = make(src.slice(i, i + 2), `${glide} ${small}`);\n\t\t\t\t// おぁ has no romanisable onset, but it still articulates like one.\n\t\t\t\treturn { syl: { ...syl, cls: \"semivowel\" }, len: 2 };\n\t\t\t}\n\t\t\t// Anything else keeps the base consonant and takes the small kana as\n\t\t\t// its vowel: ぢぇ is /je/, くゎ is a labialised /ka/, づぉ is /zo/. The\n\t\t\t// nucleus is what the estimator needs, and this gets it right for every\n\t\t\t// combination a recording list can invent.\n\t\t\treturn {\n\t\t\t\tsyl: make(src.slice(i, i + 2), `${baseConsonant} ${small}`),\n\t\t\t\tlen: 2,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst one = KANA[hira[i]];\n\tif (one) return { syl: make(src.slice(i, i + 1), one), len: 1 };\n\treturn null;\n}\n\n/**\n * Split a kana string into moras.\n *\n * Returns null if any character is not kana we can resolve — that is the\n * signal to skip the file entirely, which is what keeps a bank's karaoke\n * tracks and readme audio out of the generated oto.ini.\n */\nexport function splitKana(text: string): Syllable[] | null {\n\tconst src = text.normalize(\"NFC\");\n\tconst hira = toHiragana(src);\n\tconst out: Syllable[] = [];\n\n\tfor (let i = 0; i < hira.length; ) {\n\t\tconst ch = hira[i];\n\t\t// っ marks a geminate: the closure belongs to the following mora, and\n\t\t// there is nothing to voice on its own.\n\t\tif (ch === \"っ\" || ch === \"ー\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst read = readSyllable(src, hira, i);\n\t\tif (!read) return null;\n\t\tout.push(read.syl);\n\t\ti += read.len;\n\t}\n\n\treturn out.length > 0 ? out : null;\n}\n\n/**\n * Vowel a following mora connects to, as written in a 連続音 alias\n * (`a か`). ん connects as \"n\".\n */\nexport function connectingVowel(syl: Syllable): string {\n\treturn syl.vowel;\n}\n","/**\n * Folder → oto.ini, with no manual step in between.\n *\n * The filename carries the transcript, so the recording style falls out of it:\n * one mora per file is 単独音, several is 連続音. Everything else — which\n * aliases to emit, where the phrase head goes, whether a trailing R belongs on\n * the end — follows from the same parse.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\nimport { parseWav } from \"../converter/wav.js\";\nimport {\n\testimateSequence,\n\testimateSolo,\n\testimateVowelJoin,\n} from \"./estimate.js\";\nimport { analyze, type Frames } from \"./frames.js\";\nimport { type Syllable, splitKana, toHiragana } from \"./kana.js\";\n\nexport interface GenerateOptions {\n\t/**\n\t * Appended to every alias — the usual home for a multi-pitch or expression\n\t * marker (`_G4`, `強`). Defaults to the folder's own note name when it has\n\t * one; pass `\"\"` to suppress that.\n\t */\n\tsuffix?: string;\n\t/** Emit `- か` phrase-head aliases alongside the bare kana. Default true. */\n\theadAliases?: boolean;\n\t/** Emit `* あ` 母音結合 aliases for vowel-only files. Default true. */\n\tvowelJoinAliases?: boolean;\n}\n\n/** One file that could not be transcribed, and why. */\nexport interface SkippedFile {\n\twav: string;\n\treason: string;\n}\n\nexport interface GenerateResult {\n\tentries: OtoEntry[];\n\tskipped: SkippedFile[];\n\t/** Recording style inferred from the filenames. */\n\tstyle: \"solo\" | \"sequence\" | \"mixed\" | \"empty\";\n}\n\n/** What one recording produced. */\nexport interface FileResult {\n\tentries: OtoEntry[];\n\t/** Set instead of entries when the file could not be set up. */\n\tskipped: SkippedFile | null;\n\t/** Style this one file was read as, or null if it was skipped. */\n\tstyle: \"solo\" | \"sequence\" | null;\n}\n\nexport interface WavInput {\n\t/** Filename as it appears in oto.ini, e.g. `_ああいあう.wav`. */\n\tname: string;\n\tdata: ArrayBuffer;\n}\n\n/** A rest/breath marker that ends a 連続音 phrase. */\nconst REST = /[RrRr]$|息$|吸$/;\n\ninterface Transcript {\n\tsyllables: Syllable[];\n\ttrailingRest: boolean;\n\t/** Non-kana marker before the kana, e.g. the `x` of `_xか.wav`. */\n\tprefix: string;\n\t/** Non-kana marker after the kana, e.g. the `b` of `_あb.wav`. */\n\tmark: string;\n}\n\n/**\n * Read the transcript out of a filename.\n *\n * The leading `_` that marks a recording-list file, an extension, and a\n * trailing pitch tag are all noise; what is left has to be kana end to end, or\n * the file is not a voice sample we can set up (a karaoke track, a sample song,\n * a readme recording).\n */\nexport function transcribe(filename: string): Transcript | null {\n\tlet body = filename.replace(/\\.[^.]+$/, \"\");\n\tbody = body.replace(/^[_\\-\\s]+/, \"\");\n\t// Drop a per-file pitch tag such as `_C4` / `_A#3`.\n\tbody = body.replace(/_[A-G][#b]?-?\\d$/i, \"\");\n\tbody = body.trim();\n\tif (!body) return null;\n\n\t// Take markers ride along into the alias rather than being discarded: a bank\n\t// that recorded `_あb.wav` as a second take means its oto.ini to say `あb`,\n\t// and `_ううわうぉわ↑.wav` is a distinct entry from the unmarked one.\n\tlet mark = \"\";\n\tconst arrows = /[↑↓→]+$/.exec(body);\n\tif (arrows) {\n\t\tmark = arrows[0];\n\t\tbody = body.slice(0, -arrows[0].length);\n\t}\n\n\tlet trailingRest = false;\n\tif (REST.test(body)) {\n\t\ttrailingRest = true;\n\t\tbody = body.replace(REST, \"\");\n\t}\n\n\tconst take = /[A-Za-z0-9'][A-Za-z0-9']?$/.exec(body);\n\tif (take && body.length > take[0].length) {\n\t\tmark = take[0] + mark;\n\t\tbody = body.slice(0, -take[0].length);\n\t}\n\n\t// A leading ASCII marker only counts when kana follows it — `_xか.wav` is a\n\t// devoiced か, while `1646312012.wav` is not a recording at all.\n\tlet prefix = \"\";\n\tconst head = /^[A-Za-z]{1,2}(?=[ぁ-ゟァ-ヿ])/.exec(body);\n\tif (head) {\n\t\tprefix = head[0];\n\t\tbody = body.slice(head[0].length);\n\t}\n\tif (!body) return null;\n\n\tconst syllables = splitKana(body);\n\tif (!syllables) return null;\n\treturn { syllables, trailingRest, prefix, mark };\n}\n\n/**\n * Alias suffix implied by a folder's name.\n *\n * A multi-pitch bank keeps one folder per pitch and merges every oto.ini into\n * one alias namespace, so without the pitch tag each folder's `- あ` would\n * overwrite the last. The tag is taken either from a folder named for nothing\n * but the pitch (`G4`) or from an explicit `_G4` token inside a longer name\n * (`多音階03:_G4(連続音)`). A bare `G4` buried in a name is left alone — in\n * `表情音01:強(G4歌連続音)` it describes the take, and the suffix the bank\n * actually uses there is `強`, which no filename carries.\n */\nexport function suffixFromFolderName(folder: string): string {\n\tif (/^[A-G][#b]?-?\\d$/.test(folder)) return `_${folder}`;\n\tconst tagged = /_([A-G][#b]?-?\\d)(?![0-9A-Za-z])/.exec(folder);\n\treturn tagged ? `_${tagged[1]}` : \"\";\n}\n\nfunction aliasesFor(name: string, headAliases: boolean): string[] {\n\treturn headAliases ? [name, `- ${name}`] : [name];\n}\n\n/**\n * Estimate oto.ini entries for every WAV in one folder.\n *\n * Decoding and analysis are per-file and independent, so a bad WAV is reported\n * and skipped rather than failing the folder.\n */\nexport function generateOtoForFile(\n\tfile: WavInput,\n\toptions: GenerateOptions = {},\n): FileResult {\n\tconst suffix = options.suffix ?? \"\";\n\tconst headAliases = options.headAliases ?? true;\n\tconst vowelJoinAliases = options.vowelJoinAliases ?? true;\n\n\tconst transcript = transcribe(file.name);\n\tif (!transcript) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"filename is not kana\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\n\tlet frames: Frames;\n\ttry {\n\t\tframes = analyze(parseWav(file.data));\n\t} catch (err) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: {\n\t\t\t\twav: file.name,\n\t\t\t\treason: err instanceof Error ? err.message : String(err),\n\t\t\t},\n\t\t\tstyle: null,\n\t\t};\n\t}\n\tif (frames.n < 8) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"too short to analyse\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\n\tconst { syllables, trailingRest, prefix, mark } = transcript;\n\n\tif (syllables.length === 1 && !trailingRest) {\n\t\tconst syl = syllables[0];\n\t\tconst name = `${prefix}${syl.kana}${mark}${suffix}`;\n\t\tconst entries = estimateSolo(\n\t\t\tfile.name,\n\t\t\tframes,\n\t\t\tsyl,\n\t\t\taliasesFor(name, headAliases),\n\t\t);\n\n\t\t// あ/い/う/え/お/ん also get a 母音結合 entry, cut from the steady part of\n\t\t// the same note — the `* あ` aliases a 連続音-style phrase leans on.\n\t\tif (vowelJoinAliases && (syl.cls === \"vowel\" || syl.cls === \"nasalN\")) {\n\t\t\tconst join = estimateVowelJoin(file.name, frames, syl, `* ${name}`);\n\t\t\tif (join) entries.push(join);\n\t\t}\n\t\treturn { entries, skipped: null, style: \"solo\" };\n\t}\n\n\tconst entries = estimateSequence(file.name, frames, syllables, {\n\t\tsuffix: `${mark}${suffix}`,\n\t\tprefix,\n\t\ttrailingRest,\n\t});\n\tif (entries.length === 0) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"could not segment the phrase\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\treturn { entries, skipped: null, style: \"sequence\" };\n}\n\n/**\n * Estimate oto.ini entries for every WAV in one folder.\n *\n * Decoding and analysis are per-file and independent, so a bad WAV is reported\n * and skipped rather than failing the folder. A caller that needs to stay\n * responsive — a browser UI, say — should drive {@link generateOtoForFile}\n * itself and yield between files.\n */\nexport function generateOto(\n\tfiles: readonly WavInput[],\n\toptions: GenerateOptions = {},\n): GenerateResult {\n\tconst entries: OtoEntry[] = [];\n\tconst skipped: SkippedFile[] = [];\n\tlet solo = 0;\n\tlet sequence = 0;\n\n\tfor (const file of files) {\n\t\tconst result = generateOtoForFile(file, options);\n\t\tentries.push(...result.entries);\n\t\tif (result.skipped) skipped.push(result.skipped);\n\t\tif (result.style === \"solo\") solo++;\n\t\tif (result.style === \"sequence\") sequence++;\n\t}\n\n\treturn { entries, skipped, style: summarise(solo, sequence) };\n}\n\n/** Fold per-file styles into the one label that describes the folder. */\nexport function summarise(\n\tsolo: number,\n\tsequence: number,\n): GenerateResult[\"style\"] {\n\tif (solo && sequence) return \"mixed\";\n\tif (sequence) return \"sequence\";\n\tif (solo) return \"solo\";\n\treturn \"empty\";\n}\n\n/** Exposed for callers that want to pre-flight a folder without decoding audio. */\nexport function looksLikeVoiceFolder(names: readonly string[]): boolean {\n\treturn names.some(\n\t\t(n) => /\\.wav$/i.test(n) && transcribe(n) !== null && toHiragana(n) !== \"\",\n\t);\n}\n","/**\n * oto.ini serialisation.\n *\n * UTAU reads oto.ini as Shift-JIS, and OpenUtau follows a bank's declared\n * encoding, so writing UTF-8 would leave every kana alias mojibake in the\n * original editor. There is no Shift-JIS *encoder* in the platform — only a\n * decoder — so the table is built by decoding every legal byte pair once and\n * inverting the result.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\n\nlet reverseTable: Map<string, number> | null = null;\n\nfunction shiftJisTable(): Map<string, number> {\n\tif (reverseTable) return reverseTable;\n\tconst table = new Map<string, number>();\n\tconst decoder = new TextDecoder(\"shift_jis\", { fatal: false });\n\n\t// ASCII, plus the yen/overline substitutions Shift-JIS makes at 0x5C/0x7E.\n\tfor (let b = 0; b < 0x80; b++) {\n\t\ttable.set(decoder.decode(new Uint8Array([b])), b);\n\t}\n\t// Half-width katakana.\n\tfor (let b = 0xa1; b <= 0xdf; b++) {\n\t\ttable.set(decoder.decode(new Uint8Array([b])), b);\n\t}\n\t// Two-byte planes.\n\tconst pair = new Uint8Array(2);\n\tfor (let lead = 0x81; lead <= 0xfc; lead++) {\n\t\tif (lead > 0x9f && lead < 0xe0) continue;\n\t\tpair[0] = lead;\n\t\tfor (let trail = 0x40; trail <= 0xfc; trail++) {\n\t\t\tif (trail === 0x7f) continue;\n\t\t\tpair[1] = trail;\n\t\t\tconst ch = decoder.decode(pair);\n\t\t\t// A byte pair the decoder rejects comes back as U+FFFD, and a few map\n\t\t\t// to two characters; neither is usable as a round-trip entry.\n\t\t\tif (ch.length !== 1 || ch === \"�\") continue;\n\t\t\tif (!table.has(ch)) table.set(ch, (lead << 8) | trail);\n\t\t}\n\t}\n\n\treverseTable = table;\n\treturn table;\n}\n\n/**\n * Encode text as Shift-JIS. Characters with no Shift-JIS form become `?`,\n * matching what UTAU's own tools do rather than corrupting the line.\n */\nexport function encodeShiftJis(text: string): Uint8Array {\n\tconst table = shiftJisTable();\n\tconst out: number[] = [];\n\tfor (const ch of text) {\n\t\tconst code = table.get(ch);\n\t\tif (code === undefined) out.push(0x3f);\n\t\telse if (code > 0xff) out.push(code >> 8, code & 0xff);\n\t\telse out.push(code);\n\t}\n\treturn new Uint8Array(out);\n}\n\n/** Trim trailing zeros so `120.000` prints as `120`. */\nfunction num(v: number): string {\n\tconst s = v.toFixed(3);\n\treturn s.replace(/\\.?0+$/, \"\") || \"0\";\n}\n\n/** Render entries as oto.ini text (CRLF, as UTAU writes it). */\nexport function formatOto(entries: readonly OtoEntry[]): string {\n\treturn entries\n\t\t.map(\n\t\t\t(e) =>\n\t\t\t\t`${e.wav}=${e.alias},${num(e.offset)},${num(e.consonant)},${num(e.cutoff)},${num(e.pre)},${num(e.overlap)}`,\n\t\t)\n\t\t.join(\"\\r\\n\")\n\t\t.concat(\"\\r\\n\");\n}\n\n/** Render entries as Shift-JIS oto.ini bytes, ready to write to disk. */\nexport function encodeOto(entries: readonly OtoEntry[]): Uint8Array {\n\treturn encodeShiftJis(formatOto(entries));\n}\n","/**\n * Asset loading for the TTS stack: the Go UtauTTS wasm (~10 MB), the\n * jpreprocess wasm (~2 MB) and its naist-jdic dictionary (~29 MB gzipped,\n * ~80 MB inflated) and the TCN prosody model (~1 MB).\n *\n * Everything goes through {@link fetchAsset}, which streams the download with\n * progress callbacks and stores the raw response in the Cache API so the second\n * visit skips the network entirely (the browser HTTP cache alone is not\n * reliable for files this size).\n */\n\nexport interface AssetProgress {\n\turl: string;\n\t/** Bytes received so far (compressed bytes for gzipped files). */\n\tloaded: number;\n\t/** Total bytes when the server sent Content-Length, otherwise 0. */\n\ttotal: number;\n\t/** True when served from the Cache API (no network). */\n\tfromCache: boolean;\n}\n\nexport interface AssetFetchOptions {\n\t/**\n\t * Cache API bucket name. `null` disables caching. Defaults to\n\t * `\"koe-tts-assets-v1\"`.\n\t */\n\tcacheName?: string | null;\n\tonProgress?: (progress: AssetProgress) => void;\n\tsignal?: AbortSignal;\n\t/**\n\t * Check the cached copy against the server with a HEAD request (ETag,\n\t * Last-Modified or Content-Length) so a redeployed asset is refetched.\n\t * Offline or on error the cached copy is used. Default true.\n\t */\n\trevalidate?: boolean;\n}\n\nconst DEFAULT_CACHE = \"koe-tts-assets-v1\";\n\nasync function openCache(\n\tname: string | null | undefined,\n): Promise<Cache | null> {\n\tif (name === null) return null;\n\ttry {\n\t\tif (typeof caches === \"undefined\") return null;\n\t\treturn await caches.open(name ?? DEFAULT_CACHE);\n\t} catch {\n\t\t// file:// pages, private windows and insecure origins have no Cache API.\n\t\treturn null;\n\t}\n}\n\n/**\n * HEAD the asset and compare validators with the cached copy. Network errors\n * (offline) count as \"current\" so the cache keeps working without a server.\n */\nasync function cachedCopyIsCurrent(\n\turl: string,\n\tcached: Response,\n\tsignal?: AbortSignal,\n): Promise<boolean> {\n\tlet head: Response;\n\ttry {\n\t\thead = await fetch(url, { method: \"HEAD\", signal, cache: \"no-cache\" });\n\t} catch {\n\t\treturn true;\n\t}\n\tif (!head.ok) return true;\n\tfor (const name of [\"etag\", \"last-modified\", \"content-length\"]) {\n\t\tconst remote = head.headers.get(name);\n\t\tconst local = cached.headers.get(name);\n\t\tif (remote && local) return remote === local;\n\t}\n\treturn true;\n}\n\n/**\n * Fetch a static asset with download progress, backed by the Cache API.\n *\n * The returned Response has a fully buffered body, so it can be handed to\n * `WebAssembly.instantiateStreaming` / wasm-bindgen `init()` as-is.\n */\nexport async function fetchAsset(\n\turl: string,\n\toptions: AssetFetchOptions = {},\n): Promise<Response> {\n\tconst { onProgress, signal, revalidate = true } = options;\n\tconst cache = await openCache(options.cacheName);\n\tif (cache) {\n\t\ttry {\n\t\t\tconst hit = await cache.match(url);\n\t\t\tif (\n\t\t\t\thit &&\n\t\t\t\t(!revalidate || (await cachedCopyIsCurrent(url, hit, signal)))\n\t\t\t) {\n\t\t\t\tconst total = Number(hit.headers.get(\"content-length\")) || 0;\n\t\t\t\tonProgress?.({ url, loaded: total, total, fromCache: true });\n\t\t\t\treturn hit;\n\t\t\t}\n\t\t} catch {\n\t\t\t// fall through to the network\n\t\t}\n\t}\n\n\tconst response = await fetch(url, { signal });\n\tif (!response.ok) {\n\t\tthrow new Error(`fetch ${url}: HTTP ${response.status}`);\n\t}\n\tconst total = Number(response.headers.get(\"content-length\")) || 0;\n\tlet body: Uint8Array<ArrayBuffer>;\n\tif (response.body && onProgress) {\n\t\tconst reader = response.body.getReader();\n\t\tconst parts: Uint8Array[] = [];\n\t\tlet loaded = 0;\n\t\tonProgress({ url, loaded, total, fromCache: false });\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tparts.push(value);\n\t\t\tloaded += value.byteLength;\n\t\t\tonProgress({ url, loaded, total, fromCache: false });\n\t\t}\n\t\tbody = new Uint8Array(new ArrayBuffer(loaded));\n\t\tlet offset = 0;\n\t\tfor (const part of parts) {\n\t\t\tbody.set(part, offset);\n\t\t\toffset += part.byteLength;\n\t\t}\n\t} else {\n\t\tbody = new Uint8Array(await response.arrayBuffer());\n\t\tonProgress?.({\n\t\t\turl,\n\t\t\tloaded: body.byteLength,\n\t\t\ttotal: total || body.byteLength,\n\t\t\tfromCache: false,\n\t\t});\n\t}\n\n\tconst headers = new Headers();\n\tfor (const name of [\"content-type\", \"etag\", \"last-modified\"]) {\n\t\tconst value = response.headers.get(name);\n\t\tif (value) headers.set(name, value);\n\t}\n\theaders.set(\"content-length\", String(body.byteLength));\n\tconst buffered = new Response(body, { status: 200, headers });\n\tif (cache) {\n\t\ttry {\n\t\t\tawait cache.put(url, buffered.clone());\n\t\t} catch {\n\t\t\t// quota exceeded or opaque response: caching is best effort\n\t\t}\n\t}\n\treturn buffered;\n}\n\n/** {@link fetchAsset} and return the body bytes. */\nexport async function fetchAssetBytes(\n\turl: string,\n\toptions?: AssetFetchOptions,\n): Promise<Uint8Array> {\n\treturn new Uint8Array(await (await fetchAsset(url, options)).arrayBuffer());\n}\n\n/** {@link fetchAsset} and return the body as text. */\nexport async function fetchAssetText(\n\turl: string,\n\toptions?: AssetFetchOptions,\n): Promise<string> {\n\treturn (await fetchAsset(url, options)).text();\n}\n\n/** The naist-jdic files produced by jpreprocess's dictionary build, in `init_dictionary` order. */\nexport const NAIST_JDIC_FILES = [\n\t\"metadata.json\",\n\t\"char_def.bin\",\n\t\"matrix.mtx\",\n\t\"dict.da\",\n\t\"dict.vals\",\n\t\"unk.bin\",\n\t\"dict.wordsidx\",\n\t\"dict.words\",\n] as const;\n\nexport type NaistJdicFile = (typeof NAIST_JDIC_FILES)[number];\n\nexport type NaistJdicData = Record<NaistJdicFile, Uint8Array>;\n\n/** The subset of the wasm-bindgen module surface used by koe. */\nexport interface JpreprocessModule {\n\tinit_dictionary(\n\t\tmetadata: Uint8Array,\n\t\tcharDef: Uint8Array,\n\t\tmatrix: Uint8Array,\n\t\tdictDa: Uint8Array,\n\t\tdictVals: Uint8Array,\n\t\tunk: Uint8Array,\n\t\twordsIdx: Uint8Array,\n\t\twords: Uint8Array,\n\t): void;\n\tanalyze_text(text: string): string;\n\tis_ready(): boolean;\n\t/** Load an HTS voice (.htsvoice bytes) for `analyze_prosody`. */\n\tinit_voice?(htsvoice: Uint8Array): void;\n\tis_voice_ready?(): boolean;\n\t/** HTS phoneme durations + F0 for the text (JSON, see `HtsProsodyFrames`). */\n\tanalyze_prosody?(text: string, speed: number): string;\n}\n\nasync function inflate(bytes: Uint8Array): Promise<Uint8Array> {\n\tif (typeof DecompressionStream === \"undefined\") {\n\t\tthrow new Error(\n\t\t\t\"DecompressionStream is not available; serve the dictionary uncompressed\",\n\t\t);\n\t}\n\tconst stream = new Blob([bytes as BlobPart])\n\t\t.stream()\n\t\t.pipeThrough(new DecompressionStream(\"gzip\"));\n\treturn new Uint8Array(await new Response(stream).arrayBuffer());\n}\n\nexport interface LoadNaistJdicOptions extends AssetFetchOptions {\n\t/** Files are `<name>.gz` and inflated in the browser. Default true. */\n\tcompressed?: boolean;\n}\n\n/**\n * Download (or read from the Cache API) the naist-jdic dictionary files for\n * jpreprocess. `baseUrl` is the directory holding `dict.da.gz` etc.\n *\n * Progress is reported per file via `onProgress`; sum `loaded`/`total` across\n * the {@link NAIST_JDIC_FILES} URLs for an aggregate bar.\n */\nexport async function loadNaistJdic(\n\tbaseUrl: string,\n\toptions: LoadNaistJdicOptions = {},\n): Promise<NaistJdicData> {\n\tconst { compressed = true, ...fetchOptions } = options;\n\tconst base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\tconst entries = await Promise.all(\n\t\tNAIST_JDIC_FILES.map(async (name) => {\n\t\t\tconst raw = await fetchAssetBytes(\n\t\t\t\t`${base}${name}${compressed ? \".gz\" : \"\"}`,\n\t\t\t\tfetchOptions,\n\t\t\t);\n\t\t\treturn [name, compressed ? await inflate(raw) : raw] as const;\n\t\t}),\n\t);\n\treturn Object.fromEntries(entries) as NaistJdicData;\n}\n\n/** Hand the loaded dictionary to the jpreprocess wasm module (once per page). */\nexport function initJpreprocessDictionary(\n\tmodule: JpreprocessModule,\n\tdata: NaistJdicData,\n): void {\n\tmodule.init_dictionary(\n\t\tdata[\"metadata.json\"],\n\t\tdata[\"char_def.bin\"],\n\t\tdata[\"matrix.mtx\"],\n\t\tdata[\"dict.da\"],\n\t\tdata[\"dict.vals\"],\n\t\tdata[\"unk.bin\"],\n\t\tdata[\"dict.wordsidx\"],\n\t\tdata[\"dict.words\"],\n\t);\n}\n","import type { FeatureFrame } from \"./openjtalk_features.js\";\n\n/**\n * Prosody transplant from an HTS voice (Open JTalk's statistical model, run by\n * jbonsai inside the jpreprocess wasm): HTS decides *how long* each mora is and\n * *what pitch contour* the sentence has; the UTAU voice bank only supplies the\n * timbre. This is the same division of labour as Cantari (VOICEVOX prosody +\n * worldline) but with a 1-2 MB model that runs in the browser.\n */\n\n/** One phoneme of the HTS timeline (`analyze_prosody` output). */\nexport interface HtsPhoneme {\n\tphone: string;\n\tstart_ms: number;\n\tduration_ms: number;\n}\n\n/** Raw `analyze_prosody` result. */\nexport interface HtsProsodyFrames {\n\tframe_ms: number;\n\tsample_rate: number;\n\tphonemes: HtsPhoneme[];\n\t/** F0 in Hz per frame; 0 = unvoiced. */\n\tf0_hz: number[];\n}\n\n/** HTS prosody aligned to the UtauTTS mora sequence, ready for `plan()`. */\nexport interface HtsProsody {\n\t/** Per feature-frame (mora or pause) duration in ms, same order as the features. */\n\tmoraDurationsMs: number[];\n\t/** Cents relative to the speaker median, on the plan time axis (0 = first mora onset). */\n\tpitchCurve: { frame_ms: number; cents: number[] };\n\t/** Median voiced F0 of the HTS utterance in Hz. */\n\tmedianHz: number;\n\t/** Total planned duration in ms (sum of `moraDurationsMs`). */\n\tdurationMs: number;\n\t/**\n\t * Per feature-frame flag: HTS predicted the mora nucleus as a devoiced vowel\n\t * (Open JTalk's upper-case `I`/`U`, e.g. the \"su\" in \"desu\"). Pauses are false.\n\t */\n\tdevoiced: boolean[];\n\t/**\n\t * Optional per feature-frame linear gain (1 = unity) applied to the units of\n\t * that mora on top of UtauTTS's own volume; filled by `shapeProsody`.\n\t */\n\tmoraGains?: number[];\n}\n\nexport interface AlignHtsOptions {\n\t/** Multiplier on the cents curve. 1 = HTS as-is. Default 1. */\n\tintonationStrength?: number;\n\t/** Output frame period for the pitch curve in ms. Default 10 (worldline's frame). */\n\tframeMs?: number;\n\t/** Pause length used when the features have a pause HTS did not produce. Default 150. */\n\tfallbackPauseMs?: number;\n\t/**\n\t * Soft limit for the cents curve: excursions beyond `kneeCents` are halved,\n\t * then hard-clamped at `maxCents`. HTS voices end phrases with a creaky\n\t * drop of close to an octave, which WORLD resynthesis of a singing sample\n\t * cannot follow cleanly. Defaults: knee 400, max 700.\n\t */\n\tkneeCents?: number;\n\tmaxCents?: number;\n}\n\n/** Mora nuclei in Open JTalk phoneme notation (upper case = devoiced vowel). */\nconst NUCLEUS = new Set([\n\t\"a\",\n\t\"i\",\n\t\"u\",\n\t\"e\",\n\t\"o\",\n\t\"A\",\n\t\"I\",\n\t\"U\",\n\t\"E\",\n\t\"O\",\n\t\"N\",\n\t\"cl\",\n]);\n\n/** Halve excursions beyond ±knee, then clamp at ±max (keeps the shape, tames the extremes). */\nfunction softLimit(value: number, knee: number, max: number): number {\n\tconst magnitude = Math.abs(value);\n\tconst limited =\n\t\tmagnitude <= knee ? magnitude : knee + (magnitude - knee) * 0.5;\n\treturn Math.sign(value) * Math.min(max, limited);\n}\n\ninterface Segment {\n\tpause: boolean;\n\tstartMs: number;\n\tdurationMs: number;\n\t/** Nucleus was an upper-case (devoiced) vowel. */\n\tdevoiced: boolean;\n}\n\nconst DEVOICED = new Set([\"A\", \"I\", \"U\", \"E\", \"O\"]);\n\n/** Group HTS phonemes into morae / pauses. Leading `sil` is dropped, trailing `sil` becomes a pause. */\nfunction segmentPhonemes(phonemes: HtsPhoneme[]): Segment[] {\n\tconst segments: Segment[] = [];\n\tlet openStart: number | null = null;\n\tfor (let i = 0; i < phonemes.length; i++) {\n\t\tconst { phone, start_ms, duration_ms } = phonemes[i];\n\t\tif (phone === \"sil\" || phone === \"pau\") {\n\t\t\tif (openStart !== null) {\n\t\t\t\t// Consonant without a nucleus (should not happen): fold into a mora.\n\t\t\t\tsegments.push({\n\t\t\t\t\tpause: false,\n\t\t\t\t\tstartMs: openStart,\n\t\t\t\t\tdurationMs: start_ms - openStart,\n\t\t\t\t\tdevoiced: false,\n\t\t\t\t});\n\t\t\t\topenStart = null;\n\t\t\t}\n\t\t\tif (i === 0) continue;\n\t\t\tsegments.push({\n\t\t\t\tpause: true,\n\t\t\t\tstartMs: start_ms,\n\t\t\t\tdurationMs: duration_ms,\n\t\t\t\tdevoiced: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (openStart === null) openStart = start_ms;\n\t\tif (NUCLEUS.has(phone)) {\n\t\t\tsegments.push({\n\t\t\t\tpause: false,\n\t\t\t\tstartMs: openStart,\n\t\t\t\tdurationMs: start_ms + duration_ms - openStart,\n\t\t\t\tdevoiced: DEVOICED.has(phone),\n\t\t\t});\n\t\t\topenStart = null;\n\t\t}\n\t}\n\tif (openStart !== null) {\n\t\tconst last = phonemes[phonemes.length - 1];\n\t\tsegments.push({\n\t\t\tpause: false,\n\t\t\tstartMs: openStart,\n\t\t\tdurationMs: last.start_ms + last.duration_ms - openStart,\n\t\t\tdevoiced: false,\n\t\t});\n\t}\n\treturn segments;\n}\n\n/**\n * Align HTS phoneme timing and F0 to the mora/pause sequence in `features`\n * (from `openjtalkAnalyze`). Returns null when the two mora sequences cannot\n * be matched, in which case the caller should fall back to the TCN contour.\n */\nexport function alignHtsProsody(\n\tframes: HtsProsodyFrames,\n\tfeatures: FeatureFrame[],\n\toptions: AlignHtsOptions = {},\n): HtsProsody | null {\n\tconst {\n\t\tintonationStrength = 1,\n\t\tframeMs = 10,\n\t\tfallbackPauseMs = 150,\n\t\tkneeCents = 400,\n\t\tmaxCents = 700,\n\t} = options;\n\tconst segments = segmentPhonemes(frames.phonemes);\n\n\t// Two-pointer walk: morae must pair 1:1; pauses may be missing on either side.\n\tconst durations: number[] = new Array(features.length).fill(0);\n\tconst htsStart: (number | null)[] = new Array(features.length).fill(null);\n\tconst devoiced: boolean[] = new Array(features.length).fill(false);\n\tlet s = 0;\n\tfor (let f = 0; f < features.length; f++) {\n\t\tconst feature = features[f];\n\t\twhile (s < segments.length && segments[s].pause && !feature.pause) s++; // HTS pause the features lack\n\t\tconst segment = segments[s];\n\t\tif (feature.pause) {\n\t\t\tif (segment?.pause) {\n\t\t\t\tdurations[f] = segment.durationMs;\n\t\t\t\thtsStart[f] = segment.startMs;\n\t\t\t\ts++;\n\t\t\t} else {\n\t\t\t\tdurations[f] = fallbackPauseMs; // features pause HTS lacks (e.g. unreadable token)\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (!segment) return null;\n\t\tdurations[f] = segment.durationMs;\n\t\thtsStart[f] = segment.startMs;\n\t\tdevoiced[f] = segment.devoiced;\n\t\ts++;\n\t}\n\tif (segments.slice(s).some((segment) => !segment.pause)) return null; // HTS has morae left over\n\n\t// Continuous F0 in log2 domain (interpolate across unvoiced runs, hold at edges).\n\tconst f0 = frames.f0_hz;\n\tconst logF0 = new Float64Array(f0.length);\n\tconst voiced: number[] = [];\n\tfor (let i = 0; i < f0.length; i++) if (f0[i] > 0) voiced.push(i);\n\tif (voiced.length === 0) return null;\n\tconst sorted = voiced.map((i) => f0[i]).sort((a, b) => a - b);\n\tconst medianHz = sorted[Math.floor(sorted.length / 2)];\n\tfor (let i = 0, v = 0; i < f0.length; i++) {\n\t\tif (f0[i] > 0) {\n\t\t\tlogF0[i] = Math.log2(f0[i]);\n\t\t\tcontinue;\n\t\t}\n\t\twhile (v < voiced.length && voiced[v] < i) v++;\n\t\tconst right = voiced[v];\n\t\tconst left = v > 0 ? voiced[v - 1] : undefined;\n\t\tif (left === undefined) logF0[i] = Math.log2(f0[right]);\n\t\telse if (right === undefined) logF0[i] = Math.log2(f0[left]);\n\t\telse {\n\t\t\tconst t = (i - left) / (right - left);\n\t\t\tlogF0[i] = Math.log2(f0[left]) * (1 - t) + Math.log2(f0[right]) * t;\n\t\t}\n\t}\n\tconst logMedian = Math.log2(medianHz);\n\tconst htsCentsAt = (tMs: number): number => {\n\t\tconst position = Math.max(0, tMs) / frames.frame_ms;\n\t\tconst left = Math.min(logF0.length - 1, Math.floor(position));\n\t\tconst right = Math.min(logF0.length - 1, left + 1);\n\t\tconst t = position - Math.floor(position);\n\t\treturn (logF0[left] * (1 - t) + logF0[right] * t - logMedian) * 1200;\n\t};\n\n\t// Plan time axis: morae start at the cumulative sum of the assigned durations.\n\tconst planStart: number[] = [];\n\tlet cursor = 0;\n\tfor (let f = 0; f < features.length; f++) {\n\t\tplanStart.push(cursor);\n\t\tcursor += durations[f];\n\t}\n\tconst durationMs = cursor;\n\tconst count = Math.max(2, Math.ceil(durationMs / frameMs) + 2);\n\tconst cents = new Array<number>(count);\n\tlet f = 0;\n\tfor (let frame = 0; frame < count; frame++) {\n\t\tconst tMs = frame * frameMs;\n\t\twhile (f + 1 < features.length && tMs >= planStart[f + 1]) f++;\n\t\tconst start = htsStart[f];\n\t\t// Pauses HTS did not produce have no HTS time: hold the value at the next mora onset.\n\t\tlet htsMs: number;\n\t\tif (start !== null) htsMs = start + (tMs - planStart[f]);\n\t\telse {\n\t\t\tconst next = htsStart.slice(f + 1).find((value) => value !== null);\n\t\t\thtsMs = next ?? frames.phonemes.at(-1)?.start_ms ?? 0;\n\t\t}\n\t\tcents[frame] = softLimit(\n\t\t\thtsCentsAt(htsMs) * intonationStrength,\n\t\t\tkneeCents,\n\t\t\tmaxCents,\n\t\t);\n\t}\n\treturn {\n\t\tmoraDurationsMs: durations,\n\t\tpitchCurve: { frame_ms: frameMs, cents },\n\t\tmedianHz,\n\t\tdurationMs,\n\t\tdevoiced,\n\t};\n}\n","export interface NjdNode {\n string: string;\n pos: string;\n pos_group1: string;\n pron: string;\n read: string;\n acc: number;\n mora_size: number;\n chain_flag: number;\n}\n\nexport interface FeatureFrame {\n mora: string;\n pause: boolean;\n accent_phrase_position?: number;\n accent_phrase_length?: number;\n accent_nucleus?: number;\n accent_high?: boolean;\n accent_phrase_start?: boolean;\n accent_phrase_end?: boolean;\n word_start?: boolean;\n word_end?: boolean;\n pos?: string;\n pos_group1?: string;\n}\n\nconst PUNCTUATION = new Set([\"、\", \"。\", \"?\", \"!\", \",\", \".\", \"?\", \"!\"]);\nconst SMALL_KANA = new Set([\"ぁ\", \"ぃ\", \"ぅ\", \"ぇ\", \"ぉ\", \"ゃ\", \"ゅ\", \"ょ\", \"ゎ\", \"ゕ\", \"ゖ\"]);\n\nfunction toHiragana(character: string): string {\n const code = character.charCodeAt(0);\n if (0x30A1 <= code && code <= 0x30F6) {\n return String.fromCharCode(code - 0x60);\n }\n return character;\n}\n\nfunction splitMorae(reading: string): FeatureFrame[] {\n const result: FeatureFrame[] = [];\n const normalized = reading.normalize(\"NFC\").replace(/'/g, \"\").replace(/’/g, \"\");\n for (const character of normalized) {\n if (/\\s/.test(character) || PUNCTUATION.has(character)) {\n if (result.length > 0 && !result[result.length - 1].pause) {\n result.push({ mora: \"\", pause: true });\n }\n continue;\n }\n const mora = toHiragana(character);\n if (SMALL_KANA.has(mora) && result.length > 0 && !result[result.length - 1].pause) {\n result[result.length - 1].mora += mora;\n } else {\n result.push({ mora, pause: false });\n }\n }\n return result;\n}\n\nfunction isHigh(position: number, accent: number): boolean {\n if (accent === 1) return position === 1;\n if (accent > 1) return 2 <= position && position <= accent;\n return position >= 2;\n}\n\nexport function analyze(nodes: NjdNode[]): { reading: string, features: FeatureFrame[] } {\n const reading_parts: string[] = [];\n const result: FeatureFrame[] = [];\n let index = 0;\n \n while (index < nodes.length) {\n const node = nodes[index];\n const pronunciation = (node.pron || \"\").replace(/'/g, \"\").replace(/’/g, \"\");\n if (node.mora_size === 0 || PUNCTUATION.has(node.string)) {\n reading_parts.push(node.string || \"、\");\n if (result.length > 0 && !result[result.length - 1].pause) {\n result.push({ mora: \"\", pause: true });\n }\n index++;\n continue;\n }\n\n const phrase_nodes: { current: NjdNode, morae: FeatureFrame[] }[] = [];\n while (index < nodes.length) {\n const current = nodes[index];\n if (current.mora_size === 0 || PUNCTUATION.has(current.string)) {\n break;\n }\n if (phrase_nodes.length > 0 && current.chain_flag !== 1) {\n break;\n }\n const current_pronunciation = (current.pron || \"\").replace(/'/g, \"\").replace(/’/g, \"\");\n const morae = splitMorae(current_pronunciation).filter(item => !item.pause);\n phrase_nodes.push({ current, morae });\n reading_parts.push(current_pronunciation);\n index++;\n }\n\n const phrase_length = phrase_nodes.reduce((sum, item) => sum + item.morae.length, 0);\n const accent = phrase_nodes[0].current.acc || 0;\n let phrase_position = 0;\n\n for (const { current, morae } of phrase_nodes) {\n for (let word_position = 1; word_position <= morae.length; word_position++) {\n phrase_position++;\n result.push({\n mora: morae[word_position - 1].mora,\n pause: false,\n accent_phrase_position: phrase_position,\n accent_phrase_length: phrase_length,\n accent_nucleus: accent,\n accent_high: isHigh(phrase_position, accent),\n accent_phrase_start: phrase_position === 1,\n accent_phrase_end: phrase_position === phrase_length,\n word_start: word_position === 1,\n word_end: word_position === morae.length,\n pos: current.pos || \"*\",\n pos_group1: current.pos_group1 || \"*\",\n });\n }\n }\n }\n return { reading: reading_parts.join(\"\"), features: result };\n}\nexport function sparse_features(token: FeatureFrame): Record<string, number> {\n if (token.pause || token.accent_phrase_position === undefined || token.accent_phrase_length === undefined || token.accent_nucleus === undefined) {\n return {};\n }\n const phrase_length = Math.max(1, token.accent_phrase_length);\n const phrase_position = token.accent_phrase_position;\n const nucleus = token.accent_nucleus;\n \n const result: Record<string, number> = {\n \"accent_position\": phrase_position / phrase_length,\n \"accent_from_end\": (phrase_length - phrase_position) / phrase_length,\n \"accent_nucleus_position\": nucleus / phrase_length,\n \"accent_high\": token.accent_high ? 1.0 : 0.0,\n \"accent_phrase_start\": token.accent_phrase_start ? 1.0 : 0.0,\n \"accent_phrase_end\": token.accent_phrase_end ? 1.0 : 0.0,\n \"word_start\": token.word_start ? 1.0 : 0.0,\n \"word_end\": token.word_end ? 1.0 : 0.0,\n };\n \n result[`pos=${token.pos || \"*\"}`] = 1.0;\n result[`pos_group1=${token.pos_group1 || \"*\"}`] = 1.0;\n \n if (nucleus === 0) {\n result[\"accent_type=heiban\"] = 1.0;\n } else if (phrase_position < nucleus) {\n result[\"accent_type=before\"] = 1.0;\n } else if (phrase_position === nucleus) {\n result[\"accent_type=nucleus\"] = 1.0;\n } else {\n result[\"accent_type=after\"] = 1.0;\n }\n \n return result;\n}\r\n","import type { HtsProsody } from \"./hts.js\";\nimport type { FeatureFrame } from \"./openjtalk_features.js\";\n\n/**\n * Rule-based residuals on top of the HTS prosody (a cut-down Fujisaki-style\n * layer): the statistical model gives the accent shape, these rules add what\n * the HTS voices were not trained for and what a concatenative voice bank\n * lacks on its own.\n *\n * - question rise: a sentence ending in 「?」 gets at least a minimum rise\n * on its last mora; Open JTalk's interrogative label flag already makes\n * tohoku-f01 rise, so this only tops up voices/sentences that do not\n * - energy envelope: loudness follows pitch (accented morae louder, phrase\n * ends softer), which a plain unit concatenation renders flat\n * - devoiced vowels: morae HTS predicted as devoiced (「です」「ます」…) are\n * attenuated so the voiced sample does not shout a vowel the speaker\n * would whisper\n *\n * Zero assets, negligible compute; everything is mora-level arithmetic.\n */\nexport interface ShapeProsodyOptions {\n\t/** Treat the utterance as a question (see {@link isQuestion}). Default false. */\n\tquestion?: boolean;\n\t/**\n\t * Minimum rise across the final mora of a question, in cents. Open JTalk\n\t * labels carry an interrogative flag and HTS voices trained with it (e.g.\n\t * tohoku-f01) already rise; the rule only tops up whatever is missing, so\n\t * it is a safety net for voices/sentences where the rise does not appear.\n\t * Default 350.\n\t */\n\tquestionRiseCents?: number;\n\t/**\n\t * Loudness coupling: dB per 100 cents of pitch relative to the speaker\n\t * median. 0 disables the energy envelope. Default 0.5 (≈ +2 dB at +400 cent).\n\t */\n\tenergyDbPerSemitone?: number;\n\t/** Linear gain for morae with a devoiced nucleus. Default 0.5 (−6 dB). */\n\tdevoicedGain?: number;\n\t/** Clamp for the per-mora gain. Defaults 0.35 … 1.8. */\n\tminGain?: number;\n\tmaxGain?: number;\n}\n\n/** Closing brackets/quotes/spaces that may follow the final punctuation. */\nconst TRAILING = /[\\s」』))〕】>>\"'”’]+$/u;\n\n/** True when the text ends with a question mark (「?」 or \"?\"), ignoring closing quotes. */\nexport function isQuestion(text: string): boolean {\n\treturn /[??]$/u.test(text.replace(TRAILING, \"\"));\n}\n\nfunction smoothstep(t: number): number {\n\tconst x = Math.min(1, Math.max(0, t));\n\treturn x * x * (3 - 2 * x);\n}\n\n/**\n * Apply the residual rules to an aligned HTS prosody. Returns a new object;\n * `prosody` is not modified. Pass the result to `plan({ prosody })`: the pitch\n * curve carries the question rise, `moraGains` the energy envelope.\n */\nexport function shapeProsody(\n\tprosody: HtsProsody,\n\tfeatures: FeatureFrame[],\n\toptions: ShapeProsodyOptions = {},\n): HtsProsody {\n\tconst {\n\t\tquestion = false,\n\t\tquestionRiseCents = 350,\n\t\tenergyDbPerSemitone = 0.5,\n\t\tdevoicedGain = 0.5,\n\t\tminGain = 0.35,\n\t\tmaxGain = 1.8,\n\t} = options;\n\tconst { frame_ms: frameMs } = prosody.pitchCurve;\n\tconst cents = prosody.pitchCurve.cents.slice();\n\tconst count = Math.min(features.length, prosody.moraDurationsMs.length);\n\n\t// Mora boundaries on the plan time axis, in frames.\n\tconst startFrame: number[] = [];\n\tconst endFrame: number[] = [];\n\tlet cursor = 0;\n\tfor (let f = 0; f < count; f++) {\n\t\tstartFrame.push(cursor / frameMs);\n\t\tcursor += prosody.moraDurationsMs[f];\n\t\tendFrame.push(cursor / frameMs);\n\t}\n\tconst frameRange = (f: number): [number, number] => [\n\t\tMath.max(0, Math.min(cents.length, Math.round(startFrame[f]))),\n\t\tMath.max(0, Math.min(cents.length, Math.round(endFrame[f]))),\n\t];\n\n\t// ── Question rise on the last spoken mora (top-up only) ──\n\tif (question && questionRiseCents > 0) {\n\t\tlet last = -1;\n\t\tfor (let f = count - 1; f >= 0; f--) {\n\t\t\tif (!features[f].pause) {\n\t\t\t\tlast = f;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (last >= 0) {\n\t\t\tconst [from, to] = frameRange(last);\n\t\t\tif (to > from) {\n\t\t\t\tconst existing = cents[to - 1] - cents[from];\n\t\t\t\tconst shortfall = questionRiseCents - existing;\n\t\t\t\tif (shortfall > 0) {\n\t\t\t\t\t// Hold the first quarter, then add the missing rise; keep the peak\n\t\t\t\t\t// through whatever follows (trailing pause / release).\n\t\t\t\t\tfor (let frame = from; frame < cents.length; frame++) {\n\t\t\t\t\t\tconst t = (frame - from) / (to - from);\n\t\t\t\t\t\tcents[frame] += shortfall * smoothstep((t - 0.25) / 0.75);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Per-mora gain: pitch-coupled loudness × devoicing ──\n\tconst moraGains: number[] = new Array(features.length).fill(1);\n\tfor (let f = 0; f < count; f++) {\n\t\tif (features[f].pause) continue;\n\t\tlet gainDb = 0;\n\t\tif (energyDbPerSemitone !== 0) {\n\t\t\tconst [from, to] = frameRange(f);\n\t\t\tif (to > from) {\n\t\t\t\tlet sum = 0;\n\t\t\t\tfor (let frame = from; frame < to; frame++) sum += cents[frame];\n\t\t\t\tgainDb += (sum / (to - from) / 100) * energyDbPerSemitone;\n\t\t\t}\n\t\t}\n\t\tlet gain = 10 ** (gainDb / 20);\n\t\tif (prosody.devoiced[f]) gain *= devoicedGain;\n\t\tmoraGains[f] = Math.min(maxGain, Math.max(minGain, gain));\n\t}\n\n\treturn {\n\t\t...prosody,\n\t\tpitchCurve: { frame_ms: frameMs, cents },\n\t\tmoraGains,\n\t};\n}\n","import type { VoiceBank } from \"../engine/voice-bank.js\";\nimport {\n\tMIN_WORLDLINE_SAMPLES,\n\ttype PhraseUnit,\n\tWORLDLINE_SAMPLE_RATE,\n\ttype Worldline,\n} from \"../engine/worldline.js\";\nimport type { HtsProsody } from \"./hts.js\";\nimport { type FeatureFrame, sparse_features } from \"./openjtalk_features.js\";\n\n// ── Plan JSON produced by cmd/utautts-wasm ──────────────────────────────────\n\n/** One unit of the UtauTTS synthesis plan (`internal/plan.Unit`). */\nexport interface UtauTTSUnit {\n\tposition: number;\n\trole: string;\n\tmora: string;\n\talias: string;\n\tnote_start_ms: number;\n\tduration_ms: number;\n\toffset_ms: number;\n\tconsonant_ms: number;\n\tcutoff_ms: number;\n\tpreutterance_ms: number;\n\toverlap_ms: number;\n\tsilent?: boolean;\n\tpitch_factor: number;\n\tenergy_factor: number;\n\teffective_preutterance_ms: number;\n\teffective_consonant_ms: number;\n\teffective_overlap_ms: number;\n\tsource_f0_hz?: number;\n\ttarget_f0_hz?: number;\n\t[extra: string]: unknown;\n}\n\n/** Placement of one unit on the worldline phrase timeline (`render.WorldlineTimelineUnit`). */\nexport interface UtauTTSTimelineUnit {\n\tindex: number;\n\tposition: number;\n\trole: string;\n\tmora: string;\n\talias: string;\n\tnote_start_ms: number;\n\tduration_ms: number;\n\tposition_ms: number;\n\tskip_ms: number;\n\tlength_ms: number;\n\tfade_in_ms: number;\n\tfade_out_ms: number;\n\toffset_ms: number;\n\trequired_length_ms: number;\n\tconsonant_ms: number;\n\tcutoff_ms: number;\n\ttone: number;\n\tconsonant_velocity: number;\n\tvolume: number;\n\tenergy_factor: number;\n\tsource_f0_hz: number;\n\ttarget_f0_hz: number;\n\tenvelope?: { x_ms: number; y: number }[];\n}\n\n/** Whole-phrase placement + F0 curve (`render.WorldlineTimeline`). */\nexport interface UtauTTSTimeline {\n\tframe_ms: number;\n\tleading_ms: number;\n\t/** Timeline length in ms (plan duration + release + leading margin). */\n\tduration_ms: number;\n\treference_hz: number;\n\t/** Target F0 in Hz per `frame_ms` frame, starting at timeline 0. */\n\tf0_curve: number[];\n\tunits: UtauTTSTimelineUnit[];\n}\n\nexport interface UtauTTSPlan {\n\treading: string;\n\tlanguage: string;\n\tmorae: { Text: string; Consonant: string; Vowel: string; Pause: boolean }[];\n\tplan: {\n\t\tduration_ms: number;\n\t\tsingle_cv?: boolean;\n\t\tleading_margin_ms?: number;\n\t\tunits: UtauTTSUnit[];\n\t\t[extra: string]: unknown;\n\t};\n\t/** Frame pitch curve in cents relative to each unit's own pitch (plan time base). */\n\tpitch_curve?: { frame_ms: number; cents: number[] };\n\tmora_timings: { StartMS: number; DurationMS: number }[];\n\ttimeline: UtauTTSTimeline;\n\t/** @deprecated use `plan.duration_ms` */\n\tduration_ms: number;\n\t/** @deprecated use `plan.units` */\n\tunits: UtauTTSUnit[];\n\t/** @deprecated use `pitch_curve` */\n\tpitch_cents?: number[];\n\t/** @deprecated use `pitch_curve` */\n\tpitch_frame_ms?: number;\n}\n\ninterface WasmResult {\n\tsuccess: boolean;\n\terror?: string;\n\tplan?: string;\n\tid?: string;\n\taliases?: number;\n}\n\ndeclare function utautts_plan(requestJSON: string): WasmResult;\ndeclare function utautts_set_model(modelJSON: string): WasmResult;\ndeclare function utautts_set_bank(bankJSON: string): WasmResult;\ndeclare class Go {\n\timportObject: WebAssembly.Imports;\n\trun(instance: WebAssembly.Instance): Promise<void>;\n}\n\n// ── Options ─────────────────────────────────────────────────────────────────\n\n/** Synthesis parameters, same meaning and defaults as `utautts-cli` / the UtauTTS GUI. */\nexport interface UtauTTSOptions {\n\t/** Voicebank tone for prefix.map lookups. Default \"C4\". */\n\ttone?: string;\n\t/** Base mora length in ms (0 = UtauTTS default 140). */\n\tmoraDurationMs?: number;\n\t/** Pause length for punctuation in ms (0 = UtauTTS default 180). */\n\tpauseDurationMs?: number;\n\t/** Release envelope in ms. Default 20. */\n\treleaseMs?: number;\n\t/** Cap on the leading preutterance margin before the first mora (0 = no cap). */\n\tleadingPreutteranceMs?: number;\n\t/** Apply the TCN frame pitch contour and source pitch stabilisation. Default true. */\n\tapplyPitch?: boolean;\n\t/** Contour strength 0..4. Default 1. */\n\tintonationStrength?: number;\n\t/** UtauTTS experimental speech timing (voicebank calibration). Default false. */\n\tspeechTiming?: boolean;\n\twordBoundaryEnvelope?: boolean;\n\t/**\n\t * External prosody (mora durations + cents curve) from `alignHtsProsody`.\n\t * When set, UtauTTS uses these instead of its own durations and TCN contour;\n\t * `intonationStrength` is applied by `alignHtsProsody`, not here.\n\t */\n\tprosody?: HtsProsody;\n}\n\n/** One rendered piece of audio. Sum overlapping chunks: seams are equal-power crossfades. */\nexport interface UtauTTSChunk {\n\t/** Float32 PCM at 48 kHz. */\n\tpcm: Float32Array;\n\t/** Where the chunk starts on the timeline (ms from timeline 0). */\n\tstartMs: number;\n\tindex: number;\n\t/** Timeline units rendered into this chunk (context units for seams excluded). */\n\tunits: UtauTTSTimelineUnit[];\n}\n\nexport interface UtauTTSRenderOptions {\n\t/** Units in the first chunk (small → audio starts sooner). Default 3. */\n\tfirstChunkUnits?: number;\n\t/** Units per later chunk. Default 6. */\n\tchunkUnits?: number;\n\t/** Crossfade length at a mid-phrase seam in ms. Default 20. */\n\tseamCrossfadeMs?: number;\n\tsignal?: AbortSignal;\n\tgender?: number;\n\ttension?: number;\n\tbreathiness?: number;\n\tvoicing?: number;\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n/**\n * Build the kana reading UtauTTS parses from the jpreprocess token features,\n * so the mora sequence and the feature frames line up 1:1 by construction.\n */\nexport function readingFromFeatures(features: FeatureFrame[]): string {\n\treturn features.map((frame) => (frame.pause ? \"、\" : frame.mora)).join(\"\");\n}\n\nconst FS = WORLDLINE_SAMPLE_RATE;\nconst msToSamples = (ms: number): number => Math.round((ms / 1000) * FS);\n\n/** Sample the timeline F0 curve (Hz) at an absolute timeline time with linear interpolation. */\nfunction f0At(timeline: UtauTTSTimeline, tMs: number): number {\n\tconst curve = timeline.f0_curve;\n\tif (curve.length === 0) return timeline.reference_hz || 220;\n\tconst position = Math.max(0, tMs) / timeline.frame_ms;\n\tconst left = Math.floor(position);\n\tif (left >= curve.length - 1) return curve[curve.length - 1];\n\tconst progress = position - left;\n\treturn curve[left] * (1 - progress) + curve[left + 1] * progress;\n}\n\ninterface ChunkRange {\n\t/** First own unit (inclusive). */\n\tstart: number;\n\t/** Last own unit (exclusive). */\n\tend: number;\n\t/** Chunk starts mid-phrase (needs the previous unit as context + a seam fade-in). */\n\theadSeam: boolean;\n\t/** Chunk ends mid-phrase (needs the next unit as context + a seam fade-out). */\n\ttailSeam: boolean;\n}\n\n/**\n * Scale each timeline unit's volume by the gain of the mora it belongs to\n * (`HtsProsody.moraGains`, one entry per feature frame / plan mora). Units are\n * matched by their mora index when the counts agree, else by start time.\n */\nfunction applyMoraGains(plan: UtauTTSPlan, gains: number[]): void {\n\tconst morae = plan.morae ?? [];\n\tconst timings = plan.mora_timings ?? [];\n\tconst byIndex = morae.length === gains.length;\n\tconst moraAt = (unit: UtauTTSTimelineUnit): number => {\n\t\tif (byIndex) return unit.position;\n\t\tlet found = -1;\n\t\tfor (let i = 0; i < timings.length && i < gains.length; i++) {\n\t\t\tif (timings[i].StartMS <= unit.note_start_ms + 1e-6) found = i;\n\t\t\telse break;\n\t\t}\n\t\treturn found;\n\t};\n\tfor (const unit of plan.timeline.units) {\n\t\tconst index = moraAt(unit);\n\t\tconst gain = gains[index];\n\t\tif (index < 0 || gain === undefined || !Number.isFinite(gain)) continue;\n\t\tunit.volume *= gain;\n\t}\n}\n\n/**\n * Split timeline units into chunks. Breaks are free where units do not overlap\n * (pauses); inside a phrase a break every N units costs one seam crossfade.\n */\nfunction planChunks(\n\tunits: UtauTTSTimelineUnit[],\n\tfirstChunkUnits: number,\n\tchunkUnits: number,\n): ChunkRange[] {\n\tconst ranges: ChunkRange[] = [];\n\tif (units.length === 0) return ranges;\n\tlet start = 0;\n\tlet coveredEndMs = units[0].position_ms + units[0].length_ms;\n\tlet headSeam = false;\n\tfor (let i = 1; i <= units.length; i++) {\n\t\tconst limit = ranges.length === 0 ? firstChunkUnits : chunkUnits;\n\t\tconst atEnd = i === units.length;\n\t\tconst clean = !atEnd && units[i].position_ms >= coveredEndMs - 1e-6;\n\t\tconst full = !atEnd && i - start >= limit;\n\t\tif (atEnd || clean || full) {\n\t\t\tconst tailSeam = !atEnd && !clean;\n\t\t\tranges.push({ start, end: i, headSeam, tailSeam });\n\t\t\tstart = i;\n\t\t\theadSeam = tailSeam;\n\t\t\tif (!atEnd) coveredEndMs = units[i].position_ms + units[i].length_ms;\n\t\t\tcontinue;\n\t\t}\n\t\tcoveredEndMs = Math.max(\n\t\t\tcoveredEndMs,\n\t\t\tunits[i].position_ms + units[i].length_ms,\n\t\t);\n\t}\n\treturn ranges;\n}\n\n/**\n * Where to cut between two chunks that share the boundary before `next`: just\n * after `next`'s fade-in, in its steady vowel, so both renders agree spectrally.\n */\nfunction seamTimeMs(next: UtauTTSTimelineUnit, crossfadeMs: number): number {\n\tconst earliest = next.position_ms + next.fade_in_ms + crossfadeMs / 2;\n\tconst latest = next.position_ms + next.length_ms - crossfadeMs / 2;\n\treturn Math.min(\n\t\tearliest,\n\t\tMath.max(next.position_ms + crossfadeMs / 2, latest),\n\t);\n}\n\nfunction applyFade(\n\tpcm: Float32Array,\n\tfromSample: number,\n\tsamples: number,\n\tfadeIn: boolean,\n): void {\n\tconst n = Math.max(1, Math.min(samples, pcm.length - fromSample));\n\tfor (let k = 0; k < n; k++) {\n\t\tconst t = (k + 0.5) / n;\n\t\tconst gain = fadeIn\n\t\t\t? Math.sin((Math.PI / 2) * t)\n\t\t\t: Math.cos((Math.PI / 2) * t);\n\t\tpcm[fromSample + k] *= gain;\n\t}\n}\n\n// ── Adapter ─────────────────────────────────────────────────────────────────\n\n/**\n * Text-to-speech with UtauTTS's planner (Go wasm) and koe's worldline renderer.\n *\n * Pipeline per utterance:\n * 1. jpreprocess (caller) → NJD nodes → {@link FeatureFrame}s via `openjtalkAnalyze`\n * 2. {@link plan}: UtauTTS resolves units (Viterbi), builds the timing plan,\n * predicts the TCN pitch contour and lays the units on the worldline timeline\n * exactly as its native worldline bridge would\n * 3. {@link renderChunks}: worldline renders the timeline in small chunks so\n * playback can start after the first few morae\n *\n * Load order: `initializeWasm()` once per page, `setModel()` once per model,\n * `setBank()` once per voice bank.\n */\nexport class UtauTTSAdapter {\n\tprivate static modelId: string | null = null;\n\tprivate bankAliases = new WeakMap<VoiceBank, number>();\n\tprivate currentBank: VoiceBank | null = null;\n\tprivate pcmCache = new Map<string, Promise<Float64Array | null>>();\n\n\tconstructor(private worldline: Worldline) {}\n\n\t/**\n\t * Load the UtauTTS Go wasm. `wasm_exec.js` must already be on the page.\n\t * Pass `fetch` (e.g. koe's `fetchAsset`) to stream from the Cache API.\n\t */\n\tstatic async initializeWasm(\n\t\twasmUrl = \"utautts.wasm\",\n\t\toptions: { fetch?: (url: string) => Promise<Response> } = {},\n\t): Promise<void> {\n\t\tif (typeof utautts_plan === \"function\") return;\n\t\tif (typeof Go === \"undefined\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"wasm_exec.js must be loaded before calling initializeWasm.\",\n\t\t\t);\n\t\t}\n\t\tconst go = new Go();\n\t\tconst responsePromise = (options.fetch ?? fetch)(wasmUrl);\n\t\tlet instance: WebAssembly.Instance;\n\t\ttry {\n\t\t\tinstance = (\n\t\t\t\tawait WebAssembly.instantiateStreaming(responsePromise, go.importObject)\n\t\t\t).instance;\n\t\t} catch {\n\t\t\t// Servers without the application/wasm MIME type.\n\t\t\tconst bytes = await (\n\t\t\t\tawait (options.fetch ?? fetch)(wasmUrl)\n\t\t\t).arrayBuffer();\n\t\t\tinstance = (await WebAssembly.instantiate(bytes, go.importObject))\n\t\t\t\t.instance;\n\t\t}\n\t\tvoid go.run(instance);\n\t\tfor (\n\t\t\tlet attempt = 0;\n\t\t\tattempt < 100 && typeof utautts_plan !== \"function\";\n\t\t\tattempt++\n\t\t) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t}\n\t\tif (typeof utautts_plan !== \"function\") {\n\t\t\tthrow new Error(\"utautts_plan failed to initialize in global scope.\");\n\t\t}\n\t}\n\n\tstatic get ready(): boolean {\n\t\treturn typeof utautts_plan === \"function\";\n\t}\n\n\t/** Parse and cache a prosody model (e.g. `frame-intonation-v8.json`) inside the wasm. */\n\tstatic setModel(modelJSON: string): string | null {\n\t\tUtauTTSAdapter.assertReady();\n\t\tconst result = utautts_set_model(modelJSON);\n\t\tif (!result.success)\n\t\t\tthrow new Error(`UtauTTS model error: ${result.error}`);\n\t\tUtauTTSAdapter.modelId = result.id ?? null;\n\t\treturn UtauTTSAdapter.modelId;\n\t}\n\n\tstatic get currentModelId(): string | null {\n\t\treturn UtauTTSAdapter.modelId;\n\t}\n\n\tprivate static assertReady(): void {\n\t\tif (typeof utautts_plan !== \"function\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"UtauTTS wasm is not initialized; call UtauTTSAdapter.initializeWasm() first.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Register a koe voice bank with the planner: the manifest becomes a virtual\n\t * oto.ini (koe PCM is pre-trimmed, so offset is 0) plus each sample's\n\t * recorded pitch. Called automatically by {@link plan}; cheap when unchanged.\n\t */\n\tsetBank(bank: VoiceBank): void {\n\t\tUtauTTSAdapter.assertReady();\n\t\tif (this.currentBank === bank && this.bankAliases.has(bank)) return;\n\t\tconst entries: Record<string, unknown[]> = {};\n\t\tconst pitch: Record<string, number> = {};\n\t\tfor (const [alias, phoneme] of Object.entries(bank.manifest.phonemes)) {\n\t\t\tentries[alias] = [\n\t\t\t\t{\n\t\t\t\t\tFilename: `koe:${alias}`,\n\t\t\t\t\tAlias: alias,\n\t\t\t\t\tOffset: 0,\n\t\t\t\t\tFixed: phoneme.consonant / 48,\n\t\t\t\t\tBlank: 0,\n\t\t\t\t\tPreutterance: phoneme.pre / 48,\n\t\t\t\t\tOverlap: phoneme.overlap / 48,\n\t\t\t\t\tSourceGroup: \"koe\",\n\t\t\t\t},\n\t\t\t];\n\t\t\tif (phoneme.pitch > 0) pitch[alias] = phoneme.pitch;\n\t\t}\n\t\tconst result = utautts_set_bank(\n\t\t\tJSON.stringify({\n\t\t\t\tname: \"koe\",\n\t\t\t\toto_entries: entries,\n\t\t\t\tsource_pitch_hz: pitch,\n\t\t\t}),\n\t\t);\n\t\tif (!result.success) throw new Error(`UtauTTS bank error: ${result.error}`);\n\t\tthis.bankAliases.set(bank, result.aliases ?? 0);\n\t\tthis.currentBank = bank;\n\t\tthis.pcmCache.clear();\n\t}\n\n\t/**\n\t * Plan an utterance: unit selection, timing, pitch contour and worldline\n\t * placement. `features` are the mora-level frames from `openjtalkAnalyze`\n\t * (pauses included); the kana reading is derived from them.\n\t */\n\tplan(\n\t\tbank: VoiceBank,\n\t\ttext: string,\n\t\tfeatures: FeatureFrame[],\n\t\toptions: UtauTTSOptions = {},\n\t): UtauTTSPlan {\n\t\tthis.setBank(bank);\n\t\tconst request = {\n\t\t\ttext,\n\t\t\treading: readingFromFeatures(features),\n\t\t\tframes: features.map((frame) => sparse_features(frame)),\n\t\t\ttone: options.tone ?? \"C4\",\n\t\t\tmora_duration_ms: options.moraDurationMs ?? 0,\n\t\t\tpause_duration_ms: options.pauseDurationMs ?? 0,\n\t\t\trelease_ms: options.releaseMs ?? 20,\n\t\t\tleading_preutterance_ms: options.leadingPreutteranceMs ?? 0,\n\t\t\tapply_pitch: options.applyPitch ?? true,\n\t\t\tintonation_strength: options.intonationStrength ?? 1,\n\t\t\tspeech_timing: options.speechTiming ?? false,\n\t\t\tword_boundary_envelope: options.wordBoundaryEnvelope ?? false,\n\t\t\tmora_durations_ms: options.prosody?.moraDurationsMs,\n\t\t\tpitch_curve: options.prosody?.pitchCurve,\n\t\t};\n\t\tconst response = utautts_plan(JSON.stringify(request));\n\t\tif (!response.success || !response.plan) {\n\t\t\tthrow new Error(`UtauTTS error: ${response.error ?? \"no plan\"}`);\n\t\t}\n\t\tconst plan = JSON.parse(response.plan) as UtauTTSPlan;\n\t\tconst gains = options.prosody?.moraGains;\n\t\tif (gains) applyMoraGains(plan, gains);\n\t\treturn plan;\n\t}\n\n\tprivate getPcm(bank: VoiceBank, alias: string): Promise<Float64Array | null> {\n\t\tlet cached = this.pcmCache.get(alias);\n\t\tif (!cached) {\n\t\t\tcached = bank.getPcm(alias);\n\t\t\tthis.pcmCache.set(alias, cached);\n\t\t}\n\t\treturn cached;\n\t}\n\n\t/**\n\t * Render a plan chunk by chunk. Each chunk is independent audio positioned\n\t * at `startMs`; schedule them as they arrive (see the demo) or sum them.\n\t *\n\t * Chunk breaks fall on pauses when possible. Inside a phrase a break renders\n\t * one neighbouring unit of context on each side so the unit crossfade stays\n\t * WORLD's spectral one, then the two renders are joined with a short\n\t * equal-power crossfade in the following vowel.\n\t */\n\tasync *renderChunks(\n\t\tbank: VoiceBank,\n\t\tplan: UtauTTSPlan,\n\t\toptions: UtauTTSRenderOptions = {},\n\t): AsyncGenerator<UtauTTSChunk> {\n\t\tconst {\n\t\t\tfirstChunkUnits = 3,\n\t\t\tchunkUnits = 6,\n\t\t\tseamCrossfadeMs = 20,\n\t\t\tsignal,\n\t\t} = options;\n\t\tconst timeline = plan.timeline;\n\t\tconst units = timeline.units.filter((unit) => unit.length_ms > 0);\n\t\tconst ranges = planChunks(\n\t\t\tunits,\n\t\t\tMath.max(1, firstChunkUnits),\n\t\t\tMath.max(1, chunkUnits),\n\t\t);\n\t\tconst crossfadeSamples = Math.max(2, msToSamples(seamCrossfadeMs));\n\n\t\tfor (let index = 0; index < ranges.length; index++) {\n\t\t\tif (signal?.aborted) return;\n\t\t\tconst range = ranges[index];\n\t\t\tconst renderStart = range.headSeam ? range.start - 1 : range.start;\n\t\t\tconst renderEnd = range.tailSeam ? range.end + 1 : range.end;\n\t\t\tconst rendered = units.slice(renderStart, renderEnd);\n\t\t\tconst baseMs = Math.min(...rendered.map((unit) => unit.position_ms));\n\n\t\t\tconst phraseUnits: PhraseUnit[] = [];\n\t\t\tfor (const unit of rendered) {\n\t\t\t\tconst pcm = await this.getPcm(bank, unit.alias);\n\t\t\t\tif (!pcm || pcm.length < MIN_WORLDLINE_SAMPLES) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[utautts] no usable PCM for alias \"${unit.alias}\"; skipped`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tphraseUnits.push({\n\t\t\t\t\tpcm,\n\t\t\t\t\tposMs: unit.position_ms - baseMs,\n\t\t\t\t\tskipMs: unit.skip_ms,\n\t\t\t\t\tlengthMs: unit.length_ms,\n\t\t\t\t\tfadeInMs: unit.fade_in_ms,\n\t\t\t\t\tfadeOutMs: unit.fade_out_ms,\n\t\t\t\t\tconsonantMs: unit.consonant_ms,\n\t\t\t\t\trequiredLengthMs: unit.required_length_ms,\n\t\t\t\t\tvolume: unit.volume,\n\t\t\t\t\ttone: unit.tone,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (signal?.aborted) return;\n\t\t\tif (phraseUnits.length === 0) continue;\n\n\t\t\tconst audio = this.worldline.renderPhrase({\n\t\t\t\tunits: phraseUnits,\n\t\t\t\tpitch: (tMs) => f0At(timeline, baseMs + tMs),\n\t\t\t\tgender: options.gender,\n\t\t\t\ttension: options.tension,\n\t\t\t\tbreathiness: options.breathiness,\n\t\t\t\tvoicing: options.voicing,\n\t\t\t});\n\t\t\tif (!audio || audio.length === 0) continue;\n\n\t\t\t// Trim to [head seam − xf/2, tail seam + xf/2] and fade the seams.\n\t\t\tlet fromSample = 0;\n\t\t\tlet toSample = audio.length;\n\t\t\tlet startMs = baseMs;\n\t\t\tif (range.headSeam) {\n\t\t\t\tconst seamMs = seamTimeMs(units[range.start], seamCrossfadeMs);\n\t\t\t\tfromSample = Math.max(\n\t\t\t\t\t0,\n\t\t\t\t\tmsToSamples(seamMs - baseMs) - crossfadeSamples / 2,\n\t\t\t\t);\n\t\t\t\tstartMs = baseMs + (fromSample / FS) * 1000;\n\t\t\t}\n\t\t\tif (range.tailSeam) {\n\t\t\t\tconst seamMs = seamTimeMs(units[range.end], seamCrossfadeMs);\n\t\t\t\ttoSample = Math.min(\n\t\t\t\t\taudio.length,\n\t\t\t\t\tmsToSamples(seamMs - baseMs) + crossfadeSamples / 2,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (toSample <= fromSample) continue;\n\t\t\tconst pcm = audio.slice(fromSample, toSample);\n\t\t\tif (range.headSeam) applyFade(pcm, 0, crossfadeSamples, true);\n\t\t\tif (range.tailSeam)\n\t\t\t\tapplyFade(\n\t\t\t\t\tpcm,\n\t\t\t\t\tMath.max(0, pcm.length - crossfadeSamples),\n\t\t\t\t\tcrossfadeSamples,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\n\t\t\tyield { pcm, startMs, index, units: units.slice(range.start, range.end) };\n\t\t\t// Let the event loop breathe (audio scheduling, UI) between chunks.\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 0));\n\t\t}\n\t}\n\n\t/**\n\t * Plan + render an utterance into one buffer (Float32, 48 kHz) covering the\n\t * whole timeline. Use {@link plan} + {@link renderChunks} for streaming.\n\t */\n\tasync synthesizeText(\n\t\tbank: VoiceBank,\n\t\ttext: string,\n\t\tfeatures: FeatureFrame[],\n\t\toptions: UtauTTSOptions & UtauTTSRenderOptions = {},\n\t): Promise<Float32Array | null> {\n\t\tconst plan = this.plan(bank, text, features, options);\n\t\tconst total = msToSamples(plan.timeline.duration_ms) + msToSamples(200);\n\t\tconst out = new Float32Array(total);\n\t\tlet any = false;\n\t\tfor await (const chunk of this.renderChunks(bank, plan, options)) {\n\t\t\tany = true;\n\t\t\tconst offset = msToSamples(chunk.startMs);\n\t\t\tconst n = Math.min(chunk.pcm.length, out.length - offset);\n\t\t\tfor (let k = 0; k < n; k++) out[offset + k] += chunk.pcm[k];\n\t\t}\n\t\treturn any ? out : null;\n\t}\n}\n"],"mappings":";AAcA,IAAM,cAAc;AAcb,SAAS,SAAS,QAAqC;AAC7D,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,OAAO,IAAI,SAAS,MAAM;AAEhC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,WAAU,OAAO,aAAa,KAAK,SAAS,CAAC,CAAC;AAC1E,MAAI,WAAW,WAAY,QAAO;AAElC,QAAM,UAAU,KAAK,SAAS,GAAG,IAAI;AACrC,QAAM,YAAY,KAAK,WAAW,IAAI,IAAI;AAC1C,QAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AAGvC,QAAM,YAAY,KAAK,OAAO,OAAO,aAAa,eAAe,EAAE;AACnE,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,SAAS,CAAC;AAExD,QAAM,KAAK,IAAI,aAAa,MAAM;AAClC,QAAM,MAAM,IAAI,aAAa,MAAM;AACnC,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAChC,UAAM,IAAI,cAAc,IAAI;AAC5B,OAAG,CAAC,IAAI,KAAK,WAAW,GAAG,IAAI;AAC/B,QAAI,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,IAAI;AAAA,EACrC;AAEA,SAAO;AAAA,IACN,SAAS,UAAU,IAAI,UAAU;AAAA,IACjC,WAAW,OAAO,SAAS,SAAS,KAAK,YAAY,IAAI,YAAY;AAAA,IACrE;AAAA,IACA;AAAA,EACD;AACD;AAgBO,SAAS,oBACf,KACA,SACA,OACA,YACS;AACT,MAAI,EAAE,aAAa,MAAM,IAAI,GAAG,WAAW,EAAG,QAAO;AACrD,QAAM,aAAc,IAAI,UAAU,aAAc;AAChD,MAAI,EAAE,aAAa,GAAI,QAAO;AAE9B,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,UAAU,CAAC;AAC1D,QAAM,OAAO,KAAK,IAAI,IAAI,GAAG,SAAS,GAAG,KAAK,KAAK,QAAQ,UAAU,CAAC;AAItE,MAAIA,OAAM;AACV,MAAI,MAAM;AACV,WAAS,IAAI,OAAO,KAAK,MAAM,KAAK;AACnC,UAAM,KAAK,IAAI,GAAG,CAAC;AACnB,QAAI,EAAE,KAAK,GAAI;AACf,UAAM,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI;AACxC,IAAAA,QAAO,KAAK;AACZ,WAAO;AAAA,EACR;AACA,SAAO,MAAM,IAAIA,OAAM,MAAM;AAC9B;AAGO,SAAS,kBAAkB,QAAoC;AACrE,QAAM,MAAM,SAAS,MAAM;AAC3B,SAAO,OAAO,IAAI,YAAY,IAAI,IAAI,YAAY;AACnD;AAGO,SAAS,YAAY,SAAyB;AACpD,QAAM,MAAM,QAAQ,YAAY,GAAG;AACnC,QAAM,OAAO,OAAO,IAAI,QAAQ,MAAM,GAAG,GAAG,IAAI;AAChD,QAAM,MAAM,OAAO,IAAI,QAAQ,MAAM,MAAM,CAAC,IAAI;AAChD,SAAO,GAAG,IAAI,IAAI,GAAG;AACtB;;;ACjHA,IAAM,cAAc;AAEpB,IAAM,gBAAwC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACJ;AAGO,SAAS,aAAa,MAA6B;AACzD,QAAM,IAAI,6BAA6B,KAAK,IAAI;AAChD,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,OAAO,cAAc,EAAE,CAAC,EAAE,YAAY,CAAC;AAC3C,MAAI,EAAE,CAAC,MAAM,IAAK;AAAA,WACT,EAAE,CAAC,MAAM,IAAK;AACvB,QAAM,QAAQ,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,KAAK;AAC7C,SAAO,MAAM,OAAO,OAAO,MAAM;AAClC;AAGO,SAAS,qBAAqB,OAA8B;AAClE,QAAM,IAAI,yBAAyB,KAAK,KAAK;AAC7C,SAAO,IAAI,aAAa,EAAE,CAAC,CAAC,IAAI;AACjC;AAWO,SAAS,SAAS,KAAiB,OAAe,KAAqB;AAC7E,QAAM,QAAQ;AACd,QAAM,KAAK,cAAc;AACzB,QAAM,SAAS,KAAK,MAAM,KAAK,GAAG;AAClC,QAAM,SAAS,KAAK,MAAM,KAAK,EAAE;AAEjC,QAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK;AAC/C,MAAI,SAAS,SAAS,EAAG,QAAO;AAChC,QAAM,MAAM,KAAK,IAAI,QAAQ,IAAI;AAIjC,QAAM,MAAM,IAAI,aAAa,GAAG;AAChC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC7B,QAAI,IAAI;AACR,UAAM,OAAO,QAAQ,IAAI;AACzB,aAAS,IAAI,GAAG,IAAI,OAAO,IAAK,MAAK,IAAI,OAAO,CAAC;AACjD,QAAI,CAAC,IAAI;AACT,YAAQ;AAAA,EACT;AACA,UAAQ;AAER,QAAM,KAAK,IAAI,aAAa,MAAM,CAAC;AACnC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC7B,QAAI,CAAC,KAAK;AACV,OAAG,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;AAAA,EACnC;AACA,MAAI,GAAG,GAAG,IAAI,EAAG,QAAO;AAGxB,QAAM,OAAO,CAAC,QAAwB;AACrC,UAAM,IAAI,MAAM;AAChB,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,MAAK,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG;AACrD,UAAM,IAAI,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG;AACvC,WAAO,IAAI,IAAK,IAAI,IAAK,IAAI;AAAA,EAC9B;AAEA,MAAI,UAAU;AACd,MAAI,OAAO;AACX,WAAS,MAAM,QAAQ,OAAO,QAAQ,OAAO;AAC5C,UAAM,IAAI,KAAK,GAAG;AAClB,QAAI,IAAI,MAAM;AACb,aAAO;AACP,gBAAU;AAAA,IACX;AAAA,EACD;AACA,MAAI,UAAU,KAAK,OAAO,IAAK,QAAO;AAGtC,QAAM,KAAK,KAAK,UAAU,CAAC;AAC3B,QAAM,KAAK;AACX,QAAM,KAAK,KAAK,UAAU,CAAC;AAC3B,QAAM,QAAQ,KAAK,IAAI,KAAK;AAC5B,QAAM,QAAQ,UAAU,IAAK,OAAO,KAAK,MAAO,QAAQ;AAExD,SAAO,MAAM,UAAU;AACxB;;;AC5FA,IAAM,cAAc;AAEpB,SAAS,YAAY,IAAoB;AACxC,SAAO,KAAK,MAAO,KAAK,MAAQ,WAAW;AAC5C;AAEA,IAAM,QAAQ,CAAC,GAAW,IAAY,OACrC,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;AA6BtB,SAAS,UACf,WACA,KACiC;AACjC,QAAM,QAAQ,MAAM,YAAY,IAAI,MAAM,GAAG,GAAG,SAAS;AACzD,QAAM,MACL,IAAI,SAAS,IACV,MAAM,QAAQ,YAAY,CAAC,IAAI,MAAM,GAAG,OAAO,SAAS,IACxD,MAAM,YAAY,YAAY,IAAI,MAAM,GAAG,OAAO,SAAS;AAC/D,SAAO,EAAE,OAAO,IAAI;AACrB;AAcA,SAAS,YAAY,OAA+B;AACnD,QAAM,MAAM,IAAI,WAAW,MAAM,MAAM;AACvC,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,QAAO,MAAM,CAAC;AACrD,QAAM,KAAK,KAAK,MAAM,MAAM,MAAM,MAAM;AAExC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,QAAI,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,IAAI,QAAQ,KAAK;AAAA,EAC5C;AACA,SAAO;AACR;AAcO,SAAS,UACf,KACA,KACA,gBAAgB,GACC;AACjB,QAAM,EAAE,OAAO,IAAI,IAAI,UAAU,IAAI,QAAQ,GAAG;AAIhD,QAAM,QAAQ,YAAY,IAAI,SAAS,OAAO,GAAG,CAAC;AAClD,QAAM,SAAS,MAAM;AAErB,QAAM,MAAM,MAAM,YAAY,IAAI,GAAG,GAAG,GAAG,MAAM;AACjD,QAAM,UAAU,MAAM,YAAY,IAAI,OAAO,GAAG,GAAG,MAAM;AACzD,QAAM,YAAY,MAAM,YAAY,IAAI,SAAS,GAAG,GAAG,MAAM;AAI7D,QAAM,QACL,gBAAgB,IACb,gBACA;AAAA,IACA;AAAA,IACA,KAAK,IAAI,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC;AAAA,IAC1D;AAAA,EACD;AAEH,SAAO;AAAA,IACN,KAAK;AAAA,IACL,OAAO,EAAE,QAAQ,KAAK,SAAS,WAAW,MAAM;AAAA,EACjD;AACD;AAOO,SAAS,KAAK,QAAqB,iBAAiB,KAAiB;AAC3E,QAAM,WAAyC,CAAC;AAChD,QAAM,SAAuB,CAAC;AAC9B,MAAI,aAAa;AAEjB,aAAW,EAAE,KAAK,KAAK,cAAc,KAAK,QAAQ;AACjD,UAAM,EAAE,KAAK,OAAO,MAAM,IAAI,UAAU,KAAK,KAAK,aAAa;AAC/D,QAAI,MAAM,WAAW,EAAG;AAExB,aAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,YAAY,GAAG,MAAM;AACrD,kBAAc,MAAM;AACpB,WAAO,KAAK,KAAK;AAAA,EAClB;AAEA,QAAM,MAAM,IAAI,YAAY,UAAU;AACtC,QAAM,OAAO,IAAI,WAAW,GAAG;AAC/B,MAAI,MAAM;AACV,aAAW,SAAS,QAAQ;AAC3B,SAAK;AAAA,MACJ,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU;AAAA,MAC/D;AAAA,IACD;AACA,WAAO,MAAM;AAAA,EACd;AAEA,QAAM,WAAqB;AAAA,IAC1B,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACD;AAEA,SAAO,EAAE,UAAU,IAAI;AACxB;;;AC3IO,SAAS,SAAS,SAA6B;AACrD,QAAM,UAAsB,CAAC;AAE7B,aAAW,OAAO,QAAQ,MAAM,OAAO,GAAG;AACzC,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,EAAG;AAEnC,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAI,OAAO,GAAI;AAEf,UAAM,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK;AACnC,UAAM,QAAQ,KAAK,MAAM,KAAK,CAAC,EAAE,MAAM,GAAG;AAC1C,QAAI,MAAM,SAAS,EAAG;AAEtB,UAAM,CAAC,OAAO,WAAW,cAAc,WAAW,QAAQ,UAAU,IACnE;AAED,UAAM,WAAW,MAAM,KAAK,KAAK,IAAI,QAAQ,YAAY,EAAE;AAC3D,UAAM,QAAkB;AAAA,MACvB;AAAA,MACA,OAAO;AAAA,MACP,QAAQ,WAAW,SAAS,KAAK;AAAA,MACjC,WAAW,WAAW,YAAY,KAAK;AAAA,MACvC,QAAQ,WAAW,SAAS,KAAK;AAAA,MACjC,KAAK,WAAW,MAAM,KAAK;AAAA,MAC3B,SAAS,WAAW,UAAU,KAAK;AAAA,IACpC;AAEA,QAAI,CAAC,MAAM,MAAO;AAClB,YAAQ,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AACR;;;AC9CO,SAAS,SAAS,KAA2B;AACnD,QAAM,OAAO,IAAI,SAAS,GAAG;AAE7B,QAAM,OAAO,WAAW,MAAM,CAAC;AAC/B,MAAI,SAAS,OAAQ,OAAM,IAAI,MAAM,yBAAyB,IAAI,IAAI;AAEtE,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,aAAa;AAEjB,MAAI,MAAM;AACV,SAAO,MAAM,KAAK,aAAa,GAAG;AACjC,UAAM,KAAK,WAAW,MAAM,GAAG;AAC/B,UAAM,OAAO,KAAK,UAAU,MAAM,GAAG,IAAI;AACzC,WAAO;AAEP,QAAI,OAAO,QAAQ;AAClB,oBAAc,KAAK,UAAU,KAAK,IAAI;AACtC,iBAAW,KAAK,UAAU,MAAM,GAAG,IAAI;AACvC,mBAAa,KAAK,UAAU,MAAM,GAAG,IAAI;AACzC,sBAAgB,KAAK,UAAU,MAAM,IAAI,IAAI;AAG7C,UAAI,gBAAgB,SAAU,QAAQ,IAAI;AACzC,sBAAc,KAAK,UAAU,MAAM,IAAI,IAAI;AAAA,MAC5C;AAAA,IACD,WAAW,OAAO,QAAQ;AACzB,mBAAa;AAGb,mBAAa,KAAK,IAAI,MAAM,KAAK,aAAa,GAAG;AACjD;AAAA,IACD;AAEA,WAAO,QAAQ,OAAO;AAAA,EACvB;AAEA,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,uBAAuB;AACxD,MAAI,CAAC,YAAY,CAAC,WAAY,OAAM,IAAI,MAAM,uBAAuB;AAIrE,QAAM,YACJ,gBAAgB,KAAK,kBAAkB,MACvC,gBAAgB,MACf,kBAAkB,KAAK,kBAAkB,MAAM,kBAAkB;AACpE,MAAI,CAAC,WAAW;AACf,UAAM,IAAI;AAAA,MACT,0BAA0B,WAAW,MAAM,aAAa;AAAA,IACzD;AAAA,EACD;AAEA,QAAM,iBAAiB,iBAAiB;AACxC,QAAM,eAAe,KAAK,MAAM,aAAa,cAAc;AAC3D,QAAM,UAAU,IAAI,aAAa,YAAY;AAE7C,WAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACtC,UAAM,IAAI,aAAa,IAAI;AAC3B,QAAI,gBAAgB,GAAG;AACtB,cAAQ,CAAC,IAAI,KAAK,WAAW,GAAG,IAAI;AAAA,IACrC,WAAW,kBAAkB,GAAG;AAC/B,cAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,OAAO;AAAA,IACzC,WAAW,kBAAkB,IAAI;AAChC,cAAQ,CAAC,IAAI,KAAK,SAAS,GAAG,IAAI,IAAI;AAAA,IACvC,WAAW,kBAAkB,IAAI;AAChC,YAAM,KAAK,KAAK,SAAS,CAAC,IAAK,KAAK,SAAS,IAAI,CAAC,KAAK;AACvD,UAAI,KAAK,KAAK,SAAS,IAAI,CAAC;AAC5B,UAAI,KAAK,IAAM,MAAK,KAAK;AACzB,cAAQ,CAAC,KAAM,MAAM,KAAM,MAAM;AAAA,IAClC;AAAA,EACD;AAEA,SAAO,EAAE,YAAY,UAAU,QAAQ;AACxC;AAGO,SAAS,OAAO,KAAuB;AAC7C,MAAI,IAAI,aAAa,EAAG,QAAO;AAC/B,QAAM,MAAM,IAAI,QAAQ,SAAS,IAAI;AACrC,QAAM,MAAM,IAAI,aAAa,GAAG;AAChC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC7B,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,UAAU;AACjC,aAAO,IAAI,QAAQ,IAAI,IAAI,WAAW,CAAC;AACxC,QAAI,CAAC,IAAI,MAAM,IAAI;AAAA,EACpB;AACA,SAAO,EAAE,YAAY,IAAI,YAAY,UAAU,GAAG,SAAS,IAAI;AAChE;AAGO,SAAS,SAAS,KAAc,YAA6B;AACnE,MAAI,IAAI,eAAe,WAAY,QAAO;AAC1C,QAAM,QAAQ,IAAI,aAAa;AAC/B,QAAM,SAAS,KAAK,MAAM,IAAI,QAAQ,SAAS,KAAK;AACpD,QAAM,MAAM,IAAI,aAAa,MAAM;AACnC,QAAM,MAAM,IAAI;AAChB,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAChC,UAAM,IAAI,IAAI;AACd,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,OAAO,IAAI;AACjB,QAAI,CAAC,KAAK,IAAI,EAAE,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,MAAM,IAAI,EAAE,KAAK,MAAM;AAAA,EACnE;AACA,SAAO,EAAE,YAAY,YAAY,UAAU,GAAG,SAAS,IAAI;AAC5D;AAGO,SAAS,QAAQ,SAAmC;AAC1D,QAAM,MAAM,IAAI,WAAW,QAAQ,MAAM;AACzC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,QAAI,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK;AAAA,EAClE;AACA,SAAO;AACR;AAaO,SAAS,cAAc,KAG5B;AACD,QAAM,MAAM,SAAS,GAAG;AACxB,QAAM,OAAO,OAAO,GAAG;AACvB,QAAM,YAAY,SAAS,MAAM,IAAK;AACtC,SAAO,EAAE,KAAK,QAAQ,UAAU,OAAO,GAAG,YAAY,IAAI,WAAW;AACtE;AAQO,SAAS,aAAa,KAA8B;AAC1D,SAAO,cAAc,GAAG,EAAE;AAC3B;AAEA,SAAS,WAAW,MAAgB,KAAqB;AACxD,SAAO,OAAO;AAAA,IACb,KAAK,SAAS,GAAG;AAAA,IACjB,KAAK,SAAS,MAAM,CAAC;AAAA,IACrB,KAAK,SAAS,MAAM,CAAC;AAAA,IACrB,KAAK,SAAS,MAAM,CAAC;AAAA,EACtB;AACD;;;ACrIA,IAAI,KAAK;AAAT,IAAqB,MAAM;AAA3B,IAAwC,MAAM;AAE9C,IAAI,OAAO,IAAI,GAAG;AAAA,EAAC;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA;AAAA,EAAgB;AAAA,EAAG;AAAA;AAAA,EAAoB;AAAC,CAAC;AAEhJ,IAAI,OAAO,IAAI,GAAG;AAAA,EAAC;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA;AAAA,EAAiB;AAAA,EAAG;AAAC,CAAC;AAEvI,IAAI,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;AAEpF,IAAI,OAAO,SAAU,IAAI,OAAO;AAC5B,MAAI,IAAI,IAAI,IAAI,EAAE;AAClB,WAAS,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;AACzB,MAAE,CAAC,IAAI,SAAS,KAAK,GAAG,IAAI,CAAC;AAAA,EACjC;AAEA,MAAI,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;AACrB,WAAS,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;AACzB,aAAS,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG;AAClC,QAAE,CAAC,IAAM,IAAI,EAAE,CAAC,KAAM,IAAK;AAAA,IAC/B;AAAA,EACJ;AACA,SAAO,EAAE,GAAM,EAAK;AACxB;AACA,IAAI,KAAK,KAAK,MAAM,CAAC;AAArB,IAAwB,KAAK,GAAG;AAAhC,IAAmC,QAAQ,GAAG;AAE9C,GAAG,EAAE,IAAI,KAAK,MAAM,GAAG,IAAI;AAC3B,IAAI,KAAK,KAAK,MAAM,CAAC;AAArB,IAAwB,KAAK,GAAG;AAAhC,IAAmC,QAAQ,GAAG;AAE9C,IAAI,MAAM,IAAI,IAAI,KAAK;AACvB,KAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAAG;AAExB,OAAM,IAAI,UAAW,KAAO,IAAI,UAAW;AAC/C,OAAM,IAAI,UAAW,KAAO,IAAI,UAAW;AAC3C,OAAM,IAAI,UAAW,KAAO,IAAI,SAAW;AAC3C,MAAI,CAAC,MAAO,IAAI,UAAW,KAAO,IAAI,QAAW,MAAO;AAC5D;AAJQ;AAFC;AAUT,IAAI,QAAQ,SAAU,IAAI,IAAI,GAAG;AAC7B,MAAI,IAAI,GAAG;AAEX,MAAI,IAAI;AAER,MAAI,IAAI,IAAI,IAAI,EAAE;AAElB,SAAO,IAAI,GAAG,EAAE,GAAG;AACf,QAAI,GAAG,CAAC;AACJ,QAAE,EAAE,GAAG,CAAC,IAAI,CAAC;AAAA,EACrB;AAEA,MAAI,KAAK,IAAI,IAAI,EAAE;AACnB,OAAK,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;AACrB,OAAG,CAAC,IAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAM;AAAA,EACtC;AACA,MAAI;AACJ,MAAI,GAAG;AAEH,SAAK,IAAI,IAAI,KAAK,EAAE;AAEpB,QAAI,MAAM,KAAK;AACf,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AAEpB,UAAI,GAAG,CAAC,GAAG;AAEP,YAAI,KAAM,KAAK,IAAK,GAAG,CAAC;AAExB,YAAI,MAAM,KAAK,GAAG,CAAC;AAEnB,YAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO;AAE3B,iBAAS,IAAI,KAAM,KAAK,OAAO,GAAI,KAAK,GAAG,EAAE,GAAG;AAE5C,aAAG,IAAI,CAAC,KAAK,GAAG,IAAI;AAAA,QACxB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,OACK;AACD,SAAK,IAAI,IAAI,CAAC;AACd,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACpB,UAAI,GAAG,CAAC,GAAG;AACP,WAAG,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,KAAM,KAAK,GAAG,CAAC;AAAA,MAC9C;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAEA,IAAI,MAAM,IAAI,GAAG,GAAG;AACpB,KAAS,IAAI,GAAG,IAAI,KAAK,EAAE;AACvB,MAAI,CAAC,IAAI;AADJ;AAET,KAAS,IAAI,KAAK,IAAI,KAAK,EAAE;AACzB,MAAI,CAAC,IAAI;AADJ;AAET,KAAS,IAAI,KAAK,IAAI,KAAK,EAAE;AACzB,MAAI,CAAC,IAAI;AADJ;AAET,KAAS,IAAI,KAAK,IAAI,KAAK,EAAE;AACzB,MAAI,CAAC,IAAI;AADJ;AAGT,IAAI,MAAM,IAAI,GAAG,EAAE;AACnB,KAAS,IAAI,GAAG,IAAI,IAAI,EAAE;AACtB,MAAI,CAAC,IAAI;AADJ;AAGT,IAAI,MAAoB,qBAAK,KAAK,GAAG,CAAC;AAAtC,IAAyC,OAAqB,qBAAK,KAAK,GAAG,CAAC;AAE5E,IAAI,MAAoB,qBAAK,KAAK,GAAG,CAAC;AAAtC,IAAyC,OAAqB,qBAAK,KAAK,GAAG,CAAC;AAE5E,IAAI,MAAM,SAAU,GAAG;AACnB,MAAI,IAAI,EAAE,CAAC;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG;AAC/B,QAAI,EAAE,CAAC,IAAI;AACP,UAAI,EAAE,CAAC;AAAA,EACf;AACA,SAAO;AACX;AAEA,IAAI,OAAO,SAAU,GAAG,GAAG,GAAG;AAC1B,MAAI,IAAK,IAAI,IAAK;AAClB,UAAS,EAAE,CAAC,IAAK,EAAE,IAAI,CAAC,KAAK,OAAQ,IAAI,KAAM;AACnD;AAEA,IAAI,SAAS,SAAU,GAAG,GAAG;AACzB,MAAI,IAAK,IAAI,IAAK;AAClB,UAAS,EAAE,CAAC,IAAK,EAAE,IAAI,CAAC,KAAK,IAAM,EAAE,IAAI,CAAC,KAAK,QAAS,IAAI;AAChE;AAEA,IAAI,OAAO,SAAU,GAAG;AAAE,UAAS,IAAI,KAAK,IAAK;AAAG;AAGpD,IAAI,MAAM,SAAU,GAAG,GAAG,GAAG;AACzB,MAAI,KAAK,QAAQ,IAAI;AACjB,QAAI;AACR,MAAI,KAAK,QAAQ,IAAI,EAAE;AACnB,QAAI,EAAE;AAEV,SAAO,IAAI,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC;AAClC;AAsBA,IAAI,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAEJ;AAEA,IAAI,MAAM,SAAU,KAAK,KAAK,IAAI;AAC9B,MAAI,IAAI,IAAI,MAAM,OAAO,GAAG,GAAG,CAAC;AAChC,IAAE,OAAO;AACT,MAAI,MAAM;AACN,UAAM,kBAAkB,GAAG,GAAG;AAClC,MAAI,CAAC;AACD,UAAM;AACV,SAAO;AACX;AAEA,IAAI,QAAQ,SAAU,KAAK,IAAI,KAAK,MAAM;AAEtC,MAAI,KAAK,IAAI,QAAQ,KAAK,OAAO,KAAK,SAAS;AAC/C,MAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG;AACnB,WAAO,OAAO,IAAI,GAAG,CAAC;AAC1B,MAAI,QAAQ,CAAC;AAEb,MAAI,SAAS,SAAS,GAAG,KAAK;AAE9B,MAAI,OAAO,GAAG;AAEd,MAAI;AACA,UAAM,IAAI,GAAG,KAAK,CAAC;AAEvB,MAAI,OAAO,SAAUC,IAAG;AACpB,QAAI,KAAK,IAAI;AAEb,QAAIA,KAAI,IAAI;AAER,UAAI,OAAO,IAAI,GAAG,KAAK,IAAI,KAAK,GAAGA,EAAC,CAAC;AACrC,WAAK,IAAI,GAAG;AACZ,YAAM;AAAA,IACV;AAAA,EACJ;AAEA,MAAI,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG;AAEnG,MAAI,OAAO,KAAK;AAChB,KAAG;AACC,QAAI,CAAC,IAAI;AAEL,cAAQ,KAAK,KAAK,KAAK,CAAC;AAExB,UAAI,OAAO,KAAK,KAAK,MAAM,GAAG,CAAC;AAC/B,aAAO;AACP,UAAI,CAAC,MAAM;AAEP,YAAI,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,IAAK,IAAI,IAAI,CAAC,KAAK,GAAI,IAAI,IAAI;AACnE,YAAI,IAAI,IAAI;AACR,cAAI;AACA,gBAAI,CAAC;AACT;AAAA,QACJ;AAEA,YAAI;AACA,eAAK,KAAK,CAAC;AAEf,YAAI,IAAI,IAAI,SAAS,GAAG,CAAC,GAAG,EAAE;AAE9B,WAAG,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,GAAG,IAAI;AAC3C;AAAA,MACJ,WACS,QAAQ;AACb,aAAK,MAAM,KAAK,MAAM,MAAM,GAAG,MAAM;AAAA,eAChC,QAAQ,GAAG;AAEhB,YAAI,OAAO,KAAK,KAAK,KAAK,EAAE,IAAI,KAAK,QAAQ,KAAK,KAAK,MAAM,IAAI,EAAE,IAAI;AACvE,YAAI,KAAK,OAAO,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI;AACzC,eAAO;AAEP,YAAI,MAAM,IAAI,GAAG,EAAE;AAEnB,YAAI,MAAM,IAAI,GAAG,EAAE;AACnB,iBAAS,IAAI,GAAG,IAAI,OAAO,EAAE,GAAG;AAE5B,cAAI,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC;AAAA,QAC3C;AACA,eAAO,QAAQ;AAEf,YAAI,MAAM,IAAI,GAAG,GAAG,UAAU,KAAK,OAAO;AAE1C,YAAI,MAAM,KAAK,KAAK,KAAK,CAAC;AAC1B,iBAAS,IAAI,GAAG,IAAI,MAAK;AACrB,cAAI,IAAI,IAAI,KAAK,KAAK,KAAK,MAAM,CAAC;AAElC,iBAAO,IAAI;AAEX,cAAI,IAAI,KAAK;AAEb,cAAI,IAAI,IAAI;AACR,gBAAI,GAAG,IAAI;AAAA,UACf,OACK;AAED,gBAAI,IAAI,GAAG,IAAI;AACf,gBAAI,KAAK;AACL,kBAAI,IAAI,KAAK,KAAK,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC;AAAA,qBAC7C,KAAK;AACV,kBAAI,IAAI,KAAK,KAAK,KAAK,CAAC,GAAG,OAAO;AAAA,qBAC7B,KAAK;AACV,kBAAI,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,OAAO;AACzC,mBAAO;AACH,kBAAI,GAAG,IAAI;AAAA,UACnB;AAAA,QACJ;AAEA,YAAI,KAAK,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK,IAAI,SAAS,IAAI;AAEtD,cAAM,IAAI,EAAE;AAEZ,cAAM,IAAI,EAAE;AACZ,aAAK,KAAK,IAAI,KAAK,CAAC;AACpB,aAAK,KAAK,IAAI,KAAK,CAAC;AAAA,MACxB;AAEI,YAAI,CAAC;AACT,UAAI,MAAM,MAAM;AACZ,YAAI;AACA,cAAI,CAAC;AACT;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI;AACA,WAAK,KAAK,MAAM;AACpB,QAAI,OAAO,KAAK,OAAO,GAAG,OAAO,KAAK,OAAO;AAC7C,QAAI,OAAO;AACX,aAAQ,OAAO,KAAK;AAEhB,UAAI,IAAI,GAAG,OAAO,KAAK,GAAG,IAAI,GAAG,GAAG,MAAM,KAAK;AAC/C,aAAO,IAAI;AACX,UAAI,MAAM,MAAM;AACZ,YAAI;AACA,cAAI,CAAC;AACT;AAAA,MACJ;AACA,UAAI,CAAC;AACD,YAAI,CAAC;AACT,UAAI,MAAM;AACN,YAAI,IAAI,IAAI;AAAA,eACP,OAAO,KAAK;AACjB,eAAO,KAAK,KAAK;AACjB;AAAA,MACJ,OACK;AACD,YAAI,MAAM,MAAM;AAEhB,YAAI,MAAM,KAAK;AAEX,cAAI,IAAI,MAAM,KAAK,IAAI,KAAK,CAAC;AAC7B,gBAAM,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC;AACzC,iBAAO;AAAA,QACX;AAEA,YAAI,IAAI,GAAG,OAAO,KAAK,GAAG,IAAI,GAAG,GAAG,OAAO,KAAK;AAChD,YAAI,CAAC;AACD,cAAI,CAAC;AACT,eAAO,IAAI;AACX,YAAI,KAAK,GAAG,IAAI;AAChB,YAAI,OAAO,GAAG;AACV,cAAI,IAAI,KAAK,IAAI;AACjB,gBAAM,OAAO,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,OAAO;AAAA,QAClD;AACA,YAAI,MAAM,MAAM;AACZ,cAAI;AACA,gBAAI,CAAC;AACT;AAAA,QACJ;AACA,YAAI;AACA,eAAK,KAAK,MAAM;AACpB,YAAI,MAAM,KAAK;AACf,YAAI,KAAK,IAAI;AACT,cAAI,QAAQ,KAAK,IAAI,OAAO,KAAK,IAAI,IAAI,GAAG;AAC5C,cAAI,QAAQ,KAAK;AACb,gBAAI,CAAC;AACT,iBAAO,KAAK,MAAM,EAAE;AAChB,gBAAI,EAAE,IAAI,KAAK,QAAQ,EAAE;AAAA,QACjC;AACA,eAAO,KAAK,KAAK,EAAE;AACf,cAAI,EAAE,IAAI,IAAI,KAAK,EAAE;AAAA,MAC7B;AAAA,IACJ;AACA,OAAG,IAAI,IAAI,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI,GAAG,IAAI;AAC1C,QAAI;AACA,cAAQ,GAAG,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,GAAG,IAAI;AAAA,EACjD,SAAS,CAAC;AAEV,SAAO,MAAM,IAAI,UAAU,QAAQ,IAAI,KAAK,GAAG,EAAE,IAAI,IAAI,SAAS,GAAG,EAAE;AAC3E;AAEA,IAAI,QAAQ,SAAU,GAAG,GAAG,GAAG;AAC3B,QAAM,IAAI;AACV,MAAI,IAAK,IAAI,IAAK;AAClB,IAAE,CAAC,KAAK;AACR,IAAE,IAAI,CAAC,KAAK,KAAK;AACrB;AAEA,IAAI,UAAU,SAAU,GAAG,GAAG,GAAG;AAC7B,QAAM,IAAI;AACV,MAAI,IAAK,IAAI,IAAK;AAClB,IAAE,CAAC,KAAK;AACR,IAAE,IAAI,CAAC,KAAK,KAAK;AACjB,IAAE,IAAI,CAAC,KAAK,KAAK;AACrB;AAEA,IAAI,QAAQ,SAAU,GAAG,IAAI;AAEzB,MAAI,IAAI,CAAC;AACT,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG;AAC/B,QAAI,EAAE,CAAC;AACH,QAAE,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC;AAAA,EAChC;AACA,MAAI,IAAI,EAAE;AACV,MAAI,KAAK,EAAE,MAAM;AACjB,MAAI,CAAC;AACD,WAAO,EAAE,GAAG,IAAI,GAAG,EAAE;AACzB,MAAI,KAAK,GAAG;AACR,QAAI,IAAI,IAAI,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC;AACzB,MAAE,EAAE,CAAC,EAAE,CAAC,IAAI;AACZ,WAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EACxB;AACA,IAAE,KAAK,SAAU,GAAG,GAAG;AAAE,WAAO,EAAE,IAAI,EAAE;AAAA,EAAG,CAAC;AAG5C,IAAE,KAAK,EAAE,GAAG,IAAI,GAAG,MAAM,CAAC;AAC1B,MAAI,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AAC7C,IAAE,CAAC,IAAI,EAAE,GAAG,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,GAAM,EAAK;AAMzC,SAAO,MAAM,IAAI,GAAG;AAChB,QAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,OAAO,IAAI;AACrC,QAAI,EAAE,MAAM,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,OAAO,IAAI;AACjD,MAAE,IAAI,IAAI,EAAE,GAAG,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,GAAM,EAAK;AAAA,EAChD;AACA,MAAI,SAAS,GAAG,CAAC,EAAE;AACnB,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACxB,QAAI,GAAG,CAAC,EAAE,IAAI;AACV,eAAS,GAAG,CAAC,EAAE;AAAA,EACvB;AAEA,MAAI,KAAK,IAAI,IAAI,SAAS,CAAC;AAE3B,MAAI,MAAM,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;AAC7B,MAAI,MAAM,IAAI;AAIV,QAAI,IAAI,GAAG,KAAK;AAEhB,QAAI,MAAM,MAAM,IAAI,MAAM,KAAK;AAC/B,OAAG,KAAK,SAAU,GAAG,GAAG;AAAE,aAAO,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE;AAAA,IAAG,CAAC;AAClE,WAAO,IAAI,GAAG,EAAE,GAAG;AACf,UAAI,OAAO,GAAG,CAAC,EAAE;AACjB,UAAI,GAAG,IAAI,IAAI,IAAI;AACf,cAAM,OAAO,KAAM,MAAM,GAAG,IAAI;AAChC,WAAG,IAAI,IAAI;AAAA,MACf;AAEI;AAAA,IACR;AACA,WAAO;AACP,WAAO,KAAK,GAAG;AACX,UAAI,OAAO,GAAG,CAAC,EAAE;AACjB,UAAI,GAAG,IAAI,IAAI;AACX,cAAM,KAAM,KAAK,GAAG,IAAI,MAAM;AAAA;AAE9B,UAAE;AAAA,IACV;AACA,WAAO,KAAK,KAAK,IAAI,EAAE,GAAG;AACtB,UAAI,OAAO,GAAG,CAAC,EAAE;AACjB,UAAI,GAAG,IAAI,KAAK,IAAI;AAChB,UAAE,GAAG,IAAI;AACT,UAAE;AAAA,MACN;AAAA,IACJ;AACA,UAAM;AAAA,EACV;AACA,SAAO,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,GAAG,IAAI;AACnC;AAEA,IAAI,KAAK,SAAU,GAAG,GAAG,GAAG;AACxB,SAAO,EAAE,KAAK,KACR,KAAK,IAAI,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,IAC5C,EAAE,EAAE,CAAC,IAAI;AACpB;AAEA,IAAI,KAAK,SAAU,GAAG;AAClB,MAAI,IAAI,EAAE;AAEV,SAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACd;AACJ,MAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAEpB,MAAI,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM;AAC/B,MAAI,IAAI,SAAU,GAAG;AAAE,OAAG,KAAK,IAAI;AAAA,EAAG;AACtC,WAAS,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG;AACzB,QAAI,EAAE,CAAC,KAAK,OAAO,KAAK;AACpB,QAAE;AAAA,SACD;AACD,UAAI,CAAC,OAAO,MAAM,GAAG;AACjB,eAAO,MAAM,KAAK,OAAO;AACrB,YAAE,KAAK;AACX,YAAI,MAAM,GAAG;AACT,YAAE,MAAM,KAAO,MAAM,MAAO,IAAK,QAAU,MAAM,KAAM,IAAK,KAAK;AACjE,gBAAM;AAAA,QACV;AAAA,MACJ,WACS,MAAM,GAAG;AACd,UAAE,GAAG,GAAG,EAAE;AACV,eAAO,MAAM,GAAG,OAAO;AACnB,YAAE,IAAI;AACV,YAAI,MAAM;AACN,YAAI,MAAM,KAAM,IAAK,IAAI,GAAG,MAAM;AAAA,MAC1C;AACA,aAAO;AACH,UAAE,GAAG;AACT,YAAM;AACN,YAAM,EAAE,CAAC;AAAA,IACb;AAAA,EACJ;AACA,SAAO,EAAE,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,GAAG,EAAE;AAC1C;AAEA,IAAI,OAAO,SAAU,IAAI,IAAI;AACzB,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,EAAE;AAC7B,SAAK,GAAG,CAAC,IAAI,GAAG,CAAC;AACrB,SAAO;AACX;AAGA,IAAI,QAAQ,SAAU,KAAK,KAAK,KAAK;AAEjC,MAAI,IAAI,IAAI;AACZ,MAAI,IAAI,KAAK,MAAM,CAAC;AACpB,MAAI,CAAC,IAAI,IAAI;AACb,MAAI,IAAI,CAAC,IAAI,KAAK;AAClB,MAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AACtB,MAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;AAC1B,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE;AACrB,QAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;AAC1B,UAAQ,IAAI,IAAI,KAAK;AACzB;AAEA,IAAI,OAAO,SAAU,KAAK,KAAK,OAAO,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;AACnE,QAAM,KAAK,KAAK,KAAK;AACrB,IAAE,GAAG,GAAG;AACR,MAAIC,MAAK,MAAM,IAAI,EAAE,GAAG,MAAMA,IAAG,GAAG,MAAMA,IAAG;AAC7C,MAAIC,MAAK,MAAM,IAAI,EAAE,GAAG,MAAMA,IAAG,GAAG,MAAMA,IAAG;AAC7C,MAAI,KAAK,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,MAAM,GAAG;AACxC,MAAI,KAAK,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,MAAM,GAAG;AACxC,MAAI,SAAS,IAAI,IAAI,EAAE;AACvB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAC/B,MAAE,OAAO,KAAK,CAAC,IAAI,EAAE;AACzB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAC/B,MAAE,OAAO,KAAK,CAAC,IAAI,EAAE;AACzB,MAAI,KAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,GAAG,GAAG,OAAO,GAAG;AACjD,MAAI,OAAO;AACX,SAAO,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,EAAE;AACvC;AACJ,MAAI,OAAQ,KAAK,KAAM;AACvB,MAAI,QAAQ,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;AAC5C,MAAI,QAAQ,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,IAAI,OAAO,KAAK,QAAQ,GAAG,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE;AACpI,MAAI,MAAM,KAAK,QAAQ,SAAS,QAAQ;AACpC,WAAO,MAAM,KAAK,GAAG,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;AAClD,MAAI,IAAI,IAAI,IAAI;AAChB,QAAM,KAAK,GAAG,KAAK,QAAQ,MAAM,GAAG,KAAK;AACzC,MAAI,QAAQ,OAAO;AACf,SAAK,KAAK,KAAK,KAAK,CAAC,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,CAAC,GAAG,KAAK;AAC/D,QAAI,MAAM,KAAK,KAAK,MAAM,CAAC;AAC3B,UAAM,KAAK,GAAG,MAAM,GAAG;AACvB,UAAM,KAAK,IAAI,GAAG,MAAM,CAAC;AACzB,UAAM,KAAK,IAAI,IAAI,OAAO,CAAC;AAC3B,SAAK;AACL,aAAS,IAAI,GAAG,IAAI,MAAM,EAAE;AACxB,YAAM,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC;AACtC,SAAK,IAAI;AACT,QAAI,OAAO,CAAC,MAAM,IAAI;AACtB,aAAS,KAAK,GAAG,KAAK,GAAG,EAAE,IAAI;AAC3B,UAAI,OAAO,KAAK,EAAE;AAClB,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE,GAAG;AAClC,YAAI,MAAM,KAAK,CAAC,IAAI;AACpB,cAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG;AACrC,YAAI,MAAM;AACN,gBAAM,KAAK,GAAI,KAAK,CAAC,KAAK,IAAK,GAAG,GAAG,KAAK,KAAK,CAAC,KAAK;AAAA,MAC7D;AAAA,IACJ;AAAA,EACJ,OACK;AACD,SAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAAA,EACvC;AACA,WAAS,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;AACzB,QAAI,MAAM,KAAK,CAAC;AAChB,QAAI,MAAM,KAAK;AACX,UAAI,MAAO,OAAO,KAAM;AACxB,cAAQ,KAAK,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,MAAM,GAAG;AACjD,UAAI,MAAM;AACN,cAAM,KAAK,GAAI,OAAO,KAAM,EAAE,GAAG,KAAK,KAAK,GAAG;AAClD,UAAI,MAAM,MAAM;AAChB,cAAQ,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG;AACrC,UAAI,MAAM;AACN,gBAAQ,KAAK,GAAI,OAAO,IAAK,IAAI,GAAG,KAAK,KAAK,GAAG;AAAA,IACzD,OACK;AACD,cAAQ,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG;AAAA,IACzC;AAAA,EACJ;AACA,UAAQ,KAAK,GAAG,GAAG,GAAG,CAAC;AACvB,SAAO,IAAI,GAAG,GAAG;AACrB;AAEA,IAAI,MAAoB,oBAAI,IAAI,CAAC,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,SAAS,SAAS,OAAO,CAAC;AAE3G,IAAI,KAAmB,oBAAI,GAAG,CAAC;AAE/B,IAAI,OAAO,SAAU,KAAK,KAAK,MAAM,KAAK,MAAM,IAAI;AAChD,MAAI,IAAI,GAAG,KAAK,IAAI;AACpB,MAAI,IAAI,IAAI,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,KAAK,IAAI;AAE7D,MAAI,IAAI,EAAE,SAAS,KAAK,EAAE,SAAS,IAAI;AACvC,MAAI,MAAM,GAAG;AACb,MAAI,OAAO,GAAG,KAAK,KAAK;AACxB,MAAI,KAAK;AACL,QAAI;AACA,QAAE,CAAC,IAAI,GAAG,KAAK;AACnB,QAAI,MAAM,IAAI,MAAM,CAAC;AACrB,QAAI,IAAI,OAAO,IAAI,IAAI,MAAM;AAC7B,QAAI,SAAS,KAAK,QAAQ;AAE1B,QAAI,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,GAAG,OAAO,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAC;AACnE,QAAI,QAAQ,KAAK,KAAK,OAAO,CAAC,GAAG,QAAQ,IAAI;AAC7C,QAAI,MAAM,SAAUC,IAAG;AAAE,cAAQ,IAAIA,EAAC,IAAK,IAAIA,KAAI,CAAC,KAAK,QAAU,IAAIA,KAAI,CAAC,KAAK,SAAU;AAAA,IAAO;AAGlG,QAAI,OAAO,IAAI,IAAI,IAAK;AAExB,QAAI,KAAK,IAAI,IAAI,GAAG,GAAG,KAAK,IAAI,IAAI,EAAE;AAEtC,QAAI,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AAClE,WAAO,IAAI,IAAI,GAAG,EAAE,GAAG;AAEnB,UAAI,KAAK,IAAI,CAAC;AAEd,UAAI,OAAO,IAAI,OAAO,QAAQ,KAAK,EAAE;AACrC,WAAK,IAAI,IAAI;AACb,WAAK,EAAE,IAAI;AAGX,UAAI,MAAM,GAAG;AAET,YAAI,MAAM,IAAI;AACd,aAAK,OAAO,OAAQ,KAAK,WAAW,MAAM,OAAO,CAAC,MAAM;AACpD,gBAAM,KAAK,KAAK,GAAG,GAAG,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;AAC3D,eAAK,OAAO,KAAK,GAAG,KAAK;AACzB,mBAAS,IAAI,GAAG,IAAI,KAAK,EAAE;AACvB,eAAG,CAAC,IAAI;AACZ,mBAAS,IAAI,GAAG,IAAI,IAAI,EAAE;AACtB,eAAG,CAAC,IAAI;AAAA,QAChB;AAEA,YAAI,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,OAAO,QAAQ;AACjD,YAAI,MAAM,KAAK,MAAM,IAAI,IAAI,GAAG,GAAG;AAC/B,cAAI,OAAO,KAAK,IAAI,GAAG,GAAG,IAAI;AAC9B,cAAI,OAAO,KAAK,IAAI,OAAO,CAAC;AAG5B,cAAI,KAAK,KAAK,IAAI,KAAK,GAAG;AAC1B,iBAAO,OAAO,QAAQ,EAAE,QAAQ,QAAQ,OAAO;AAC3C,gBAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG;AAChC,kBAAI,KAAK;AACT,qBAAO,KAAK,MAAM,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,KAAK,GAAG,GAAG,EAAE;AAClD;AACJ,kBAAI,KAAK,GAAG;AACR,oBAAI,IAAI,IAAI;AAEZ,oBAAI,KAAK;AACL;AAIJ,oBAAI,MAAM,KAAK,IAAI,KAAK,KAAK,CAAC;AAC9B,oBAAI,KAAK;AACT,yBAAS,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG;AAC1B,sBAAI,KAAK,IAAI,MAAM,IAAI;AACvB,sBAAI,MAAM,KAAK,EAAE;AACjB,sBAAI,KAAK,KAAK,MAAM;AACpB,sBAAI,KAAK;AACL,yBAAK,IAAI,QAAQ;AAAA,gBACzB;AAAA,cACJ;AAAA,YACJ;AAEA,mBAAO,OAAO,QAAQ,KAAK,IAAI;AAC/B,mBAAO,OAAO,QAAQ;AAAA,UAC1B;AAAA,QACJ;AAEA,YAAI,GAAG;AAGH,eAAK,IAAI,IAAI,YAAa,MAAM,CAAC,KAAK,KAAM,MAAM,CAAC;AACnD,cAAI,MAAM,MAAM,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,IAAI;AAC1C,gBAAM,KAAK,GAAG,IAAI,KAAK,GAAG;AAC1B,YAAE,GAAG,MAAM,GAAG;AACd,YAAE,GAAG,GAAG;AACR,eAAK,IAAI;AACT,YAAE;AAAA,QACN,OACK;AACD,eAAK,IAAI,IAAI,IAAI,CAAC;AAClB,YAAE,GAAG,IAAI,CAAC,CAAC;AAAA,QACf;AAAA,MACJ;AAAA,IACJ;AACA,SAAK,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG;AAClC,WAAK,IAAI,IAAI,IAAI,CAAC;AAClB,QAAE,GAAG,IAAI,CAAC,CAAC;AAAA,IACf;AACA,UAAM,KAAK,KAAK,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;AAC7D,QAAI,CAAC,KAAK;AACN,SAAG,IAAK,MAAM,IAAK,EAAG,MAAM,IAAK,CAAC,KAAK;AAEvC,aAAO;AACP,SAAG,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI;AAAA,IAC/C;AAAA,EACJ,OACK;AACD,aAAS,IAAI,GAAG,KAAK,GAAG,IAAI,IAAI,KAAK,KAAK,OAAO;AAE7C,UAAI,IAAI,IAAI;AACZ,UAAI,KAAK,GAAG;AAER,UAAG,MAAM,IAAK,CAAC,IAAI;AACnB,YAAI;AAAA,MACR;AACA,YAAM,MAAM,GAAG,MAAM,GAAG,IAAI,SAAS,GAAG,CAAC,CAAC;AAAA,IAC9C;AACA,OAAG,IAAI;AAAA,EACX;AACA,SAAO,IAAI,GAAG,GAAG,MAAM,KAAK,GAAG,IAAI,IAAI;AAC3C;AAEA,IAAI,OAAsB,4BAAY;AAClC,MAAI,IAAI,IAAI,WAAW,GAAG;AAC1B,WAAS,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG;AAC1B,QAAI,IAAI,GAAG,IAAI;AACf,WAAO,EAAE;AACL,WAAM,IAAI,KAAM,cAAe,MAAM;AACzC,MAAE,CAAC,IAAI;AAAA,EACX;AACA,SAAO;AACX,GAAG;AAEH,IAAI,MAAM,WAAY;AAClB,MAAI,IAAI;AACR,SAAO;AAAA,IACH,GAAG,SAAU,GAAG;AAEZ,UAAI,KAAK;AACT,eAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE;AAC5B,aAAK,KAAM,KAAK,MAAO,EAAE,CAAC,CAAC,IAAK,OAAO;AAC3C,UAAI;AAAA,IACR;AAAA,IACA,GAAG,WAAY;AAAE,aAAO,CAAC;AAAA,IAAG;AAAA,EAChC;AACJ;AAyBA,IAAI,OAAO,SAAU,KAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,MAAI,CAAC,IAAI;AACL,SAAK,EAAE,GAAG,EAAE;AACZ,QAAI,IAAI,YAAY;AAChB,UAAI,OAAO,IAAI,WAAW,SAAS,MAAM;AACzC,UAAI,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM;AAC5C,aAAO,IAAI,IAAI;AACf,aAAO,IAAI,KAAK,KAAK,MAAM;AAC3B,YAAM;AACN,SAAG,IAAI,KAAK;AAAA,IAChB;AAAA,EACJ;AACA,SAAO,KAAK,KAAK,IAAI,SAAS,OAAO,IAAI,IAAI,OAAO,IAAI,OAAO,OAAQ,GAAG,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,GAAG,IAAI,KAAO,KAAK,IAAI,KAAM,KAAK,MAAM,EAAE;AACxL;AAEA,IAAI,MAAM,SAAU,GAAG,GAAG;AACtB,MAAI,IAAI,CAAC;AACT,WAAS,KAAK;AACV,MAAE,CAAC,IAAI,EAAE,CAAC;AACd,WAAS,KAAK;AACV,MAAE,CAAC,IAAI,EAAE,CAAC;AACd,SAAO;AACX;AAsIA,IAAI,KAAK,SAAU,GAAG,GAAG;AAAE,SAAO,EAAE,CAAC,IAAK,EAAE,IAAI,CAAC,KAAK;AAAI;AAE1D,IAAI,KAAK,SAAU,GAAG,GAAG;AAAE,UAAQ,EAAE,CAAC,IAAK,EAAE,IAAI,CAAC,KAAK,IAAM,EAAE,IAAI,CAAC,KAAK,KAAO,EAAE,IAAI,CAAC,KAAK,QAAS;AAAG;AAExG,IAAI,KAAK,SAAU,GAAG,GAAG;AAAE,SAAO,GAAG,GAAG,CAAC,IAAK,GAAG,GAAG,IAAI,CAAC,IAAI;AAAa;AAE1E,IAAI,SAAS,SAAU,GAAG,GAAG,GAAG;AAC5B,SAAO,GAAG,EAAE;AACR,MAAE,CAAC,IAAI,GAAG,OAAO;AACzB;AAqLO,SAAS,YAAY,MAAM,MAAM;AACpC,SAAO,KAAK,MAAM,QAAQ,CAAC,GAAG,GAAG,CAAC;AACtC;AAyEO,SAAS,YAAY,MAAM,MAAM;AACpC,SAAO,MAAM,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,KAAK,KAAK,QAAQ,KAAK,UAAU;AAC1E;AAuaA,IAAI,OAAO,SAAU,GAAG,GAAG,GAAG,GAAG;AAC7B,WAAS,KAAK,GAAG;AACb,QAAI,MAAM,EAAE,CAAC,GAAG,IAAI,IAAI,GAAG,KAAK;AAChC,QAAI,MAAM,QAAQ,GAAG;AACjB,WAAK,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;AACpC,QAAI,YAAY,OAAO,GAAG;AACtB,QAAE,CAAC,IAAI,CAAC,KAAK,EAAE;AAAA,SACd;AACD,QAAE,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE;AAC5B,WAAK,KAAK,GAAG,GAAG,CAAC;AAAA,IACrB;AAAA,EACJ;AACJ;AAEA,IAAI,KAAK,OAAO,eAAe,eAA6B,oBAAI,YAAY;AAE5E,IAAI,KAAK,OAAO,eAAe,eAA6B,oBAAI,YAAY;AAE5E,IAAI,MAAM;AACV,IAAI;AACA,KAAG,OAAO,IAAI,EAAE,QAAQ,KAAK,CAAC;AAC9B,QAAM;AACV,SACO,GAAG;AAAE;AAEZ,IAAI,QAAQ,SAAU,GAAG;AACrB,WAAS,IAAI,IAAI,IAAI,OAAK;AACtB,QAAI,IAAI,EAAE,GAAG;AACb,QAAI,MAAM,IAAI,QAAQ,IAAI,QAAQ,IAAI;AACtC,QAAI,IAAI,KAAK,EAAE;AACX,aAAO,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,EAAE;AACpC,QAAI,CAAC;AACD,WAAK,OAAO,aAAa,CAAC;AAAA,aACrB,MAAM,GAAG;AACd,YAAM,IAAI,OAAO,MAAM,EAAE,GAAG,IAAI,OAAO,MAAM,EAAE,GAAG,IAAI,OAAO,IAAK,EAAE,GAAG,IAAI,MAAO,OAC9E,KAAK,OAAO,aAAa,QAAS,KAAK,IAAK,QAAS,IAAI,IAAK;AAAA,IACtE,WACS,KAAK;AACV,WAAK,OAAO,cAAc,IAAI,OAAO,IAAK,EAAE,GAAG,IAAI,EAAG;AAAA;AAEtD,WAAK,OAAO,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,IAAI,OAAO,IAAK,EAAE,GAAG,IAAI,EAAG;AAAA,EACpF;AACJ;AAqFO,SAAS,QAAQ,KAAK,QAAQ;AACjC,MAAI,QAAQ;AACR,QAAI,OAAO,IAAI,GAAG,IAAI,MAAM;AAC5B,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,EAAE;AAC9B,WAAK,CAAC,IAAI,IAAI,WAAW,CAAC;AAC9B,WAAO;AAAA,EACX;AACA,MAAI;AACA,WAAO,GAAG,OAAO,GAAG;AACxB,MAAI,IAAI,IAAI;AACZ,MAAI,KAAK,IAAI,GAAG,IAAI,UAAU,IAAI,UAAU,EAAE;AAC9C,MAAI,KAAK;AACT,MAAI,IAAI,SAAU,GAAG;AAAE,OAAG,IAAI,IAAI;AAAA,EAAG;AACrC,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACxB,QAAI,KAAK,IAAI,GAAG,QAAQ;AACpB,UAAI,IAAI,IAAI,GAAG,KAAK,KAAM,IAAI,KAAM,EAAE;AACtC,QAAE,IAAI,EAAE;AACR,WAAK;AAAA,IACT;AACA,QAAI,IAAI,IAAI,WAAW,CAAC;AACxB,QAAI,IAAI,OAAO;AACX,QAAE,CAAC;AAAA,aACE,IAAI;AACT,QAAE,MAAO,KAAK,CAAE,GAAG,EAAE,MAAO,IAAI,EAAG;AAAA,aAC9B,IAAI,SAAS,IAAI;AACtB,UAAI,SAAS,IAAI,QAAQ,MAAO,IAAI,WAAW,EAAE,CAAC,IAAI,MAClD,EAAE,MAAO,KAAK,EAAG,GAAG,EAAE,MAAQ,KAAK,KAAM,EAAG,GAAG,EAAE,MAAQ,KAAK,IAAK,EAAG,GAAG,EAAE,MAAO,IAAI,EAAG;AAAA;AAE7F,QAAE,MAAO,KAAK,EAAG,GAAG,EAAE,MAAQ,KAAK,IAAK,EAAG,GAAG,EAAE,MAAO,IAAI,EAAG;AAAA,EACtE;AACA,SAAO,IAAI,IAAI,GAAG,EAAE;AACxB;AAQO,SAAS,UAAU,KAAK,QAAQ;AACnC,MAAI,QAAQ;AACR,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,WAAK,OAAO,aAAa,MAAM,MAAM,IAAI,SAAS,GAAG,IAAI,KAAK,CAAC;AACnE,WAAO;AAAA,EACX,WACS,IAAI;AACT,WAAO,GAAG,OAAO,GAAG;AAAA,EACxB,OACK;AACD,QAAIC,MAAK,MAAM,GAAG,GAAG,IAAIA,IAAG,GAAG,IAAIA,IAAG;AACtC,QAAI,EAAE;AACF,UAAI,CAAC;AACT,WAAO;AAAA,EACX;AACJ;AAKA,IAAI,OAAO,SAAU,GAAG,GAAG;AAAE,SAAO,IAAI,KAAK,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,GAAG,IAAI,EAAE;AAAG;AAE5E,IAAI,KAAK,SAAU,GAAG,GAAG,GAAG;AACxB,MAAI,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,KAAK,UAAU,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK;AACtI,MAAIC,MAAK,MAAM,GAAG,IAAI,KAAK,GAAG,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,MAAMA,IAAG,CAAC;AAC9G,SAAO,CAAC,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,KAAK,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG;AACpE;AAEA,IAAI,QAAQ,SAAU,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,KAAK;AAC3C,MAAI,MAAM,MAAM,YAAY,MAAM,MAAM,YAAY,OAAO,OAAO,YAAY,IAAI,IAAI;AACtF,MAAI,KAAK,MAAM,MAAM;AACrB,MAAI,KAAK,IAAI;AACT,WAAO,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG;AACrC,UAAI,GAAG,GAAG,CAAC,KAAK,GAAG;AACf,eAAO;AAAA,UACH,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI;AAAA,UAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI;AAAA,UACrB,OAAO,GAAG,GAAG,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI;AAAA,UACxC;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,IAAI;AACJ,UAAI,EAAE;AAAA,EACd;AACA,SAAO,CAAC,IAAI,IAAI,KAAK,CAAC;AAC1B;AAEA,IAAI,OAAO,SAAU,IAAI;AACrB,MAAI,KAAK;AACT,MAAI,IAAI;AACJ,aAAS,KAAK,IAAI;AACd,UAAI,IAAI,GAAG,CAAC,EAAE;AACd,UAAI,IAAI;AACJ,YAAI,CAAC;AACT,YAAM,IAAI;AAAA,IACd;AAAA,EACJ;AACA,SAAO;AACX;AAEA,IAAI,MAAM,SAAU,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI;AAC3C,MAAIC,MAAK,GAAG,QAAQ,KAAK,EAAE,OAAO,MAAM,MAAM,GAAG;AACjD,MAAI,MAAM,KAAK,EAAE;AACjB,SAAO,GAAG,GAAG,MAAM,OAAO,WAAY,QAAS,GAAG,KAAK;AACvD,MAAI,MAAM;AACN,MAAE,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,EAAE;AAC5B,IAAE,CAAC,IAAI,IAAI,KAAK;AAChB,IAAE,GAAG,IAAK,EAAE,QAAQ,KAAM,IAAI,KAAK,IAAI,EAAE,GAAG,IAAI,KAAK;AACrD,IAAE,GAAG,IAAI,EAAE,cAAc,KAAK,EAAE,GAAG,IAAI,EAAE,eAAe;AACxD,MAAI,KAAK,IAAI,KAAK,EAAE,SAAS,OAAO,KAAK,IAAI,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,YAAY,IAAI;AAClF,MAAI,IAAI,KAAK,IAAI;AACb,QAAI,EAAE;AACV,SAAO,GAAG,GAAI,KAAK,KAAQ,GAAG,SAAS,IAAI,KAAM,KAAO,GAAG,QAAQ,KAAK,KAAO,GAAG,SAAS,KAAK,KAAO,GAAG,WAAW,KAAK,IAAM,GAAG,WAAW,KAAK,CAAE,GAAG,KAAK;AAC7J,MAAI,KAAK,IAAI;AACT,WAAO,GAAG,GAAG,EAAE,GAAG;AAClB,WAAO,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;AACnC,WAAO,GAAG,IAAI,GAAG,EAAE,IAAI;AAAA,EAC3B;AACA,SAAO,GAAG,IAAI,IAAIA,GAAE;AACpB,SAAO,GAAG,IAAI,IAAI,GAAG,GAAG,KAAK;AAC7B,MAAI,MAAM,MAAM;AACZ,WAAO,GAAG,GAAG,GAAG;AAChB,WAAO,GAAG,IAAI,GAAG,EAAE,KAAK;AACxB,WAAO,GAAG,IAAI,IAAI,EAAE,GAAG,KAAK;AAAA,EAChC;AACA,IAAE,IAAI,IAAI,CAAC;AACX,OAAKA;AACL,MAAI,KAAK;AACL,aAAS,KAAK,IAAI;AACd,UAAI,MAAM,GAAG,CAAC,GAAG,IAAI,IAAI;AACzB,aAAO,GAAG,GAAG,CAAC,CAAC;AACf,aAAO,GAAG,IAAI,GAAG,CAAC;AAClB,QAAE,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI;AAAA,IAChC;AAAA,EACJ;AACA,MAAI;AACA,MAAE,IAAI,IAAI,CAAC,GAAG,KAAK;AACvB,SAAO;AACX;AAEA,IAAI,MAAM,SAAU,GAAG,GAAG,GAAG,GAAG,GAAG;AAC/B,SAAO,GAAG,GAAG,SAAS;AACtB,SAAO,GAAG,IAAI,GAAG,CAAC;AAClB,SAAO,GAAG,IAAI,IAAI,CAAC;AACnB,SAAO,GAAG,IAAI,IAAI,CAAC;AACnB,SAAO,GAAG,IAAI,IAAI,CAAC;AACvB;AAoXO,SAAS,QAAQ,MAAM,MAAM;AAChC,MAAI,CAAC;AACD,WAAO,CAAC;AACZ,MAAI,IAAI,CAAC;AACT,MAAI,QAAQ,CAAC;AACb,OAAK,MAAM,IAAI,GAAG,IAAI;AACtB,MAAI,IAAI;AACR,MAAI,MAAM;AACV,WAAS,MAAM,GAAG;AACd,QAAIC,MAAK,EAAE,EAAE,GAAG,OAAOA,IAAG,CAAC,GAAG,IAAIA,IAAG,CAAC;AACtC,QAAI,cAAc,EAAE,SAAS,IAAI,IAAI;AACrC,QAAI,IAAI,QAAQ,EAAE,GAAG,IAAI,EAAE;AAC3B,QAAI,MAAM,EAAE,SAAS,IAAI,OAAO,QAAQ,GAAG,GAAG,KAAK,KAAK,EAAE;AAC1D,QAAI,MAAM,KAAK,EAAE,KAAK;AACtB,QAAI,IAAI;AACJ,UAAI,EAAE;AACV,QAAI,IAAI,cAAc,YAAY,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE;AACzD,QAAI,IAAI,IAAI;AACZ,MAAE,EAAE,IAAI;AACR,UAAM,KAAK,IAAI,GAAG;AAAA,MACd,MAAM,KAAK;AAAA,MACX,KAAK,EAAE,EAAE;AAAA,MACT,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,GAAG,KAAK,GAAG,UAAW,KAAM,IAAI,UAAU;AAAA,MAC1C;AAAA,MACA;AAAA,IACJ,CAAC,CAAC;AACF,SAAK,KAAK,IAAI,MAAM;AACpB,WAAO,KAAK,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,EAC5C;AACA,MAAI,MAAM,IAAI,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,MAAM,MAAM;AAChD,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,GAAG;AACnC,QAAI,IAAI,MAAM,CAAC;AACf,QAAI,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM;AACrC,QAAI,OAAO,KAAK,EAAE,EAAE,SAAS,KAAK,EAAE,KAAK;AACzC,QAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI;AACvB,QAAI,KAAK,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,KAAK,QAAQ,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACzF;AACA,MAAI,KAAK,GAAG,MAAM,QAAQ,KAAK,EAAE;AACjC,SAAO;AACX;AA6TO,SAAS,UAAU,MAAM,MAAM;AAClC,MAAI,QAAQ,CAAC;AACb,MAAI,IAAI,KAAK,SAAS;AACtB,SAAO,GAAG,MAAM,CAAC,KAAK,WAAW,EAAE,GAAG;AAClC,QAAI,CAAC,KAAK,KAAK,SAAS,IAAI;AACxB,UAAI,EAAE;AAAA,EACd;AACA;AACA,MAAI,IAAI,GAAG,MAAM,IAAI,CAAC;AACtB,MAAI,CAAC;AACD,WAAO,CAAC;AACZ,MAAI,IAAI,GAAG,MAAM,IAAI,EAAE;AACvB,MAAI,IAAI,GAAG,MAAM,IAAI,EAAE,KAAK;AAC5B,MAAI,GAAG;AACH,QAAI,KAAK,GAAG,MAAM,IAAI,EAAE;AACxB,QAAI,GAAG,MAAM,EAAE,KAAK;AACpB,QAAI,GAAG;AACH,UAAI,GAAG,MAAM,KAAK,EAAE;AACpB,UAAI,GAAG,MAAM,KAAK,EAAE;AAAA,IACxB;AAAA,EACJ;AACA,MAAI,OAAO,QAAQ,KAAK;AACxB,WAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACxB,QAAIC,MAAK,GAAG,MAAM,GAAG,CAAC,GAAG,MAAMA,IAAG,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,KAAKA,IAAG,CAAC,GAAG,MAAMA,IAAG,CAAC,GAAG,IAAI,KAAK,MAAM,GAAG;AACrH,QAAI;AACJ,QAAI,CAAC,QAAQ,KAAK;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,MACd,aAAa;AAAA,IACjB,CAAC,GAAG;AACA,UAAI,CAAC;AACD,cAAM,EAAE,IAAI,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,eAC1B,OAAO;AACZ,cAAM,EAAE,IAAI,YAAY,KAAK,SAAS,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC;AAAA;AAErE,YAAI,IAAI,8BAA8B,GAAG;AAAA,IACjD;AAAA,EACJ;AACA,SAAO;AACX;;;ACnnFO,SAAS,eACf,MACmC;AACnC,QAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,QAAM,WAAW,UAAU,KAAK;AAChC,QAAM,gBAAgB,cAAc,KAAK;AACzC,QAAM,cAAc,IAAI,YAAY,WAAW;AAE/C,QAAM,UAAmC,CAAC;AAC1C,SAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,SAAS,MAAM;AAC7C,UAAM,YAAY,SAAS,OAAO;AAClC,UAAM,OAAO,cAAc,CAAC,IACzB,UACA,YAAY,OAAO,WAAW,KAAK,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AACtE,UAAM,OAAO,KAAK,QAAQ,OAAO,GAAG;AACpC,QAAI,KAAK,SAAS,GAAG,EAAG;AACxB,YAAQ,IAAI,IAAI;AAAA,MACf,aAAa,MACZ,QAAQ;AAAA,QACP,UAAU,OAAO;AAAA,UAChB,UAAU;AAAA,UACV,UAAU,aAAa,UAAU;AAAA,QAClC;AAAA,MACD;AAAA,IACF;AAAA,EACD,CAAC;AACD,SAAO,QAAQ,QAAQ,OAAO;AAC/B;AAGA,SAAS,cAAc,KAA4B;AAClD,QAAM,OAAO,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAEpE,MAAI,OAAO;AACX,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ,KAAK;AAC1C,WAAS,IAAI,IAAI,SAAS,IAAI,KAAK,IAAI,SAAS,WAAW,KAAK,GAAG,KAAK;AACvE,QAAI,KAAK,UAAU,GAAG,IAAI,MAAM,WAAY;AAC3C,aAAO;AACP;AAAA,IACD;AAAA,EACD;AACA,MAAI,OAAO,EAAG,QAAO,CAAC;AAEtB,QAAM,aAAa,KAAK,UAAU,OAAO,IAAI,IAAI;AACjD,MAAI,WAAW,KAAK,UAAU,OAAO,IAAI,IAAI;AAE7C,QAAM,QAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACpC,QAAI,KAAK,UAAU,UAAU,IAAI,MAAM,SAAY;AACnD,UAAM,OAAO,KAAK,UAAU,WAAW,GAAG,IAAI;AAC9C,UAAM,UAAU,KAAK,UAAU,WAAW,IAAI,IAAI;AAClD,UAAM,WAAW,KAAK,UAAU,WAAW,IAAI,IAAI;AACnD,UAAM,aAAa,KAAK,UAAU,WAAW,IAAI,IAAI;AACrD,UAAM,MAAM,OAAO,UAAW,CAAC;AAC/B,gBAAY,KAAK,UAAU,WAAW;AAAA,EACvC;AACA,SAAO;AACR;AASO,SAAS,SAAS,OAAyC;AACjE,QAAM,SAAS,QAAQ,OAAO,EAAE,OAAO,EAAE,CAAC;AAC1C,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,QAAM,IAAI,MAAM;AAChB,SAAO,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACrD;;;ACpFA,IAAM,QAAQ;AASP,SAAS,QAAQ,UAAoB,UAA4B;AACvE,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,QAAQ,CAAC;AAC9D,QAAM,SAAS,IAAI,YAAY,CAAC;AAChC,QAAM,OAAO,IAAI,SAAS,MAAM;AAChC,OAAK,UAAU,GAAG,OAAO,KAAK;AAC9B,OAAK,UAAU,GAAG,KAAK,YAAY,IAAI;AACvC,SAAO,IAAI,KAAK,CAAC,QAAQ,MAAM,GAAG,QAAQ,CAAC;AAC5C;AAGO,SAAS,eAAe,aAE7B;AACD,QAAM,OAAO,IAAI,SAAS,WAAW;AACrC,MAAI,KAAK,aAAa,KAAK,KAAK,UAAU,GAAG,KAAK,MAAM,OAAO;AAC9D,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC9C;AACA,SAAO,EAAE,YAAY,KAAK,UAAU,GAAG,IAAI,EAAE;AAC9C;AAGO,IAAM,UAAU,CAAC,eAA+B,IAAI;;;ACnB3D,IAAM,sBAAsB;AAE5B,IAAM,kBAAkB,KAAK,OAAO;AAEpC,IAAM,kBAAN,MAA6C;AAAA,EAC5C,YACS,MACA,MACP;AAFO;AACA;AAAA,EACN;AAAA,EAFM;AAAA,EACA;AAAA,EAET,UAAU,QAAgB,QAAsC;AAC/D,UAAM,QAAQ,KAAK,OAAO;AAC1B,WAAO,KAAK,KAAK,MAAM,OAAO,QAAQ,MAAM,EAAE,YAAY;AAAA,EAC3D;AACD;AAEA,IAAM,mBAAN,MAA8C;AAAA,EAC7C,YACS,KACA,MACP;AAFO;AACA;AAAA,EACN;AAAA,EAFM;AAAA,EACA;AAAA,EAET,MAAM,UAAU,QAAgB,QAAsC;AACrE,UAAM,QAAQ,KAAK,OAAO;AAC1B,WAAO,WAAW,KAAK,KAAK,OAAO,MAAM;AAAA,EAC1C;AACD;AAEA,eAAe,WACd,KACA,OACA,QACuB;AACvB,QAAM,MAAM,MAAM,MAAM,KAAK;AAAA,IAC5B,SAAS,EAAE,OAAO,SAAS,KAAK,IAAI,QAAQ,SAAS,CAAC,GAAG;AAAA,IACzD,aAAa;AAAA;AAAA,EACd,CAAC;AAGD,MAAI,IAAI,WAAW,KAAK;AACvB,UAAM,IAAI;AAAA,MACT,wDAAwD,IAAI,MAAM;AAAA,IACnE;AAAA,EACD;AACA,SAAO,WAAW,KAAK,MAAM;AAC9B;AAOA,eAAe,WAAW,KAAe,QAAsC;AAC9E,QAAM,SAAS,IAAI,MAAM,UAAU;AACnC,MAAI,CAAC,QAAQ;AACZ,UAAM,MAAM,MAAM,IAAI,YAAY;AAClC,QAAI,IAAI,aAAa,QAAQ;AAC5B,YAAM,IAAI;AAAA,QACT,iDAAiD,MAAM;AAAA,MACxD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACA,QAAM,MAAM,IAAI,WAAW,MAAM;AACjC,MAAI,WAAW;AACf,aAAS;AACR,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,QAAI,WAAW,MAAM,aAAa,QAAQ;AACzC,YAAM,OAAO,OAAO;AACpB,YAAM,IAAI;AAAA,QACT,iDAAiD,MAAM;AAAA,MACxD;AAAA,IACD;AACA,QAAI,IAAI,OAAO,QAAQ;AACvB,gBAAY,MAAM;AAAA,EACnB;AACA,SAAO,aAAa,SAAS,IAAI,SAAS,IAAI,OAAO,MAAM,GAAG,QAAQ;AACvE;AAEA,SAAS,mBAAmB,YAA0B;AACrD,MACC,CAAC,OAAO,UAAU,UAAU,KAC5B,aAAa,KACb,aAAa,iBACZ;AACD,UAAM,IAAI,MAAM,uCAAuC,UAAU,EAAE;AAAA,EACpE;AACD;AAEA,SAAS,cAAc,MAA6B;AACnD,QAAM,WAAW,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC;AAC1D,MACC,CAAC,YACD,OAAO,aAAa,YACpB,OAAO,SAAS,aAAa,YAC7B,SAAS,aAAa,MACrB;AACD,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC3D;AACA,SAAO;AACR;AAeO,IAAM,YAAN,MAAM,WAAU;AAAA,EACd,YAEE,UACD,QACP;AAFQ;AACD;AAAA,EACN;AAAA,EAFO;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAOT,aAAa,KAAK,KAAwC;AACzD,QAAI;AACH,UAAI,OAAO,QAAQ,UAAU;AAG5B,YAAI,UAAU,KAAK,GAAG,GAAG;AACxB,gBAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,cAAI,CAAC,IAAI,IAAI;AACZ,kBAAM,IAAI,MAAM,2BAA2B,IAAI,MAAM,EAAE;AAAA,UACxD;AACA,iBAAO,MAAM,WAAU,SAAS,MAAM,IAAI,KAAK,CAAC;AAAA,QACjD;AACA,YAAI,CAAC,YAAY,KAAK,GAAG,GAAG;AAC3B,gBAAM,IAAI,MAAM,6BAA6B,GAAG,EAAE;AAAA,QACnD;AACA,cAAM,SAAS,MAAM,WAAW,KAAK,GAAG,CAAC;AACzC,cAAM,EAAE,WAAW,IAAI,eAAe,MAAM;AAC5C,2BAAmB,UAAU;AAC7B,cAAM,OAAO,MAAM,WAAW,KAAK,GAAG,UAAU;AAChD,cAAM,WAAW,cAAc,IAAI;AACnC,eAAO,IAAI;AAAA,UACV;AAAA,UACA,IAAI,iBAAiB,KAAK,QAAQ,UAAU,CAAC;AAAA,QAC9C;AAAA,MACD;AACA,aAAO,MAAM,WAAU,SAAS,GAAG;AAAA,IACpC,SAAS,OAAO;AACf,YAAM,IAAI;AAAA,QACT,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC1F;AAAA,IACD;AAAA,EACD;AAAA,EAEA,aAAqB,SAAS,KAA+B;AAC5D,UAAM,SAAS,MAAM,IAAI,MAAM,GAAG,CAAC,EAAE,YAAY;AACjD,UAAM,EAAE,WAAW,IAAI,eAAe,MAAM;AAC5C,uBAAmB,UAAU;AAC7B,UAAM,OAAO,MAAM,IAAI,MAAM,GAAG,IAAI,UAAU,EAAE,YAAY;AAC5D,UAAM,WAAW,cAAc,IAAI;AACnC,WAAO,IAAI;AAAA,MACV;AAAA,MACA,IAAI,gBAAgB,KAAK,QAAQ,UAAU,CAAC;AAAA,IAC7C;AAAA,EACD;AAAA;AAAA,EAGA,IAAI,SAA0B;AAG7B,WAAO,OAAO,OAAO,KAAK,SAAS,UAAU,OAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,SAA8C;AAChE,QAAI,CAAC,OAAO,OAAO,KAAK,SAAS,UAAU,OAAO,EAAG,QAAO;AAC5D,UAAM,QAAQ,KAAK,SAAS,SAAS,OAAO;AAC5C,QACC,CAAC,OAAO,UAAU,MAAM,MAAM,KAC9B,CAAC,OAAO,UAAU,MAAM,MAAM,KAC9B,MAAM,SAAS,KACf,MAAM,SAAS,KACf,MAAM,SAAS,qBACd;AACD,YAAM,IAAI,MAAM,6CAA6C,OAAO,EAAE;AAAA,IACvE;AACA,WAAO,KAAK,OAAO,UAAU,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,SAA+C;AAC3D,UAAM,MAAM,MAAM,KAAK,aAAa,OAAO;AAC3C,QAAI,CAAC,IAAK,QAAO;AAGjB,UAAM,QAAQ,IAAI,WAAW,KAAK,GAAG,KAAK,MAAM,IAAI,aAAa,CAAC,CAAC;AACnE,UAAM,MAAM,IAAI,aAAa,MAAM,MAAM;AACzC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,CAAC,IAAI,MAAM,CAAC,IAAI;AAC3D,WAAO;AAAA,EACR;AACD;;;ACxLO,IAAM,YAAN,MAAgB;AAAA,EACd;AAAA,EACA;AAAA,EACA,OAAgC;AAAA,EAChC,OAAyB;AAAA,EACzB,YAAY,oBAAI,IAAY;AAAA,EAC5B,UAAU,oBAAI,IAA2B;AAAA,EAEjD,YAAY,UAA4B,CAAC,GAAG;AAC3C,SAAK,MAAM,IAAI,aAAa,EAAE,YAAY,KAAM,CAAC;AACjD,SAAK,aAAa,QAAQ,cAAc;AAAA,EACzC;AAAA,EAEA,IAAI,eAA6B;AAChC,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,WAA4B;AAC/B,WAAO,KAAK,MAAM,YAAY;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAI,YAA8B;AACjC,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAK,KAAmC;AAC7C,UAAM,KAAK,IAAI,aAAa,UAAU,KAAK,UAAU;AAGrD,SAAK,MAAM,WAAW;AACtB,SAAK,OAAO;AAEZ,SAAK,OAAO,MAAM,UAAU,KAAK,GAAG;AACpC,SAAK,UAAU,MAAM;AACrB,SAAK,QAAQ,MAAM;AAEnB,SAAK,OAAO,IAAI,iBAAiB,KAAK,KAAK,iBAAiB;AAAA,MAC3D,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,oBAAoB,CAAC,CAAC;AAAA,IACvB,CAAC;AACD,SAAK,KAAK,KAAK,YAAY,EAAE,MAAM,QAAQ,UAAU,KAAK,KAAK,SAAS,CAAC;AACzE,SAAK,KAAK,QAAQ,KAAK,IAAI,WAAW;AAEtC,YAAQ;AAAA,MACP;AAAA,MACA,OAAO,KAAK,KAAK,KAAK,SAAS,QAAQ,EAAE;AAAA,MACzC;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAGQ,cAAc,MAA6B;AAClD,QAAI,KAAK,UAAU,IAAI,IAAI,EAAG,QAAO,QAAQ,QAAQ;AACrD,UAAM,WAAW,KAAK,QAAQ,IAAI,IAAI;AACtC,QAAI,SAAU,QAAO;AACrB,QAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAM,QAAO,QAAQ,QAAQ;AAErD,UAAM,OAAO,KAAK,KAChB,aAAa,IAAI,EACjB,KAAK,CAAC,QAAQ;AACd,UAAI,CAAC,OAAO,CAAC,KAAK,KAAM;AACxB,WAAK,KAAK,KAAK,YAAY,EAAE,MAAM,WAAW,MAAM,QAAQ,IAAI,GAAG;AAAA,QAClE;AAAA,MACD,CAAC;AACD,WAAK,UAAU,IAAI,IAAI;AAAA,IACxB,CAAC,EACA,QAAQ,MAAM;AAGd,WAAK,QAAQ,OAAO,IAAI;AAAA,IACzB,CAAC;AAEF,SAAK,QAAQ,IAAI,MAAM,IAAI;AAC3B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,OAAoB,UAAuB,CAAC,GAAoB;AAC1E,QAAI,CAAC,KAAK,KAAM,OAAM,IAAI,MAAM,sCAAsC;AACtE,SAAK,KAAK,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAC3C,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO,OAAO;AACtE,UAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC;AACzD,UAAM,SAAS,QAAQ,WAAW;AAClC,SAAK,KAAK,KAAK,YAAY,EAAE,MAAM,QAAQ,OAAO,OAAO,CAAC;AAC1D,WAAO,SAAS,KAAK,cAAc,KAAK,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,OAA4B;AACjD,UAAM,QAAQ,MAAM,CAAC;AACrB,UAAM,IAAI,KAAK,MAAM;AACrB,QAAI,CAAC,SAAS,CAAC,KAAK,MAAM,YAAY,GAAI,QAAO;AACjD,UAAM,QAAQ,OAAO,OAAO,EAAE,UAAU,MAAM,OAAO,IAClD,EAAE,SAAS,MAAM,OAAO,IACxB;AACH,QAAI,CAAC,SAAS,MAAM,UAAU,EAAG,QAAO;AACxC,UAAM,WAAW,MAAM,SAAS,EAAE,kBAAkB,MAAM,SAAS;AACnE,UAAM,WAAW,MAAM,QAAQ;AAC/B,WAAO,WAAW,IAAI,MAAM,MAAM,WAAW;AAAA,EAC9C;AAAA;AAAA,EAGA,OAAa;AACZ,SAAK,MAAM,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,SAAwB;AAC7B,QAAI,KAAK,IAAI,UAAU,YAAa,OAAM,KAAK,IAAI,OAAO;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAyB;AAC9B,SAAK,MAAM,WAAW;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,UAAU,MAAM;AACrB,SAAK,QAAQ,MAAM;AACnB,QAAI,KAAK,IAAI,UAAU,SAAU,OAAM,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,SAA+C;AAC3D,WAAO,KAAK,MAAM,OAAO,OAAO,KAAK;AAAA,EACtC;AACD;;;ACxLO,IAAM,wBAAwB;AAM9B,IAAM,wBAAwB;AAGrC,IAAM,iBAAiB;AAEvB,IAAM,cAAc;AA4EpB,IAAM,cAAc,CACnB,OACA,OACA,YACa,OAAO,UAAU,aAAa,MAAM,OAAO,OAAO,IAAI;AAsF7D,IAAM,cAAc,CAAC,YAC1B,UAAU,wBAAyB;AAQ9B,SAAS,gBAAgB,OAG9B;AACD,SAAO;AAAA,IACN,OAAO,YAAY,MAAM,OAAO,CAAC;AAAA,IACjC,aAAa,YAAY,MAAM,aAAa,CAAC;AAAA,EAC9C;AACD;AAGA,IAAM,cAAc,oBAAI,IAAoC;AAE5D,SAAS,aAAa,KAA4B;AACjD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,UAAM,WAAW,SAAS;AAAA,MACzB,8BAA8B,GAAG;AAAA,IAClC;AACA,QAAI,UAAU;AACb,cAAQ;AACR;AAAA,IACD;AACA,UAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,MAAE,MAAM;AACR,MAAE,QAAQ,eAAe;AACzB,MAAE,SAAS,MAAM,QAAQ;AACzB,MAAE,UAAU,MAAM,OAAO,IAAI,MAAM,6BAA6B,GAAG,EAAE,CAAC;AACtE,aAAS,KAAK,YAAY,CAAC;AAAA,EAC5B,CAAC;AACF;AAEA,SAAS,SAAS,WAA2C;AAC5D,QAAM,SAAS,YAAY,IAAI,SAAS;AACxC,MAAI,OAAQ,QAAO;AAEnB,QAAM,UAAU,UAAU,MAAM,GAAG,UAAU,YAAY,GAAG,IAAI,CAAC;AACjE,QAAM,cAAc,MAA8B;AACjD,UAAM,UAAU,WAAW;AAC3B,QAAI,CAAC;AACJ,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAGD,WAAO,QAAQ,EAAE,YAAY,CAAC,MAAc,UAAU,EAAE,CAAC;AAAA,EAC1D;AAEA,MAAI;AACJ,MAAI,OAAO,aAAa,aAAa;AAEpC,cAAU,aAAa,SAAS,EAAE,KAAK,WAAW;AAAA,EACnD,WAAW,OAAO,WAAW,kBAAkB,YAAY;AAI1D,cAAU,QAAQ,QAAQ,EAAE,KAAK,MAAM;AACtC,MAAC,WAAW,cAA8C,SAAS;AACnE,aAAO,YAAY;AAAA,IACpB,CAAC;AAAA,EACF,OAAO;AACN,WAAO,QAAQ;AAAA,MACd,IAAI;AAAA,QACH;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACA,cAAY,IAAI,WAAW,OAAO;AAClC,SAAO;AACR;AAmBO,IAAM,YAAN,MAAM,WAAU;AAAA,EAGd,YAAoB,MAAqB;AAArB;AAAA,EAAsB;AAAA,EAAtB;AAAA,EAFnB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWtB,aAAa,KAAK,SAAmD;AACpE,WAAO,IAAI,WAAU,MAAM,SAAS,QAAQ,SAAS,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAa,QAAiD;AAC7D,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,cAAc;AAAA,MACd,UAAU;AAAA,MACV,QAAQ;AAAA,IACT,IAAI;AACJ,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,KAAK,KAAK;AAChB,UAAMC,MAAK;AAGX,QAAI,UAAU;AACd,eAAW,KAAK,OAAO;AACtB,YAAM,QAAQ,EAAE,QAAQ,EAAE;AAC1B,UAAI,QAAQ,QAAS,WAAU;AAAA,IAChC;AAEA,UAAM,KAAK,GAAG,gBAAgB;AAC9B,QAAI,CAAC,GAAI,QAAO;AAEhB,UAAM,iBAA2B,CAAC;AAElC,eAAW,KAAK,OAAO;AACtB,UAAI,CAAC,EAAE,OAAO,EAAE,IAAI,SAAS,sBAAuB;AAEpD,YAAM,SAAS,GAAG,QAAQ,cAAc;AACxC,UAAI,CAAC,OAAQ;AACb,qBAAe,KAAK,MAAM;AAE1B,YAAM,YAAY,GAAG,QAAQ,EAAE,IAAI,SAAS,CAAC;AAC7C,UAAI,CAAC,UAAW;AAChB,qBAAe,KAAK,SAAS;AAE7B,SAAG,QAAQ,IAAI,EAAE,KAAK,aAAa,CAAC;AAEpC,YAAM,KAAK,CAAC,KAAa,KAAa,SACrC,GAAG,SAAS,SAAS,KAAK,KAAK,IAAI;AACpC,SAAG,GAAGA,KAAI,KAAK;AACf,SAAG,GAAG,EAAE,IAAI,QAAQ,KAAK;AACzB,SAAG,GAAG,WAAW,GAAG;AACpB,SAAG,IAAI,GAAG,KAAK;AACf,SAAG,IAAI,GAAG,GAAG;AAGb,SAAG,IAAI,EAAE,QAAQ,IAAI,KAAK;AAC1B,SAAG,IAAI,KAAO,QAAQ;AACtB,SAAG,IAAI,GAAK,QAAQ;AACpB,SAAG,IAAI,EAAE,oBAAoB,EAAE,UAAU,QAAQ;AACjD,SAAG,IAAI,EAAE,aAAa,QAAQ;AAC9B,YAAM,QAAQ,EAAE,SAAS,cAAc;AACvC,SAAG,IAAI,OAAO,QAAQ;AACtB,SAAG,IAAI,EAAE,UAAU,KAAO,QAAQ;AAClC,SAAG,IAAI,GAAK,QAAQ;AACpB,SAAG,IAAI,OAAO,QAAQ;AACtB,SAAG,IAAI,GAAG,KAAK;AACf,SAAG,IAAI,GAAG,GAAG;AACb,SAAG,IAAI,GAAG,KAAK;AACf,SAAG,KAAK,GAAG,KAAK;AAChB,SAAG,KAAK,KAAK,KAAK;AAClB,SAAG,KAAK,GAAG,KAAK;AAChB,SAAG,KAAK,GAAG,KAAK;AAChB,SAAG,KAAK,KAAK,KAAK;AAElB,SAAG;AAAA,QACF;AAAA,QACA;AAAA,QACA,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,MACD;AAAA,IACD;AAEA,eAAW,cAAc;AACzB,UAAM,UAAU,KAAK,KAAK,UAAU,WAAW,IAAI;AACnD,UAAM,QAAQ,IAAI,aAAa,OAAO;AACtC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AAErC,aAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AACjC,YAAM,MAAM,IAAI;AAChB,YAAM,CAAC,IAAI,YAAY,KAAK,OAAO,OAAO;AAC1C,WAAK,CAAC,IAAI,YAAY,KAAK,QAAQ,OAAO;AAC1C,WAAK,CAAC,IAAI,YAAY,KAAK,SAAS,OAAO;AAC3C,WAAK,CAAC,IAAI,YAAY,KAAK,aAAa,OAAO;AAC/C,WAAK,CAAC,IAAI,YAAY,KAAK,SAAS,OAAO;AAAA,IAC5C;AAEA,UAAM,QAAQ,GAAG,QAAQ,UAAU,CAAC;AACpC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AAEnC,QAAI,SAAS,QAAQ,QAAQ,QAAQ,MAAM;AAC1C,SAAG,QAAQ,IAAI,OAAO,SAAS,CAAC;AAChC,SAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,SAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,SAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,SAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,SAAG;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,QAAI,MAAO,IAAG,MAAM,KAAK;AACzB,QAAI,KAAM,IAAG,MAAM,IAAI;AACvB,QAAI,KAAM,IAAG,MAAM,IAAI;AACvB,QAAI,KAAM,IAAG,MAAM,IAAI;AACvB,QAAI,KAAM,IAAG,MAAM,IAAI;AAEvB,UAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,QAAI,QAAQ;AACZ,QAAI,SAAS;AACZ,YAAM,SAAS,GAAG,kBAAkB,IAAI,SAAS,CAAC;AAClD,YAAM,OAAO,GAAG,SAAS,SAAS,GAAG;AACrC,UAAI,SAAS,KAAK,MAAM;AACvB,gBAAQ,IAAI,aAAa,GAAG,QAAQ,QAAQ,MAAM,MAAM,EAAE,MAAM;AAChE,WAAG,MAAM,IAAI;AAAA,MACd;AACA,SAAG,MAAM,OAAO;AAAA,IACjB;AAEA,eAAW,OAAO,gBAAgB;AACjC,SAAG,MAAM,GAAG;AAAA,IACb;AACA,OAAG,mBAAmB,EAAE;AAExB,WAAO;AAAA,EACR;AAAA,EAEA,WAAW,QAA+C;AACzD,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,MACV,cAAc;AAAA,MACd,UAAU;AAAA,IACX,IAAI;AACJ,QAAI,CAAC,OAAO,IAAI,SAAS,sBAAuB,QAAO;AAEvD,UAAM,KAAK,KAAK;AAChB,UAAMA,MAAK;AAGX,UAAM,YAAY;AAAA,MACjB,QAAQ,aAAa;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,IACT;AACA,UAAM,WAAW,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,YAAY,GAAG,CAAC;AAChE,UAAM,QAAQ;AACd,UAAM,SAAS,QAAQ;AAQvB,UAAM,QAAQ,cAAc;AAE5B,UAAM,KAAK,GAAG,gBAAgB;AAC9B,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,SAAS,GAAG,QAAQ,cAAc;AACxC,QAAI,CAAC,QAAQ;AACZ,SAAG,mBAAmB,EAAE;AACxB,aAAO;AAAA,IACR;AACA,UAAM,YAAY,GAAG,QAAQ,IAAI,SAAS,CAAC;AAC3C,QAAI,CAAC,WAAW;AACf,SAAG,MAAM,MAAM;AACf,SAAG,mBAAmB,EAAE;AACxB,aAAO;AAAA,IACR;AACA,OAAG,QAAQ,IAAI,KAAK,aAAa,CAAC;AAElC,UAAM,KAAK,CAAC,KAAa,KAAa,SACrC,GAAG,SAAS,SAAS,KAAK,KAAK,IAAI;AACpC,OAAG,GAAGA,KAAI,KAAK;AACf,OAAG,GAAG,IAAI,QAAQ,KAAK;AACvB,OAAG,GAAG,WAAW,GAAG;AACpB,OAAG,IAAI,GAAG,KAAK;AACf,OAAG,IAAI,GAAG,GAAG;AACb,OAAG,IAAI,UAAU,KAAK;AACtB,OAAG,IAAI,KAAO,QAAQ;AACtB,OAAG,IAAI,GAAK,QAAQ;AACpB,OAAG,IAAI,QAAQ,QAAQ;AACvB,OAAG,IAAI,aAAa,QAAQ;AAC5B,OAAG,IAAI,OAAO,QAAQ;AACtB,OAAG,IAAI,KAAO,QAAQ;AACtB,OAAG,IAAI,GAAK,QAAQ;AACpB,OAAG,IAAI,OAAO,QAAQ;AACtB,OAAG,IAAI,GAAG,KAAK;AACf,OAAG,IAAI,GAAG,GAAG;AACb,OAAG,IAAI,GAAG,KAAK;AACf,OAAG,KAAK,GAAG,KAAK;AAChB,OAAG,KAAK,KAAK,KAAK;AAClB,OAAG,KAAK,GAAG,KAAK;AAChB,OAAG,KAAK,GAAG,KAAK;AAChB,OAAG,KAAK,KAAK,KAAK;AAGlB,OAAG,uBAAuB,IAAI,QAAQ,OAAO,GAAK,QAAQ,GAAK,GAAK,CAAC;AACrE,OAAG,MAAM,SAAS;AAClB,OAAG,MAAM,MAAM;AAEf,UAAM,UAAU,QAAQ,SAAS,cAAc;AAC/C,UAAM,UAAU,KAAK,KAAK,UAAU,WAAW,IAAI;AAInD,UAAM,QAAQ,IAAI,aAAa,OAAO;AACtC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,UAAM,OAAO,IAAI,aAAa,OAAO;AACrC,aAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AACjC,YAAM,MAAM,IAAI;AAChB,YAAM,CAAC,IAAI,YAAY,KAAK,OAAO,OAAO;AAC1C,WAAK,CAAC,IAAI,YAAY,KAAK,QAAQ,OAAO;AAC1C,WAAK,CAAC,IAAI,YAAY,KAAK,SAAS,OAAO;AAC3C,WAAK,CAAC,IAAI,YAAY,KAAK,aAAa,OAAO;AAC/C,WAAK,CAAC,IAAI,YAAY,KAAK,SAAS,OAAO;AAAA,IAC5C;AAEA,UAAM,QAAQ,GAAG,QAAQ,UAAU,CAAC;AACpC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,UAAM,OAAO,GAAG,QAAQ,UAAU,CAAC;AACnC,QAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM;AAC/C,UAAI,MAAO,IAAG,MAAM,KAAK;AACzB,UAAI,KAAM,IAAG,MAAM,IAAI;AACvB,UAAI,KAAM,IAAG,MAAM,IAAI;AACvB,UAAI,KAAM,IAAG,MAAM,IAAI;AACvB,UAAI,KAAM,IAAG,MAAM,IAAI;AACvB,SAAG,mBAAmB,EAAE;AACxB,aAAO;AAAA,IACR;AACA,OAAG,QAAQ,IAAI,OAAO,SAAS,CAAC;AAChC,OAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,OAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,OAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,OAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAC9B,OAAG;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,OAAG,MAAM,KAAK;AACd,OAAG,MAAM,IAAI;AACb,OAAG,MAAM,IAAI;AACb,OAAG,MAAM,IAAI;AACb,OAAG,MAAM,IAAI;AAEb,UAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,QAAI,CAAC,SAAS;AACb,SAAG,mBAAmB,EAAE;AACxB,aAAO;AAAA,IACR;AACA,UAAM,SAAS,GAAG,kBAAkB,IAAI,SAAS,CAAC;AAClD,UAAM,OAAO,GAAG,SAAS,SAAS,GAAG;AACrC,UAAM,QACL,SAAS,KAAK,OACX,IAAI,aAAa,GAAG,QAAQ,QAAQ,MAAM,MAAM,EAAE,MAAM,IACxD;AAGJ,QAAI,KAAM,IAAG,MAAM,IAAI;AACvB,OAAG,MAAM,OAAO;AAChB,OAAG,mBAAmB,EAAE;AACxB,WAAO;AAAA,EACR;AACD;;;ACjlBO,IAAM,OAAO;AAEb,IAAM,SAAS;AAEtB,IAAM,MAAO,OAAO,SAAU;AAC9B,IAAM,WAAW;AACjB,IAAM,OAAO,WAAW;AAExB,IAAM,cAAc;AACpB,IAAM,aAAa,OAAO;AAC1B,IAAM,YAAY;AAClB,IAAM,SAAS;AACf,IAAM,SAAS;AA2Cf,IAAM,mBAAoB,WAAW,IAAI,OAAQ;AAG1C,SAAS,UAAU,IAAoB;AAC7C,SAAO,KAAK,MAAM,KAAK,MAAM;AAC9B;AAGO,SAAS,WAAW,QAAwB;AAClD,SAAO,SAAS;AACjB;AAGO,SAAS,YAAY,OAAuB;AAClD,SAAO,QAAQ,SAAS;AACzB;AAGA,SAAS,IAAI,IAAkB,IAAwB;AACtD,QAAM,IAAI,GAAG;AACb,WAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK;AAClC,QAAI,MAAM,KAAK;AACf,WAAO,IAAI,KAAK,QAAQ,EAAG,MAAK;AAChC,SAAK;AACL,QAAI,IAAI,GAAG;AACV,OAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC9B,OAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IAC/B;AAAA,EACD;AACA,WAAS,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG;AACtC,UAAM,MAAO,KAAK,KAAK,KAAM;AAC7B,UAAM,MAAM,KAAK,IAAI,GAAG;AACxB,UAAM,MAAM,KAAK,IAAI,GAAG;AACxB,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK;AAChC,UAAI,QAAQ;AACZ,UAAI,QAAQ;AACZ,eAAS,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK;AAClC,cAAM,MAAM,GAAG,IAAI,CAAC;AACpB,cAAM,MAAM,GAAG,IAAI,CAAC;AACpB,cAAM,MACL,GAAG,IAAI,KAAK,OAAO,EAAE,IAAI,QAAQ,GAAG,IAAI,KAAK,OAAO,EAAE,IAAI;AAC3D,cAAM,MACL,GAAG,IAAI,KAAK,OAAO,EAAE,IAAI,QAAQ,GAAG,IAAI,KAAK,OAAO,EAAE,IAAI;AAC3D,WAAG,IAAI,CAAC,IAAI,MAAM;AAClB,WAAG,IAAI,CAAC,IAAI,MAAM;AAClB,WAAG,IAAI,KAAK,OAAO,EAAE,IAAI,MAAM;AAC/B,WAAG,IAAI,KAAK,OAAO,EAAE,IAAI,MAAM;AAC/B,cAAM,SAAS,QAAQ,MAAM,QAAQ;AACrC,gBAAQ,QAAQ,MAAM,QAAQ;AAC9B,gBAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACD;AASA,SAAS,eAAe,IAA0B;AACjD,QAAM,WAAW,OAAO,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC;AACnD,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,QAAI,SAAS,CAAC,IAAI,IAAK,OAAM,SAAS,CAAC;AAAA,EACxC;AACA,SAAO,OAAO,SAAS,GAAG,IAAI,MAAM;AACrC;AAEA,SAAS,WAAW,QAAsB,GAAmB;AAC5D,QAAM,SAAS,aAAa,KAAK,MAAM,EAAE,KAAK;AAC9C,QAAM,IAAI,KAAK;AAAA,IACd,OAAO,SAAS;AAAA,IAChB,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,SAAS,EAAE,CAAC;AAAA,EAChD;AACA,SAAO,OAAO,CAAC;AAChB;AAMA,SAAS,IAAI,KAAmB,IAAY,KAAa,KAAqB;AAC7E,MAAI,IAAI;AACR,MAAI,KAAK;AACT,MAAI,KAAK;AACT,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC7B,UAAM,IAAI,IAAI,KAAK,CAAC;AACpB,UAAM,IAAI,IAAI,KAAK,IAAI,GAAG;AAC1B,SAAK,IAAI;AACT,UAAM,IAAI;AACV,UAAM,IAAI;AAAA,EACX;AACA,QAAM,QAAQ,KAAK,KAAK,KAAK,EAAE;AAC/B,SAAO,QAAQ,QAAQ,IAAI,QAAQ;AACpC;AAGO,SAAS,QAAQ,KAAsB;AAC7C,QAAM,OAAO,SAAS,OAAO,GAAG,GAAG,IAAI;AACvC,QAAM,IAAI,KAAK;AACf,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,OAAO,EAAE,SAAS,YAAY,GAAG,IAAI,CAAC;AAEjE,QAAM,QAAQ,IAAI,aAAa,CAAC;AAChC,QAAM,YAAY,IAAI,aAAa,CAAC;AACpC,QAAM,SAAS,IAAI,aAAa,CAAC;AACjC,QAAM,OAAO,IAAI,aAAa,CAAC;AAC/B,QAAM,SAAS,IAAI,aAAa,CAAC;AAEjC,QAAM,SAAS,IAAI,aAAa,QAAQ;AACxC,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AAClC,WAAO,CAAC,IAAI,MAAM,MAAM,KAAK,IAAK,IAAI,KAAK,KAAK,IAAK,QAAQ;AAAA,EAC9D;AAEA,QAAM,KAAK,IAAI,aAAa,QAAQ;AACpC,QAAM,KAAK,IAAI,aAAa,QAAQ;AACpC,QAAM,MAAM,IAAI,aAAa,IAAI;AACjC,QAAM,UAAU,IAAI,aAAa,IAAI;AAErC,QAAM,UAAU,KAAK,MAAO,OAAQ,OAAO,KAAM,IAAI;AAErD,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,UAAM,MAAM,IAAI;AAChB,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AAClC,YAAM,IAAI,EAAE,MAAM,CAAC,KAAK;AACxB,gBAAU,IAAI;AACd,SAAG,CAAC,IAAI,IAAI,OAAO,CAAC;AACpB,SAAG,CAAC,IAAI;AAAA,IACT;AACA,UAAM,CAAC,IAAI,KAAK,KAAK,MAAM,SAAS,WAAW,KAAK;AAEpD,QAAI,IAAI,EAAE;AAEV,QAAI,SAAS;AACb,QAAI,UAAU;AACd,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC9B,YAAM,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AACjD,UAAI,CAAC,IAAI;AACT,UAAI,IAAI,QAAS,WAAU;AAAA,UACtB,YAAW;AAIhB,YAAM,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,KAAK,MAAM,QAAQ,CAAC,IAAI,IAAI;AAC7D,UAAI,IAAI,EAAG,YAAW;AAAA,IACvB;AACA,YAAQ,IAAI,GAAG;AACf,cAAU,CAAC,IAAI,WAAW,SAAS,UAAU;AAC7C,WAAO,CAAC,IAAI,KAAK,KAAK,MAAM,UAAU,OAAO,IAAI;AACjD,SAAK,CAAC,IAAI,MAAM,IAAI,IAAI;AAAA,EACzB;AAEA,QAAM,WAAW,OAAO,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC;AACtD,QAAM,eAAe,OAAO,QAAQ,KAAK,MAAM,KAAK,MAAM,CAAC;AAC3D,QAAM,cAAc,eAAe,YAAY;AAC/C,QAAM,UAAU,WAAW,UAAU,GAAG;AACxC,QAAM,UAAU,eAAe,QAAQ;AACvC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,SAAS,CAAC,IAAI,OAAQ,UAAS,SAAS,CAAC;AAMzE,QAAM,WAAW,IAAI,aAAa,KAAK,MAAM,EAAE,SAAS,WAAW,CAAC;AACpE,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,aAAS,CAAC,KAAK,EAAE,IAAI,WAAW,IAAI,EAAE,IAAI,cAAc,CAAC,KAAK;AAAA,EAC/D;AACA,QAAM,SAAS,KAAK,MAAM,aAAa,MAAM;AAC7C,QAAM,SAAS,KAAK,MAAM,aAAa,MAAM;AAE7C,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,QAAI,SAAS,CAAC,IAAI,SAAS,GAAI,MAAK,KAAK,CAAC;AAAA,EAC3C;AACA,QAAM,OAAiB,CAAC;AACxB,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,EAAE,CAAC;AACrD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,MAAM;AAC3C,UAAM,KAAK,KAAK,MAAO,KAAK,CAAC,IAAI,MAAO,WAAW;AACnD,QAAI,KAAK,YAAY,UAAU,SAAS,OAAQ;AAChD,QAAI,OAAO;AACX,QAAI,UAAU;AACd,aAAS,MAAM,QAAQ,OAAO,QAAQ,OAAO;AAC5C,YAAM,IAAI,IAAI,UAAU,IAAI,WAAW,GAAG;AAC1C,UAAI,IAAI,MAAM;AACb,eAAO;AACP,kBAAU;AAAA,MACX;AAAA,IACD;AACA,QAAI,OAAO,OAAO,UAAU,EAAG,MAAK,KAAK,OAAO;AAAA,EACjD;AACA,OAAK,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACzB,QAAM,YAAY,KAAK,SAAS,KAAK,KAAK,UAAU,CAAC,IAAI;AACzD,QAAM,KAAK,YAAY,aAAa,YAAY;AAEhD,MAAI,WAAW;AACd,UAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,MAAM,YAAY,GAAG,CAAC;AACvD,UAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK,YAAY,GAAG,CAAC;AACtD,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAG3B,UAAI,SAAS,CAAC,IAAI,UAAU,EAAG;AAC/B,YAAM,KAAK,KAAK,MAAO,IAAI,MAAO,WAAW;AAC7C,UAAI,KAAK,YAAY,MAAM,SAAS,OAAQ;AAC5C,UAAI,OAAO;AACX,eAAS,MAAM,IAAI,OAAO,IAAI,OAAO;AACpC,cAAM,IAAI,IAAI,UAAU,IAAI,WAAW,GAAG;AAC1C,YAAI,IAAI,KAAM,QAAO;AAAA,MACtB;AACA,aAAO,CAAC,IAAI;AAAA,IACb;AAAA,EACD;AAGA,QAAM,aAAa,WAAW,MAAM,GAAG,KAAK;AAC5C,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,MAAK,CAAC,KAAK;AAEvC,SAAO;AAAA,IACN;AAAA,IACA,YAAa,EAAE,SAAS,OAAQ;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,OAAO,MAAM,CAAC;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAGO,SAAS,OAAO,KAAmB,OAA6B;AACtE,MAAI,SAAS,EAAG,QAAO,aAAa,KAAK,GAAG;AAC5C,QAAM,SAAS,IAAI,aAAa,IAAI,SAAS,CAAC;AAC9C,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,QAAO,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC;AAEtE,QAAM,MAAM,IAAI,aAAa,IAAI,MAAM;AACvC,QAAM,OAAO,SAAS;AACtB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,UAAM,KAAK,KAAK,IAAI,GAAG,IAAI,IAAI;AAC/B,UAAM,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,OAAO,CAAC;AAC5C,QAAI,CAAC,KAAK,OAAO,EAAE,IAAI,OAAO,EAAE,MAAM,KAAK;AAAA,EAC5C;AACA,SAAO;AACR;AAGO,SAAS,WAAW,KAA0B;AACpD,SAAO,QAAQ,SAAS,GAAG,CAAC;AAC7B;;;AC3QA,IAAM,eAAqD;AAAA,EAC1D,OAAO;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACP,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACP,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACV,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,oBAAoB;AAAA,IACnB,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,iBAAiB;AAAA,IAChB,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACV,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,kBAAkB;AAAA,IACjB,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA;AAAA;AAAA,IAGd,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AAAA,EACA,eAAe;AAAA,IACd,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB;AACD;AAGA,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AAGvB,IAAM,mBAAmB;AAEzB,IAAM,gBAAgB;AAEtB,IAAM,0BAA0B;AAQhC,IAAM,sBAAsB;AAG5B,IAAM,sBAAsB;AAE5B,IAAM,gBAAgB;AAEtB,IAAM,uBAAuB;AAE7B,SAASC,OAAM,GAAW,IAAY,IAAoB;AACzD,SAAO,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;AACpC;AAGA,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAE5B,IAAM,kBAAkB;AAExB,IAAM,uBAAuB;AAQ7B,IAAM,0BAA0B;AAGhC,SAAS,eAAe,GAAmB;AAC1C,SAAO,KAAK;AAAA,IACX,KAAK,IAAI,EAAE,UAAU,qBAAqB,EAAE,SAAS,EAAE;AAAA,IACvD,EAAE,SAAS;AAAA,EACZ;AACD;AAGO,SAAS,eAAe,GAAW,MAAc,IAAoB;AAC3E,QAAM,KAAK,eAAe,CAAC;AAC3B,WAAS,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK;AAC3D,QAAI,EAAE,SAAS,CAAC,KAAK,GAAI,QAAO;AAAA,EACjC;AACA,SAAO,KAAK,IAAI,GAAG,IAAI;AACxB;AAGO,SAAS,aAAa,GAAW,MAAc,IAAoB;AACzE,QAAM,KAAK,eAAe,CAAC;AAC3B,WAAS,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,MAAM,KAAK;AAClD,QAAI,EAAE,SAAS,CAAC,KAAK,GAAI,QAAO;AAAA,EACjC;AACA,SAAO,KAAK,IAAI,EAAE,IAAI,GAAG,EAAE;AAC5B;AAUO,SAAS,mBACf,GACA,MACA,IACA,WACS;AACT,QAAM,KAAK,KAAK,IAAI,GAAG,IAAI;AAC3B,MAAI,QAAQ,eAAe,GAAG,MAAM,EAAE;AAEtC,MAAI,WAAW;AAKd,UAAM,QAAQ,EAAE,SAAS;AACzB,UAAM,WAAW,EAAE,cAAc;AACjC,aAAS,IAAI,IAAI,IAAI,OAAO,KAAK;AAChC,YAAM,UACL,EAAE,UAAU,CAAC,KAAK,wBAAwB,EAAE,SAAS,CAAC,KAAK;AAC5D,UAAI,WAAW,EAAE,OAAO,CAAC,KAAK,UAAU;AACvC,gBAAQ;AACR;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAOA,QAAM,OAAO,EAAE,UAAU;AACzB,QAAM,IAAI,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;AAClC,SAAO,QAAQ,IAAI;AAClB,UAAM,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC;AACnC,UAAM,eACL,EAAE,SAAS,KAAK,IAAI,EAAE,SAAS,IAAI,KAAK;AACzC,QAAI,CAAC,gBAAgB,EAAE,SAAS,QAAQ,CAAC,KAAK,KAAM;AACpD;AAAA,EACD;AACA,SAAO;AACR;AAMO,SAAS,eAAe,GAAW,MAAc,IAAoB;AAC3E,QAAM,OAAO,KAAK,KAAK,gBAAgB,MAAM;AAC7C,QAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE;AAC3B,WAAS,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,KAAK;AAC5C,QAAI,EAAE,OAAO,CAAC,IAAI,iBAAkB;AACpC,QAAI,MAAM;AACV,WAAO,IAAI,MAAM,MAAM,EAAE,OAAO,IAAI,GAAG,KAAK,iBAAkB;AAC9D,QAAI,OAAO,KAAM,QAAO;AACxB,SAAK;AAAA,EACN;AACA,SAAO;AACR;AAWA,SAAS,kBAAkB,GAAW,MAAc,IAAoB;AACvE,QAAM,KAAK,KAAK,IAAI,GAAG,IAAI;AAC3B,QAAM,KAAK,KAAK,IAAI,EAAE,IAAI,GAAG,EAAE;AAC/B,MAAI,MAAM,GAAI,QAAO;AAErB,QAAM,IAAI,KAAK,IAAI,GAAG,UAAU,EAAE,CAAC;AACnC,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,WAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC7B,UAAM,OACL,EAAE,SAAS,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AAGrE,UAAM,eACJ,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,IAC9B,EAAE,UAAU,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,KACrC;AACD,UAAM,QAAQ,OAAO,cAAc,EAAE,KAAK,CAAC;AAC3C,QAAI,QAAQ,WAAW;AACtB,kBAAY;AACZ,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAMA,SAAS,gBAAgB,GAAW,YAAoB,OAAuB;AAC9E,QAAM,QAAQ;AACd,QAAM,QAAQ;AACd,QAAM,OAAO,aAAa,UAAU,KAAK;AACzC,QAAM,KAAK,KAAK,IAAI,OAAO,aAAa,UAAU,KAAK,CAAC;AACxD,MAAI,MAAM,KAAM,QAAO,KAAK,IAAI,OAAO,aAAa,UAAU,KAAK,CAAC;AAEpE,QAAM,OAAO,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,EAAE,CAAC,CAAC;AACtD,QAAM,OAAO,KAAK,KAAK,KAAK,MAAM;AAClC,WAAS,IAAI,MAAM,IAAI,KAAK,MAAM,KAAK;AACtC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC9B,UAAI,KAAK,IAAI,CAAC,IAAI,MAAM;AACvB,iBAAS;AACT;AAAA,MACD;AAAA,IACD;AACA,QAAI,OAAQ,QAAO;AAAA,EACpB;AACA,SAAO;AACR;AAMA,SAAS,eAAe,GAAW,MAAc,UAA0B;AAC1E,MAAI,OAAO;AACX,WAAS,IAAI,MAAM,KAAK,UAAU,KAAK;AACtC,QAAI,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,IAAI,EAAG,QAAO;AAAA,EAC9C;AAGA,QAAM,KAAK,EAAE,SAAS,IAAI,IAAI;AAC9B,QAAM,OAAO,KAAK,KAAK,KAAK,MAAM;AAClC,WAAS,IAAI,MAAM,KAAK,WAAW,MAAM,KAAK;AAC7C,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC9B,UAAI,EAAE,SAAS,IAAI,CAAC,KAAK,IAAI;AAC5B,kBAAU;AACV;AAAA,MACD;AAAA,IACD;AAGA,QAAI,QAAS,QAAO,KAAK,IAAI,MAAM,IAAI,oBAAoB;AAAA,EAC5D;AAGA,SAAO,KAAK,IAAI,MAAM,WAAW,oBAAoB;AACtD;AAGA,SAAS,cACR,GACA,WACA,YACU;AACV,MAAI,aAAa,YAAY,UAAU,EAAE,EAAG,QAAO;AACnD,MAAI,eAAe;AACnB,WAAS,IAAI,WAAW,IAAI,YAAY,KAAK;AAC5C,QAAI,EAAE,OAAO,CAAC,KAAK,iBAAkB;AAAA,EACtC;AACA,SAAO,iBAAiB,aAAa,aAAa;AACnD;AAiBO,SAAS,WACf,GACA,KACA,MACA,IACe;AACf,QAAM,MAAM,aAAa,GAAG;AAC5B,QAAM,YAAY,mBAAmB,GAAG,MAAM,IAAI,IAAI,cAAc;AACpE,QAAM,YAAY,KAAK;AAAA,IACtB;AAAA,IACA,YAAY,UAAU,IAAI,iBAAiB,EAAE;AAAA,EAC9C;AAEA,MAAI;AACJ,MAAI,CAAC,IAAI,iBAAiB;AAEzB,UAAM,IAAI,eAAe,GAAG,WAAW,SAAS;AAChD,iBAAa,KAAK,IAAI,IAAI,YAAY,UAAU,EAAE;AAAA,EACnD,WAAW,QAAQ,WAAW,QAAQ,UAAU;AAC/C,UAAM,IAAI,eAAe,GAAG,WAAW,SAAS;AAChD,iBAAa,KAAK,IAAI,IAAI;AAAA,EAC3B,OAAO;AACN,UAAM,aAAa,eAAe,GAAG,WAAW,SAAS;AACzD,UAAM,OAAO,cAAc,IAAI,aAAa;AAI5C,iBAAa;AAAA,MACZ;AAAA,MACA,OAAO,UAAU,uBAAuB;AAAA,MACxC,KAAK,IAAI,IAAI,OAAO,UAAU,IAAI,cAAc,CAAC;AAAA,IAClD;AAAA,EACD;AACA,eAAaA,OAAM,YAAY,WAAW,KAAK,IAAI,WAAW,KAAK,CAAC,CAAC;AAErE,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,QAAQ,gBAAgB,GAAG,YAAY,EAAE;AAAA,IACzC,WACC,QAAQ,mBAAmB,cAAc,GAAG,WAAW,UAAU;AAAA,EACnE;AACD;AAGA,SAAS,MAAM,IAAoB;AAClC,SAAO,KAAK,MAAM,KAAK,GAAI,IAAI;AAChC;AASA,SAAS,WACR,KACA,OACA,GACA,KACA,KACA,UACW;AACX,QAAM,MAAM,aAAa,GAAG;AAI5B,MAAI,WAAW,YAAY,IAAI,SAAS,IAAI,IAAI;AAChD,QAAM,UAAU,YAAY,IAAI,UAAU;AAC1C,aAAW,KAAK,IAAI,UAAU,UAAU,IAAI,cAAc;AAC1D,aAAWA,OAAM,UAAU,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;AAEtD,QAAM,MAAM,KAAK,IAAI,GAAG,UAAU,QAAQ;AAE1C,MAAI;AACJ,MAAI,IAAI,mBAAmB,QAAW;AAIrC,cAAU,IAAI;AAAA,EACf,OAAO;AAEN,cAAUA;AAAA,MACT,IAAI,eAAe;AAAA,MACnB,KAAK,IAAI,gBAAgB,GAAG;AAAA,MAC5B,KAAK,IAAI,gBAAgB,GAAG;AAAA,IAC7B;AAAA,EACD;AAIA,QAAM,YAAY,KAAK;AAAA,IACtB,MAAM;AAAA,IACN,KAAK,IAAI,OAAO,IAAI;AAAA,IACpB,YAAY,IAAI,MAAM,IAAI;AAAA,EAC3B;AAGA,QAAM,QAAQ,KAAK,IAAI,YAAY,QAAQ,GAAG,WAAW,YAAY,EAAE;AACvE,QAAM,SAAS,EAAE,KAAK,IAAI,OAAO,EAAE,UAAU,IAAI;AAEjD,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,QAAQ,MAAM,QAAQ;AAAA,IACtB,WAAW,MAAM,SAAS;AAAA,IAC1B,QAAQ,MAAM,MAAM;AAAA,IACpB,KAAK,MAAM,GAAG;AAAA,IACd,SAAS,MAAM,OAAO;AAAA,EACvB;AACD;AAQO,SAAS,aACf,KACA,GACA,KACA,SACa;AACb,QAAM,aAAa,eAAe,GAAG,GAAG,EAAE,CAAC;AAC3C,QAAM,WAAW,aAAa,GAAG,YAAY,EAAE,CAAC;AAChD,QAAM,MAAM,WAAW,GAAG,IAAI,KAAK,GAAG,QAAQ;AAC9C,QAAM,MAAM,eAAe,GAAG,IAAI,QAAQ,QAAQ;AAClD,SAAO,QAAQ,IAAI,CAAC,UAAU,WAAW,KAAK,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC;AAC3E;AAMO,SAAS,kBACf,KACA,GACA,KACA,OACkB;AAClB,QAAM,aAAa,eAAe,GAAG,GAAG,EAAE,CAAC;AAC3C,QAAM,WAAW,aAAa,GAAG,YAAY,EAAE,CAAC;AAChD,QAAM,MAAM,WAAW,GAAG,IAAI,KAAK,GAAG,QAAQ;AAC9C,QAAM,MAAM,eAAe,GAAG,IAAI,QAAQ,QAAQ;AAKlD,QAAM,MAAM;AACZ,QAAM,UAAU;AAChB,QAAM,YAAY;AAGlB,QAAM,WAAW,YAAY,IAAI,MAAM;AACvC,QAAM,QAAQ,YAAY,GAAG;AAC7B,MAAI,WAAW,KAAK,QAAQ,WAAW,YAAY,GAAI,QAAO;AAE9D,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,QAAQ,MAAM,QAAQ;AAAA,IACtB;AAAA,IACA,QAAQ,MAAM,EAAE,QAAQ,SAAS;AAAA,IACjC;AAAA,IACA;AAAA,EACD;AACD;AAaA,IAAM,mBAAmB;AAGzB,SAAS,QAAQ,QAGf;AACD,QAAM,IAAI,OAAO;AACjB,MAAI,IAAI,EAAG,QAAO,EAAE,WAAW,OAAO,CAAC,KAAK,GAAG,OAAO,EAAE;AACxD,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,MAAM;AACV,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,UAAM;AACN,UAAM,OAAO,CAAC;AACd,WAAO,IAAI;AACX,WAAO,IAAI,OAAO,CAAC;AAAA,EACpB;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK;AAC7B,QAAM,QAAQ,UAAU,KAAK,IAAI,MAAM,KAAK,MAAM,QAAQ;AAC1D,SAAO,EAAE,YAAY,KAAK,QAAQ,MAAM,GAAG,MAAM;AAClD;AAGA,SAAS,cAAc,GAAyB;AAC/C,QAAM,IAAI,KAAK,IAAI,GAAG,UAAU,EAAE,CAAC;AACnC,QAAM,MAAM,IAAI,aAAa,EAAE,CAAC;AAChC,WAAS,IAAI,GAAG,IAAI,EAAE,GAAG,KAAK;AAC7B,UAAM,OACL,EAAE,SAAS,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACrE,QAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI;AAAA,EAC1C;AACA,SAAO,OAAO,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC;AAC7C;AAWO,SAAS,WAAW,GAAW,OAA4B;AACjE,MAAI,QAAQ,EAAG,QAAO;AACtB,QAAM,WAAW,cAAc,CAAC;AAChC,QAAM,WAAW,eAAe,GAAG,GAAG,EAAE,CAAC;AACzC,QAAM,SAAS,aAAa,GAAG,UAAU,EAAE,CAAC;AAC5C,QAAM,OAAO,SAAS;AACtB,MAAI,OAAO,UAAU,EAAE,EAAG,QAAO;AAEjC,MAAI,UAAU,GAAG;AAChB,WAAO,EAAE,OAAO,UAAU,UAAU,MAAM,QAAQ,CAAC,QAAQ,EAAE;AAAA,EAC9D;AAEA,QAAM,aAAa;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,EACR;AACA,QAAM,OAAO,EAAE,OAAO,WAAW,OAAO,UAAU,UAAU,OAAO,MAAM;AACzE,QAAM,SAAS,CAAC,eAA8B;AAC7C,eAAW,aAAa,YAAY;AACnC,eACK,KAAK,YAAY,MACrB,MAAM,YAAY,MAClB,MAAM,YAAY,MACjB;AAGD,cAAMC,QAAO,aAAa,UAAU,KAAK,MAAM,KAAK,IAAI,CAAC;AACzD,cAAM,MAAM,KAAK;AACjB,cAAM,UAAU,SAAS,KAAK;AAC9B,iBACK,QAAQ,WAAW,KAAK,MAC5B,SAAS,WAAW,KAAK,KACzB,SAAS,GACR;AACD,cAAI,cAAc,SAAS,QAAQ,KAAK,KAAK,QAAS;AACtD,cAAI,QAAQ;AACZ,mBAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,kBAAM,SAAS,QAAQ,IAAI;AAC3B,kBAAM,KAAKA,MAAKD,OAAM,KAAK,MAAM,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;AACrD,qBAAS,SAAS,EAAE,IAAI,KAAK,IAAI,KAAK,MAAM,IAAI;AAAA,UACjD;AACA,cAAI,QAAQ,KAAK,OAAO;AACvB,iBAAK,QAAQ;AACb,iBAAK,QAAQ;AACb,iBAAK,WAAW;AAAA,UACjB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAMA,SAAO,IAAI;AACX,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,EAAG,QAAO,KAAK;AAC9C,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,EAAG,QAAO;AAEzC,QAAM,OAAO,aAAa,UAAU,KAAK,MAAM,KAAK,WAAW,IAAI,CAAC;AACpE,QAAM,UAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,YAAQ;AAAA,MACP,KAAKA,OAAM,KAAK,MAAM,KAAK,QAAQ,IAAI,KAAK,QAAQ,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;AAAA,IACnE;AAAA,EACD;AAKA,QAAM,EAAE,WAAW,MAAM,IAAI,QAAQ,OAAO;AAC5C,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,UAAM,SAAS,YAAY,QAAQ;AACnC,UAAM,UAAU,KAAK;AAAA,MACpB,UAAU,QAAQ,CAAC,IAAI,UAAU;AAAA,IAClC;AACA,WAAO,KAAK,IAAI,IAAI,KAAK,IAAI,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO;AAAA,EACnE;AAEA,SAAO;AAAA,IACN,OAAO,OAAO,CAAC;AAAA,IACf,UAAU,QAAQ,IAAI,QAAQ,KAAK;AAAA,IACnC;AAAA,EACD;AACD;AAMA,SAAS,aAAa,KAAmB,MAA0B;AAClE,QAAM,IAAI,IAAI;AACd,QAAM,MAAM,IAAI,WAAW,CAAC;AAC5B,QAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,UAAM,QAAQ,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI;AACtC,WAAO,QAAQ,OAAO;AACrB,aAAO,OAAO,QAAQ,IAAI,MAAM,OAAO,CAAC,CAAC,KAAK,IAAI,IAAI,EAAG;AACzD,YAAM,MAAM,IAAI;AAAA,IACjB;AACA,WAAO,MAAM,IAAI,IAAI,IAAI,KAAM;AAC/B,QAAI,CAAC,IAAI,MAAM,IAAI;AAAA,EACpB;AACA,SAAO;AACR;AAWA,SAAS,mBACR,UACA,MACA,IACA,UACW;AACX,QAAM,KAAK,UAAU,GAAG;AACxB,QAAM,KAAK,KAAK,IAAI,UAAU,IAAI,GAAG,KAAK,OAAO,KAAK,QAAQ,CAAC,CAAC;AAChE,QAAM,MAAgB,CAAC;AACvB,MAAI,KAAK,IAAI;AACZ,QAAI,OAAO;AACX,aAAS,IAAI,MAAM,IAAI,IAAI,IAAK,SAAQ,SAAS,CAAC;AAClD,YAAQ,KAAK,IAAI,GAAG,KAAK,IAAI;AAE7B,UAAM,IAAI,IAAI,aAAa,KAAK,CAAC;AACjC,QAAI,OAAO;AACX,aAAS,MAAM,IAAI,OAAO,IAAI,OAAO;AACpC,UAAI,MAAM;AACV,UAAI,IAAI;AACR,eAAS,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,KAAK;AAC1C,gBAAQ,SAAS,CAAC,IAAI,SAAS,SAAS,IAAI,GAAG,IAAI;AAAA,MACpD;AACA,QAAE,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI;AAC3B,UAAI,EAAE,GAAG,IAAI,KAAM,QAAO,EAAE,GAAG;AAAA,IAChC;AACA,QAAI,OAAO,GAAG;AACb,eAAS,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO;AACvC,YAAI,EAAE,GAAG,IAAI,OAAO,IAAK;AACzB,YAAI,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,EAAG;AAChD,YAAI,KAAK,GAAG;AACZ,YAAI,IAAI,UAAU,EAAG;AAAA,MACtB;AAAA,IACD;AAAA,EACD;AACA,MAAI,KAAK,QAAQ;AAKjB,QAAM,mBAA6B,CAAC;AACpC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,WAAW,UAAU,GAAG;AAC9B,aAAW,KAAK,KAAK;AACpB,eAAW,WAAW,CAAC,GAAG,GAAG,CAAC,GAAG;AAChC,YAAM,MAAM,KAAK,MAAM,IAAI,OAAO;AAClC,UAAI,MAAM,YAAY,KAAK,IAAI,GAAG,EAAG;AACrC,WAAK,IAAI,GAAG;AACZ,uBAAiB,KAAK,GAAG;AAAA,IAC1B;AAAA,EACD;AAGA,MAAI,iBAAiB,WAAW,EAAG,kBAAiB,KAAK,QAAQ;AACjE,SAAO;AACR;AAUA,SAAS,mBACR,GACA,KACA,OACA,MACS;AACT,MAAI,aAAa,GAAG,EAAE,gBAAiB,QAAO,QAAQ;AAEtD,QAAM,KAAK,KAAK,IAAI,GAAG,QAAQ,UAAU,GAAG,CAAC;AAC7C,QAAM,KAAK,KAAK,IAAI,MAAM,QAAQ,UAAU,GAAG,CAAC;AAChD,MAAI,WAAW;AACf,WAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC7B,QAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,QAAQ,EAAG,YAAW;AAAA,EAClD;AACA,MAAI,EAAE,OAAO,QAAQ,KAAK,iBAAkB,QAAO;AAEnD,QAAM,UAAU;AAAA,IACf;AAAA,IACA;AAAA,IACA,KAAK,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;AAAA,EAClC;AACA,SAAO,WAAW,IAAI,UAAU;AACjC;AAYO,SAAS,iBACf,KACA,GACA,WACA,OAAqE,CAAC,GACzD;AACb,QAAM,OAAO,WAAW,GAAG,UAAU,MAAM;AAC3C,MAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAM,aAAa,WAAW,KAAK,QAAQ;AAG3C,QAAM,MAAMA,OAAM,aAAa,GAAG,IAAI,mBAAmB;AACzD,QAAM,UAAU,MAAM,MAAM,CAAC;AAC7B,QAAM,YAAY,MAAM,MAAM,GAAG;AACjC,QAAM,SAAS,KAAK,UAAU;AAG9B,QAAM,SAAS,KAAK,UAAU;AAE9B,QAAM,UAAsB,CAAC;AAC7B,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAC1C,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,QAAQ,KAAK,OAAO,CAAC;AAC3B,UAAM,OACL,IAAI,IAAI,UAAU,SACf,KAAK,OAAO,IAAI,CAAC,IACjB,aAAa,GAAG,OAAO,EAAE,CAAC;AAE9B,QAAI;AACJ,QAAI,MAAM,GAAG;AAGZ,mBAAa,WAAW,GAAG,IAAI,KAAK,GAAG,IAAI,EAAE;AAAA,IAC9C,OAAO;AACN,mBAAa,mBAAmB,GAAG,IAAI,KAAK,OAAO,IAAI;AAAA,IACxD;AAEA,UAAM,SAAS,YAAY,UAAU;AACrC,UAAM,WAAWA,OAAM,SAAS,KAAK,GAAG,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC;AAC/D,UAAM,YAAY,SAAS;AAG3B,UAAM,QAAQ,KAAK,IAAI,EAAE,YAAY,SAAU,aAAa,IAAK,CAAC;AAElE,UAAM,QACL,MAAM,IACH,KAAK,MAAM,GAAG,IAAI,IAAI,GAAG,MAAM,KAC/B,GAAG,UAAU,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,GAAG,MAAM;AAElD,YAAQ,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,MACA,QAAQ,MAAM,QAAQ;AAAA,MACtB,WAAW,KAAK,IAAI,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;AAAA,MAC3D,QAAQ,MAAM,CAAC,KAAK,IAAI,QAAQ,UAAU,YAAY,EAAE,CAAC;AAAA,MACzD,KAAK,MAAM,SAAS;AAAA,MACpB,SAAS,MAAM,IAAI,IAAI,KAAK,IAAI,SAAS,MAAM,SAAS,CAAC;AAAA,IAC1D,CAAC;AAAA,EACF;AAEA,MAAI,KAAK,gBAAgB,UAAU,SAAS,GAAG;AAC9C,UAAM,OAAO,UAAU,UAAU,SAAS,CAAC;AAC3C,UAAM,YAAY,KAAK,OAAO,UAAU,SAAS,CAAC;AAClD,UAAM,WAAW,aAAa,GAAG,WAAW,EAAE,CAAC;AAC/C,UAAM,QAAQ,eAAe,GAAG,WAAW,QAAQ;AACnD,UAAM,SAAS,YAAY,KAAK;AAChC,UAAM,WAAWA,OAAM,SAAS,KAAK,GAAG,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC;AAC/D,UAAM,YAAY,SAAS;AAC3B,YAAQ,KAAK;AAAA,MACZ;AAAA,MACA,OAAO,GAAG,KAAK,KAAK,KAAK,MAAM;AAAA,MAC/B,QAAQ,MAAM,QAAQ;AAAA,MACtB,WAAW,MAAM,SAAS;AAAA,MAC1B,QAAQ;AAAA,QACP,EAAE,KAAK,IAAI,EAAE,YAAY,YAAY,QAAQ,CAAC,IAAI;AAAA,MACnD;AAAA,MACA,KAAK,MAAM,SAAS;AAAA,MACpB,SAAS,KAAK,IAAI,SAAS,MAAM,SAAS,CAAC;AAAA,IAC5C,CAAC;AAAA,EACF;AAEA,SAAO;AACR;;;AC92BA,IAAM,WAA2C;AAAA,EAChD,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,GAAG;AACJ;AAMA,IAAM,OAA+B;AAAA,EACpC,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AACJ;AAGA,IAAM,QAAgC;AAAA,EACrC,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AACJ;AAGA,IAAM,UAAkC;AAAA,EACvC,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AAAA,EACJ,cAAI;AACL;AAOO,SAAS,WAAW,GAAmB;AAC7C,MAAI,MAAM;AACV,aAAW,MAAM,GAAG;AACnB,UAAM,IAAI,GAAG,YAAY,CAAC,KAAK;AAE/B,WAAO,KAAK,SAAU,KAAK,QAAS,OAAO,cAAc,IAAI,EAAI,IAAI;AAAA,EACtE;AACA,SAAO;AACR;AAEA,SAAS,KAAK,MAAc,MAAwB;AACnD,QAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAM,YAAY,KAAK,MAAM,GAAG,EAAE;AAClC,QAAM,QAAQ,KAAK,MAAM,KAAK,CAAC;AAC/B,SAAO,EAAE,MAAM,WAAW,OAAO,KAAK,SAAS,SAAS,KAAK,QAAQ;AACtE;AAMA,SAAS,aACR,KACA,MACA,GACwC;AACxC,QAAM,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAC/B,MAAI,IAAI,WAAW,GAAG;AACrB,UAAM,WAAW,QAAQ,GAAG;AAC5B,QAAI,SAAU,QAAO,EAAE,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,QAAQ,GAAG,KAAK,EAAE;AAExE,UAAM,QAAQ,MAAM,IAAI,CAAC,CAAC;AAC1B,UAAM,OAAO,KAAK,IAAI,CAAC,CAAC;AACxB,QAAI,SAAS,MAAM;AAClB,YAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,YAAM,gBAAgB,KAAK,MAAM,GAAG,EAAE;AACtC,YAAM,YAAY,KAAK,MAAM,KAAK,CAAC;AAEnC,UAAI,cAAc,OAAO,SAAS,GAAG,aAAa,GAAG,GAAG;AACvD,cAAM,OAAO,GAAG,aAAa,KAAK,KAAK;AACvC,eAAO,EAAE,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE;AAAA,MACvD;AAEA,UAAI,CAAC,eAAe;AACnB,cAAM,QAAQ,cAAc,MAAM,MAAM,cAAc,MAAM,MAAM;AAClE,cAAM,MAAM,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE;AAEzD,eAAO,EAAE,KAAK,EAAE,GAAG,KAAK,KAAK,YAAY,GAAG,KAAK,EAAE;AAAA,MACpD;AAKA,aAAO;AAAA,QACN,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,aAAa,IAAI,KAAK,EAAE;AAAA,QAC1D,KAAK;AAAA,MACN;AAAA,IACD;AAAA,EACD;AAEA,QAAM,MAAM,KAAK,KAAK,CAAC,CAAC;AACxB,MAAI,IAAK,QAAO,EAAE,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,EAAE;AAC9D,SAAO;AACR;AASO,SAAS,UAAU,MAAiC;AAC1D,QAAM,MAAM,KAAK,UAAU,KAAK;AAChC,QAAM,OAAO,WAAW,GAAG;AAC3B,QAAM,MAAkB,CAAC;AAEzB,WAAS,IAAI,GAAG,IAAI,KAAK,UAAU;AAClC,UAAM,KAAK,KAAK,CAAC;AAGjB,QAAI,OAAO,YAAO,OAAO,UAAK;AAC7B;AACA;AAAA,IACD;AACA,UAAM,OAAO,aAAa,KAAK,MAAM,CAAC;AACtC,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI,KAAK,KAAK,GAAG;AACjB,SAAK,KAAK;AAAA,EACX;AAEA,SAAO,IAAI,SAAS,IAAI,MAAM;AAC/B;;;ACxQA,IAAM,OAAO;AAmBN,SAAS,WAAW,UAAqC;AAC/D,MAAI,OAAO,SAAS,QAAQ,YAAY,EAAE;AAC1C,SAAO,KAAK,QAAQ,aAAa,EAAE;AAEnC,SAAO,KAAK,QAAQ,qBAAqB,EAAE;AAC3C,SAAO,KAAK,KAAK;AACjB,MAAI,CAAC,KAAM,QAAO;AAKlB,MAAI,OAAO;AACX,QAAM,SAAS,UAAU,KAAK,IAAI;AAClC,MAAI,QAAQ;AACX,WAAO,OAAO,CAAC;AACf,WAAO,KAAK,MAAM,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM;AAAA,EACvC;AAEA,MAAI,eAAe;AACnB,MAAI,KAAK,KAAK,IAAI,GAAG;AACpB,mBAAe;AACf,WAAO,KAAK,QAAQ,MAAM,EAAE;AAAA,EAC7B;AAEA,QAAM,OAAO,6BAA6B,KAAK,IAAI;AACnD,MAAI,QAAQ,KAAK,SAAS,KAAK,CAAC,EAAE,QAAQ;AACzC,WAAO,KAAK,CAAC,IAAI;AACjB,WAAO,KAAK,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM;AAAA,EACrC;AAIA,MAAI,SAAS;AACb,QAAM,OAAO,6BAA6B,KAAK,IAAI;AACnD,MAAI,MAAM;AACT,aAAS,KAAK,CAAC;AACf,WAAO,KAAK,MAAM,KAAK,CAAC,EAAE,MAAM;AAAA,EACjC;AACA,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,YAAY,UAAU,IAAI;AAChC,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,EAAE,WAAW,cAAc,QAAQ,KAAK;AAChD;AAaO,SAAS,qBAAqB,QAAwB;AAC5D,MAAI,mBAAmB,KAAK,MAAM,EAAG,QAAO,IAAI,MAAM;AACtD,QAAM,SAAS,mCAAmC,KAAK,MAAM;AAC7D,SAAO,SAAS,IAAI,OAAO,CAAC,CAAC,KAAK;AACnC;AAEA,SAAS,WAAW,MAAc,aAAgC;AACjE,SAAO,cAAc,CAAC,MAAM,KAAK,IAAI,EAAE,IAAI,CAAC,IAAI;AACjD;AAQO,SAAS,mBACf,MACA,UAA2B,CAAC,GACf;AACb,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,mBAAmB,QAAQ,oBAAoB;AAErD,QAAM,aAAa,WAAW,KAAK,IAAI;AACvC,MAAI,CAAC,YAAY;AAChB,WAAO;AAAA,MACN,SAAS,CAAC;AAAA,MACV,SAAS,EAAE,KAAK,KAAK,MAAM,QAAQ,uBAAuB;AAAA,MAC1D,OAAO;AAAA,IACR;AAAA,EACD;AAEA,MAAI;AACJ,MAAI;AACH,aAAS,QAAQ,SAAS,KAAK,IAAI,CAAC;AAAA,EACrC,SAASE,MAAK;AACb,WAAO;AAAA,MACN,SAAS,CAAC;AAAA,MACV,SAAS;AAAA,QACR,KAAK,KAAK;AAAA,QACV,QAAQA,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG;AAAA,MACxD;AAAA,MACA,OAAO;AAAA,IACR;AAAA,EACD;AACA,MAAI,OAAO,IAAI,GAAG;AACjB,WAAO;AAAA,MACN,SAAS,CAAC;AAAA,MACV,SAAS,EAAE,KAAK,KAAK,MAAM,QAAQ,uBAAuB;AAAA,MAC1D,OAAO;AAAA,IACR;AAAA,EACD;AAEA,QAAM,EAAE,WAAW,cAAc,QAAQ,KAAK,IAAI;AAElD,MAAI,UAAU,WAAW,KAAK,CAAC,cAAc;AAC5C,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,OAAO,GAAG,MAAM,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,MAAM;AACjD,UAAMC,WAAU;AAAA,MACf,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW,MAAM,WAAW;AAAA,IAC7B;AAIA,QAAI,qBAAqB,IAAI,QAAQ,WAAW,IAAI,QAAQ,WAAW;AACtE,YAAM,OAAO,kBAAkB,KAAK,MAAM,QAAQ,KAAK,KAAK,IAAI,EAAE;AAClE,UAAI,KAAM,CAAAA,SAAQ,KAAK,IAAI;AAAA,IAC5B;AACA,WAAO,EAAE,SAAAA,UAAS,SAAS,MAAM,OAAO,OAAO;AAAA,EAChD;AAEA,QAAM,UAAU,iBAAiB,KAAK,MAAM,QAAQ,WAAW;AAAA,IAC9D,QAAQ,GAAG,IAAI,GAAG,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,EACD,CAAC;AACD,MAAI,QAAQ,WAAW,GAAG;AACzB,WAAO;AAAA,MACN,SAAS,CAAC;AAAA,MACV,SAAS,EAAE,KAAK,KAAK,MAAM,QAAQ,+BAA+B;AAAA,MAClE,OAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO,EAAE,SAAS,SAAS,MAAM,OAAO,WAAW;AACpD;AAUO,SAAS,YACf,OACA,UAA2B,CAAC,GACX;AACjB,QAAM,UAAsB,CAAC;AAC7B,QAAM,UAAyB,CAAC;AAChC,MAAI,OAAO;AACX,MAAI,WAAW;AAEf,aAAW,QAAQ,OAAO;AACzB,UAAM,SAAS,mBAAmB,MAAM,OAAO;AAC/C,YAAQ,KAAK,GAAG,OAAO,OAAO;AAC9B,QAAI,OAAO,QAAS,SAAQ,KAAK,OAAO,OAAO;AAC/C,QAAI,OAAO,UAAU,OAAQ;AAC7B,QAAI,OAAO,UAAU,WAAY;AAAA,EAClC;AAEA,SAAO,EAAE,SAAS,SAAS,OAAO,UAAU,MAAM,QAAQ,EAAE;AAC7D;AAGO,SAAS,UACf,MACA,UAC0B;AAC1B,MAAI,QAAQ,SAAU,QAAO;AAC7B,MAAI,SAAU,QAAO;AACrB,MAAI,KAAM,QAAO;AACjB,SAAO;AACR;;;AC3PA,IAAI,eAA2C;AAE/C,SAAS,gBAAqC;AAC7C,MAAI,aAAc,QAAO;AACzB,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,UAAU,IAAI,YAAY,aAAa,EAAE,OAAO,MAAM,CAAC;AAG7D,WAAS,IAAI,GAAG,IAAI,KAAM,KAAK;AAC9B,UAAM,IAAI,QAAQ,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAAA,EACjD;AAEA,WAAS,IAAI,KAAM,KAAK,KAAM,KAAK;AAClC,UAAM,IAAI,QAAQ,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAAA,EACjD;AAEA,QAAM,OAAO,IAAI,WAAW,CAAC;AAC7B,WAAS,OAAO,KAAM,QAAQ,KAAM,QAAQ;AAC3C,QAAI,OAAO,OAAQ,OAAO,IAAM;AAChC,SAAK,CAAC,IAAI;AACV,aAAS,QAAQ,IAAM,SAAS,KAAM,SAAS;AAC9C,UAAI,UAAU,IAAM;AACpB,WAAK,CAAC,IAAI;AACV,YAAM,KAAK,QAAQ,OAAO,IAAI;AAG9B,UAAI,GAAG,WAAW,KAAK,OAAO,SAAK;AACnC,UAAI,CAAC,MAAM,IAAI,EAAE,EAAG,OAAM,IAAI,IAAK,QAAQ,IAAK,KAAK;AAAA,IACtD;AAAA,EACD;AAEA,iBAAe;AACf,SAAO;AACR;AAMO,SAAS,eAAe,MAA0B;AACxD,QAAM,QAAQ,cAAc;AAC5B,QAAM,MAAgB,CAAC;AACvB,aAAW,MAAM,MAAM;AACtB,UAAM,OAAO,MAAM,IAAI,EAAE;AACzB,QAAI,SAAS,OAAW,KAAI,KAAK,EAAI;AAAA,aAC5B,OAAO,IAAM,KAAI,KAAK,QAAQ,GAAG,OAAO,GAAI;AAAA,QAChD,KAAI,KAAK,IAAI;AAAA,EACnB;AACA,SAAO,IAAI,WAAW,GAAG;AAC1B;AAGA,SAAS,IAAI,GAAmB;AAC/B,QAAM,IAAI,EAAE,QAAQ,CAAC;AACrB,SAAO,EAAE,QAAQ,UAAU,EAAE,KAAK;AACnC;AAGO,SAAS,UAAU,SAAsC;AAC/D,SAAO,QACL;AAAA,IACA,CAAC,MACA,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,OAAO,CAAC;AAAA,EAC3G,EACC,KAAK,MAAM,EACX,OAAO,MAAM;AAChB;AAGO,SAAS,UAAU,SAA0C;AACnE,SAAO,eAAe,UAAU,OAAO,CAAC;AACzC;;;AC9CA,IAAM,gBAAgB;AAEtB,eAAe,UACd,MACwB;AACxB,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI;AACH,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,MAAM,OAAO,KAAK,QAAQ,aAAa;AAAA,EAC/C,QAAQ;AAEP,WAAO;AAAA,EACR;AACD;AAMA,eAAe,oBACd,KACA,QACA,QACmB;AACnB,MAAI;AACJ,MAAI;AACH,WAAO,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,QAAQ,OAAO,WAAW,CAAC;AAAA,EACtE,QAAQ;AACP,WAAO;AAAA,EACR;AACA,MAAI,CAAC,KAAK,GAAI,QAAO;AACrB,aAAW,QAAQ,CAAC,QAAQ,iBAAiB,gBAAgB,GAAG;AAC/D,UAAM,SAAS,KAAK,QAAQ,IAAI,IAAI;AACpC,UAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI;AACrC,QAAI,UAAU,MAAO,QAAO,WAAW;AAAA,EACxC;AACA,SAAO;AACR;AAQA,eAAsB,WACrB,KACA,UAA6B,CAAC,GACV;AACpB,QAAM,EAAE,YAAY,QAAQ,aAAa,KAAK,IAAI;AAClD,QAAM,QAAQ,MAAM,UAAU,QAAQ,SAAS;AAC/C,MAAI,OAAO;AACV,QAAI;AACH,YAAM,MAAM,MAAM,MAAM,MAAM,GAAG;AACjC,UACC,QACC,CAAC,cAAe,MAAM,oBAAoB,KAAK,KAAK,MAAM,IAC1D;AACD,cAAMC,SAAQ,OAAO,IAAI,QAAQ,IAAI,gBAAgB,CAAC,KAAK;AAC3D,qBAAa,EAAE,KAAK,QAAQA,QAAO,OAAAA,QAAO,WAAW,KAAK,CAAC;AAC3D,eAAO;AAAA,MACR;AAAA,IACD,QAAQ;AAAA,IAER;AAAA,EACD;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK,EAAE,OAAO,CAAC;AAC5C,MAAI,CAAC,SAAS,IAAI;AACjB,UAAM,IAAI,MAAM,SAAS,GAAG,UAAU,SAAS,MAAM,EAAE;AAAA,EACxD;AACA,QAAM,QAAQ,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC,KAAK;AAChE,MAAI;AACJ,MAAI,SAAS,QAAQ,YAAY;AAChC,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,QAAsB,CAAC;AAC7B,QAAI,SAAS;AACb,eAAW,EAAE,KAAK,QAAQ,OAAO,WAAW,MAAM,CAAC;AACnD,eAAS;AACR,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,YAAM,KAAK,KAAK;AAChB,gBAAU,MAAM;AAChB,iBAAW,EAAE,KAAK,QAAQ,OAAO,WAAW,MAAM,CAAC;AAAA,IACpD;AACA,WAAO,IAAI,WAAW,IAAI,YAAY,MAAM,CAAC;AAC7C,QAAI,SAAS;AACb,eAAW,QAAQ,OAAO;AACzB,WAAK,IAAI,MAAM,MAAM;AACrB,gBAAU,KAAK;AAAA,IAChB;AAAA,EACD,OAAO;AACN,WAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAClD,iBAAa;AAAA,MACZ;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,OAAO,SAAS,KAAK;AAAA,MACrB,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,QAAQ;AAC5B,aAAW,QAAQ,CAAC,gBAAgB,QAAQ,eAAe,GAAG;AAC7D,UAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACvC,QAAI,MAAO,SAAQ,IAAI,MAAM,KAAK;AAAA,EACnC;AACA,UAAQ,IAAI,kBAAkB,OAAO,KAAK,UAAU,CAAC;AACrD,QAAM,WAAW,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAC5D,MAAI,OAAO;AACV,QAAI;AACH,YAAM,MAAM,IAAI,KAAK,SAAS,MAAM,CAAC;AAAA,IACtC,QAAQ;AAAA,IAER;AAAA,EACD;AACA,SAAO;AACR;AAGA,eAAsB,gBACrB,KACA,SACsB;AACtB,SAAO,IAAI,WAAW,OAAO,MAAM,WAAW,KAAK,OAAO,GAAG,YAAY,CAAC;AAC3E;AAGA,eAAsB,eACrB,KACA,SACkB;AAClB,UAAQ,MAAM,WAAW,KAAK,OAAO,GAAG,KAAK;AAC9C;AAGO,IAAM,mBAAmB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AA2BA,eAAe,QAAQ,OAAwC;AAC9D,MAAI,OAAO,wBAAwB,aAAa;AAC/C,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,QAAM,SAAS,IAAI,KAAK,CAAC,KAAiB,CAAC,EACzC,OAAO,EACP,YAAY,IAAI,oBAAoB,MAAM,CAAC;AAC7C,SAAO,IAAI,WAAW,MAAM,IAAI,SAAS,MAAM,EAAE,YAAY,CAAC;AAC/D;AAcA,eAAsB,cACrB,SACA,UAAgC,CAAC,GACR;AACzB,QAAM,EAAE,aAAa,MAAM,GAAG,aAAa,IAAI;AAC/C,QAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACzD,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC7B,iBAAiB,IAAI,OAAO,SAAS;AACpC,YAAM,MAAM,MAAM;AAAA,QACjB,GAAG,IAAI,GAAG,IAAI,GAAG,aAAa,QAAQ,EAAE;AAAA,QACxC;AAAA,MACD;AACA,aAAO,CAAC,MAAM,aAAa,MAAM,QAAQ,GAAG,IAAI,GAAG;AAAA,IACpD,CAAC;AAAA,EACF;AACA,SAAO,OAAO,YAAY,OAAO;AAClC;AAGO,SAAS,0BACf,QACA,MACO;AACP,SAAO;AAAA,IACN,KAAK,eAAe;AAAA,IACpB,KAAK,cAAc;AAAA,IACnB,KAAK,YAAY;AAAA,IACjB,KAAK,SAAS;AAAA,IACd,KAAK,WAAW;AAAA,IAChB,KAAK,SAAS;AAAA,IACd,KAAK,eAAe;AAAA,IACpB,KAAK,YAAY;AAAA,EAClB;AACD;;;ACvMA,IAAM,UAAU,oBAAI,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGD,SAAS,UAAU,OAAe,MAAcC,MAAqB;AACpE,QAAM,YAAY,KAAK,IAAI,KAAK;AAChC,QAAM,UACL,aAAa,OAAO,YAAY,QAAQ,YAAY,QAAQ;AAC7D,SAAO,KAAK,KAAK,KAAK,IAAI,KAAK,IAAIA,MAAK,OAAO;AAChD;AAUA,IAAM,WAAW,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGlD,SAAS,gBAAgB,UAAmC;AAC3D,QAAM,WAAsB,CAAC;AAC7B,MAAI,YAA2B;AAC/B,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,UAAM,EAAE,OAAO,UAAU,YAAY,IAAI,SAAS,CAAC;AACnD,QAAI,UAAU,SAAS,UAAU,OAAO;AACvC,UAAI,cAAc,MAAM;AAEvB,iBAAS,KAAK;AAAA,UACb,OAAO;AAAA,UACP,SAAS;AAAA,UACT,YAAY,WAAW;AAAA,UACvB,UAAU;AAAA,QACX,CAAC;AACD,oBAAY;AAAA,MACb;AACA,UAAI,MAAM,EAAG;AACb,eAAS,KAAK;AAAA,QACb,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,UAAU;AAAA,MACX,CAAC;AACD;AAAA,IACD;AACA,QAAI,cAAc,KAAM,aAAY;AACpC,QAAI,QAAQ,IAAI,KAAK,GAAG;AACvB,eAAS,KAAK;AAAA,QACb,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY,WAAW,cAAc;AAAA,QACrC,UAAU,SAAS,IAAI,KAAK;AAAA,MAC7B,CAAC;AACD,kBAAY;AAAA,IACb;AAAA,EACD;AACA,MAAI,cAAc,MAAM;AACvB,UAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,aAAS,KAAK;AAAA,MACb,OAAO;AAAA,MACP,SAAS;AAAA,MACT,YAAY,KAAK,WAAW,KAAK,cAAc;AAAA,MAC/C,UAAU;AAAA,IACX,CAAC;AAAA,EACF;AACA,SAAO;AACR;AAOO,SAAS,gBACf,QACA,UACA,UAA2B,CAAC,GACR;AACpB,QAAM;AAAA,IACL,qBAAqB;AAAA,IACrB,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,WAAW;AAAA,EACZ,IAAI;AACJ,QAAM,WAAW,gBAAgB,OAAO,QAAQ;AAGhD,QAAM,YAAsB,IAAI,MAAM,SAAS,MAAM,EAAE,KAAK,CAAC;AAC7D,QAAM,WAA8B,IAAI,MAAM,SAAS,MAAM,EAAE,KAAK,IAAI;AACxE,QAAM,WAAsB,IAAI,MAAM,SAAS,MAAM,EAAE,KAAK,KAAK;AACjE,MAAI,IAAI;AACR,WAASC,KAAI,GAAGA,KAAI,SAAS,QAAQA,MAAK;AACzC,UAAM,UAAU,SAASA,EAAC;AAC1B,WAAO,IAAI,SAAS,UAAU,SAAS,CAAC,EAAE,SAAS,CAAC,QAAQ,MAAO;AACnE,UAAM,UAAU,SAAS,CAAC;AAC1B,QAAI,QAAQ,OAAO;AAClB,UAAI,SAAS,OAAO;AACnB,kBAAUA,EAAC,IAAI,QAAQ;AACvB,iBAASA,EAAC,IAAI,QAAQ;AACtB;AAAA,MACD,OAAO;AACN,kBAAUA,EAAC,IAAI;AAAA,MAChB;AACA;AAAA,IACD;AACA,QAAI,CAAC,QAAS,QAAO;AACrB,cAAUA,EAAC,IAAI,QAAQ;AACvB,aAASA,EAAC,IAAI,QAAQ;AACtB,aAASA,EAAC,IAAI,QAAQ;AACtB;AAAA,EACD;AACA,MAAI,SAAS,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,QAAQ,KAAK,EAAG,QAAO;AAGhE,QAAM,KAAK,OAAO;AAClB,QAAM,QAAQ,IAAI,aAAa,GAAG,MAAM;AACxC,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,IAAK,KAAI,GAAG,CAAC,IAAI,EAAG,QAAO,KAAK,CAAC;AAChE,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,SAAS,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC5D,QAAM,WAAW,OAAO,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC;AACrD,WAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAC1C,QAAI,GAAG,CAAC,IAAI,GAAG;AACd,YAAM,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC;AAC1B;AAAA,IACD;AACA,WAAO,IAAI,OAAO,UAAU,OAAO,CAAC,IAAI,EAAG;AAC3C,UAAM,QAAQ,OAAO,CAAC;AACtB,UAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI;AACrC,QAAI,SAAS,OAAW,OAAM,CAAC,IAAI,KAAK,KAAK,GAAG,KAAK,CAAC;AAAA,aAC7C,UAAU,OAAW,OAAM,CAAC,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC;AAAA,SACtD;AACJ,YAAM,KAAK,IAAI,SAAS,QAAQ;AAChC,YAAM,CAAC,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK,GAAG,KAAK,CAAC,IAAI;AAAA,IACnE;AAAA,EACD;AACA,QAAM,YAAY,KAAK,KAAK,QAAQ;AACpC,QAAM,aAAa,CAAC,QAAwB;AAC3C,UAAM,WAAW,KAAK,IAAI,GAAG,GAAG,IAAI,OAAO;AAC3C,UAAM,OAAO,KAAK,IAAI,MAAM,SAAS,GAAG,KAAK,MAAM,QAAQ,CAAC;AAC5D,UAAM,QAAQ,KAAK,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC;AACjD,UAAM,IAAI,WAAW,KAAK,MAAM,QAAQ;AACxC,YAAQ,MAAM,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,aAAa;AAAA,EACjE;AAGA,QAAM,YAAsB,CAAC;AAC7B,MAAI,SAAS;AACb,WAASA,KAAI,GAAGA,KAAI,SAAS,QAAQA,MAAK;AACzC,cAAU,KAAK,MAAM;AACrB,cAAU,UAAUA,EAAC;AAAA,EACtB;AACA,QAAM,aAAa;AACnB,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,OAAO,IAAI,CAAC;AAC7D,QAAM,QAAQ,IAAI,MAAc,KAAK;AACrC,MAAI,IAAI;AACR,WAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC3C,UAAM,MAAM,QAAQ;AACpB,WAAO,IAAI,IAAI,SAAS,UAAU,OAAO,UAAU,IAAI,CAAC,EAAG;AAC3D,UAAM,QAAQ,SAAS,CAAC;AAExB,QAAI;AACJ,QAAI,UAAU,KAAM,SAAQ,SAAS,MAAM,UAAU,CAAC;AAAA,SACjD;AACJ,YAAM,OAAO,SAAS,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC,UAAU,UAAU,IAAI;AACjE,cAAQ,QAAQ,OAAO,SAAS,GAAG,EAAE,GAAG,YAAY;AAAA,IACrD;AACA,UAAM,KAAK,IAAI;AAAA,MACd,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACA,SAAO;AAAA,IACN,iBAAiB;AAAA,IACjB,YAAY,EAAE,UAAU,SAAS,MAAM;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;;;AC3OA,IAAM,cAAc,oBAAI,IAAI,CAAC,UAAK,UAAK,UAAK,UAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AACpE,IAAM,aAAa,oBAAI,IAAI,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG,CAAC;AAElF,SAASC,YAAW,WAA2B;AAC3C,QAAM,OAAO,UAAU,WAAW,CAAC;AACnC,MAAI,SAAU,QAAQ,QAAQ,OAAQ;AAClC,WAAO,OAAO,aAAa,OAAO,EAAI;AAAA,EAC1C;AACA,SAAO;AACX;AAEA,SAAS,WAAW,SAAiC;AACjD,QAAM,SAAyB,CAAC;AAChC,QAAM,aAAa,QAAQ,UAAU,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,QAAQ,MAAM,EAAE;AAC9E,aAAW,aAAa,YAAY;AAChC,QAAI,KAAK,KAAK,SAAS,KAAK,YAAY,IAAI,SAAS,GAAG;AACpD,UAAI,OAAO,SAAS,KAAK,CAAC,OAAO,OAAO,SAAS,CAAC,EAAE,OAAO;AACvD,eAAO,KAAK,EAAE,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,MACzC;AACA;AAAA,IACJ;AACA,UAAM,OAAOA,YAAW,SAAS;AACjC,QAAI,WAAW,IAAI,IAAI,KAAK,OAAO,SAAS,KAAK,CAAC,OAAO,OAAO,SAAS,CAAC,EAAE,OAAO;AAC/E,aAAO,OAAO,SAAS,CAAC,EAAE,QAAQ;AAAA,IACtC,OAAO;AACH,aAAO,KAAK,EAAE,MAAM,OAAO,MAAM,CAAC;AAAA,IACtC;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,OAAO,UAAkB,QAAyB;AACvD,MAAI,WAAW,EAAG,QAAO,aAAa;AACtC,MAAI,SAAS,EAAG,QAAO,KAAK,YAAY,YAAY;AACpD,SAAO,YAAY;AACvB;AAEO,SAASC,SAAQ,OAAiE;AACrF,QAAM,gBAA0B,CAAC;AACjC,QAAM,SAAyB,CAAC;AAChC,MAAI,QAAQ;AAEZ,SAAO,QAAQ,MAAM,QAAQ;AACzB,UAAM,OAAO,MAAM,KAAK;AACxB,UAAM,iBAAiB,KAAK,QAAQ,IAAI,QAAQ,MAAM,EAAE,EAAE,QAAQ,MAAM,EAAE;AAC1E,QAAI,KAAK,cAAc,KAAK,YAAY,IAAI,KAAK,MAAM,GAAG;AACtD,oBAAc,KAAK,KAAK,UAAU,QAAG;AACrC,UAAI,OAAO,SAAS,KAAK,CAAC,OAAO,OAAO,SAAS,CAAC,EAAE,OAAO;AACvD,eAAO,KAAK,EAAE,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,MACzC;AACA;AACA;AAAA,IACJ;AAEA,UAAM,eAA8D,CAAC;AACrE,WAAO,QAAQ,MAAM,QAAQ;AACzB,YAAM,UAAU,MAAM,KAAK;AAC3B,UAAI,QAAQ,cAAc,KAAK,YAAY,IAAI,QAAQ,MAAM,GAAG;AAC5D;AAAA,MACJ;AACA,UAAI,aAAa,SAAS,KAAK,QAAQ,eAAe,GAAG;AACrD;AAAA,MACJ;AACA,YAAM,yBAAyB,QAAQ,QAAQ,IAAI,QAAQ,MAAM,EAAE,EAAE,QAAQ,MAAM,EAAE;AACrF,YAAM,QAAQ,WAAW,qBAAqB,EAAE,OAAO,UAAQ,CAAC,KAAK,KAAK;AAC1E,mBAAa,KAAK,EAAE,SAAS,MAAM,CAAC;AACpC,oBAAc,KAAK,qBAAqB;AACxC;AAAA,IACJ;AAEA,UAAM,gBAAgB,aAAa,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,MAAM,QAAQ,CAAC;AACnF,UAAM,SAAS,aAAa,CAAC,EAAE,QAAQ,OAAO;AAC9C,QAAI,kBAAkB;AAEtB,eAAW,EAAE,SAAS,MAAM,KAAK,cAAc;AAC3C,eAAS,gBAAgB,GAAG,iBAAiB,MAAM,QAAQ,iBAAiB;AACxE;AACA,eAAO,KAAK;AAAA,UACR,MAAM,MAAM,gBAAgB,CAAC,EAAE;AAAA,UAC/B,OAAO;AAAA,UACP,wBAAwB;AAAA,UACxB,sBAAsB;AAAA,UACtB,gBAAgB;AAAA,UAChB,aAAa,OAAO,iBAAiB,MAAM;AAAA,UAC3C,qBAAqB,oBAAoB;AAAA,UACzC,mBAAmB,oBAAoB;AAAA,UACvC,YAAY,kBAAkB;AAAA,UAC9B,UAAU,kBAAkB,MAAM;AAAA,UAClC,KAAK,QAAQ,OAAO;AAAA,UACpB,YAAY,QAAQ,cAAc;AAAA,QACtC,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AACA,SAAO,EAAE,SAAS,cAAc,KAAK,EAAE,GAAG,UAAU,OAAO;AAC/D;AACO,SAAS,gBAAgB,OAA6C;AACzE,MAAI,MAAM,SAAS,MAAM,2BAA2B,UAAa,MAAM,yBAAyB,UAAa,MAAM,mBAAmB,QAAW;AAC7I,WAAO,CAAC;AAAA,EACZ;AACA,QAAM,gBAAgB,KAAK,IAAI,GAAG,MAAM,oBAAoB;AAC5D,QAAM,kBAAkB,MAAM;AAC9B,QAAM,UAAU,MAAM;AAEtB,QAAM,SAAiC;AAAA,IACnC,mBAAmB,kBAAkB;AAAA,IACrC,oBAAoB,gBAAgB,mBAAmB;AAAA,IACvD,2BAA2B,UAAU;AAAA,IACrC,eAAe,MAAM,cAAc,IAAM;AAAA,IACzC,uBAAuB,MAAM,sBAAsB,IAAM;AAAA,IACzD,qBAAqB,MAAM,oBAAoB,IAAM;AAAA,IACrD,cAAc,MAAM,aAAa,IAAM;AAAA,IACvC,YAAY,MAAM,WAAW,IAAM;AAAA,EACvC;AAEA,SAAO,OAAO,MAAM,OAAO,GAAG,EAAE,IAAI;AACpC,SAAO,cAAc,MAAM,cAAc,GAAG,EAAE,IAAI;AAElD,MAAI,YAAY,GAAG;AACf,WAAO,oBAAoB,IAAI;AAAA,EACnC,WAAW,kBAAkB,SAAS;AAClC,WAAO,oBAAoB,IAAI;AAAA,EACnC,WAAW,oBAAoB,SAAS;AACpC,WAAO,qBAAqB,IAAI;AAAA,EACpC,OAAO;AACH,WAAO,mBAAmB,IAAI;AAAA,EAClC;AAEA,SAAO;AACX;;;AC/GA,IAAM,WAAW;AAGV,SAAS,WAAW,MAAuB;AACjD,SAAO,SAAS,KAAK,KAAK,QAAQ,UAAU,EAAE,CAAC;AAChD;AAEA,SAAS,WAAW,GAAmB;AACtC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACpC,SAAO,IAAI,KAAK,IAAI,IAAI;AACzB;AAOO,SAAS,aACf,SACA,UACA,UAA+B,CAAC,GACnB;AACb,QAAM;AAAA,IACL,WAAW;AAAA,IACX,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,eAAe;AAAA,IACf,UAAU;AAAA,IACV,UAAU;AAAA,EACX,IAAI;AACJ,QAAM,EAAE,UAAU,QAAQ,IAAI,QAAQ;AACtC,QAAM,QAAQ,QAAQ,WAAW,MAAM,MAAM;AAC7C,QAAM,QAAQ,KAAK,IAAI,SAAS,QAAQ,QAAQ,gBAAgB,MAAM;AAGtE,QAAM,aAAuB,CAAC;AAC9B,QAAM,WAAqB,CAAC;AAC5B,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,eAAW,KAAK,SAAS,OAAO;AAChC,cAAU,QAAQ,gBAAgB,CAAC;AACnC,aAAS,KAAK,SAAS,OAAO;AAAA,EAC/B;AACA,QAAM,aAAa,CAAC,MAAgC;AAAA,IACnD,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,QAAQ,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC;AAAA,IAC7D,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,QAAQ,KAAK,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,EAC5D;AAGA,MAAI,YAAY,oBAAoB,GAAG;AACtC,QAAI,OAAO;AACX,aAAS,IAAI,QAAQ,GAAG,KAAK,GAAG,KAAK;AACpC,UAAI,CAAC,SAAS,CAAC,EAAE,OAAO;AACvB,eAAO;AACP;AAAA,MACD;AAAA,IACD;AACA,QAAI,QAAQ,GAAG;AACd,YAAM,CAAC,MAAM,EAAE,IAAI,WAAW,IAAI;AAClC,UAAI,KAAK,MAAM;AACd,cAAM,WAAW,MAAM,KAAK,CAAC,IAAI,MAAM,IAAI;AAC3C,cAAM,YAAY,oBAAoB;AACtC,YAAI,YAAY,GAAG;AAGlB,mBAAS,QAAQ,MAAM,QAAQ,MAAM,QAAQ,SAAS;AACrD,kBAAM,KAAK,QAAQ,SAAS,KAAK;AACjC,kBAAM,KAAK,KAAK,YAAY,YAAY,IAAI,QAAQ,IAAI;AAAA,UACzD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAGA,QAAM,YAAsB,IAAI,MAAM,SAAS,MAAM,EAAE,KAAK,CAAC;AAC7D,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,QAAI,SAAS,CAAC,EAAE,MAAO;AACvB,QAAI,SAAS;AACb,QAAI,wBAAwB,GAAG;AAC9B,YAAM,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC;AAC/B,UAAI,KAAK,MAAM;AACd,YAAI,MAAM;AACV,iBAAS,QAAQ,MAAM,QAAQ,IAAI,QAAS,QAAO,MAAM,KAAK;AAC9D,kBAAW,OAAO,KAAK,QAAQ,MAAO;AAAA,MACvC;AAAA,IACD;AACA,QAAI,OAAO,OAAO,SAAS;AAC3B,QAAI,QAAQ,SAAS,CAAC,EAAG,SAAQ;AACjC,cAAU,CAAC,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,IAAI,CAAC;AAAA,EACzD;AAEA,SAAO;AAAA,IACN,GAAG;AAAA,IACH,YAAY,EAAE,UAAU,SAAS,MAAM;AAAA,IACvC;AAAA,EACD;AACD;;;ACmCO,SAAS,oBAAoB,UAAkC;AACrE,SAAO,SAAS,IAAI,CAAC,UAAW,MAAM,QAAQ,WAAM,MAAM,IAAK,EAAE,KAAK,EAAE;AACzE;AAEA,IAAM,KAAK;AACX,IAAMC,eAAc,CAAC,OAAuB,KAAK,MAAO,KAAK,MAAQ,EAAE;AAGvE,SAAS,KAAK,UAA2B,KAAqB;AAC7D,QAAM,QAAQ,SAAS;AACvB,MAAI,MAAM,WAAW,EAAG,QAAO,SAAS,gBAAgB;AACxD,QAAM,WAAW,KAAK,IAAI,GAAG,GAAG,IAAI,SAAS;AAC7C,QAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,MAAI,QAAQ,MAAM,SAAS,EAAG,QAAO,MAAM,MAAM,SAAS,CAAC;AAC3D,QAAM,WAAW,WAAW;AAC5B,SAAO,MAAM,IAAI,KAAK,IAAI,YAAY,MAAM,OAAO,CAAC,IAAI;AACzD;AAkBA,SAAS,eAAe,MAAmB,OAAuB;AACjE,QAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,QAAM,UAAU,KAAK,gBAAgB,CAAC;AACtC,QAAM,UAAU,MAAM,WAAW,MAAM;AACvC,QAAM,SAAS,CAAC,SAAsC;AACrD,QAAI,QAAS,QAAO,KAAK;AACzB,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,IAAI,MAAM,QAAQ,KAAK;AAC5D,UAAI,QAAQ,CAAC,EAAE,WAAW,KAAK,gBAAgB,KAAM,SAAQ;AAAA,UACxD;AAAA,IACN;AACA,WAAO;AAAA,EACR;AACA,aAAW,QAAQ,KAAK,SAAS,OAAO;AACvC,UAAM,QAAQ,OAAO,IAAI;AACzB,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,QAAQ,KAAK,SAAS,UAAa,CAAC,OAAO,SAAS,IAAI,EAAG;AAC/D,SAAK,UAAU;AAAA,EAChB;AACD;AAMA,SAAS,WACR,OACA,iBACA,YACe;AACf,QAAM,SAAuB,CAAC;AAC9B,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,QAAQ;AACZ,MAAI,eAAe,MAAM,CAAC,EAAE,cAAc,MAAM,CAAC,EAAE;AACnD,MAAI,WAAW;AACf,WAAS,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK;AACvC,UAAM,QAAQ,OAAO,WAAW,IAAI,kBAAkB;AACtD,UAAM,QAAQ,MAAM,MAAM;AAC1B,UAAM,QAAQ,CAAC,SAAS,MAAM,CAAC,EAAE,eAAe,eAAe;AAC/D,UAAM,OAAO,CAAC,SAAS,IAAI,SAAS;AACpC,QAAI,SAAS,SAAS,MAAM;AAC3B,YAAM,WAAW,CAAC,SAAS,CAAC;AAC5B,aAAO,KAAK,EAAE,OAAO,KAAK,GAAG,UAAU,SAAS,CAAC;AACjD,cAAQ;AACR,iBAAW;AACX,UAAI,CAAC,MAAO,gBAAe,MAAM,CAAC,EAAE,cAAc,MAAM,CAAC,EAAE;AAC3D;AAAA,IACD;AACA,mBAAe,KAAK;AAAA,MACnB;AAAA,MACA,MAAM,CAAC,EAAE,cAAc,MAAM,CAAC,EAAE;AAAA,IACjC;AAAA,EACD;AACA,SAAO;AACR;AAMA,SAAS,WAAW,MAA2B,aAA6B;AAC3E,QAAM,WAAW,KAAK,cAAc,KAAK,aAAa,cAAc;AACpE,QAAM,SAAS,KAAK,cAAc,KAAK,YAAY,cAAc;AACjE,SAAO,KAAK;AAAA,IACX;AAAA,IACA,KAAK,IAAI,KAAK,cAAc,cAAc,GAAG,MAAM;AAAA,EACpD;AACD;AAEA,SAAS,UACR,KACA,YACA,SACA,QACO;AACP,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,IAAI,SAAS,UAAU,CAAC;AAChE,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,UAAM,KAAK,IAAI,OAAO;AACtB,UAAM,OAAO,SACV,KAAK,IAAK,KAAK,KAAK,IAAK,CAAC,IAC1B,KAAK,IAAK,KAAK,KAAK,IAAK,CAAC;AAC7B,QAAI,aAAa,CAAC,KAAK;AAAA,EACxB;AACD;AAkBO,IAAM,iBAAN,MAAM,gBAAe;AAAA,EAM3B,YAAoB,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EALpB,OAAe,UAAyB;AAAA,EAChC,cAAc,oBAAI,QAA2B;AAAA,EAC7C,cAAgC;AAAA,EAChC,WAAW,oBAAI,IAA0C;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjE,aAAa,eACZ,UAAU,gBACV,UAA0D,CAAC,GAC3C;AAChB,QAAI,OAAO,iBAAiB,WAAY;AACxC,QAAI,OAAO,OAAO,aAAa;AAC9B,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,UAAM,KAAK,IAAI,GAAG;AAClB,UAAM,mBAAmB,QAAQ,SAAS,OAAO,OAAO;AACxD,QAAI;AACJ,QAAI;AACH,kBACC,MAAM,YAAY,qBAAqB,iBAAiB,GAAG,YAAY,GACtE;AAAA,IACH,QAAQ;AAEP,YAAM,QAAQ,OACb,OAAO,QAAQ,SAAS,OAAO,OAAO,GACrC,YAAY;AACd,kBAAY,MAAM,YAAY,YAAY,OAAO,GAAG,YAAY,GAC9D;AAAA,IACH;AACA,SAAK,GAAG,IAAI,QAAQ;AACpB,aACK,UAAU,GACd,UAAU,OAAO,OAAO,iBAAiB,YACzC,WACC;AACD,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,IACvD;AACA,QAAI,OAAO,iBAAiB,YAAY;AACvC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACrE;AAAA,EACD;AAAA,EAEA,WAAW,QAAiB;AAC3B,WAAO,OAAO,iBAAiB;AAAA,EAChC;AAAA;AAAA,EAGA,OAAO,SAAS,WAAkC;AACjD,oBAAe,YAAY;AAC3B,UAAM,SAAS,kBAAkB,SAAS;AAC1C,QAAI,CAAC,OAAO;AACX,YAAM,IAAI,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACvD,oBAAe,UAAU,OAAO,MAAM;AACtC,WAAO,gBAAe;AAAA,EACvB;AAAA,EAEA,WAAW,iBAAgC;AAC1C,WAAO,gBAAe;AAAA,EACvB;AAAA,EAEA,OAAe,cAAoB;AAClC,QAAI,OAAO,iBAAiB,YAAY;AACvC,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAuB;AAC9B,oBAAe,YAAY;AAC3B,QAAI,KAAK,gBAAgB,QAAQ,KAAK,YAAY,IAAI,IAAI,EAAG;AAC7D,UAAM,UAAqC,CAAC;AAC5C,UAAM,QAAgC,CAAC;AACvC,eAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACtE,cAAQ,KAAK,IAAI;AAAA,QAChB;AAAA,UACC,UAAU,OAAO,KAAK;AAAA,UACtB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,OAAO,QAAQ,YAAY;AAAA,UAC3B,OAAO;AAAA,UACP,cAAc,QAAQ,MAAM;AAAA,UAC5B,SAAS,QAAQ,UAAU;AAAA,UAC3B,aAAa;AAAA,QACd;AAAA,MACD;AACA,UAAI,QAAQ,QAAQ,EAAG,OAAM,KAAK,IAAI,QAAQ;AAAA,IAC/C;AACA,UAAM,SAAS;AAAA,MACd,KAAK,UAAU;AAAA,QACd,MAAM;AAAA,QACN,aAAa;AAAA,QACb,iBAAiB;AAAA,MAClB,CAAC;AAAA,IACF;AACA,QAAI,CAAC,OAAO,QAAS,OAAM,IAAI,MAAM,uBAAuB,OAAO,KAAK,EAAE;AAC1E,SAAK,YAAY,IAAI,MAAM,OAAO,WAAW,CAAC;AAC9C,SAAK,cAAc;AACnB,SAAK,SAAS,MAAM;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KACC,MACA,MACA,UACA,UAA0B,CAAC,GACb;AACd,SAAK,QAAQ,IAAI;AACjB,UAAM,UAAU;AAAA,MACf;AAAA,MACA,SAAS,oBAAoB,QAAQ;AAAA,MACrC,QAAQ,SAAS,IAAI,CAAC,UAAU,gBAAgB,KAAK,CAAC;AAAA,MACtD,MAAM,QAAQ,QAAQ;AAAA,MACtB,kBAAkB,QAAQ,kBAAkB;AAAA,MAC5C,mBAAmB,QAAQ,mBAAmB;AAAA,MAC9C,YAAY,QAAQ,aAAa;AAAA,MACjC,yBAAyB,QAAQ,yBAAyB;AAAA,MAC1D,aAAa,QAAQ,cAAc;AAAA,MACnC,qBAAqB,QAAQ,sBAAsB;AAAA,MACnD,eAAe,QAAQ,gBAAgB;AAAA,MACvC,wBAAwB,QAAQ,wBAAwB;AAAA,MACxD,mBAAmB,QAAQ,SAAS;AAAA,MACpC,aAAa,QAAQ,SAAS;AAAA,IAC/B;AACA,UAAM,WAAW,aAAa,KAAK,UAAU,OAAO,CAAC;AACrD,QAAI,CAAC,SAAS,WAAW,CAAC,SAAS,MAAM;AACxC,YAAM,IAAI,MAAM,kBAAkB,SAAS,SAAS,SAAS,EAAE;AAAA,IAChE;AACA,UAAM,OAAO,KAAK,MAAM,SAAS,IAAI;AACrC,UAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAI,MAAO,gBAAe,MAAM,KAAK;AACrC,WAAO;AAAA,EACR;AAAA,EAEQ,OAAO,MAAiB,OAA6C;AAC5E,QAAI,SAAS,KAAK,SAAS,IAAI,KAAK;AACpC,QAAI,CAAC,QAAQ;AACZ,eAAS,KAAK,OAAO,KAAK;AAC1B,WAAK,SAAS,IAAI,OAAO,MAAM;AAAA,IAChC;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,aACN,MACA,MACA,UAAgC,CAAC,GACF;AAC/B,UAAM;AAAA,MACL,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB;AAAA,IACD,IAAI;AACJ,UAAM,WAAW,KAAK;AACtB,UAAM,QAAQ,SAAS,MAAM,OAAO,CAAC,SAAS,KAAK,YAAY,CAAC;AAChE,UAAM,SAAS;AAAA,MACd;AAAA,MACA,KAAK,IAAI,GAAG,eAAe;AAAA,MAC3B,KAAK,IAAI,GAAG,UAAU;AAAA,IACvB;AACA,UAAM,mBAAmB,KAAK,IAAI,GAAGA,aAAY,eAAe,CAAC;AAEjE,aAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS;AACnD,UAAI,QAAQ,QAAS;AACrB,YAAM,QAAQ,OAAO,KAAK;AAC1B,YAAM,cAAc,MAAM,WAAW,MAAM,QAAQ,IAAI,MAAM;AAC7D,YAAM,YAAY,MAAM,WAAW,MAAM,MAAM,IAAI,MAAM;AACzD,YAAM,WAAW,MAAM,MAAM,aAAa,SAAS;AACnD,YAAM,SAAS,KAAK,IAAI,GAAG,SAAS,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC;AAEnE,YAAM,cAA4B,CAAC;AACnC,iBAAW,QAAQ,UAAU;AAC5B,cAAMC,OAAM,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;AAC9C,YAAI,CAACA,QAAOA,KAAI,SAAS,uBAAuB;AAC/C,kBAAQ;AAAA,YACP,sCAAsC,KAAK,KAAK;AAAA,UACjD;AACA;AAAA,QACD;AACA,oBAAY,KAAK;AAAA,UAChB,KAAAA;AAAA,UACA,OAAO,KAAK,cAAc;AAAA,UAC1B,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK;AAAA,UAClB,kBAAkB,KAAK;AAAA,UACvB,QAAQ,KAAK;AAAA,UACb,MAAM,KAAK;AAAA,QACZ,CAAC;AAAA,MACF;AACA,UAAI,QAAQ,QAAS;AACrB,UAAI,YAAY,WAAW,EAAG;AAE9B,YAAM,QAAQ,KAAK,UAAU,aAAa;AAAA,QACzC,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,KAAK,UAAU,SAAS,GAAG;AAAA,QAC3C,QAAQ,QAAQ;AAAA,QAChB,SAAS,QAAQ;AAAA,QACjB,aAAa,QAAQ;AAAA,QACrB,SAAS,QAAQ;AAAA,MAClB,CAAC;AACD,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAGlC,UAAI,aAAa;AACjB,UAAI,WAAW,MAAM;AACrB,UAAI,UAAU;AACd,UAAI,MAAM,UAAU;AACnB,cAAM,SAAS,WAAW,MAAM,MAAM,KAAK,GAAG,eAAe;AAC7D,qBAAa,KAAK;AAAA,UACjB;AAAA,UACAD,aAAY,SAAS,MAAM,IAAI,mBAAmB;AAAA,QACnD;AACA,kBAAU,SAAU,aAAa,KAAM;AAAA,MACxC;AACA,UAAI,MAAM,UAAU;AACnB,cAAM,SAAS,WAAW,MAAM,MAAM,GAAG,GAAG,eAAe;AAC3D,mBAAW,KAAK;AAAA,UACf,MAAM;AAAA,UACNA,aAAY,SAAS,MAAM,IAAI,mBAAmB;AAAA,QACnD;AAAA,MACD;AACA,UAAI,YAAY,WAAY;AAC5B,YAAM,MAAM,MAAM,MAAM,YAAY,QAAQ;AAC5C,UAAI,MAAM,SAAU,WAAU,KAAK,GAAG,kBAAkB,IAAI;AAC5D,UAAI,MAAM;AACT;AAAA,UACC;AAAA,UACA,KAAK,IAAI,GAAG,IAAI,SAAS,gBAAgB;AAAA,UACzC;AAAA,UACA;AAAA,QACD;AAED,YAAM,EAAE,KAAK,SAAS,OAAO,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,GAAG,EAAE;AAExE,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,IACtD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACL,MACA,MACA,UACA,UAAiD,CAAC,GACnB;AAC/B,UAAM,OAAO,KAAK,KAAK,MAAM,MAAM,UAAU,OAAO;AACpD,UAAM,QAAQA,aAAY,KAAK,SAAS,WAAW,IAAIA,aAAY,GAAG;AACtE,UAAM,MAAM,IAAI,aAAa,KAAK;AAClC,QAAI,MAAM;AACV,qBAAiB,SAAS,KAAK,aAAa,MAAM,MAAM,OAAO,GAAG;AACjE,YAAM;AACN,YAAM,SAASA,aAAY,MAAM,OAAO;AACxC,YAAM,IAAI,KAAK,IAAI,MAAM,IAAI,QAAQ,IAAI,SAAS,MAAM;AACxD,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,SAAS,CAAC,KAAK,MAAM,IAAI,CAAC;AAAA,IAC3D;AACA,WAAO,MAAM,MAAM;AAAA,EACpB;AACD;","names":["num","l","_a","_b","i","_a","_a","fl","_a","_a","FS","clamp","near","err","entries","total","max","f","toHiragana","analyze","msToSamples","pcm"]}
1
+ {"version":3,"sources":["../src/converter/frq.ts","../src/converter/pitch.ts","../src/converter/pack.ts","../src/converter/parse-oto.ts","../src/converter/wav.ts","../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js","../src/converter/zip.ts","../src/koe.ts","../src/engine/voice-bank.ts","../src/engine/index.ts","../src/engine/worldline.ts","../src/oto/frames.ts","../src/oto/estimate.ts","../src/oto/kana.ts","../src/oto/generate.ts","../src/oto/write.ts","../src/utautts/assets.ts","../src/utautts/hts.ts","../src/utautts/openjtalk_features.ts","../src/utautts/prosody_rules.ts","../src/utautts/style.ts","../src/utautts/UtauTTSAdapter.ts"],"sourcesContent":["/**\r\n * UTAU `.frq` frequency-analysis files (FREQ0003). The same format OpenUtau\r\n * reads: an 8-byte header, hop size, the average fundamental frequency of the\r\n * whole recording, then a per-frame f0 / amplitude curve.\r\n *\r\n * Layout:\r\n * char[8] \"FREQ0003\"\r\n * int32 hopSize ← in ORIGINAL WAV samples\r\n * float64 averageF0 ← whole-file average in Hz\r\n * byte[16] (blank)\r\n * int32 length\r\n * { float64 f0, float64 amp } × length\r\n */\r\n\r\nconst HEADER_SIZE = 40;\r\n\r\nexport interface FrqData {\r\n\t/** Analysis hop in samples of the ORIGINAL wav (not the 48 kHz conversion) */\r\n\thopSize: number;\r\n\t/** Whole-file average f0 in Hz, as stored in the header */\r\n\taverageF0: number;\r\n\t/** Per-frame f0 in Hz — 0 where the analyser found no clear pitch */\r\n\tf0: Float64Array;\r\n\t/** Per-frame amplitude, parallel to {@link f0} */\r\n\tamp: Float64Array;\r\n}\r\n\r\n/** Parse a `.frq` file, including the per-frame curve. Null if not FREQ0003. */\r\nexport function parseFrq(buffer: ArrayBuffer): FrqData | null {\r\n\tif (buffer.byteLength < HEADER_SIZE) return null;\r\n\tconst view = new DataView(buffer);\r\n\r\n\tlet header = \"\";\r\n\tfor (let i = 0; i < 8; i++) header += String.fromCharCode(view.getUint8(i));\r\n\tif (header !== \"FREQ0003\") return null;\r\n\r\n\tconst hopSize = view.getInt32(8, true);\r\n\tconst averageF0 = view.getFloat64(12, true); // little-endian\r\n\tconst declared = view.getInt32(36, true);\r\n\t// Trust the file's actual size over the declared count — truncated frq files\r\n\t// are common enough that reading past the buffer must not throw.\r\n\tconst available = Math.floor((buffer.byteLength - HEADER_SIZE) / 16);\r\n\tconst length = Math.max(0, Math.min(declared, available));\r\n\r\n\tconst f0 = new Float64Array(length);\r\n\tconst amp = new Float64Array(length);\r\n\tfor (let i = 0; i < length; i++) {\r\n\t\tconst p = HEADER_SIZE + i * 16;\r\n\t\tf0[i] = view.getFloat64(p, true);\r\n\t\tamp[i] = view.getFloat64(p + 8, true);\r\n\t}\r\n\r\n\treturn {\r\n\t\thopSize: hopSize > 0 ? hopSize : 256,\r\n\t\taverageF0: Number.isFinite(averageF0) && averageF0 > 0 ? averageF0 : 0,\r\n\t\tf0,\r\n\t\tamp,\r\n\t};\r\n}\r\n\r\n/**\r\n * Average f0 over the voiced frames covering a time span of the recording.\r\n *\r\n * The header's whole-file average includes leading silence and unvoiced\r\n * consonants, so it can sit well away from the pitch actually sounding in the\r\n * region a note is built from. Playback resamples the whole phoneme by one\r\n * scalar ratio, so an inaccurate value both detunes the note and makes two\r\n * crossfading notes drift apart in phase across the overlap — a 1% error at\r\n * 233 Hz drifts ~25° over a 30 ms overlap and ~84° over 100 ms.\r\n *\r\n * @param startMs / endMs span within the ORIGINAL recording, in milliseconds\r\n * @param sourceRate sample rate of the original WAV the frq describes\r\n * @returns Hz, or 0 when the span holds no voiced frames\r\n */\r\nexport function frqAverageF0InRange(\r\n\tfrq: FrqData,\r\n\tstartMs: number,\r\n\tendMs: number,\r\n\tsourceRate: number,\r\n): number {\r\n\tif (!(sourceRate > 0) || frq.f0.length === 0) return 0;\r\n\tconst perFrameMs = (frq.hopSize / sourceRate) * 1000;\r\n\tif (!(perFrameMs > 0)) return 0;\r\n\r\n\tconst first = Math.max(0, Math.floor(startMs / perFrameMs));\r\n\tconst last = Math.min(frq.f0.length - 1, Math.ceil(endMs / perFrameMs));\r\n\r\n\t// Amplitude-weighted so quiet fringe frames (a decaying tail, a breath)\r\n\t// don't pull the average away from the body of the vowel.\r\n\tlet num = 0;\r\n\tlet den = 0;\r\n\tfor (let i = first; i <= last; i++) {\r\n\t\tconst hz = frq.f0[i];\r\n\t\tif (!(hz > 0)) continue; // unvoiced / undetected\r\n\t\tconst w = frq.amp[i] > 0 ? frq.amp[i] : 1;\r\n\t\tnum += hz * w;\r\n\t\tden += w;\r\n\t}\r\n\treturn den > 0 ? num / den : 0;\r\n}\r\n\r\n/** Whole-file average f0 in Hz from a `.frq` file, or null. */\r\nexport function parseFrqAverageF0(buffer: ArrayBuffer): number | null {\r\n\tconst frq = parseFrq(buffer);\r\n\treturn frq && frq.averageF0 > 0 ? frq.averageF0 : null;\r\n}\r\n\r\n/** Map a WAV filename to its sibling frq filename: \"あ.wav\" → \"あ_wav.frq\". */\r\nexport function frqFileName(wavName: string): string {\r\n\tconst dot = wavName.lastIndexOf(\".\");\r\n\tconst base = dot >= 0 ? wavName.slice(0, dot) : wavName;\r\n\tconst ext = dot >= 0 ? wavName.slice(dot + 1) : \"wav\";\r\n\treturn `${base}_${ext}.frq`;\r\n}\r\n","const SAMPLE_RATE = 48000;\n\nconst NAME_SEMITONE: Record<string, number> = {\n\tc: 0,\n\td: 2,\n\te: 4,\n\tf: 5,\n\tg: 7,\n\ta: 9,\n\tb: 11,\n};\n\n/** Parse a note name like \"E4\", \"G#4\", \"Db5\" → frequency in Hz (null if invalid). */\nexport function noteNameToHz(name: string): number | null {\n\tconst m = /^([A-Ga-g])([#b]?)(-?\\d+)$/.exec(name);\n\tif (!m) return null;\n\tlet semi = NAME_SEMITONE[m[1].toLowerCase()];\n\tif (m[2] === \"#\") semi++;\n\telse if (m[2] === \"b\") semi--;\n\tconst midi = (parseInt(m[3], 10) + 1) * 12 + semi;\n\treturn 440 * 2 ** ((midi - 69) / 12);\n}\n\n/** Recorded pitch encoded in a multi-pitch alias suffix: \"a い_E4\" → 329.63 Hz. */\nexport function pitchFromAliasSuffix(alias: string): number | null {\n\tconst m = /_([A-Ga-g][#b]?-?\\d+)$/.exec(alias);\n\treturn m ? noteNameToHz(m[1]) : null;\n}\n\n/**\n * Estimate the fundamental frequency (Hz) of a voiced region by normalized\n * autocorrelation. Returns 0 when no clear pitch is found (unvoiced consonant,\n * silence, or a region too short to analyse).\n *\n * The signal is decimated to a lower analysis rate for speed; f0 below ~700 Hz\n * is well within the resulting Nyquist limit. A parabolic interpolation around\n * the best lag gives sub-sample (sub-semitone) accuracy.\n */\nexport function detectF0(pcm: Int16Array, start: number, end: number): number {\n\tconst DECIM = 4;\n\tconst sr = SAMPLE_RATE / DECIM; // 12 kHz analysis rate\n\tconst minLag = Math.floor(sr / 700); // highest f0 we look for\n\tconst maxLag = Math.floor(sr / 70); // lowest f0 we look for\n\n\tconst outLen = Math.floor((end - start) / DECIM);\n\tif (outLen < maxLag + 2) return 0;\n\tconst win = Math.min(outLen, 1500); // up to ~0.125 s of vowel\n\n\t// Decimate (box-average) + remove DC, and build a prefix sum of squares so\n\t// each lag's window energy is O(1).\n\tconst buf = new Float32Array(win);\n\tlet mean = 0;\n\tfor (let i = 0; i < win; i++) {\n\t\tlet s = 0;\n\t\tconst base = start + i * DECIM;\n\t\tfor (let j = 0; j < DECIM; j++) s += pcm[base + j];\n\t\tbuf[i] = s;\n\t\tmean += s;\n\t}\n\tmean /= win;\n\n\tconst sq = new Float64Array(win + 1);\n\tfor (let i = 0; i < win; i++) {\n\t\tbuf[i] -= mean;\n\t\tsq[i + 1] = sq[i] + buf[i] * buf[i];\n\t}\n\tif (sq[win] < 1) return 0; // effectively silent\n\n\t// Normalized autocorrelation: 2·r(lag) / (E[0..n] + E[lag..lag+n]) ∈ [-1, 1].\n\tconst norm = (lag: number): number => {\n\t\tconst n = win - lag;\n\t\tlet r = 0;\n\t\tfor (let i = 0; i < n; i++) r += buf[i] * buf[i + lag];\n\t\tconst e = sq[n] + (sq[lag + n] - sq[lag]);\n\t\treturn e > 0 ? (2 * r) / e : 0;\n\t};\n\n\tlet bestLag = -1;\n\tlet best = 0;\n\tfor (let lag = minLag; lag <= maxLag; lag++) {\n\t\tconst v = norm(lag);\n\t\tif (v > best) {\n\t\t\tbest = v;\n\t\t\tbestLag = lag;\n\t\t}\n\t}\n\tif (bestLag < 1 || best < 0.4) return 0; // unvoiced / no clear period\n\n\t// Parabolic interpolation around the peak\n\tconst y0 = norm(bestLag - 1);\n\tconst y1 = best;\n\tconst y2 = norm(bestLag + 1);\n\tconst denom = y0 - 2 * y1 + y2;\n\tconst shift = denom !== 0 ? (0.5 * (y0 - y2)) / denom : 0;\n\n\treturn sr / (bestLag + shift);\n}\n","import type { Manifest, PhonemeEntry } from \"../types.js\";\r\nimport type { OtoEntry } from \"./parse-oto.js\";\r\nimport { detectF0 } from \"./pitch.js\";\r\n\r\nconst TARGET_RATE = 48000;\r\n\r\nfunction msToSamples(ms: number): number {\r\n\treturn Math.round((ms / 1000) * TARGET_RATE);\r\n}\r\n\r\nconst clamp = (v: number, lo: number, hi: number) =>\r\n\tMath.max(lo, Math.min(hi, v));\r\n\r\nexport interface PackInput {\r\n\toto: OtoEntry;\r\n\t/** Full PCM of the source WAV (48kHz / 16bit / mono) */\r\n\tpcm: Int16Array;\r\n\t/** Known recorded pitch in Hz (e.g. from the .frq file). 0/undefined → auto-detect. */\r\n\trecordedPitch?: number;\r\n}\r\n\r\nexport interface PackOutput {\r\n\tmanifest: Manifest;\r\n\t/** Raw PCM blob — Int16 / 48kHz / mono */\r\n\tbin: ArrayBuffer;\r\n}\r\n\r\nexport interface TrimmedPhoneme {\r\n\t/** PCM trimmed to the oto region [offset, cutoff] */\r\n\tpcm: Int16Array;\r\n\t/** Manifest params relative to the trimmed start (sample 0 = oto offset) */\r\n\tentry: Omit<PhonemeEntry, \"offset\">;\r\n}\r\n\r\n/**\r\n * Resolve an oto entry's usable region within the full 48 kHz PCM.\r\n *\r\n * Shared with the converter CLI, which needs the same bounds to look up the\r\n * region's local f0 in a `.frq` curve.\r\n */\r\nexport function otoRegion(\r\n\tpcmLength: number,\r\n\toto: OtoEntry,\r\n): { start: number; end: number } {\r\n\tconst start = clamp(msToSamples(oto.offset), 0, pcmLength);\r\n\tconst end =\r\n\t\toto.cutoff < 0\r\n\t\t\t? clamp(start + msToSamples(-oto.cutoff), start, pcmLength)\r\n\t\t\t: clamp(pcmLength - msToSamples(oto.cutoff), start, pcmLength);\r\n\treturn { start, end };\r\n}\r\n\r\n/**\r\n * Remove the DC offset from a phoneme slice, returning an independent copy.\r\n *\r\n * A sample sitting off-centre cannot be crossfaded cleanly no matter how well\r\n * the phase is aligned: the two constant offsets simply add, so the seam gets a\r\n * step in its mean. Centring each phoneme at pack time is the only place this\r\n * can be fixed cheaply, and it is a precondition for the playback-side phase\r\n * alignment to actually deliver a flat crossfade.\r\n *\r\n * The copy is required as well as convenient — several oto entries routinely\r\n * point into the same source WAV, so the slices must not share storage.\r\n */\r\nfunction centerSlice(slice: Int16Array): Int16Array {\r\n\tconst out = new Int16Array(slice.length);\r\n\tif (slice.length === 0) return out;\r\n\r\n\tlet sum = 0;\r\n\tfor (let i = 0; i < slice.length; i++) sum += slice[i];\r\n\tconst dc = Math.round(sum / slice.length);\r\n\r\n\tfor (let i = 0; i < slice.length; i++) {\r\n\t\tout[i] = clamp(slice[i] - dc, -32768, 32767);\r\n\t}\r\n\treturn out;\r\n}\r\n\r\n/**\r\n * Cut the full WAV PCM down to its usable oto region and recompute parameters\r\n * relative to the trimmed start.\r\n *\r\n * UTAU oto.ini values are all in ms and measured from `offset` (the left blank),\r\n * except `cutoff` (right blank):\r\n * - cutoff >= 0 : measured from the END of the file\r\n * - cutoff < 0 : region length from offset = |cutoff|\r\n *\r\n * After trimming, sample 0 == oto offset, so pre/overlap/consonant carry over\r\n * unchanged (just converted to samples), and the slice length is the region end.\r\n */\r\nexport function trimToOto(\r\n\tpcm: Int16Array,\r\n\toto: OtoEntry,\r\n\trecordedPitch = 0,\r\n): TrimmedPhoneme {\r\n\tconst { start, end } = otoRegion(pcm.length, oto);\r\n\r\n\t// Centre the slice: the stored PCM is what playback crossfades, so the DC\r\n\t// offset has to go before it is written to voice.bin.\r\n\tconst slice = centerSlice(pcm.subarray(start, end));\r\n\tconst length = slice.length;\r\n\r\n\tconst pre = clamp(msToSamples(oto.pre), 0, length);\r\n\tconst overlap = clamp(msToSamples(oto.overlap), 0, length);\r\n\tconst consonant = clamp(msToSamples(oto.consonant), 0, length);\r\n\r\n\t// Prefer the known recorded pitch (from the .frq file or alias suffix); only\r\n\t// fall back to autocorrelation on the sustained vowel when none is available.\r\n\tconst pitch =\r\n\t\trecordedPitch > 0\r\n\t\t\t? recordedPitch\r\n\t\t\t: detectF0(\r\n\t\t\t\t\tslice,\r\n\t\t\t\t\tMath.min(Math.max(pre, consonant), Math.max(0, length - 1)),\r\n\t\t\t\t\tlength,\r\n\t\t\t\t);\r\n\r\n\treturn {\r\n\t\tpcm: slice,\r\n\t\tentry: { length, pre, overlap, consonant, pitch },\r\n\t};\r\n}\r\n\r\n/**\r\n * Pack phonemes into voice.bin + manifest.json.\r\n * Each phoneme is trimmed to its oto region and DC-centred first.\r\n * Duplicate aliases are silently overwritten by the later entry.\r\n */\r\nexport function pack(inputs: PackInput[], referencePitch = 220): PackOutput {\r\n\tconst phonemes: Record<string, PhonemeEntry> = {};\r\n\tconst chunks: Int16Array[] = [];\r\n\tlet byteOffset = 0;\r\n\r\n\tfor (const { oto, pcm, recordedPitch } of inputs) {\r\n\t\tconst { pcm: slice, entry } = trimToOto(pcm, oto, recordedPitch);\r\n\t\tif (slice.length === 0) continue;\r\n\r\n\t\tphonemes[oto.alias] = { offset: byteOffset, ...entry };\r\n\t\tbyteOffset += slice.byteLength;\r\n\t\tchunks.push(slice);\r\n\t}\r\n\r\n\tconst bin = new ArrayBuffer(byteOffset);\r\n\tconst view = new Uint8Array(bin);\r\n\tlet pos = 0;\r\n\tfor (const chunk of chunks) {\r\n\t\tview.set(\r\n\t\t\tnew Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength),\r\n\t\t\tpos,\r\n\t\t);\r\n\t\tpos += chunk.byteLength;\r\n\t}\r\n\r\n\tconst manifest: Manifest = {\r\n\t\tsampleRate: 48000,\r\n\t\treferencePitch,\r\n\t\tphonemes,\r\n\t};\r\n\r\n\treturn { manifest, bin };\r\n}\r\n","export interface OtoEntry {\n\t/** Source WAV filename */\n\twav: string;\n\t/** Phoneme alias */\n\talias: string;\n\t/** Left blank — offset from WAV start (ms) */\n\toffset: number;\n\t/** Consonant portion end from offset (ms) */\n\tconsonant: number;\n\t/** Right blank — negative = from WAV end, positive = from offset (ms) */\n\tcutoff: number;\n\t/** Preutterance from offset (ms) */\n\tpre: number;\n\t/** Overlap / crossfade region (ms) */\n\toverlap: number;\n}\n\n/**\n * Parse oto.ini content (already decoded to UTF-8 string).\n * Silently skips malformed lines.\n */\nexport function parseOto(content: string): OtoEntry[] {\n\tconst entries: OtoEntry[] = [];\n\n\tfor (const raw of content.split(/\\r?\\n/)) {\n\t\tconst line = raw.trim();\n\t\tif (!line || line.startsWith(\"#\")) continue;\n\n\t\tconst eq = line.indexOf(\"=\");\n\t\tif (eq === -1) continue;\n\n\t\tconst wav = line.slice(0, eq).trim();\n\t\tconst parts = line.slice(eq + 1).split(\",\");\n\t\tif (parts.length < 6) continue;\n\n\t\tconst [alias, offsetStr, consonantStr, cutoffStr, preStr, overlapStr] =\n\t\t\tparts;\n\t\t// Empty alias → use filename without extension (UTAU spec default)\n\t\tconst aliasStr = alias.trim() || wav.replace(/\\.[^.]+$/, \"\");\n\t\tconst entry: OtoEntry = {\n\t\t\twav,\n\t\t\talias: aliasStr,\n\t\t\toffset: parseFloat(offsetStr) || 0,\n\t\t\tconsonant: parseFloat(consonantStr) || 0,\n\t\t\tcutoff: parseFloat(cutoffStr) || 0,\n\t\t\tpre: parseFloat(preStr) || 0,\n\t\t\toverlap: parseFloat(overlapStr) || 0,\n\t\t};\n\n\t\tif (!entry.alias) continue;\n\t\tentries.push(entry);\n\t}\n\n\treturn entries;\n}\n","export interface WavData {\r\n\tsampleRate: number;\r\n\tchannels: number;\r\n\t/** Normalized samples in [-1, 1], interleaved if multi-channel */\r\n\tsamples: Float32Array;\r\n}\r\n\r\n/** Parse a WAV file from an ArrayBuffer. Supports PCM 8/16/24-bit and IEEE float 32-bit. */\r\nexport function parseWav(buf: ArrayBuffer): WavData {\r\n\tconst view = new DataView(buf);\r\n\r\n\tconst riff = readFourCC(view, 0);\r\n\tif (riff !== \"RIFF\") throw new Error(`Not a RIFF file (got \"${riff}\")`);\r\n\r\n\tlet sampleRate = 0;\r\n\tlet channels = 0;\r\n\tlet bitsPerSample = 0;\r\n\tlet audioFormat = 1;\r\n\tlet dataOffset = 0;\r\n\tlet dataLength = 0;\r\n\r\n\tlet pos = 12;\r\n\twhile (pos < view.byteLength - 8) {\r\n\t\tconst id = readFourCC(view, pos);\r\n\t\tconst size = view.getUint32(pos + 4, true);\r\n\t\tpos += 8;\r\n\r\n\t\tif (id === \"fmt \") {\r\n\t\t\taudioFormat = view.getUint16(pos, true);\r\n\t\t\tchannels = view.getUint16(pos + 2, true);\r\n\t\t\tsampleRate = view.getUint32(pos + 4, true);\r\n\t\t\tbitsPerSample = view.getUint16(pos + 14, true);\r\n\t\t\t// WAVE_FORMAT_EXTENSIBLE: the real format code is the first 2 bytes of\r\n\t\t\t// the SubFormat GUID in the extension.\r\n\t\t\tif (audioFormat === 0xfffe && size >= 40) {\r\n\t\t\t\taudioFormat = view.getUint16(pos + 24, true);\r\n\t\t\t}\r\n\t\t} else if (id === \"data\") {\r\n\t\t\tdataOffset = pos;\r\n\t\t\t// Clamp to the actual file size — a corrupt chunk header could otherwise\r\n\t\t\t// send sample reads past the end of the buffer.\r\n\t\t\tdataLength = Math.min(size, view.byteLength - pos);\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tpos += size + (size & 1);\r\n\t}\r\n\r\n\tif (!dataOffset) throw new Error(\"WAV has no data chunk\");\r\n\tif (!channels || !sampleRate) throw new Error(\"WAV fmt chunk missing\");\r\n\r\n\t// Reject anything the sample loop below cannot decode — falling through\r\n\t// would silently produce all-zero (silent) audio.\r\n\tconst supported =\r\n\t\t(audioFormat === 3 && bitsPerSample === 32) ||\r\n\t\t(audioFormat === 1 &&\r\n\t\t\t(bitsPerSample === 8 || bitsPerSample === 16 || bitsPerSample === 24));\r\n\tif (!supported) {\r\n\t\tthrow new Error(\r\n\t\t\t`Unsupported WAV format ${audioFormat} / ${bitsPerSample}-bit (need PCM 8/16/24-bit or IEEE float 32-bit)`,\r\n\t\t);\r\n\t}\r\n\r\n\tconst bytesPerSample = bitsPerSample >> 3;\r\n\tconst totalSamples = Math.floor(dataLength / bytesPerSample);\r\n\tconst samples = new Float32Array(totalSamples);\r\n\r\n\tfor (let i = 0; i < totalSamples; i++) {\r\n\t\tconst p = dataOffset + i * bytesPerSample;\r\n\t\tif (audioFormat === 3) {\r\n\t\t\tsamples[i] = view.getFloat32(p, true);\r\n\t\t} else if (bitsPerSample === 8) {\r\n\t\t\tsamples[i] = (view.getUint8(p) - 128) / 128;\r\n\t\t} else if (bitsPerSample === 16) {\r\n\t\t\tsamples[i] = view.getInt16(p, true) / 32768;\r\n\t\t} else if (bitsPerSample === 24) {\r\n\t\t\tconst lo = view.getUint8(p) | (view.getUint8(p + 1) << 8);\r\n\t\t\tlet hi = view.getUint8(p + 2);\r\n\t\t\tif (hi & 0x80) hi = hi | 0xffffff00;\r\n\t\t\tsamples[i] = ((hi << 16) | lo) / 8388608;\r\n\t\t}\r\n\t}\r\n\r\n\treturn { sampleRate, channels, samples };\r\n}\r\n\r\n/** Mix down to mono by averaging all channels. */\r\nexport function toMono(wav: WavData): WavData {\r\n\tif (wav.channels === 1) return wav;\r\n\tconst len = wav.samples.length / wav.channels;\r\n\tconst out = new Float32Array(len);\r\n\tfor (let i = 0; i < len; i++) {\r\n\t\tlet sum = 0;\r\n\t\tfor (let c = 0; c < wav.channels; c++)\r\n\t\t\tsum += wav.samples[i * wav.channels + c];\r\n\t\tout[i] = sum / wav.channels;\r\n\t}\r\n\treturn { sampleRate: wav.sampleRate, channels: 1, samples: out };\r\n}\r\n\r\n/** Linear interpolation resample to targetRate. Expects mono input. */\r\nexport function resample(wav: WavData, targetRate: number): WavData {\r\n\tif (wav.sampleRate === targetRate) return wav;\r\n\tconst ratio = wav.sampleRate / targetRate;\r\n\tconst outLen = Math.floor(wav.samples.length / ratio);\r\n\tconst out = new Float32Array(outLen);\r\n\tconst src = wav.samples;\r\n\tfor (let i = 0; i < outLen; i++) {\r\n\t\tconst x = i * ratio;\r\n\t\tconst xi = Math.floor(x);\r\n\t\tconst frac = x - xi;\r\n\t\tout[i] = (src[xi] ?? 0) + ((src[xi + 1] ?? 0) - (src[xi] ?? 0)) * frac;\r\n\t}\r\n\treturn { sampleRate: targetRate, channels: 1, samples: out };\r\n}\r\n\r\n/** Convert Float32 [-1,1] samples to Int16 PCM. */\r\nexport function toInt16(samples: Float32Array): Int16Array {\r\n\tconst out = new Int16Array(samples.length);\r\n\tfor (let i = 0; i < samples.length; i++) {\r\n\t\tout[i] = Math.round(Math.max(-1, Math.min(1, samples[i])) * 32767);\r\n\t}\r\n\treturn out;\r\n}\r\n\r\n/**\r\n * Decode a WAV to 48kHz/16bit/mono Int16 PCM, reporting the source sample rate.\r\n *\r\n * The rate is needed to index a sibling `.frq` file, whose analysis hop is\r\n * counted in ORIGINAL samples — see {@link frqAverageF0InRange}.\r\n *\r\n * Note this does not touch amplitude: peak levels are carried through\r\n * unchanged, so a bank's own relative loudness between phonemes is preserved\r\n * (UTAU's engine instead normalises each region to −6 dBFS, which is why its\r\n * イ/エ段 and 語尾 samples come out louder than recorded).\r\n */\r\nexport function readWavPcm48k(buf: ArrayBuffer): {\r\n\tpcm: Int16Array;\r\n\tsourceRate: number;\r\n} {\r\n\tconst wav = parseWav(buf);\r\n\tconst mono = toMono(wav);\r\n\tconst resampled = resample(mono, 48000);\r\n\treturn { pcm: toInt16(resampled.samples), sourceRate: wav.sampleRate };\r\n}\r\n\r\n/**\r\n * Convert a WAV to 48kHz/16bit/mono Int16 PCM.\r\n *\r\n * @deprecated Misnomer — this never normalised amplitude. Use\r\n * {@link readWavPcm48k}, which also reports the source sample rate.\r\n */\r\nexport function normalizePcm(buf: ArrayBuffer): Int16Array {\r\n\treturn readWavPcm48k(buf).pcm;\r\n}\r\n\r\nfunction readFourCC(view: DataView, pos: number): string {\r\n\treturn String.fromCharCode(\r\n\t\tview.getUint8(pos),\r\n\t\tview.getUint8(pos + 1),\r\n\t\tview.getUint8(pos + 2),\r\n\t\tview.getUint8(pos + 3),\r\n\t);\r\n}\r\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Some of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + ';addEventListener(\"error\",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})'\n ], { type: 'text/javascript' }))));\n w.onmessage = function (e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err = new Error(ed[0]);\n err['code'] = ed[1];\n err.stack = ed[2];\n cb(err, null);\n }\n else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new i32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return { b: b, r: r };\n};\nvar _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i) {\n if (cd[i])\n ++l[cd[i] - 1];\n }\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 1; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i) {\n if (cd[i]) {\n co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);\n }\n }\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p + 7) / 8) | 0; };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n return new u8(v.subarray(s, e));\n};\n/**\n * Codes for errors generated within this library\n */\nexport var FlateErrorCode = {\n UnexpectedEOF: 0,\n InvalidBlockType: 1,\n InvalidLengthLiteral: 2,\n InvalidDistance: 3,\n StreamFinished: 4,\n NoStreamHandler: 5,\n InvalidHeader: 6,\n NoCallback: 7,\n InvalidUTF8: 8,\n ExtraFieldTooLong: 9,\n InvalidDate: 10,\n FilenameTooLong: 11,\n StreamFinishing: 12,\n InvalidZipData: 13,\n UnknownCompressionMethod: 14\n};\n// error codes\nvar ec = [\n 'unexpected EOF',\n 'invalid block type',\n 'invalid length/literal',\n 'invalid distance',\n 'stream finished',\n 'no stream handler',\n , // determined by compression function\n 'no callback',\n 'invalid UTF-8 data',\n 'extra field too long',\n 'date not in range 1980-2099',\n 'filename too long',\n 'stream finishing',\n 'invalid zip data'\n // determined by unknown compression method\n];\n;\nvar err = function (ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, st, buf, dict) {\n // source length dict length\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n // have to estimate size\n var resize = noBuf || st.i != 2;\n // no state\n var noSt = st.i;\n // Assumes roughly 33% compression ratio average\n if (noBuf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n // ensure size\n if (resize)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (;; lpos = pos) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n // don't reallocate for streams or user buffers\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n d[o + 2] |= v >> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return { t: et, l: 0 };\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return { t: v, l: 1 };\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return { t: new u8(tr), l: mbt };\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return { c: cl.subarray(0, cli), n: s };\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;\n var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;\n var _c = lc(dlt), lclt = _c.c, nlc = _c.n;\n var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n ++lcfreq[lclt[i] & 31];\n for (var i = 0; i < lcdt.length; ++i)\n ++lcfreq[lcdt[i] & 31];\n var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];\n if (bs >= 0 && flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n var sym = syms[i];\n if (sym > 255) {\n var len = (sym >> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (sym >> 23) & 31), p += fleb[len];\n var dst = sym & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[sym]), p += ll[sym];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, st) {\n var s = st.z || dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var lst = st.l;\n var pos = (st.r || 0) & 7;\n if (lvl) {\n if (pos)\n w[0] = st.r >> 3;\n var opt = deo[lvl - 1];\n var n = opt >> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new i32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx blkpos\n var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;\n for (; i + 2 < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768 previous index mod\n var imod = i & 32767, pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = i - dif + j & 32767;\n var pti = prev[ti];\n var cd = ti - pti & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += imod - pimod & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one int32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n for (i = Math.max(i, wi); i < s; ++i) {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n if (!lst) {\n st.r = (pos & 7) | w[(pos / 8) | 0] << 3;\n // shft(pos) now 1 less if pos & 7 != 0\n pos -= 7;\n st.h = head, st.p = prev, st.i = i, st.w = wi;\n }\n }\n else {\n for (var i = st.w || 0; i < s + lst; i += 65535) {\n // end\n var e = i + 65535;\n if (e >= s) {\n // write final block\n w[(pos / 8) | 0] = lst;\n e = s;\n }\n pos = wfblk(w, pos + 1, dat.subarray(i, e));\n }\n st.i = s;\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new Int32Array(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && -306674912) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = -1;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return ~c; }\n };\n};\n// Adler32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length | 0;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 2655, l);\n for (; i < e; ++i)\n m += n += d[i];\n n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);\n }\n a = n, b = m;\n },\n d: function () {\n a %= 65521, b %= 65521;\n return (a & 255) << 24 | (a & 0xFF00) << 8 | (b & 255) << 8 | (b >> 8);\n }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n if (!st) {\n st = { l: 1 };\n if (opt.dictionary) {\n var dict = opt.dictionary.subarray(-32768);\n var newDat = new u8(dict.length + dat.length);\n newDat.set(dict);\n newDat.set(dat, dict.length);\n dat = newDat;\n st.w = dict.length;\n }\n }\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? (st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20) : (12 + opt.mem), pre, post, st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\\s+/g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return fnStr;\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n fnStr = wcln(fns[i], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td = mrg({}, ch[id].e);\n return wk(ch[id].c + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt]; };\nvar bDflt = function () { return [u8, u16, i32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zls]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get opts\nvar gopt = function (o) { return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n}; };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) {\n if (ev.data[0]) {\n strm.push(ev.data[0], ev.data[1]);\n postMessage([ev.data[0].length]);\n }\n else\n strm.flush(ev.data[1]);\n };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id, flush, ext) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else if (!Array.isArray(dat))\n ext(dat);\n else if (dat.length == 1) {\n strm.queuedSize -= dat[0];\n if (strm.ondrain)\n strm.ondrain(dat[0]);\n }\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.queuedSize = 0;\n strm.push = function (d, f) {\n if (!strm.ondata)\n err(5);\n if (t)\n strm.ondata(err(4, 0, 1), null, !!f);\n strm.queuedSize += d.length;\n // can fail for cross-realm Uint8Array, but ok - only a small performance penalty\n w.postMessage([d, t = f], d.buffer instanceof ArrayBuffer ? [d.buffer] : []);\n };\n strm.terminate = function () { w.terminate(); };\n if (flush) {\n strm.flush = function (sync) { w.postMessage([0, sync]); };\n }\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; };\n// read 8 bytes\nvar b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, 'invalid gzip data');\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + (o.filename ? o.filename.length + 1 : 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (o.dictionary && 32);\n c[1] |= 31 - ((c[0] << 8) | c[1]) % 31;\n if (o.dictionary) {\n var h = adler();\n h.p(o.dictionary);\n wbytes(c, 2, h.d());\n }\n};\n// zlib start\nvar zls = function (d, dict) {\n if ((d[0] & 15) != 8 || (d[0] >> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n err(6, 'invalid zlib data');\n if ((d[1] >> 5 & 1) == +!dict)\n err(6, 'invalid zlib data: ' + (d[1] & 32 ? 'need' : 'unexpected') + ' dictionary');\n return (d[1] >> 3 & 4) + 2;\n};\nfunction StrmOpt(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n this.s = { l: 0, i: 32768, w: 32768, z: 32768 };\n // Buffer length must always be 0 mod 32768 for index calculations to be correct when modifying head and prev\n // 98304 = 32768 (lookback) + 65536 (common chunk size)\n this.b = new u8(98304);\n if (this.o.dictionary) {\n var dict = this.o.dictionary.subarray(-32768);\n this.b.set(dict, 32768 - dict.length);\n this.s.i = 32768 - dict.length;\n }\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, this.s), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n var endLen = chunk.length + this.s.z;\n if (endLen > this.b.length) {\n if (endLen > 2 * this.b.length - 32768) {\n var newBuf = new u8(endLen & -32768);\n newBuf.set(this.b.subarray(0, this.s.z));\n this.b = newBuf;\n }\n var split = this.b.length - this.s.z;\n this.b.set(chunk.subarray(0, split), this.s.z);\n this.s.z = this.b.length;\n this.p(this.b, false);\n this.b.set(this.b.subarray(-32768));\n this.b.set(chunk.subarray(split), 32768);\n this.s.z = chunk.length - split + 32768;\n this.s.i = 32766, this.s.w = 32768;\n }\n else {\n this.b.set(chunk, this.s.z);\n this.s.z += chunk.length;\n }\n this.s.l = final & 1;\n if (this.s.z > this.s.w + 8191 || final) {\n this.p(this.b, final || false);\n this.s.w = this.s.i, this.s.i -= 2;\n }\n if (final) {\n // cleanup unneeded buffers/state to reduce memory usage\n this.s = this.o = {};\n this.b = et;\n }\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * deflated output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible. A separate DEFLATE stream may be concatenated\n * with the current output after a sync flush.\n */\n Deflate.prototype.flush = function (sync) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n this.p(this.b, false);\n this.s.w = this.s.i, this.s.i -= 2;\n // could technically skip writing the type-0 block for (this.s.r & 7) == 0,\n // but the deterministic trailer (00 00 FF FF) is useful in some situations\n if (sync) {\n var c = new u8(6);\n c[0] = this.s.r >> 3;\n // write empty, non-final type-0 block\n var ep = wfblk(c, this.s.r, et);\n this.s.r = 0;\n this.ondata(c.subarray(0, ep >> 3), false);\n }\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6, 1);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n return dopt(data, opts || {}, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n function Inflate(opts, cb) {\n // no StrmOpt here to avoid adding to workerizer\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate.prototype.e = function (c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate.prototype.c = function (final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n function AsyncInflate(opts, cb) {\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Inflate(ev.data);\n onmessage = astrm(strm);\n }, 7, 0);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gopt(ev.data[1]))); }, 1, cb);\n}\nexport function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n this.l += chunk.length;\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, this.s);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * GZIPped output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Gzip.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8, 1);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (!opts)\n opts = {};\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming single or multi-member GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n function Gunzip(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n }\n else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, 0);\n // process concatenated GZIP\n if (this.s.f && !this.s.l) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n else if (final) {\n Inflate.prototype.c.call(this, final);\n }\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming single or multi-member GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n function AsyncGunzip(opts, cb) {\n var _this = this;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gunzip(ev.data);\n strm.onmember = function (offset) { return postMessage(offset); };\n onmessage = astrm(strm);\n }, 9, 0, function (offset) { return _this.onmember && _this.onmember(offset); });\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0], ev.data[1])); }, 3, cb);\n}\nexport function gunzipSync(data, opts) {\n var st = gzs(data);\n if (st + 8 > data.length)\n err(6, 'invalid gzip data');\n return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && (this.o.dictionary ? 6 : 2), f && 4, this.s);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * zlibbed output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Zlib.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10, 1);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (!opts)\n opts = {};\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, opts.dictionary ? 6 : 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n function Unzlib(opts, cb) {\n Inflate.call(this, opts, cb);\n this.v = opts && opts.dictionary ? 2 : 1;\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 6 && !final)\n return;\n this.p = this.p.subarray(zls(this.p, this.v - 1)), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n err(6, 'invalid zlib data');\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n function AsyncUnzlib(opts, cb) {\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Unzlib(ev.data);\n onmessage = astrm(strm);\n }, 11, 0);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gopt(ev.data[1]))); }, 5, cb);\n}\nexport function unzlibSync(data, opts) {\n return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n function Decompress(opts, cb) {\n this.o = StrmOpt.call(this, opts, cb) || {};\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n }\n // init substream\n // overriden by AsyncDecompress\n Decompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (dat, final) {\n _this.ondata(dat, final);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(this.o)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(this.o)\n : new this.Z(this.o);\n this.i();\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n function AsyncDecompress(opts, cb) {\n Decompress.call(this, opts, cb);\n this.queuedSize = 0;\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n }\n AsyncDecompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (err, dat, final) {\n _this.ondata(err, dat, final);\n };\n this.s.ondrain = function (size) {\n _this.queuedSize -= size;\n if (_this.ondrain)\n _this.ondrain(size);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n this.queuedSize += chunk.length;\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param opts The decompression options\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, opts) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, opts)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, opts)\n : unzlibSync(data, opts);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k, op = o;\n if (Array.isArray(val))\n op = mrg(o, val[1]), val = val[0];\n if (ArrayBuffer.isView(val))\n t[n] = [val, op];\n else {\n t[n += '/'] = [new u8(0), op];\n fltn(val, n, t, o);\n }\n }\n};\n// text encoder\nvar te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();\n// text decoder\nvar td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();\n// text decoder stream\nvar tds = 0;\ntry {\n td.decode(et, { stream: true });\n tds = 1;\n}\ncatch (e) { }\n// decode UTF8\nvar dutf8 = function (d) {\n for (var r = '', i = 0;;) {\n var c = d[i++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i + eb > d.length)\n return { s: r, r: slc(d, i - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63));\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63));\n }\n};\n/**\n * Streaming UTF-8 decoding\n */\nvar DecodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is decoded\n */\n function DecodeUTF8(cb) {\n this.ondata = cb;\n if (tds)\n this.t = new TextDecoder();\n else\n this.p = et;\n }\n /**\n * Pushes a chunk to be decoded from UTF-8 binary\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n DecodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n final = !!final;\n if (this.t) {\n this.ondata(this.t.decode(chunk, { stream: true }), final);\n if (final) {\n if (this.t.decode().length)\n err(8);\n this.t = null;\n }\n return;\n }\n if (!this.p)\n err(4);\n var dat = new u8(this.p.length + chunk.length);\n dat.set(this.p);\n dat.set(chunk, this.p.length);\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (final) {\n if (r.length)\n err(8);\n this.p = null;\n }\n else\n this.p = r;\n this.ondata(s, final);\n };\n return DecodeUTF8;\n}());\nexport { DecodeUTF8 };\n/**\n * Streaming UTF-8 encoding\n */\nvar EncodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is encoded\n */\n function EncodeUTF8(cb) {\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be encoded to UTF-8\n * @param chunk The string data to push\n * @param final Whether this is the last chunk\n */\n EncodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.ondata(strToU8(chunk), this.d = final || false);\n };\n return EncodeUTF8;\n}());\nexport { EncodeUTF8 };\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n if (latin1) {\n var ar_1 = new u8(str.length);\n for (var i = 0; i < str.length; ++i)\n ar_1[i] = str.charCodeAt(i);\n return ar_1;\n }\n if (te)\n return te.encode(str);\n var l = str.length;\n var ar = new u8(str.length + (str.length >> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n if (latin1) {\n var r = '';\n for (var i = 0; i < dat.length; i += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));\n return r;\n }\n else if (td) {\n return td.decode(dat);\n }\n else {\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (r.length)\n err(8);\n return s;\n }\n}\n;\n// deflate bit flag\nvar dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; };\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];\n};\n// read zip64 header sizes\nvar z64hs = function (d, b, l, z, sc, su, off) {\n var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;\n var nf = nsc + nsu + noff;\n if (z && nf) {\n for (; b + 4 < e; b += 4 + b2(d, b + 2)) {\n if (b2(d, b) == 1) {\n return [\n nsc ? b8(d, b + 4 + 8 * nsu) : sc,\n nsu ? b8(d, b + 4) : su,\n noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,\n 1\n ];\n }\n }\n // z == 2 for unknown whether or not zip64\n if (z < 2)\n err(13);\n }\n return [sc, su, off, 0];\n};\n// extra field length\nvar exfl = function (ex) {\n var le = 0;\n if (ex) {\n for (var k in ex) {\n var l = ex[k].length;\n if (l > 65535)\n err(9);\n le += l + 4;\n }\n }\n return le;\n};\n// write zip header\nvar wzh = function (d, b, f, fn, u, c, ce, co) {\n var fl = fn.length, ex = f.extra, col = co && co.length;\n var exl = exfl(ex);\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b++] = 20, d[b++] = f.os;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (f.flag << 1) | (c < 0 && 8), d[b++] = u && 8;\n d[b++] = f.compression & 255, d[b++] = f.compression >> 8;\n var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n err(10);\n wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >> 1)), b += 4;\n if (c != -1) {\n wbytes(d, b, f.crc);\n wbytes(d, b + 4, c < 0 ? -c - 2 : c);\n wbytes(d, b + 8, f.size);\n }\n wbytes(d, b + 12, fl);\n wbytes(d, b + 14, exl), b += 16;\n if (ce != null) {\n wbytes(d, b, col);\n wbytes(d, b + 6, f.attrs);\n wbytes(d, b + 10, ce), b += 14;\n }\n d.set(fn, b);\n b += fl;\n if (exl) {\n for (var k in ex) {\n var exf = ex[k], l = exf.length;\n wbytes(d, b, +k);\n wbytes(d, b + 2, l);\n d.set(exf, b + 4), b += 4 + l;\n }\n }\n if (col)\n d.set(co, b), b += col;\n return b;\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\n/**\n * A pass-through stream to keep data uncompressed in a ZIP archive.\n */\nvar ZipPassThrough = /*#__PURE__*/ (function () {\n /**\n * Creates a pass-through stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n */\n function ZipPassThrough(filename) {\n this.filename = filename;\n this.c = crc();\n this.size = 0;\n this.compression = 0;\n }\n /**\n * Processes a chunk and pushes to the output stream. You can override this\n * method in a subclass for custom behavior, but by default this passes\n * the data through. You must call this.ondata(err, chunk, final) at some\n * point in this method.\n * @param chunk The chunk to process\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.process = function (chunk, final) {\n this.ondata(null, chunk, final);\n };\n /**\n * Pushes a chunk to be added. If you are subclassing this with a custom\n * compression algorithm, note that you must push data from the source\n * file only, pre-compression.\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n this.c.p(chunk);\n this.size += chunk.length;\n if (final)\n this.crc = this.c.d();\n // we shouldn't really do this cast, but properly handling ArrayBufferLike\n // makes the API unergonomic with Buffer\n this.process(chunk, final || false);\n };\n return ZipPassThrough;\n}());\nexport { ZipPassThrough };\n// I don't extend because TypeScript extension adds 1kB of runtime bloat\n/**\n * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate\n * for better performance\n */\nvar ZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function ZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new Deflate(opts, function (dat, final) {\n _this.ondata(null, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n }\n ZipDeflate.prototype.process = function (chunk, final) {\n try {\n this.d.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return ZipDeflate;\n}());\nexport { ZipDeflate };\n/**\n * Asynchronous streaming DEFLATE compression for ZIP archives\n */\nvar AsyncZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function AsyncZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new AsyncDeflate(opts, function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n this.terminate = this.d.terminate;\n }\n AsyncZipDeflate.prototype.process = function (chunk, final) {\n this.d.push(chunk, final);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return AsyncZipDeflate;\n}());\nexport { AsyncZipDeflate };\n// TODO: Better tree shaking\n/**\n * A zippable archive to which files can incrementally be added\n */\nvar Zip = /*#__PURE__*/ (function () {\n /**\n * Creates an empty ZIP archive to which files can be added\n * @param cb The callback to call whenever data for the generated ZIP archive\n * is available\n */\n function Zip(cb) {\n this.ondata = cb;\n this.u = [];\n this.d = 1;\n }\n /**\n * Adds a file to the ZIP archive\n * @param file The file stream to add\n */\n Zip.prototype.add = function (file) {\n var _this = this;\n if (!this.ondata)\n err(5);\n // finishing or finished\n if (this.d & 2)\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false);\n else {\n var f = strToU8(file.filename), fl_1 = f.length;\n var com = file.comment, o = com && strToU8(com);\n var u = fl_1 != file.filename.length || (o && (com.length != o.length));\n var hl_1 = fl_1 + exfl(file.extra) + 30;\n if (fl_1 > 65535)\n this.ondata(err(11, 0, 1), null, false);\n var header = new u8(hl_1);\n wzh(header, 0, file, f, u, -1);\n var chks_1 = [header];\n var pAll_1 = function () {\n for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) {\n var chk = chks_2[_i];\n _this.ondata(null, chk, false);\n }\n chks_1 = [];\n };\n var tr_1 = this.d;\n this.d = 0;\n var ind_1 = this.u.length;\n var uf_1 = mrg(file, {\n f: f,\n u: u,\n o: o,\n t: function () {\n if (file.terminate)\n file.terminate();\n },\n r: function () {\n pAll_1();\n if (tr_1) {\n var nxt = _this.u[ind_1 + 1];\n if (nxt)\n nxt.r();\n else\n _this.d = 1;\n }\n tr_1 = 1;\n }\n });\n var cl_1 = 0;\n file.ondata = function (err, dat, final) {\n if (err) {\n _this.ondata(err, dat, final);\n _this.terminate();\n }\n else {\n cl_1 += dat.length;\n chks_1.push(dat);\n if (final) {\n var dd = new u8(16);\n wbytes(dd, 0, 0x8074B50);\n wbytes(dd, 4, file.crc);\n wbytes(dd, 8, cl_1);\n wbytes(dd, 12, file.size);\n chks_1.push(dd);\n uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size;\n if (tr_1)\n uf_1.r();\n tr_1 = 1;\n }\n else if (tr_1)\n pAll_1();\n }\n };\n this.u.push(uf_1);\n }\n };\n /**\n * Ends the process of adding files and prepares to emit the final chunks.\n * This *must* be called after adding all desired files for the resulting\n * ZIP file to work properly.\n */\n Zip.prototype.end = function () {\n var _this = this;\n if (this.d & 2) {\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true);\n return;\n }\n if (this.d)\n this.e();\n else\n this.u.push({\n r: function () {\n if (!(_this.d & 1))\n return;\n _this.u.splice(-1, 1);\n _this.e();\n },\n t: function () { }\n });\n this.d = 3;\n };\n Zip.prototype.e = function () {\n var bt = 0, l = 0, tl = 0;\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0);\n }\n var out = new u8(tl + 22);\n for (var _b = 0, _c = this.u; _b < _c.length; _b++) {\n var f = _c[_b];\n wzh(out, bt, f, f.f, f.u, -f.c - 2, l, f.o);\n bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b;\n }\n wzf(out, bt, this.u.length, tl, l);\n this.ondata(null, out, true);\n this.d = 2;\n };\n /**\n * A method to terminate any internal workers used by the stream. Subsequent\n * calls to add() will fail.\n */\n Zip.prototype.terminate = function () {\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n f.t();\n }\n this.d = 2;\n };\n return Zip;\n}());\nexport { Zip };\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n var l = f.c.length;\n wzh(out, tot, f, f.f, f.u, l);\n var badd = 30 + f.f.length + exfl(f.extra);\n var loc = tot + badd;\n out.set(f.c, loc);\n wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l;\n }\n catch (e) {\n return cbd(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cbd(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), size = file.length;\n c.p(file);\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n var compression = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n var l = d.length;\n files[i] = mrg(p, {\n size: size,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n compression: compression\n });\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n if (!--lft)\n cbf();\n }\n };\n if (s > 65535)\n cbl(err(11, 0, 1), null);\n if (!compression)\n cbl(null, file);\n else if (size < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (!opts)\n opts = {};\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var compression = p.level == 0 ? 0 : 8;\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n if (s > 65535)\n err(11);\n var d = compression ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push(mrg(p, {\n size: file.length,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n o: o,\n compression: compression\n }));\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f, f.f, f.u, f.c.length);\n var badd = 30 + f.f.length + exfl(f.extra);\n out.set(f.c, f.o + badd);\n wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Streaming pass-through decompression for ZIP archives\n */\nvar UnzipPassThrough = /*#__PURE__*/ (function () {\n function UnzipPassThrough() {\n }\n UnzipPassThrough.prototype.push = function (chunk, final) {\n // same as ZipPassThrough: cast to retain Buffer ergonomics\n this.ondata(null, chunk, final);\n };\n UnzipPassThrough.compression = 0;\n return UnzipPassThrough;\n}());\nexport { UnzipPassThrough };\n/**\n * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for\n * better performance.\n */\nvar UnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function UnzipInflate() {\n var _this = this;\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n UnzipInflate.prototype.push = function (chunk, final) {\n try {\n this.i.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n UnzipInflate.compression = 8;\n return UnzipInflate;\n}());\nexport { UnzipInflate };\n/**\n * Asynchronous streaming DEFLATE decompression for ZIP archives\n */\nvar AsyncUnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function AsyncUnzipInflate(_, sz) {\n var _this = this;\n if (sz < 320000) {\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n else {\n this.i = new AsyncInflate(function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.terminate = this.i.terminate;\n }\n }\n AsyncUnzipInflate.prototype.push = function (chunk, final) {\n if (this.i.terminate)\n chunk = slc(chunk, 0);\n this.i.push(chunk, final);\n };\n AsyncUnzipInflate.compression = 8;\n return AsyncUnzipInflate;\n}());\nexport { AsyncUnzipInflate };\n/**\n * A ZIP archive decompression stream that emits files as they are discovered\n */\nvar Unzip = /*#__PURE__*/ (function () {\n /**\n * Creates a ZIP decompression stream\n * @param cb The callback to call whenever a file in the ZIP archive is found\n */\n function Unzip(cb) {\n this.onfile = cb;\n this.k = [];\n this.o = {\n 0: UnzipPassThrough\n };\n this.p = et;\n }\n /**\n * Pushes a chunk to be unzipped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzip.prototype.push = function (chunk, final) {\n var _this = this;\n if (!this.onfile)\n err(5);\n if (!this.p)\n err(4);\n if (this.c > 0) {\n var len = Math.min(this.c, chunk.length);\n var toAdd = chunk.subarray(0, len);\n this.c -= len;\n if (this.d)\n this.d.push(toAdd, !this.c);\n else\n this.k[0].push(toAdd);\n chunk = chunk.subarray(len);\n if (chunk.length)\n return this.push(chunk, final);\n }\n else {\n var f = 0, i = 0, is = void 0, buf = void 0;\n if (!this.p.length)\n buf = chunk;\n else if (!chunk.length)\n buf = this.p;\n else {\n buf = new u8(this.p.length + chunk.length);\n buf.set(this.p), buf.set(chunk, this.p.length);\n }\n var l = buf.length, oc = this.c, add = oc && this.d;\n var _loop_2 = function () {\n var sig = b4(buf, i);\n if (sig == 0x4034B50) {\n f = 1, is = i;\n this_1.d = null;\n this_1.c = 0;\n var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);\n if (l > i + 30 + fnl + es) {\n var chks_3 = [];\n this_1.k.unshift(chks_3);\n f = 2;\n var lsc = b4(buf, i + 18), lsu = b4(buf, i + 22);\n var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);\n var _a = z64hs(buf, i, es, 2, lsc, lsu, 0), sc_1 = _a[0], su_1 = _a[1], z64 = _a[3];\n if (dd)\n sc_1 = -1 - z64;\n i += es;\n this_1.c = sc_1;\n var d_1;\n var file_1 = {\n name: fn_1,\n compression: cmp_1,\n start: function () {\n if (!file_1.ondata)\n err(5);\n if (!sc_1)\n file_1.ondata(null, et, true);\n else {\n var ctr = _this.o[cmp_1];\n if (!ctr)\n file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false);\n d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);\n d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); };\n for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {\n var dat = chks_4[_i];\n d_1.push(dat, false);\n }\n if (_this.k[0] == chks_3 && _this.c)\n _this.d = d_1;\n else\n d_1.push(et, true);\n }\n },\n terminate: function () {\n if (d_1 && d_1.terminate)\n d_1.terminate();\n }\n };\n if (sc_1 >= 0)\n file_1.size = sc_1, file_1.originalSize = su_1;\n this_1.onfile(file_1);\n }\n return \"break\";\n }\n else if (oc) {\n if (sig == 0x8074B50) {\n is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;\n return \"break\";\n }\n else if (sig == 0x2014B50) {\n is = i -= 4, f = 3, this_1.c = 0;\n return \"break\";\n }\n }\n };\n var this_1 = this;\n for (; i < l - 4; ++i) {\n var state_1 = _loop_2();\n if (state_1 === \"break\")\n break;\n }\n this.p = et;\n if (oc < 0) {\n var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i);\n if (add)\n add.push(dat, !!f);\n else\n this.k[+(f == 2)].push(dat);\n }\n if (f & 2)\n return this.push(buf.subarray(i), final);\n this.p = buf.subarray(i);\n }\n if (final) {\n if (this.c)\n err(13);\n this.p = null;\n }\n };\n /**\n * Registers a decoder with the stream, allowing for files compressed with\n * the compression type provided to be expanded correctly\n * @param decoder The decoder constructor\n */\n Unzip.prototype.register = function (decoder) {\n this.o[decoder.compression] = decoder;\n };\n return Unzip;\n}());\nexport { Unzip };\nvar mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); };\nexport function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n // Synchronously decompress under 512KB, or barely-compressed data\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl(err(14, 'unknown compression type ' + c_1, 1), null);\n }\n else\n cbl(null, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_3(i);\n }\n }\n else\n cbd(null, {});\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @param opts The ZIP extraction options\n * @returns The decompressed files\n */\nexport function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, 'unknown compression type ' + c_2);\n }\n }\n return files;\n}\n","import { unzipSync, zipSync } from \"fflate\";\n\n/** Minimal file-like handle so zip entries can stand in for `File` objects. */\nexport interface ZipFile {\n\tarrayBuffer(): Promise<ArrayBuffer>;\n}\n\n/**\n * Extracts a zip archive into a flat path → file map, mirroring the shape of\n * `webkitdirectory` file lists so the converter can treat both sources the same.\n *\n * Many UTAU voicebank zips are packed on Windows without the UTF-8 flag, so\n * entry names are Shift_JIS bytes. fflate decodes those as latin1 (1 byte =\n * 1 code point) rather than mangling them, so we can losslessly recover the\n * original bytes and re-decode with the right encoding per entry.\n */\nexport function unzipToFileMap(\n\tdata: ArrayBuffer,\n): Promise<Record<string, ZipFile>> {\n\tconst bytes = new Uint8Array(data);\n\tconst unzipped = unzipSync(bytes);\n\tconst isUtf8ByIndex = readUtf8Flags(bytes);\n\tconst sjisDecoder = new TextDecoder(\"shift_jis\");\n\n\tconst fileMap: Record<string, ZipFile> = {};\n\tObject.keys(unzipped).forEach((rawName, i) => {\n\t\tconst fileBytes = unzipped[rawName];\n\t\tconst name = isUtf8ByIndex[i]\n\t\t\t? rawName\n\t\t\t: sjisDecoder.decode(Uint8Array.from(rawName, (c) => c.charCodeAt(0)));\n\t\tconst path = name.replace(/\\\\/g, \"/\");\n\t\tif (path.endsWith(\"/\")) return; // directory entry\n\t\tfileMap[path] = {\n\t\t\tarrayBuffer: () =>\n\t\t\t\tPromise.resolve(\n\t\t\t\t\tfileBytes.buffer.slice(\n\t\t\t\t\t\tfileBytes.byteOffset,\n\t\t\t\t\t\tfileBytes.byteOffset + fileBytes.byteLength,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t};\n\t});\n\treturn Promise.resolve(fileMap);\n}\n\n/** Walks the central directory to read the UTF-8 language flag (bit 11) of each entry, in order. */\nfunction readUtf8Flags(buf: Uint8Array): boolean[] {\n\tconst view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n\n\tlet eocd = -1;\n\tconst maxBack = Math.min(buf.length, 65557); // 22 + max comment length\n\tfor (let i = buf.length - 22; i >= buf.length - maxBack && i >= 0; i--) {\n\t\tif (view.getUint32(i, true) === 0x06054b50) {\n\t\t\teocd = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (eocd < 0) return [];\n\n\tconst entryCount = view.getUint16(eocd + 10, true);\n\tlet cdOffset = view.getUint32(eocd + 16, true);\n\n\tconst flags: boolean[] = [];\n\tfor (let i = 0; i < entryCount; i++) {\n\t\tif (view.getUint32(cdOffset, true) !== 0x02014b50) break;\n\t\tconst flag = view.getUint16(cdOffset + 8, true);\n\t\tconst nameLen = view.getUint16(cdOffset + 28, true);\n\t\tconst extraLen = view.getUint16(cdOffset + 30, true);\n\t\tconst commentLen = view.getUint16(cdOffset + 32, true);\n\t\tflags.push((flag & 0x800) !== 0);\n\t\tcdOffset += 46 + nameLen + extraLen + commentLen;\n\t}\n\treturn flags;\n}\n\n/**\n * Pack a path → bytes map into a zip Blob.\n *\n * Entry names are written as UTF-8 with the language flag set, which is what\n * every current unzip tool reads — including Windows Explorer, so a bank whose\n * folders are named in Japanese comes back out intact.\n */\nexport function zipFiles(files: Record<string, Uint8Array>): Blob {\n\tconst packed = zipSync(files, { level: 6 });\n\tconst bytes = new Uint8Array(packed.length);\n\tbytes.set(packed);\n\treturn new Blob([bytes], { type: \"application/zip\" });\n}\n","import type { Manifest } from \"./types.js\";\n\n/** Magic number 'KOE\\0' (stored big-endian as 0x4B 0x4F 0x45 0x00). */\nconst MAGIC = 0x4b4f4500;\n\n/**\n * Koe Archive Format (.koe)\n * [4B] magic 'KOE\\0' (big-endian)\n * [4B] JSON length (little-endian)\n * [N ] manifest JSON (UTF-8)\n * [M ] raw PCM (Int16 / 48kHz / mono); phoneme offsets are relative to here\n */\nexport function packKoe(manifest: Manifest, pcmParts: BlobPart[]): Blob {\n\tconst json = new TextEncoder().encode(JSON.stringify(manifest));\n\tconst header = new ArrayBuffer(8);\n\tconst view = new DataView(header);\n\tview.setUint32(0, MAGIC, false); // magic, big-endian\n\tview.setUint32(4, json.byteLength, true); // json length, little-endian\n\treturn new Blob([header, json, ...pcmParts]);\n}\n\n/** Read the 8-byte header → JSON length. Throws on bad magic. */\nexport function parseKoeHeader(headerBytes: ArrayBuffer): {\n\tjsonLength: number;\n} {\n\tconst view = new DataView(headerBytes);\n\tif (view.byteLength < 8 || view.getUint32(0, false) !== MAGIC) {\n\t\tthrow new Error(\"Not a .koe file (bad magic)\");\n\t}\n\treturn { jsonLength: view.getUint32(4, true) };\n}\n\n/** Byte offset where PCM data begins, given the JSON length. */\nexport const pcmBase = (jsonLength: number): number => 8 + jsonLength;\n","import { parseKoeHeader, pcmBase } from \"../koe.js\";\nimport type { Manifest } from \"../types.js\";\n\n/**\n * Supplies raw bytes from the PCM section of a .koe archive on demand.\n * - BlobVoiceSource: slices an in-memory Blob / File (no full-buffer copy)\n * - RangeVoiceSource: HTTP Range requests against a URL (mobile-friendly)\n * `base` is the byte offset where PCM data starts (8 + jsonLength).\n */\ninterface VoiceSource {\n\treadBytes(offset: number, length: number): Promise<ArrayBuffer>;\n}\n\n/** Hard ceiling on a single phoneme's PCM size (~10.5 MB / ~55s at 48kHz). */\nconst MAX_PHONEME_SAMPLES = 5_242_880;\n/** Hard ceiling on the manifest JSON header itself. */\nconst MAX_JSON_LENGTH = 50 * 1024 * 1024;\n\nclass BlobVoiceSource implements VoiceSource {\n\tconstructor(\n\t\tprivate blob: Blob,\n\t\tprivate base: number,\n\t) {}\n\treadBytes(offset: number, length: number): Promise<ArrayBuffer> {\n\t\tconst start = this.base + offset;\n\t\treturn this.blob.slice(start, start + length).arrayBuffer();\n\t}\n}\n\nclass RangeVoiceSource implements VoiceSource {\n\tconstructor(\n\t\tprivate url: string,\n\t\tprivate base: number,\n\t) {}\n\tasync readBytes(offset: number, length: number): Promise<ArrayBuffer> {\n\t\tconst start = this.base + offset;\n\t\treturn rangeFetch(this.url, start, length);\n\t}\n}\n\nasync function rangeFetch(\n\turl: string,\n\tstart: number,\n\tlength: number,\n): Promise<ArrayBuffer> {\n\tconst res = await fetch(url, {\n\t\theaders: { Range: `bytes=${start}-${start + length - 1}` },\n\t\tcredentials: \"omit\", // never leak cookies / auth to a MML-supplied URL\n\t});\n\t// A server that ignores Range and returns 200 with the full file would\n\t// blow past the requested size and exhaust memory; only accept 206.\n\tif (res.status !== 206) {\n\t\tthrow new Error(\n\t\t\t`.koe fetch failed: expected 206 Partial Content, got ${res.status}`,\n\t\t);\n\t}\n\treturn readCapped(res, length);\n}\n\n/**\n * Read a response body without trusting its declared size: a server can answer\n * 206 yet still stream an oversized body. Abort as soon as the read exceeds\n * the requested byte count, before buffering the excess.\n */\nasync function readCapped(res: Response, length: number): Promise<ArrayBuffer> {\n\tconst reader = res.body?.getReader();\n\tif (!reader) {\n\t\tconst buf = await res.arrayBuffer();\n\t\tif (buf.byteLength > length) {\n\t\t\tthrow new Error(\n\t\t\t\t`.koe fetch failed: response exceeds requested ${length} bytes`,\n\t\t\t);\n\t\t}\n\t\treturn buf;\n\t}\n\tconst out = new Uint8Array(length);\n\tlet received = 0;\n\tfor (;;) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tif (received + value.byteLength > length) {\n\t\t\tawait reader.cancel();\n\t\t\tthrow new Error(\n\t\t\t\t`.koe fetch failed: response exceeds requested ${length} bytes`,\n\t\t\t);\n\t\t}\n\t\tout.set(value, received);\n\t\treceived += value.byteLength;\n\t}\n\treturn received === length ? out.buffer : out.buffer.slice(0, received);\n}\n\nfunction validateJsonLength(jsonLength: number): void {\n\tif (\n\t\t!Number.isInteger(jsonLength) ||\n\t\tjsonLength < 0 ||\n\t\tjsonLength > MAX_JSON_LENGTH\n\t) {\n\t\tthrow new Error(`manifest JSON length out of bounds: ${jsonLength}`);\n\t}\n}\n\nfunction parseManifest(json: ArrayBuffer): Manifest {\n\tconst manifest = JSON.parse(new TextDecoder().decode(json)) as Manifest;\n\tif (\n\t\t!manifest ||\n\t\ttypeof manifest !== \"object\" ||\n\t\ttypeof manifest.phonemes !== \"object\" ||\n\t\tmanifest.phonemes === null\n\t) {\n\t\tthrow new Error(\"invalid manifest: missing phonemes table\");\n\t}\n\treturn manifest;\n}\n\n/**\n * Read-only access to a .koe voice bank: its manifest plus per-phoneme PCM,\n * fetched on demand (Blob slice or HTTP Range). The full bank is never held in\n * memory.\n *\n * Pure data — no AudioContext, no AudioWorklet, no DOM. Use this when you only\n * need the source samples (e.g. to feed the {@link Worldline} renderer or any\n * other vocoder). {@link KoeEngine} builds its concatenative playback on top of\n * this same class.\n *\n * const bank = await VoiceBank.load(koeBlobOrUrl);\n * const pcm = await bank.getPcm('a'); // Float64 [-1, 1]\n */\nexport class VoiceBank {\n\tprivate constructor(\n\t\t/** The voice bank manifest (sample rate, reference pitch, phoneme table). */\n\t\treadonly manifest: Manifest,\n\t\tprivate source: VoiceSource,\n\t) {}\n\n\t/**\n\t * Parse a .koe archive header + manifest and bind a lazy PCM source.\n\t * @param koe a Blob/File of the .koe archive, or a URL (served with Range support)\n\t */\n\tstatic async load(koe: Blob | string): Promise<VoiceBank> {\n\t\ttry {\n\t\t\tif (typeof koe === \"string\") {\n\t\t\t\t// Range requests on blob: URLs are not portable (Firefox/Safari answer\n\t\t\t\t// 200); the data already lives in memory, so read it back as a Blob.\n\t\t\t\tif (/^blob:/i.test(koe)) {\n\t\t\t\t\tconst res = await fetch(koe);\n\t\t\t\t\tif (!res.ok) {\n\t\t\t\t\t\tthrow new Error(`blob: URL fetch failed: ${res.status}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn await VoiceBank.fromBlob(await res.blob());\n\t\t\t\t}\n\t\t\t\tif (!/^https?:/i.test(koe)) {\n\t\t\t\t\tthrow new Error(`unsupported URL protocol: ${koe}`);\n\t\t\t\t}\n\t\t\t\tconst header = await rangeFetch(koe, 0, 8);\n\t\t\t\tconst { jsonLength } = parseKoeHeader(header);\n\t\t\t\tvalidateJsonLength(jsonLength);\n\t\t\t\tconst json = await rangeFetch(koe, 8, jsonLength);\n\t\t\t\tconst manifest = parseManifest(json);\n\t\t\t\treturn new VoiceBank(\n\t\t\t\t\tmanifest,\n\t\t\t\t\tnew RangeVoiceSource(koe, pcmBase(jsonLength)),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn await VoiceBank.fromBlob(koe);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to load .koe voice bank: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate static async fromBlob(koe: Blob): Promise<VoiceBank> {\n\t\tconst header = await koe.slice(0, 8).arrayBuffer();\n\t\tconst { jsonLength } = parseKoeHeader(header);\n\t\tvalidateJsonLength(jsonLength);\n\t\tconst json = await koe.slice(8, 8 + jsonLength).arrayBuffer();\n\t\tconst manifest = parseManifest(json);\n\t\treturn new VoiceBank(\n\t\t\tmanifest,\n\t\t\tnew BlobVoiceSource(koe, pcmBase(jsonLength)),\n\t\t);\n\t}\n\n\t/** True if the bank contains a phoneme under this alias. */\n\thas(phoneme: string): boolean {\n\t\t// Own-property check: a plain [phoneme] access would also match inherited\n\t\t// Object.prototype keys like \"toString\" / \"constructor\".\n\t\treturn Object.hasOwn(this.manifest.phonemes, phoneme);\n\t}\n\n\t/**\n\t * Raw Int16 PCM bytes (48 kHz / mono) for a phoneme, or null if unknown.\n\t * The returned ArrayBuffer is freshly allocated and safe to transfer to a\n\t * worker / AudioWorklet.\n\t */\n\tasync readPcmBytes(phoneme: string): Promise<ArrayBuffer | null> {\n\t\tif (!Object.hasOwn(this.manifest.phonemes, phoneme)) return null;\n\t\tconst entry = this.manifest.phonemes[phoneme];\n\t\tif (\n\t\t\t!Number.isInteger(entry.offset) ||\n\t\t\t!Number.isInteger(entry.length) ||\n\t\t\tentry.offset < 0 ||\n\t\t\tentry.length < 0 ||\n\t\t\tentry.length > MAX_PHONEME_SAMPLES\n\t\t) {\n\t\t\tthrow new Error(`manifest entry out of bounds for phoneme: ${phoneme}`);\n\t\t}\n\t\treturn this.source.readBytes(entry.offset, entry.length * 2); // Int16 = 2 bytes/sample\n\t}\n\n\t/**\n\t * A phoneme's PCM as a Float64Array normalised to [-1, 1], or null if unknown.\n\t * Intended for external analysis / resynthesis such as the WORLD vocoder.\n\t */\n\tasync getPcm(phoneme: string): Promise<Float64Array | null> {\n\t\tconst buf = await this.readPcmBytes(phoneme);\n\t\tif (!buf) return null;\n\t\t// A truncated read (Blob clamped at EOF) can yield an odd byte count,\n\t\t// which the Int16Array(buffer) constructor rejects — floor to whole samples.\n\t\tconst int16 = new Int16Array(buf, 0, Math.floor(buf.byteLength / 2));\n\t\tconst f64 = new Float64Array(int16.length);\n\t\tfor (let i = 0; i < int16.length; i++) f64[i] = int16[i] / 32768;\n\t\treturn f64;\n\t}\n}\n","import type { Manifest, NoteEvent } from \"../types.js\";\r\nimport { VoiceBank } from \"./voice-bank.js\";\r\n\r\nexport type { NoteEvent };\r\n\r\nexport interface KoeEngineOptions {\r\n\t/** URL to koe-worklet.js. Defaults to './koe-worklet.js'. */\r\n\tworkletUrl?: string;\r\n}\r\n\r\nexport interface PlayOptions {\r\n\t/**\r\n\t * Play the first note's lead-in (its consonant / preutterance region) instead\r\n\t * of skipping straight to the vowel.\r\n\t *\r\n\t * Every note but the first gets its lead-in from the crossfade with the note\r\n\t * before it. The first note has no predecessor, so the lead-in has to come\r\n\t * from somewhere: with `leadIn` the phrase starts one preutterance EARLIER\r\n\t * relative to its beats, and {@link KoeEngine.play} returns that offset in\r\n\t * samples so a sequencer can schedule around it. Left off (the default), the\r\n\t * first note keeps its beat exactly but opens on its vowel, dropping the\r\n\t * consonant.\r\n\t */\r\n\tleadIn?: boolean;\r\n}\r\n\r\n/**\r\n * Main-thread API for the koe concatenative synthesis engine.\r\n *\r\n * Loads a single .koe archive. The full voice bank is never held in memory:\r\n * phonemes are fetched on demand (via {@link VoiceBank}) and cached in the\r\n * audio thread.\r\n *\r\n * const engine = new KoeEngine();\r\n * await engine.load(koeBlobOrUrl);\r\n * await engine.play([{ phoneme: 'a', pitch: 440, duration: 48000 }]);\r\n *\r\n * For analysis / resynthesis (e.g. {@link Worldline}) you usually only need the\r\n * raw samples — use {@link VoiceBank} directly instead, which needs no\r\n * AudioContext or worklet.\r\n */\r\nexport class KoeEngine {\r\n\tprivate ctx: AudioContext;\r\n\tprivate workletUrl: string;\r\n\tprivate node: AudioWorkletNode | null = null;\r\n\tprivate bank: VoiceBank | null = null;\r\n\tprivate delivered = new Set<string>();\r\n\tprivate pending = new Map<string, Promise<void>>();\r\n\r\n\tconstructor(options: KoeEngineOptions = {}) {\r\n\t\tthis.ctx = new AudioContext({ sampleRate: 48000 });\r\n\t\tthis.workletUrl = options.workletUrl ?? \"./koe-worklet.js\";\r\n\t}\r\n\r\n\tget audioContext(): AudioContext {\r\n\t\treturn this.ctx;\r\n\t}\r\n\r\n\tget manifest(): Manifest | null {\r\n\t\treturn this.bank?.manifest ?? null;\r\n\t}\r\n\r\n\t/** The underlying voice bank (manifest + on-demand PCM), or null before load(). */\r\n\tget voiceBank(): VoiceBank | null {\r\n\t\treturn this.bank;\r\n\t}\r\n\r\n\t/**\r\n\t * Register the worklet and bind a .koe voice bank.\r\n\t * @param koe a Blob/File of the .koe archive, or a URL (served with Range support)\r\n\t */\r\n\tasync load(koe: Blob | string): Promise<void> {\r\n\t\tawait this.ctx.audioWorklet.addModule(this.workletUrl);\r\n\r\n\t\t// Re-loading: tear down the previous node, or both would keep playing.\r\n\t\tthis.node?.disconnect();\r\n\t\tthis.node = null;\r\n\r\n\t\tthis.bank = await VoiceBank.load(koe);\r\n\t\tthis.delivered.clear();\r\n\t\tthis.pending.clear();\r\n\r\n\t\tthis.node = new AudioWorkletNode(this.ctx, \"koe-processor\", {\r\n\t\t\tnumberOfInputs: 0,\r\n\t\t\tnumberOfOutputs: 1,\r\n\t\t\toutputChannelCount: [1],\r\n\t\t});\r\n\t\tthis.node.port.postMessage({ type: \"init\", manifest: this.bank.manifest });\r\n\t\tthis.node.connect(this.ctx.destination);\r\n\r\n\t\tconsole.log(\r\n\t\t\t\"[koe] ready —\",\r\n\t\t\tObject.keys(this.bank.manifest.phonemes).length,\r\n\t\t\t\"phonemes (on-demand)\",\r\n\t\t);\r\n\t}\r\n\r\n\t/** Fetch one phoneme's PCM and deliver it to the worklet (deduped, cached). */\r\n\tprivate ensurePhoneme(name: string): Promise<void> {\r\n\t\tif (this.delivered.has(name)) return Promise.resolve();\r\n\t\tconst existing = this.pending.get(name);\r\n\t\tif (existing) return existing;\r\n\t\tif (!this.bank || !this.node) return Promise.resolve();\r\n\r\n\t\tconst load = this.bank\r\n\t\t\t.readPcmBytes(name)\r\n\t\t\t.then((buf) => {\r\n\t\t\t\tif (!buf || !this.node) return;\r\n\t\t\t\tthis.node.port.postMessage({ type: \"phoneme\", name, buffer: buf }, [\r\n\t\t\t\t\tbuf,\r\n\t\t\t\t]);\r\n\t\t\t\tthis.delivered.add(name);\r\n\t\t\t})\r\n\t\t\t.finally(() => {\r\n\t\t\t\t// Always clear pending — a failed fetch must stay retryable, or the\r\n\t\t\t\t// rejected promise would poison every later play() of this phoneme.\r\n\t\t\t\tthis.pending.delete(name);\r\n\t\t\t});\r\n\r\n\t\tthis.pending.set(name, load);\r\n\t\treturn load;\r\n\t}\r\n\r\n\t/**\r\n\t * Stop current playback, preload the phonemes for `notes`, then queue them.\r\n\t *\r\n\t * @returns the lead-in offset in samples — how far the first note's audio\r\n\t * starts ahead of its beat. 0 unless {@link PlayOptions.leadIn}.\r\n\t */\r\n\tasync play(notes: NoteEvent[], options: PlayOptions = {}): Promise<number> {\r\n\t\tif (!this.node) throw new Error(\"KoeEngine: call load() before play()\");\r\n\t\tthis.node.port.postMessage({ type: \"stop\" });\r\n\t\tconst names = [...new Set(notes.map((n) => n.phoneme))].filter(Boolean);\r\n\t\tawait Promise.all(names.map((n) => this.ensurePhoneme(n)));\r\n\t\tconst leadIn = options.leadIn === true;\r\n\t\tthis.node.port.postMessage({ type: \"play\", notes, leadIn });\r\n\t\treturn leadIn ? this.leadInSamples(notes) : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Output samples the first note's lead-in occupies ahead of its beat —\r\n\t * mirrors what the worklet does with `leadIn`, so callers can compensate.\r\n\t */\r\n\tprivate leadInSamples(notes: NoteEvent[]): number {\r\n\t\tconst first = notes[0];\r\n\t\tconst m = this.bank?.manifest;\r\n\t\tif (!first || !m || first.phoneme === \"\") return 0;\r\n\t\tconst entry = Object.hasOwn(m.phonemes, first.phoneme)\r\n\t\t\t? m.phonemes[first.phoneme]\r\n\t\t\t: undefined;\r\n\t\tif (!entry || entry.length <= 0) return 0;\r\n\t\tconst recorded = entry.pitch || m.referencePitch || first.pitch || 1;\r\n\t\tconst stepRate = first.pitch / recorded;\r\n\t\treturn stepRate > 0 ? entry.pre / stepRate : 0;\r\n\t}\r\n\r\n\t/** Stop playback and clear the queue. */\r\n\tstop(): void {\r\n\t\tthis.node?.port.postMessage({ type: \"stop\" });\r\n\t}\r\n\r\n\t/** Resume the AudioContext if suspended (e.g. after autoplay block). */\r\n\tasync resume(): Promise<void> {\r\n\t\tif (this.ctx.state === \"suspended\") await this.ctx.resume();\r\n\t}\r\n\r\n\t/**\r\n\t * Tear down the worklet node and close the AudioContext, releasing the audio\r\n\t * hardware. The engine cannot be reused afterwards — create a new one.\r\n\t */\r\n\tasync dispose(): Promise<void> {\r\n\t\tthis.node?.disconnect();\r\n\t\tthis.node = null;\r\n\t\tthis.bank = null;\r\n\t\tthis.delivered.clear();\r\n\t\tthis.pending.clear();\r\n\t\tif (this.ctx.state !== \"closed\") await this.ctx.close();\r\n\t}\r\n\r\n\t/**\r\n\t * Read a phoneme's raw PCM and return it as a Float64Array normalised to\r\n\t * [-1, 1]. Convenience that forwards to the underlying {@link VoiceBank}.\r\n\t * Intended for external analysis such as the WORLD vocoder.\r\n\t */\r\n\tasync getPcm(phoneme: string): Promise<Float64Array | null> {\r\n\t\treturn this.bank?.getPcm(phoneme) ?? null;\r\n\t}\r\n}\r\n","import type { PhonemeEntry } from \"../types.js\";\n\n/** Output sample rate of the worldline synthesizer. */\nexport const WORLDLINE_SAMPLE_RATE = 48000;\n\n/**\n * WORLD needs roughly 85 ms of audio for stable F0 analysis. Phonemes with\n * fewer samples than this are rejected (renderNote returns null).\n */\nexport const MIN_WORLDLINE_SAMPLES = 4096;\n\n/** SynthRequest struct layout — 120 bytes, WASM32. */\nconst SYNTH_REQ_SIZE = 120;\n/** Frame period hardcoded in worldline's phrase_synth.cpp. */\nconst WL_FRAME_MS = 10;\n\n/**\n * The subset of the Emscripten module surface that we call. worldline.js is an\n * MODULARIZE=1 / EXPORT_NAME=WorldlineModule build of OpenUtau's worldline.\n */\ninterface WorldlineWasm {\n\t_PhraseSynthNew(): number;\n\t_PhraseSynthDelete(ps: number): void;\n\t_PhraseSynthAddRequest(\n\t\tps: number,\n\t\treq: number,\n\t\tposMs: number,\n\t\tskipMs: number,\n\t\tlengthMs: number,\n\t\tfadeInMs: number,\n\t\tfadeOutMs: number,\n\t\tflag: number,\n\t): void;\n\t_PhraseSynthSetCurves(\n\t\tps: number,\n\t\tf0: number,\n\t\tgender: number,\n\t\ttension: number,\n\t\tbreathiness: number,\n\t\tvoicing: number,\n\t\tlength: number,\n\t\tframeMs: number,\n\t): void;\n\t_PhraseSynthSynth(ps: number, yPtrPtr: number, flag: number): number;\n\t_malloc(size: number): number;\n\t_free(ptr: number): void;\n\tsetValue(ptr: number, value: number, type: string): void;\n\tgetValue(ptr: number, type: string): number;\n\tHEAPF32: Float32Array;\n\tHEAPF64: Float64Array;\n}\n\ntype WorldlineFactory = (opts?: {\n\tlocateFile?: (path: string) => string;\n}) => Promise<WorldlineWasm>;\n\ndeclare global {\n\t// Injected by worldline.js when loaded as a classic <script> or via importScripts.\n\t// eslint-disable-next-line no-var\n\tvar WorldlineModule: WorldlineFactory | undefined;\n\t// Present in classic Web Workers (used to load worldline.js off the main thread).\n\t// eslint-disable-next-line no-var\n\tvar importScripts: ((...urls: string[]) => void) | undefined;\n}\n\nexport interface WorldlineLoadOptions {\n\t/**\n\t * URL of `worldline.js` (the Emscripten loader). The matching\n\t * `worldline.wasm` must sit next to it — it is resolved relative to this URL.\n\t *\n\t * When consuming koe from npm + a CDN this is typically e.g.\n\t * `https://cdn.jsdelivr.net/npm/@onjmin/koe/dist/world/worldline.js`, or your\n\t * own hosted copy of `dist/world/`.\n\t */\n\tscriptUrl: string;\n}\n\n/**\n * A per-frame expression value: either a flat constant for the whole note, or\n * a function evaluated once per 10ms WORLD frame for a custom curve (vibrato,\n * portamento, scoop-in, humanize jitter, hand-drawn automation, …).\n *\n * `tMs` is elapsed time from the start of the rendered buffer (0 = includes\n * the `preMs` lead-in), `totalMs` is the full rendered length (`preMs +\n * durationMs`). Callers own all curve shaping — worldline itself has no\n * opinion on what \"vibrato\" or \"scoop\" means, it just samples whatever\n * function you give it once per frame.\n */\nexport type CurveInput = number | ((tMs: number, totalMs: number) => number);\n\nconst sampleCurve = (\n\tinput: number,\n\tcurve: CurveInput,\n\ttotalMs: number,\n): number => (typeof curve === \"function\" ? curve(input, totalMs) : curve);\n\n/**\n * One sample placed on a phrase timeline (mirrors worldline's\n * `PhraseSynth::AddRequest` + the UTAU `SynthRequest` fields that matter for\n * speech). All times are ms.\n */\nexport interface PhraseUnit {\n\tpcm: Float64Array;\n\t/** Where the (offset-trimmed) sample head is placed on the phrase timeline. */\n\tposMs: number;\n\t/** Leading part of the resampled sample to skip before `posMs`. */\n\tskipMs: number;\n\t/** How much of the resampled sample is used from `posMs`. */\n\tlengthMs: number;\n\tfadeInMs: number;\n\tfadeOutMs: number;\n\t/** Fixed (unstretched) consonant region of the sample. */\n\tconsonantMs: number;\n\t/** Trim from the sample tail; defaults to two WORLD frames. */\n\tcutMs?: number;\n\t/**\n\t * UTAU \"required length\": the resampler stretches the sample to this total\n\t * length (consonant kept, vowel stretched). Defaults to `lengthMs`. UtauTTS\n\t * rounds it up to 50 ms steps so the vowel loop has slack for the release.\n\t */\n\trequiredLengthMs?: number;\n\t/** UTAU volume, 100 = unity. */\n\tvolume?: number;\n\t/**\n\t * MIDI note the resampler targets before the F0 curve is applied. Pick the\n\t * note closest to the sample's own pitch to keep the formant shift minimal.\n\t */\n\ttone?: number;\n}\n\nexport interface RenderPhraseParams {\n\tunits: PhraseUnit[];\n\tpitch: CurveInput;\n\tgender?: CurveInput;\n\ttension?: CurveInput;\n\tbreathiness?: CurveInput;\n\tvoicing?: CurveInput;\n\ttempo?: number;\n}\n\nexport interface RenderNoteParams {\n\t/**\n\t * Source phoneme PCM normalised to [-1, 1] (e.g. from\n\t * `VoiceBank.getPcm()` / `KoeEngine.getPcm()`).\n\t */\n\tpcm: Float64Array;\n\t/**\n\t * Target output pitch in Hz. Pass a function for vibrato, portamento,\n\t * scoop-in, pitch-drift humanize, etc. — it is sampled once per 10ms frame.\n\t */\n\tpitch: CurveInput;\n\t/** Sustain / vowel duration in ms (the lead-in below is rendered on top). */\n\tdurationMs: number;\n\t/** Preutterance / lead-in in ms — convert from {@link PhonemeEntry.pre}. */\n\tpreMs: number;\n\t/** Consonant length in ms — convert from {@link PhonemeEntry.consonant}. */\n\tconsonantMs: number;\n\t/** Reference tempo in BPM for worldline's internal timing. Default 120. */\n\ttempo?: number;\n\t/**\n\t * Formant/gender shift, 0-1. 0.5 (default) = unmodified. Below 0.5 skews\n\t * toward a lower/thicker formant (older, huskier); above 0.5 toward a\n\t * higher/thinner one (younger, brighter) — pitch itself is unaffected.\n\t */\n\tgender?: CurveInput;\n\t/**\n\t * Tension, 0-1. 0.5 (default) = neutral. Higher = tighter/more strained\n\t * (\"こぶし\"-style push); lower = more relaxed/breathy-adjacent.\n\t */\n\ttension?: CurveInput;\n\t/** Breathiness, 0-1. 0.5 (default) = neutral. Higher = airier/whispered. */\n\tbreathiness?: CurveInput;\n\t/**\n\t * Voicing ratio, 0-1. 1.0 (default) = fully voiced. Lower blends toward an\n\t * unvoiced/falsetto-adjacent texture.\n\t */\n\tvoicing?: CurveInput;\n}\n\n/** Convert a sample count at 48 kHz to milliseconds. */\nexport const samplesToMs = (samples: number): number =>\n\t(samples / WORLDLINE_SAMPLE_RATE) * 1000;\n\n/**\n * Derive {@link RenderNoteParams} lead-in / consonant fields from a manifest\n * entry, so callers don't repeat the sample→ms conversion.\n *\n * const params = { pcm, pitch, durationMs, ...leadInFromEntry(entry) };\n */\nexport function leadInFromEntry(entry: PhonemeEntry): {\n\tpreMs: number;\n\tconsonantMs: number;\n} {\n\treturn {\n\t\tpreMs: samplesToMs(entry.pre || 0),\n\t\tconsonantMs: samplesToMs(entry.consonant || 0),\n\t};\n}\n\n// Cache module factories by script URL so repeated loads share one WASM instance.\nconst moduleCache = new Map<string, Promise<WorldlineWasm>>();\n\nfunction injectScript(src: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst existing = document.querySelector<HTMLScriptElement>(\n\t\t\t`script[data-koe-worldline=\"${src}\"]`,\n\t\t);\n\t\tif (existing) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tconst s = document.createElement(\"script\");\n\t\ts.src = src;\n\t\ts.dataset.koeWorldline = src;\n\t\ts.onload = () => resolve();\n\t\ts.onerror = () => reject(new Error(`worldline: failed to load ${src}`));\n\t\tdocument.head.appendChild(s);\n\t});\n}\n\nfunction loadWasm(scriptUrl: string): Promise<WorldlineWasm> {\n\tconst cached = moduleCache.get(scriptUrl);\n\tif (cached) return cached;\n\n\tconst baseUrl = scriptUrl.slice(0, scriptUrl.lastIndexOf(\"/\") + 1);\n\tconst instantiate = (): Promise<WorldlineWasm> => {\n\t\tconst factory = globalThis.WorldlineModule;\n\t\tif (!factory)\n\t\t\tthrow new Error(\n\t\t\t\t\"worldline: WorldlineModule global was not defined by the script\",\n\t\t\t);\n\t\t// locateFile resolves worldline.wasm next to the script; fetch works in both\n\t\t// the DOM and Web Workers, so the WASM instantiates the same way off-thread.\n\t\treturn factory({ locateFile: (f: string) => baseUrl + f });\n\t};\n\n\tlet promise: Promise<WorldlineWasm>;\n\tif (typeof document !== \"undefined\") {\n\t\t// Main thread / DOM: load worldline.js via a <script> tag.\n\t\tpromise = injectScript(scriptUrl).then(instantiate);\n\t} else if (typeof globalThis.importScripts === \"function\") {\n\t\t// Classic Web Worker: importScripts runs worldline.js synchronously in the\n\t\t// worker's global scope, defining globalThis.WorldlineModule. This lets the\n\t\t// heavy WORLD synthesis run off the main thread.\n\t\tpromise = Promise.resolve().then(() => {\n\t\t\t(globalThis.importScripts as (...urls: string[]) => void)(scriptUrl);\n\t\t\treturn instantiate();\n\t\t});\n\t} else {\n\t\treturn Promise.reject(\n\t\t\tnew Error(\n\t\t\t\t\"Worldline.load requires a DOM or a classic Web Worker (importScripts) to load worldline.js\",\n\t\t\t),\n\t\t);\n\t}\n\tmoduleCache.set(scriptUrl, promise);\n\treturn promise;\n}\n\n/**\n * High-quality WORLD-vocoder note renderer (OpenUtau's worldline via WASM).\n *\n * Pure synthesis: PCM in → PCM out. No AudioContext, no scheduling — the caller\n * owns playback (schedule the returned buffer on its own timeline). Pair it with\n * {@link VoiceBank} for the source samples:\n *\n * const bank = await VoiceBank.load(koeUrl);\n * const wl = await Worldline.load({ scriptUrl: '.../world/worldline.js' });\n *\n * const entry = bank.manifest.phonemes[alias];\n * const pcm = await bank.getPcm(alias);\n * const audio = wl.renderNote({\n * pcm, pitch: 440, durationMs: 500, ...leadInFromEntry(entry),\n * });\n * // audio: Float32 @ 48 kHz, layout [lead-in/consonant ≈ preMs][vowel ≈ durationMs]\n */\nexport class Worldline {\n\treadonly sampleRate = WORLDLINE_SAMPLE_RATE;\n\n\tprivate constructor(private wasm: WorldlineWasm) {}\n\n\t/**\n\t * Load + instantiate the worldline WASM module (deduped per scriptUrl).\n\t *\n\t * Works on the main thread (loads via `<script>`) and inside a classic Web\n\t * Worker (loads via `importScripts`), so the heavy synthesis can run\n\t * off-thread. The matching `worldline.wasm` is fetched next to scriptUrl.\n\t */\n\tstatic async load(options: WorldlineLoadOptions): Promise<Worldline> {\n\t\treturn new Worldline(await loadWasm(options.scriptUrl));\n\t}\n\n\t/**\n\t * Render one note to Float32 PCM at 48 kHz.\n\t *\n\t * The output buffer is laid out as [lead-in/consonant ≈ preMs][vowel ≈\n\t * durationMs], rendered from sample offset 0 (no leading silence). The vowel\n\t * onset (the \"beat\") sits at ≈ preMs into the buffer, so a sequencer should\n\t * place the buffer at `beatTime − preMs` and may trim/crossfade the lead-in.\n\t *\n\t * No internal crossfade is applied — apply fades externally.\n\t *\n\t * @returns Float32 PCM, or null when `pcm` is shorter than\n\t * {@link MIN_WORLDLINE_SAMPLES} (too short for stable F0 analysis).\n\t */\n\n\trenderPhrase(params: RenderPhraseParams): Float32Array | null {\n\t\tconst {\n\t\t\tunits,\n\t\t\tpitch,\n\t\t\tgender = 0.5,\n\t\t\ttension = 0.5,\n\t\t\tbreathiness = 0.5,\n\t\t\tvoicing = 1.0,\n\t\t\ttempo = 120,\n\t\t} = params;\n\t\tif (units.length === 0) return null;\n\n\t\tconst WL = this.wasm;\n\t\tconst FS = WORLDLINE_SAMPLE_RATE;\n\n\t\t// Calculate total duration from the last unit's posMs + lengthMs\n\t\tlet totalMs = 0;\n\t\tfor (const u of units) {\n\t\t\tconst endMs = u.posMs + u.lengthMs;\n\t\t\tif (endMs > totalMs) totalMs = endMs;\n\t\t}\n\n\t\tconst ps = WL._PhraseSynthNew();\n\t\tif (!ps) return null;\n\n\t\tconst pointersToFree: number[] = [];\n\n\t\tfor (const u of units) {\n\t\t\tif (!u.pcm || u.pcm.length < MIN_WORLDLINE_SAMPLES) continue;\n\n\t\t\tconst reqPtr = WL._malloc(SYNTH_REQ_SIZE);\n\t\t\tif (!reqPtr) continue;\n\t\t\tpointersToFree.push(reqPtr);\n\n\t\t\tconst samplePtr = WL._malloc(u.pcm.length * 8);\n\t\t\tif (!samplePtr) continue;\n\t\t\tpointersToFree.push(samplePtr);\n\n\t\t\tWL.HEAPF64.set(u.pcm, samplePtr >> 3);\n\n\t\t\tconst sv = (off: number, val: number, type: string) =>\n\t\t\t\tWL.setValue(reqPtr + off, val, type);\n\t\t\tsv(0, FS, \"i32\");\n\t\t\tsv(4, u.pcm.length, \"i32\");\n\t\t\tsv(8, samplePtr, \"*\");\n\t\t\tsv(12, 0, \"i32\");\n\t\t\tsv(16, 0, \"*\");\n\t\t\t// The F0 curve set below overrides per-frame pitch; the tone only seeds\n\t\t\t// the resampler, so default to A4 unless the caller knows the sample pitch.\n\t\t\tsv(20, u.tone ?? 69, \"i32\");\n\t\t\tsv(24, 100.0, \"double\");\n\t\t\tsv(32, 0.0, \"double\");\n\t\t\tsv(40, u.requiredLengthMs ?? u.lengthMs, \"double\");\n\t\t\tsv(48, u.consonantMs, \"double\");\n\t\t\tconst cutMs = u.cutMs ?? WL_FRAME_MS * 2;\n\t\t\tsv(56, cutMs, \"double\");\n\t\t\tsv(64, u.volume ?? 100.0, \"double\");\n\t\t\tsv(72, 0.0, \"double\");\n\t\t\tsv(80, tempo, \"double\");\n\t\t\tsv(88, 0, \"i32\");\n\t\t\tsv(92, 0, \"*\");\n\t\t\tsv(96, 0, \"i32\");\n\t\t\tsv(100, 0, \"i32\");\n\t\t\tsv(104, 100, \"i32\");\n\t\t\tsv(108, 0, \"i32\");\n\t\t\tsv(112, 0, \"i32\");\n\t\t\tsv(116, 100, \"i32\");\n\n\t\t\tWL._PhraseSynthAddRequest(\n\t\t\t\tps,\n\t\t\t\treqPtr,\n\t\t\t\tu.posMs,\n\t\t\t\tu.skipMs,\n\t\t\t\tu.lengthMs,\n\t\t\t\tu.fadeInMs,\n\t\t\t\tu.fadeOutMs,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\n\t\ttotalMs += WL_FRAME_MS * 2;\n\t\tconst nFrames = Math.ceil(totalMs / WL_FRAME_MS) + 4;\n\t\tconst f0Arr = new Float64Array(nFrames);\n\t\tconst gArr = new Float64Array(nFrames);\n\t\tconst tArr = new Float64Array(nFrames);\n\t\tconst bArr = new Float64Array(nFrames);\n\t\tconst vArr = new Float64Array(nFrames);\n\n\t\tfor (let i = 0; i < nFrames; i++) {\n\t\t\tconst tMs = i * WL_FRAME_MS;\n\t\t\tf0Arr[i] = sampleCurve(tMs, pitch, totalMs);\n\t\t\tgArr[i] = sampleCurve(tMs, gender, totalMs);\n\t\t\ttArr[i] = sampleCurve(tMs, tension, totalMs);\n\t\t\tbArr[i] = sampleCurve(tMs, breathiness, totalMs);\n\t\t\tvArr[i] = sampleCurve(tMs, voicing, totalMs);\n\t\t}\n\n\t\tconst f0Ptr = WL._malloc(nFrames * 8);\n\t\tconst gPtr = WL._malloc(nFrames * 8);\n\t\tconst tPtr = WL._malloc(nFrames * 8);\n\t\tconst bPtr = WL._malloc(nFrames * 8);\n\t\tconst vPtr = WL._malloc(nFrames * 8);\n\n\t\tif (f0Ptr && gPtr && tPtr && bPtr && vPtr) {\n\t\t\tWL.HEAPF64.set(f0Arr, f0Ptr >> 3);\n\t\t\tWL.HEAPF64.set(gArr, gPtr >> 3);\n\t\t\tWL.HEAPF64.set(tArr, tPtr >> 3);\n\t\t\tWL.HEAPF64.set(bArr, bPtr >> 3);\n\t\t\tWL.HEAPF64.set(vArr, vPtr >> 3);\n\t\t\tWL._PhraseSynthSetCurves(\n\t\t\t\tps,\n\t\t\t\tf0Ptr,\n\t\t\t\tgPtr,\n\t\t\t\ttPtr,\n\t\t\t\tbPtr,\n\t\t\t\tvPtr,\n\t\t\t\tnFrames,\n\t\t\t\tWL_FRAME_MS,\n\t\t\t);\n\t\t}\n\n\t\tif (f0Ptr) WL._free(f0Ptr);\n\t\tif (gPtr) WL._free(gPtr);\n\t\tif (tPtr) WL._free(tPtr);\n\t\tif (bPtr) WL._free(bPtr);\n\t\tif (vPtr) WL._free(vPtr);\n\n\t\tconst yPtrPtr = WL._malloc(4);\n\t\tlet audio = null;\n\t\tif (yPtrPtr) {\n\t\t\tconst outLen = WL._PhraseSynthSynth(ps, yPtrPtr, 0);\n\t\t\tconst yPtr = WL.getValue(yPtrPtr, \"*\");\n\t\t\tif (outLen > 0 && yPtr) {\n\t\t\t\taudio = new Float32Array(WL.HEAPF32.buffer, yPtr, outLen).slice();\n\t\t\t\tWL._free(yPtr);\n\t\t\t}\n\t\t\tWL._free(yPtrPtr);\n\t\t}\n\n\t\tfor (const ptr of pointersToFree) {\n\t\t\tWL._free(ptr);\n\t\t}\n\t\tWL._PhraseSynthDelete(ps);\n\n\t\treturn audio;\n\t}\n\n\trenderNote(params: RenderNoteParams): Float32Array | null {\n\t\tconst {\n\t\t\tpcm,\n\t\t\tpitch,\n\t\t\tdurationMs,\n\t\t\tpreMs,\n\t\t\tconsonantMs,\n\t\t\ttempo = 120,\n\t\t\tgender = 0.5,\n\t\t\ttension = 0.5,\n\t\t\tbreathiness = 0.5,\n\t\t\tvoicing = 1.0,\n\t\t} = params;\n\t\tif (!pcm || pcm.length < MIN_WORLDLINE_SAMPLES) return null;\n\n\t\tconst WL = this.wasm;\n\t\tconst FS = WORLDLINE_SAMPLE_RATE;\n\t\t// Representative pitch for the resampler's target note — the midpoint of\n\t\t// the vowel sustain when pitch is a curve, otherwise the flat value.\n\t\tconst basePitch = sampleCurve(\n\t\t\tpreMs + durationMs / 2,\n\t\t\tpitch,\n\t\t\tpreMs + durationMs,\n\t\t);\n\t\tconst midiNote = Math.round(69 + 12 * Math.log2(basePitch / 440));\n\t\tconst posMs = 0; // no leading silence\n\t\tconst reqLen = preMs + durationMs; // render lead-in/consonant + vowel\n\n\t\t// cut_off must trim at least ~2 frames off the tail. PhraseSynth::AddRequest\n\t\t// computes the trim frame count as ceil(in_length_ms)/frame_ms, but\n\t\t// PyinEstimator yields floor(N/nhop)−1 frames — one fewer. With cut_off=0 the\n\t\t// requested frame count exceeds f0_.size() and Model::Trim's f0_.erase() runs\n\t\t// past end(), causing \"memory access out of bounds\". Trimming 2 frames keeps\n\t\t// it within bounds.\n\t\tconst cutMs = WL_FRAME_MS * 2;\n\n\t\tconst ps = WL._PhraseSynthNew();\n\t\tif (!ps) return null;\n\t\tconst reqPtr = WL._malloc(SYNTH_REQ_SIZE);\n\t\tif (!reqPtr) {\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tconst samplePtr = WL._malloc(pcm.length * 8);\n\t\tif (!samplePtr) {\n\t\t\tWL._free(reqPtr);\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tWL.HEAPF64.set(pcm, samplePtr >> 3);\n\n\t\tconst sv = (off: number, val: number, type: string) =>\n\t\t\tWL.setValue(reqPtr + off, val, type);\n\t\tsv(0, FS, \"i32\");\n\t\tsv(4, pcm.length, \"i32\");\n\t\tsv(8, samplePtr, \"*\");\n\t\tsv(12, 0, \"i32\");\n\t\tsv(16, 0, \"*\");\n\t\tsv(20, midiNote, \"i32\");\n\t\tsv(24, 100.0, \"double\");\n\t\tsv(32, 0.0, \"double\");\n\t\tsv(40, reqLen, \"double\");\n\t\tsv(48, consonantMs, \"double\");\n\t\tsv(56, cutMs, \"double\");\n\t\tsv(64, 100.0, \"double\");\n\t\tsv(72, 0.0, \"double\");\n\t\tsv(80, tempo, \"double\");\n\t\tsv(88, 0, \"i32\");\n\t\tsv(92, 0, \"*\");\n\t\tsv(96, 0, \"i32\");\n\t\tsv(100, 0, \"i32\");\n\t\tsv(104, 100, \"i32\");\n\t\tsv(108, 0, \"i32\");\n\t\tsv(112, 0, \"i32\");\n\t\tsv(116, 100, \"i32\");\n\n\t\t// skip/fadeIn/fadeOut all 0 — crossfade is handled externally.\n\t\tWL._PhraseSynthAddRequest(ps, reqPtr, posMs, 0.0, reqLen, 0.0, 0.0, 0);\n\t\tWL._free(samplePtr);\n\t\tWL._free(reqPtr);\n\n\t\tconst totalMs = posMs + reqLen + WL_FRAME_MS * 2;\n\t\tconst nFrames = Math.ceil(totalMs / WL_FRAME_MS) + 4;\n\t\t// Sample each curve once per 10ms frame. Plain numbers short-circuit to a\n\t\t// flat fill (same cost as before); functions get evaluated per-frame so\n\t\t// callers can draw vibrato, portamento, scoop-in, humanize jitter, etc.\n\t\tconst f0Arr = new Float64Array(nFrames);\n\t\tconst gArr = new Float64Array(nFrames);\n\t\tconst tArr = new Float64Array(nFrames);\n\t\tconst bArr = new Float64Array(nFrames);\n\t\tconst vArr = new Float64Array(nFrames);\n\t\tfor (let i = 0; i < nFrames; i++) {\n\t\t\tconst tMs = i * WL_FRAME_MS;\n\t\t\tf0Arr[i] = sampleCurve(tMs, pitch, totalMs);\n\t\t\tgArr[i] = sampleCurve(tMs, gender, totalMs);\n\t\t\ttArr[i] = sampleCurve(tMs, tension, totalMs);\n\t\t\tbArr[i] = sampleCurve(tMs, breathiness, totalMs);\n\t\t\tvArr[i] = sampleCurve(tMs, voicing, totalMs);\n\t\t}\n\n\t\tconst f0Ptr = WL._malloc(nFrames * 8);\n\t\tconst gPtr = WL._malloc(nFrames * 8);\n\t\tconst tPtr = WL._malloc(nFrames * 8);\n\t\tconst bPtr = WL._malloc(nFrames * 8);\n\t\tconst vPtr = WL._malloc(nFrames * 8);\n\t\tif (!f0Ptr || !gPtr || !tPtr || !bPtr || !vPtr) {\n\t\t\tif (f0Ptr) WL._free(f0Ptr);\n\t\t\tif (gPtr) WL._free(gPtr);\n\t\t\tif (tPtr) WL._free(tPtr);\n\t\t\tif (bPtr) WL._free(bPtr);\n\t\t\tif (vPtr) WL._free(vPtr);\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tWL.HEAPF64.set(f0Arr, f0Ptr >> 3);\n\t\tWL.HEAPF64.set(gArr, gPtr >> 3);\n\t\tWL.HEAPF64.set(tArr, tPtr >> 3);\n\t\tWL.HEAPF64.set(bArr, bPtr >> 3);\n\t\tWL.HEAPF64.set(vArr, vPtr >> 3);\n\t\tWL._PhraseSynthSetCurves(\n\t\t\tps,\n\t\t\tf0Ptr,\n\t\t\tgPtr,\n\t\t\ttPtr,\n\t\t\tbPtr,\n\t\t\tvPtr,\n\t\t\tnFrames,\n\t\t\tWL_FRAME_MS,\n\t\t);\n\t\tWL._free(f0Ptr);\n\t\tWL._free(gPtr);\n\t\tWL._free(tPtr);\n\t\tWL._free(bPtr);\n\t\tWL._free(vPtr);\n\n\t\tconst yPtrPtr = WL._malloc(4);\n\t\tif (!yPtrPtr) {\n\t\t\tWL._PhraseSynthDelete(ps);\n\t\t\treturn null;\n\t\t}\n\t\tconst outLen = WL._PhraseSynthSynth(ps, yPtrPtr, 0);\n\t\tconst yPtr = WL.getValue(yPtrPtr, \"*\");\n\t\tconst audio =\n\t\t\toutLen > 0 && yPtr\n\t\t\t\t? new Float32Array(WL.HEAPF32.buffer, yPtr, outLen).slice()\n\t\t\t\t: null;\n\t\t// The wrapper allocates *y with `new float[]` for the caller to release;\n\t\t// Emscripten's operator new is malloc-backed, so _free reclaims it.\n\t\tif (yPtr) WL._free(yPtr);\n\t\tWL._free(yPtrPtr);\n\t\tWL._PhraseSynthDelete(ps);\n\t\treturn audio;\n\t}\n}\n","/**\n * Frame-level acoustic features used to locate mora boundaries.\n *\n * Everything downstream reasons in *frames* at a fixed 2 ms hop, so a frame\n * index doubles as a millisecond timestamp once multiplied by {@link HOP_MS}.\n * The analysis runs at 16 kHz regardless of the source rate: that is well past\n * the 4–8 kHz band where fricative noise lives, and keeps a 512-point FFT to\n * 32 ms — short enough to see a plosive burst, long enough to resolve F1.\n */\n\nimport { parseWav, resample, toMono, type WavData } from \"../converter/wav.js\";\n\n/** Analysis rate. */\nexport const RATE = 16000;\n/** Hop between frames, in milliseconds. */\nexport const HOP_MS = 2;\n\nconst HOP = (RATE * HOP_MS) / 1000; // 32 samples\nconst FFT_SIZE = 512; // 32 ms window\nconst BINS = FFT_SIZE / 2;\n/** Pitch analysis runs on a ×2 decimation of the 16 kHz signal. */\nconst PITCH_DECIM = 2;\nconst PITCH_RATE = RATE / PITCH_DECIM; // 8 kHz\nconst PITCH_WIN = 512; // 64 ms — at least 4 periods at 70 Hz\nconst MIN_F0 = 70;\nconst MAX_F0 = 600;\n\nexport interface Frames {\n\t/** Number of frames. */\n\tn: number;\n\t/** Source duration in milliseconds. */\n\tdurationMs: number;\n\t/** Short-time level in dBFS, −120 for digital silence. */\n\trmsDb: Float32Array;\n\t/** {@link rmsDb} smoothed over ~30 ms, for threshold crossings. */\n\tsmoothDb: Float32Array;\n\t/** Normalised autocorrelation peak, 0–1. Above ~0.5 reads as voiced. */\n\tvoiced: Float32Array;\n\t/** Share of spectral energy above 4 kHz — high for /s/, /sh/, /ch/. */\n\thighRatio: Float32Array;\n\t/** Level of the >4 kHz band alone, in dB. Frication shows here first. */\n\thighDb: Float32Array;\n\t/** Noise floor of {@link highDb}, in dB. */\n\thighFloorDb: number;\n\t/** Positive spectral flux, normalised so its own median is 1. */\n\tflux: Float32Array;\n\t/** Median f0 of the voiced portion, in Hz (0 when nothing is voiced). */\n\tf0: number;\n\t/** Noise floor in dBFS, estimated from the quietest tenth of the file. */\n\tfloorDb: number;\n\t/**\n\t * Level of the quietest 50 ms in the file — a true noise floor, unlike\n\t * {@link floorDb}, which a short recording's own voice can drag upwards.\n\t * Used to trace an attack back past the point where it is merely audible.\n\t */\n\tquietDb: number;\n\t/** Loudest smoothed frame, in dBFS. */\n\tpeakDb: number;\n}\n\n/**\n * Offset from a frame's first sample to the middle of its analysis window.\n *\n * Every feature a frame carries describes the whole window, so the event it\n * reports actually happened around the window's centre. Ignoring that biases\n * every boundary half a window early — 16 ms here, which is large enough to\n * shift a preutterance audibly.\n */\nconst WINDOW_CENTRE_MS = (FFT_SIZE / 2 / RATE) * 1000;\n\n/** Convert a *duration* in milliseconds to a count of frames. */\nexport function msToFrame(ms: number): number {\n\treturn Math.round(ms / HOP_MS);\n}\n\n/** Convert a *duration* in frames to milliseconds. */\nexport function framesToMs(frames: number): number {\n\treturn frames * HOP_MS;\n}\n\n/** Convert a frame *index* to the time in the signal that it describes. */\nexport function frameTimeMs(frame: number): number {\n\treturn frame * HOP_MS + WINDOW_CENTRE_MS;\n}\n\n/** In-place iterative radix-2 FFT over split real/imaginary arrays. */\nfunction fft(re: Float32Array, im: Float32Array): void {\n\tconst n = re.length;\n\tfor (let i = 1, j = 0; i < n; i++) {\n\t\tlet bit = n >> 1;\n\t\tfor (; j & bit; bit >>= 1) j ^= bit;\n\t\tj ^= bit;\n\t\tif (i < j) {\n\t\t\t[re[i], re[j]] = [re[j], re[i]];\n\t\t\t[im[i], im[j]] = [im[j], im[i]];\n\t\t}\n\t}\n\tfor (let len = 2; len <= n; len <<= 1) {\n\t\tconst ang = (-2 * Math.PI) / len;\n\t\tconst wRe = Math.cos(ang);\n\t\tconst wIm = Math.sin(ang);\n\t\tfor (let i = 0; i < n; i += len) {\n\t\t\tlet curRe = 1;\n\t\t\tlet curIm = 0;\n\t\t\tfor (let k = 0; k < len >> 1; k++) {\n\t\t\t\tconst aRe = re[i + k];\n\t\t\t\tconst aIm = im[i + k];\n\t\t\t\tconst bRe =\n\t\t\t\t\tre[i + k + (len >> 1)] * curRe - im[i + k + (len >> 1)] * curIm;\n\t\t\t\tconst bIm =\n\t\t\t\t\tre[i + k + (len >> 1)] * curIm + im[i + k + (len >> 1)] * curRe;\n\t\t\t\tre[i + k] = aRe + bRe;\n\t\t\t\tim[i + k] = aIm + bIm;\n\t\t\t\tre[i + k + (len >> 1)] = aRe - bRe;\n\t\t\t\tim[i + k + (len >> 1)] = aIm - bIm;\n\t\t\t\tconst nextRe = curRe * wRe - curIm * wIm;\n\t\t\t\tcurIm = curRe * wIm + curIm * wRe;\n\t\t\t\tcurRe = nextRe;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Noise floor: the level of the quietest 50 ms in the file.\n *\n * A low percentile is the obvious estimator and the wrong one — a short,\n * quietly recorded mora can be more than 90 % voice, which drags a tenth-\n * percentile \"floor\" up into the consonant and hides the attack entirely.\n */\nfunction quietestWindow(db: Float32Array): number {\n\tconst averaged = smooth(db, Math.round(50 / HOP_MS));\n\tlet min = Infinity;\n\tfor (let i = 0; i < averaged.length; i++) {\n\t\tif (averaged[i] < min) min = averaged[i];\n\t}\n\treturn Number.isFinite(min) ? min : -120;\n}\n\nfunction percentile(values: Float32Array, p: number): number {\n\tconst sorted = Float32Array.from(values).sort();\n\tconst i = Math.min(\n\t\tsorted.length - 1,\n\t\tMath.max(0, Math.round(p * (sorted.length - 1))),\n\t);\n\treturn sorted[i];\n}\n\n/**\n * Normalised cross-correlation of `buf` at `lag`, over `win` samples from\n * `at`. Returns a value in [-1, 1]; 1 means perfectly periodic at that lag.\n */\nfunction ncc(buf: Float32Array, at: number, win: number, lag: number): number {\n\tlet r = 0;\n\tlet e0 = 0;\n\tlet e1 = 0;\n\tfor (let i = 0; i < win; i++) {\n\t\tconst a = buf[at + i];\n\t\tconst b = buf[at + i + lag];\n\t\tr += a * b;\n\t\te0 += a * a;\n\t\te1 += b * b;\n\t}\n\tconst denom = Math.sqrt(e0 * e1);\n\treturn denom > 1e-12 ? r / denom : 0;\n}\n\n/** Extract every feature the mora estimator needs from one mono signal. */\nexport function analyze(wav: WavData): Frames {\n\tconst mono = resample(toMono(wav), RATE);\n\tconst x = mono.samples;\n\tconst n = Math.max(1, Math.floor((x.length - FFT_SIZE) / HOP) + 1);\n\n\tconst rmsDb = new Float32Array(n);\n\tconst highRatio = new Float32Array(n);\n\tconst highDb = new Float32Array(n);\n\tconst flux = new Float32Array(n);\n\tconst voiced = new Float32Array(n);\n\n\tconst window = new Float32Array(FFT_SIZE);\n\tfor (let i = 0; i < FFT_SIZE; i++) {\n\t\twindow[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / FFT_SIZE);\n\t}\n\n\tconst re = new Float32Array(FFT_SIZE);\n\tconst im = new Float32Array(FFT_SIZE);\n\tconst mag = new Float32Array(BINS);\n\tconst prevMag = new Float32Array(BINS);\n\t// 4 kHz is the boundary between \"voice\" and \"sibilant hiss\" at this rate.\n\tconst highBin = Math.floor((4000 / (RATE / 2)) * BINS);\n\n\tfor (let t = 0; t < n; t++) {\n\t\tconst off = t * HOP;\n\t\tlet energy = 0;\n\t\tfor (let i = 0; i < FFT_SIZE; i++) {\n\t\t\tconst s = x[off + i] ?? 0;\n\t\t\tenergy += s * s;\n\t\t\tre[i] = s * window[i];\n\t\t\tim[i] = 0;\n\t\t}\n\t\trmsDb[t] = 10 * Math.log10(energy / FFT_SIZE + 1e-12);\n\n\t\tfft(re, im);\n\n\t\tlet lowSum = 0;\n\t\tlet highSum = 0;\n\t\tlet fluxSum = 0;\n\t\tfor (let b = 1; b < BINS; b++) {\n\t\t\tconst m = Math.sqrt(re[b] * re[b] + im[b] * im[b]);\n\t\t\tmag[b] = m;\n\t\t\tif (b < highBin) lowSum += m;\n\t\t\telse highSum += m;\n\t\t\t// Log-domain flux: a doubling counts the same whether the frame is\n\t\t\t// loud or quiet, so a consonant release inside a soft passage still\n\t\t\t// registers as an onset.\n\t\t\tconst d = Math.log10(m + 1e-6) - Math.log10(prevMag[b] + 1e-6);\n\t\t\tif (d > 0) fluxSum += d;\n\t\t}\n\t\tprevMag.set(mag);\n\t\thighRatio[t] = highSum / (lowSum + highSum + 1e-12);\n\t\thighDb[t] = 20 * Math.log10(highSum / BINS + 1e-9);\n\t\tflux[t] = t === 0 ? 0 : fluxSum;\n\t}\n\n\tconst smoothDb = smooth(rmsDb, Math.round(30 / HOP_MS));\n\tconst smoothHighDb = smooth(highDb, Math.round(20 / HOP_MS));\n\tconst highFloorDb = quietestWindow(smoothHighDb);\n\tconst floorDb = percentile(smoothDb, 0.1);\n\tconst quietDb = quietestWindow(smoothDb);\n\tlet peakDb = -120;\n\tfor (let t = 0; t < n; t++) if (smoothDb[t] > peakDb) peakDb = smoothDb[t];\n\n\t// --- pitch ---------------------------------------------------------------\n\t// Decimate for speed, then find the file's own f0 once and track only a\n\t// narrow lag band around it. A full search per frame would dominate runtime\n\t// and, on a single sustained note, buy nothing.\n\tconst pitchBuf = new Float32Array(Math.floor(x.length / PITCH_DECIM));\n\tfor (let i = 0; i < pitchBuf.length; i++) {\n\t\tpitchBuf[i] = (x[i * PITCH_DECIM] + x[i * PITCH_DECIM + 1]) * 0.5;\n\t}\n\tconst minLag = Math.floor(PITCH_RATE / MAX_F0);\n\tconst maxLag = Math.floor(PITCH_RATE / MIN_F0);\n\n\tconst loud: number[] = [];\n\tfor (let t = 0; t < n; t++) {\n\t\tif (smoothDb[t] > peakDb - 10) loud.push(t);\n\t}\n\tconst lags: number[] = [];\n\tconst step = Math.max(1, Math.floor(loud.length / 24));\n\tfor (let k = 0; k < loud.length; k += step) {\n\t\tconst at = Math.floor((loud[k] * HOP) / PITCH_DECIM);\n\t\tif (at + PITCH_WIN + maxLag >= pitchBuf.length) continue;\n\t\tlet best = 0;\n\t\tlet bestLag = 0;\n\t\tfor (let lag = minLag; lag <= maxLag; lag++) {\n\t\t\tconst v = ncc(pitchBuf, at, PITCH_WIN, lag);\n\t\t\tif (v > best) {\n\t\t\t\tbest = v;\n\t\t\t\tbestLag = lag;\n\t\t\t}\n\t\t}\n\t\tif (best > 0.5 && bestLag > 0) lags.push(bestLag);\n\t}\n\tlags.sort((a, b) => a - b);\n\tconst centreLag = lags.length ? lags[lags.length >> 1] : 0;\n\tconst f0 = centreLag ? PITCH_RATE / centreLag : 0;\n\n\tif (centreLag) {\n\t\tconst lo = Math.max(minLag, Math.floor(centreLag / 1.7));\n\t\tconst hi = Math.min(maxLag, Math.ceil(centreLag * 1.7));\n\t\tfor (let t = 0; t < n; t++) {\n\t\t\t// Silence is never voiced, and skipping it keeps the inner loop off\n\t\t\t// the long tails of room tone that bracket every recording.\n\t\t\tif (smoothDb[t] < floorDb + 6) continue;\n\t\t\tconst at = Math.floor((t * HOP) / PITCH_DECIM);\n\t\t\tif (at + PITCH_WIN + hi >= pitchBuf.length) continue;\n\t\t\tlet best = 0;\n\t\t\tfor (let lag = lo; lag <= hi; lag++) {\n\t\t\t\tconst v = ncc(pitchBuf, at, PITCH_WIN, lag);\n\t\t\t\tif (v > best) best = v;\n\t\t\t}\n\t\t\tvoiced[t] = best;\n\t\t}\n\t}\n\n\t// Normalise flux by its own median so thresholds are scale-free.\n\tconst medianFlux = percentile(flux, 0.5) || 1;\n\tfor (let t = 0; t < n; t++) flux[t] /= medianFlux;\n\n\treturn {\n\t\tn,\n\t\tdurationMs: (x.length / RATE) * 1000,\n\t\trmsDb,\n\t\tsmoothDb,\n\t\tvoiced,\n\t\thighRatio,\n\t\thighDb: smoothHighDb,\n\t\thighFloorDb,\n\t\tflux: smooth(flux, 3),\n\t\tf0,\n\t\tfloorDb,\n\t\tquietDb,\n\t\tpeakDb,\n\t};\n}\n\n/** Centred moving average over `width` frames, with shrinking edge windows. */\nexport function smooth(src: Float32Array, width: number): Float32Array {\n\tif (width <= 1) return Float32Array.from(src);\n\tconst prefix = new Float64Array(src.length + 1);\n\tfor (let i = 0; i < src.length; i++) prefix[i + 1] = prefix[i] + src[i];\n\n\tconst out = new Float32Array(src.length);\n\tconst half = width >> 1;\n\tfor (let i = 0; i < src.length; i++) {\n\t\tconst lo = Math.max(0, i - half);\n\t\tconst hi = Math.min(src.length, i + half + 1);\n\t\tout[i] = (prefix[hi] - prefix[lo]) / (hi - lo);\n\t}\n\treturn out;\n}\n\n/** Convenience wrapper: decode a WAV buffer and analyse it. */\nexport function analyzeWav(buf: ArrayBuffer): Frames {\n\treturn analyze(parseWav(buf));\n}\n","/**\n * Parameter estimation for oto.ini entries.\n *\n * The rules encoded here follow the UTAU音源制作wiki's 原音設定 articles\n * (https://w.atwiki.jp/vbmaker/pages/17.html and its 単独音 / 連続音 sequels):\n *\n * - オフセット sits just before the consonant, keeping a little room so the\n * attack is never clipped.\n * - 先行発声 marks where the *vowel* begins — the voicing onset for a voiceless\n * consonant, the release for a nasal or a flap, the midpoint of the glide for\n * や/わ行.\n * - 子音部 runs from the offset through the vowel's onset until the spectrum\n * settles, so a long note stretches only steady-state vowel.\n * - オーバーラップ is ~20 ms for さ/な/ま/ら行, ~30 ms for や/わ行, and goes\n * *negative* for 破裂音 to reproduce the silent closure of か/た/ぱ行.\n * - 右ブランク lands just before the note starts to decay.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\nimport {\n\ttype Frames,\n\tframesToMs,\n\tframeTimeMs,\n\tHOP_MS,\n\tmsToFrame,\n\tsmooth,\n} from \"./frames.js\";\nimport type { ConsonantClass, Syllable } from \"./kana.js\";\n\n/** Per-class settings derived from the wiki's 原音設定解説. */\ninterface Articulation {\n\t/**\n\t * Longest consonant kept ahead of the vowel. The wiki warns that a 先行発声\n\t * past ~100 ms reads as a staccato \"溜め\"; sibilants are the exception, and\n\t * routinely run longer in hand-tuned banks.\n\t */\n\tmaxConsonantMs: number;\n\t/** Silence kept before the consonant so the attack is not clipped. */\n\tleadInMs: number;\n\t/**\n\t * オーバーラップ as a fraction of the preutterance.\n\t *\n\t * The wiki gives absolutes — 20 ms for さ/な/ま/ら行, 30 ms for や/わ行,\n\t * \"下限は15ミリ秒、上限は先行発声と同じ値くらい\" — but a fraction expresses the\n\t * same rule while scaling with how long the consonant actually came out. The\n\t * ratios below are what the reference banks work out to: roughly 0.6 of the\n\t * preutterance for sonorants, 0.3 for the obstruents whose noise should not\n\t * bleed into the previous note.\n\t */\n\toverlapRatio: number;\n\t/** Overrides {@link overlapRatio} when the class wants a fixed value. */\n\tfixedOverlapMs?: number;\n\t/** True when the vocal folds are already running during the consonant. */\n\tvoicedConsonant: boolean;\n\t/** True when the consonant is noise, and so begins in the >4 kHz band. */\n\tfricationOnset: boolean;\n}\n\nconst ARTICULATION: Record<ConsonantClass, Articulation> = {\n\tvowel: {\n\t\tmaxConsonantMs: 40,\n\t\tleadInMs: 3,\n\t\toverlapRatio: 0,\n\t\tfixedOverlapMs: 20,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tnasalN: {\n\t\tmaxConsonantMs: 40,\n\t\tleadInMs: 3,\n\t\toverlapRatio: 0,\n\t\tfixedOverlapMs: 20,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tnasal: {\n\t\tmaxConsonantMs: 110,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tliquid: {\n\t\tmaxConsonantMs: 80,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tsemivowel: {\n\t\tmaxConsonantMs: 75,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.6,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n\tfricativeVoiceless: {\n\t\tmaxConsonantMs: 140,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.3,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: true,\n\t},\n\tfricativeVoiced: {\n\t\tmaxConsonantMs: 130,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.4,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: true,\n\t},\n\taffricate: {\n\t\tmaxConsonantMs: 120,\n\t\tleadInMs: 5,\n\t\toverlapRatio: 0.3,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: true,\n\t},\n\tplosiveVoiceless: {\n\t\tmaxConsonantMs: 90,\n\t\tleadInMs: 8,\n\t\toverlapRatio: 0,\n\t\t// か/た/ぱ行 need a gap, not a crossfade: the wiki asks for a negative\n\t\t// overlap so the closure that precedes the burst survives synthesis.\n\t\tfixedOverlapMs: -10,\n\t\tvoicedConsonant: false,\n\t\tfricationOnset: false,\n\t},\n\tplosiveVoiced: {\n\t\tmaxConsonantMs: 90,\n\t\tleadInMs: 8,\n\t\toverlapRatio: 0.55,\n\t\tvoicedConsonant: true,\n\t\tfricationOnset: false,\n\t},\n};\n\n/** Overlap never goes below this, nor above the preutterance. */\nconst MIN_OVERLAP_MS = 12;\nconst MAX_OVERLAP_MS = 40;\n\n/** Periodicity above which a frame counts as voiced. */\nconst VOICED_THRESHOLD = 0.55;\n/** A voiced run shorter than this is a glitch, not the start of a vowel. */\nconst VOICED_RUN_MS = 24;\n/** な/ま/ら行 always hold their consonant at least this long before releasing. */\nconst MIN_VOICED_CONSONANT_MS = 22;\n/**\n * Frames added to a within-phrase onset before it is taken as the vowel start.\n *\n * The onset track peaks while the transition is still happening; the note\n * belongs where the new vowel has arrived, which the reference banks put\n * consistently later.\n */\nconst SEQUENCE_ONSET_BIAS = 12; // 24 ms\n\n/** Ceiling on a 連続音 entry's 先行発声, in milliseconds. */\nconst MAX_SEQUENCE_PRE_MS = 250;\n/** dB below the note's peak at which it counts as having started to decay. */\nconst DECAY_DROP_DB = 4;\n/** Margin left between the end of the usable region and the note's release. */\nconst RELEASE_GUARD_FRAMES = 10; // 20 ms\n\nfunction clamp(v: number, lo: number, hi: number): number {\n\treturn Math.min(hi, Math.max(lo, v));\n}\n\n/** How far above the noise floor a frame has to sit to count as sound. */\nconst SOUND_OVER_FLOOR_DB = 8;\n/** Ceiling on that threshold, relative to the loudest frame. */\nconst SOUND_UNDER_PEAK_DB = 15;\n/** dB the level must still be dropping over 6 ms for the attack to continue. */\nconst ATTACK_SLOPE_DB = 1;\n/** Share of energy above 4 kHz that marks a frame as frication. */\nconst FRICATION_HIGH_RATIO = 0.45;\n/**\n * Frication has to sit within this much of the loudest frame to count.\n *\n * Not a distance above the noise floor: on a recording cropped so tightly that\n * the /s/ *is* the quietest thing in the file, there is no floor to measure\n * against, and the loudest frame is the only stable reference.\n */\nconst FRICATION_UNDER_PEAK_DB = 30;\n\n/** Level above which a frame is \"sound\" rather than room tone. */\nfunction soundThreshold(f: Frames): number {\n\treturn Math.min(\n\t\tMath.max(f.floorDb + SOUND_OVER_FLOOR_DB, f.peakDb - 34),\n\t\tf.peakDb - SOUND_UNDER_PEAK_DB,\n\t);\n}\n\n/** First frame in [from, to) whose smoothed level clears the sound threshold. */\nexport function findSoundStart(f: Frames, from: number, to: number): number {\n\tconst th = soundThreshold(f);\n\tfor (let t = Math.max(0, from); t < Math.min(f.n, to); t++) {\n\t\tif (f.smoothDb[t] >= th) return t;\n\t}\n\treturn Math.max(0, from);\n}\n\n/** Last frame in (from, to] still above the sound threshold. */\nexport function findSoundEnd(f: Frames, from: number, to: number): number {\n\tconst th = soundThreshold(f);\n\tfor (let t = Math.min(f.n, to) - 1; t > from; t--) {\n\t\tif (f.smoothDb[t] >= th) return t;\n\t}\n\treturn Math.min(f.n - 1, to);\n}\n\n/**\n * Where the consonant itself begins.\n *\n * Broadband level finds most attacks, but /s/ and /sh/ start as quiet hiss that\n * barely moves the meter while dominating the band above 4 kHz. Watching that\n * band as well is what stops さ行 from being set up as if the vowel's own\n * aspiration were the consonant.\n */\nexport function findConsonantStart(\n\tf: Frames,\n\tfrom: number,\n\tto: number,\n\tfrication: boolean,\n): number {\n\tconst lo = Math.max(0, from);\n\tlet start = findSoundStart(f, from, to);\n\n\tif (frication) {\n\t\t// /s/ and /sh/ can be 20 dB down on the vowel and still be unmistakable,\n\t\t// because almost all of what little energy they have sits above 4 kHz.\n\t\t// A ratio test catches that where an absolute level never would — and on\n\t\t// a tightly cropped recording there is no quiet high band to compare to.\n\t\tconst level = f.peakDb - FRICATION_UNDER_PEAK_DB;\n\t\tconst absolute = f.highFloorDb + 8;\n\t\tfor (let t = lo; t < start; t++) {\n\t\t\tconst byRatio =\n\t\t\t\tf.highRatio[t] >= FRICATION_HIGH_RATIO && f.smoothDb[t] >= level;\n\t\t\tif (byRatio || f.highDb[t] >= absolute) {\n\t\t\t\tstart = t;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// The threshold above says \"this is clearly the mora\"; the attack itself\n\t// begins earlier. Walk back while the level is still falling — /h/ and /f/\n\t// ramp in over tens of milliseconds without ever being loud or sibilant, and\n\t// a ramp is the one thing that distinguishes them from room tone, which is\n\t// flat. Stop where the curve levels off, or where it reaches the floor.\n\tconst foot = f.quietDb + 6;\n\tconst k = Math.max(1, msToFrame(6));\n\twhile (start > lo) {\n\t\tconst back = Math.max(lo, start - k);\n\t\tconst stillFalling =\n\t\t\tf.smoothDb[start] - f.smoothDb[back] >= ATTACK_SLOPE_DB;\n\t\tif (!stillFalling && f.smoothDb[start - 1] <= foot) break;\n\t\tstart--;\n\t}\n\treturn start;\n}\n\n/**\n * First frame of a sustained voiced run in [from, to). This is the vowel onset\n * for か/さ/た/は/ぱ行, whose consonants carry no voicing of their own.\n */\nexport function findVoiceOnset(f: Frames, from: number, to: number): number {\n\tconst need = Math.ceil(VOICED_RUN_MS / HOP_MS);\n\tconst hi = Math.min(f.n, to);\n\tfor (let t = Math.max(0, from); t < hi; t++) {\n\t\tif (f.voiced[t] < VOICED_THRESHOLD) continue;\n\t\tlet run = 0;\n\t\twhile (t + run < hi && f.voiced[t + run] >= VOICED_THRESHOLD) run++;\n\t\tif (run >= need) return t;\n\t\tt += run;\n\t}\n\treturn -1;\n}\n\n/**\n * Where a *voiced* consonant hands over to its vowel.\n *\n * な/ま行 release into the vowel with a step up in level; ら行 flaps do the\n * same over a few milliseconds; ざ行 lose their high-frequency noise; や/わ行\n * glide, and the wiki asks for the midpoint of that glide. All four show up as\n * a peak in the same combined measure — a local rise in level plus spectral\n * change — so one search covers them.\n */\nfunction findVoicedRelease(f: Frames, from: number, to: number): number {\n\tconst lo = Math.max(1, from);\n\tconst hi = Math.min(f.n - 1, to);\n\tif (hi <= lo) return lo;\n\n\tconst k = Math.max(1, msToFrame(10));\n\tlet best = lo;\n\tlet bestScore = -Infinity;\n\tfor (let t = lo; t < hi; t++) {\n\t\tconst rise =\n\t\t\tf.smoothDb[Math.min(f.n - 1, t + k)] - f.smoothDb[Math.max(0, t - k)];\n\t\t// Losing sibilance is as much a vowel onset as gaining loudness: ざ行 and\n\t\t// じゃ行 arrive by shedding their noise band, not by getting louder.\n\t\tconst deSibilance =\n\t\t\t(f.highRatio[Math.max(0, t - k)] -\n\t\t\t\tf.highRatio[Math.min(f.n - 1, t + k)]) *\n\t\t\t30;\n\t\tconst score = rise + deSibilance + f.flux[t];\n\t\tif (score > bestScore) {\n\t\t\tbestScore = score;\n\t\t\tbest = t;\n\t\t}\n\t}\n\treturn best;\n}\n\n/**\n * End of the transition into the vowel: the point past which the spectrum\n * stops moving, which is where 子音部/固定範囲 may stop.\n */\nfunction findVowelStable(f: Frames, vowelOnset: number, limit: number): number {\n\tconst minMs = 45;\n\tconst maxMs = 110;\n\tconst from = vowelOnset + msToFrame(minMs);\n\tconst to = Math.min(limit, vowelOnset + msToFrame(maxMs));\n\tif (to <= from) return Math.min(limit, vowelOnset + msToFrame(minMs));\n\n\tconst calm = smooth(f.flux, Math.max(1, msToFrame(12)));\n\tconst need = Math.ceil(20 / HOP_MS);\n\tfor (let t = from; t < to - need; t++) {\n\t\tlet steady = true;\n\t\tfor (let k = 0; k < need; k++) {\n\t\t\tif (calm[t + k] > 1.05) {\n\t\t\t\tsteady = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (steady) return t;\n\t}\n\treturn to;\n}\n\n/**\n * Where the note starts to fall away. Walking forward from the loudest frame\n * keeps a slow vibrato dip from being mistaken for the release.\n */\nfunction findDecayStart(f: Frames, from: number, soundEnd: number): number {\n\tlet peak = from;\n\tfor (let t = from; t <= soundEnd; t++) {\n\t\tif (f.smoothDb[t] > f.smoothDb[peak]) peak = t;\n\t}\n\t// A shallow threshold on purpose: hand-set banks stop the 右ブランク while the\n\t// note is still strong, well before the tail has run out.\n\tconst th = f.smoothDb[peak] - DECAY_DROP_DB;\n\tconst need = Math.ceil(24 / HOP_MS);\n\tfor (let t = peak; t <= soundEnd - need; t++) {\n\t\tlet falling = true;\n\t\tfor (let k = 0; k < need; k++) {\n\t\t\tif (f.smoothDb[t + k] >= th) {\n\t\t\t\tfalling = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Back off a little further: 右ブランク should stop *before* the decay, so\n\t\t// nothing inside the stretched region is already fading.\n\t\tif (falling) return Math.max(from, t - RELEASE_GUARD_FRAMES);\n\t}\n\t// No clear release in range — the note runs to the end of what we can hear,\n\t// so keep the same margin off that instead.\n\treturn Math.max(from, soundEnd - RELEASE_GUARD_FRAMES);\n}\n\n/** True when a が/だ/ば行 mora prevoices — a low \"ん\"-like hum before the burst. */\nfunction hasPrevoicing(\n\tf: Frames,\n\tconsStart: number,\n\tvowelOnset: number,\n): boolean {\n\tif (vowelOnset - consStart < msToFrame(25)) return false;\n\tlet voicedFrames = 0;\n\tfor (let t = consStart; t < vowelOnset; t++) {\n\t\tif (f.voiced[t] >= VOICED_THRESHOLD) voicedFrames++;\n\t}\n\treturn voicedFrames >= (vowelOnset - consStart) * 0.6;\n}\n\n/** Frame positions the oto parameters are built from. */\nexport interface MoraPosition {\n\t/** Frame where the consonant (or vowel, if there is none) begins. */\n\tconsStart: number;\n\t/** Frame where the vowel begins — the 先行発声 anchor. */\n\tvowelOnset: number;\n\t/** Frame past which the vowel is steady. */\n\tstable: number;\n\t/** True when a voiced stop prevoiced into its burst. */\n\tprevoiced: boolean;\n}\n\n/**\n * Locate one mora inside `[from, to)`, given what consonant it starts with.\n */\nexport function locateMora(\n\tf: Frames,\n\tcls: ConsonantClass,\n\tfrom: number,\n\tto: number,\n): MoraPosition {\n\tconst art = ARTICULATION[cls];\n\tconst consStart = findConsonantStart(f, from, to, art.fricationOnset);\n\tconst searchEnd = Math.min(\n\t\tto,\n\t\tconsStart + msToFrame(art.maxConsonantMs + 60),\n\t);\n\n\tlet vowelOnset: number;\n\tif (!art.voicedConsonant) {\n\t\t// Voiceless consonant: the vowel is exactly where the folds start.\n\t\tconst v = findVoiceOnset(f, consStart, searchEnd);\n\t\tvowelOnset = v >= 0 ? v : consStart + msToFrame(30);\n\t} else if (cls === \"vowel\" || cls === \"nasalN\") {\n\t\tconst v = findVoiceOnset(f, consStart, searchEnd);\n\t\tvowelOnset = v >= 0 ? v : consStart;\n\t} else {\n\t\tconst voiceStart = findVoiceOnset(f, consStart, searchEnd);\n\t\tconst base = voiceStart >= 0 ? voiceStart : consStart;\n\t\t// な/ま行 hold their nasal for a good 30–80 ms before releasing, so the\n\t\t// search has to start past the voicing onset — otherwise the onset itself\n\t\t// is the strongest thing in the window and wins.\n\t\tvowelOnset = findVoicedRelease(\n\t\t\tf,\n\t\t\tbase + msToFrame(MIN_VOICED_CONSONANT_MS),\n\t\t\tMath.min(to, base + msToFrame(art.maxConsonantMs)),\n\t\t);\n\t}\n\tvowelOnset = clamp(vowelOnset, consStart, Math.max(consStart, to - 1));\n\n\treturn {\n\t\tconsStart,\n\t\tvowelOnset,\n\t\tstable: findVowelStable(f, vowelOnset, to),\n\t\tprevoiced:\n\t\t\tcls === \"plosiveVoiced\" && hasPrevoicing(f, consStart, vowelOnset),\n\t};\n}\n\n/** Round to the 0.001 ms oto.ini files conventionally carry. */\nfunction round(ms: number): number {\n\treturn Math.round(ms * 1000) / 1000;\n}\n\n/**\n * Turn frame positions into the five oto.ini numbers.\n *\n * `endFrame` is where the usable region stops; 右ブランク is always written in\n * its negative form (relative to the offset), which stays correct no matter how\n * much silence trails the file.\n */\nfunction buildEntry(\n\twav: string,\n\talias: string,\n\tf: Frames,\n\tcls: ConsonantClass,\n\tpos: MoraPosition,\n\tendFrame: number,\n): OtoEntry {\n\tconst art = ARTICULATION[cls];\n\n\t// Offset: leave a little air before the attack, but never let the consonant\n\t// run longer than the class allows.\n\tlet offsetMs = frameTimeMs(pos.consStart) - art.leadInMs;\n\tconst vowelMs = frameTimeMs(pos.vowelOnset);\n\toffsetMs = Math.max(offsetMs, vowelMs - art.maxConsonantMs);\n\toffsetMs = clamp(offsetMs, 0, Math.max(0, vowelMs - 1));\n\n\tconst pre = Math.max(1, vowelMs - offsetMs);\n\n\tlet overlap: number;\n\tif (art.fixedOverlapMs !== undefined) {\n\t\t// Bare vowels have no consonant to hide a crossfade in, so the wiki lets\n\t\t// the overlap run past the (tiny) preutterance; plosives take their\n\t\t// negative closure gap. Neither scales with anything measured.\n\t\toverlap = art.fixedOverlapMs;\n\t} else {\n\t\t// \"下限はどの発音であっても早くて15ミリ秒程度、上限は先行発声と同じ値くらい\"\n\t\toverlap = clamp(\n\t\t\tart.overlapRatio * pre,\n\t\t\tMath.min(MIN_OVERLAP_MS, pre),\n\t\t\tMath.min(MAX_OVERLAP_MS, pre),\n\t\t);\n\t}\n\n\t// 子音部: through the vowel onset and on until the vowel is steady, so only\n\t// steady-state vowel ever gets stretched.\n\tconst consonant = Math.max(\n\t\tpre + 10,\n\t\tMath.abs(overlap) + 10,\n\t\tframeTimeMs(pos.stable) - offsetMs,\n\t);\n\n\t// Keep at least a little stretchable vowel past the fixed region.\n\tconst endMs = Math.max(frameTimeMs(endFrame), offsetMs + consonant + 30);\n\tconst cutoff = -(Math.min(endMs, f.durationMs) - offsetMs);\n\n\treturn {\n\t\twav,\n\t\talias,\n\t\toffset: round(offsetMs),\n\t\tconsonant: round(consonant),\n\t\tcutoff: round(cutoff),\n\t\tpre: round(pre),\n\t\toverlap: round(overlap),\n\t};\n}\n\n/**\n * 単独音: one mora per file, one entry per alias.\n *\n * `aliases` lets a caller emit the usual family for a file — the bare kana plus\n * a `- か` head variant — all sharing the same measurements.\n */\nexport function estimateSolo(\n\twav: string,\n\tf: Frames,\n\tsyl: Syllable,\n\taliases: string[],\n): OtoEntry[] {\n\tconst soundStart = findSoundStart(f, 0, f.n);\n\tconst soundEnd = findSoundEnd(f, soundStart, f.n);\n\tconst pos = locateMora(f, syl.cls, 0, soundEnd);\n\tconst end = findDecayStart(f, pos.stable, soundEnd);\n\treturn aliases.map((alias) => buildEntry(wav, alias, f, syl.cls, pos, end));\n}\n\n/**\n * A 母音結合 entry (`* あ`): a mid-phrase vowel taken from the steady part of\n * the note, with the long symmetric crossfade those aliases are used with.\n */\nexport function estimateVowelJoin(\n\twav: string,\n\tf: Frames,\n\tsyl: Syllable,\n\talias: string,\n): OtoEntry | null {\n\tconst soundStart = findSoundStart(f, 0, f.n);\n\tconst soundEnd = findSoundEnd(f, soundStart, f.n);\n\tconst pos = locateMora(f, syl.cls, 0, soundEnd);\n\tconst end = findDecayStart(f, pos.stable, soundEnd);\n\n\t// The wiki's values for 母音結合: 先行発声 50, オーバーラップ twice that, and\n\t// a 固定範囲 just past the crossfade. They only work if the note is long\n\t// enough to hold them.\n\tconst pre = 50;\n\tconst overlap = 100;\n\tconst consonant = 110;\n\t// The entry begins exactly where the vowel settled: everything a 母音結合\n\t// alias plays is steady-state, with the preutterance sitting inside it.\n\tconst offsetMs = frameTimeMs(pos.stable);\n\tconst endMs = frameTimeMs(end);\n\tif (offsetMs < 0 || endMs - offsetMs < consonant + 40) return null;\n\n\treturn {\n\t\twav,\n\t\talias,\n\t\toffset: round(offsetMs),\n\t\tconsonant,\n\t\tcutoff: round(-(endMs - offsetMs)),\n\t\tpre,\n\t\toverlap,\n\t};\n}\n\n/** A 連続音 recording's rhythmic grid. */\nexport interface Grid {\n\t/** Frame of the first mora's onset. */\n\tstart: number;\n\t/** Frames between successive moras. */\n\tinterval: number;\n\t/** Per-mora onset frames, snapped to the strongest nearby transition. */\n\tonsets: number[];\n}\n\n/** How far a snapped onset may pull away from the fitted tempo line. */\nconst GRID_SNAP_WEIGHT = 0.6;\n\n/** Least-squares line through (index, value) pairs. */\nfunction fitLine(values: readonly number[]): {\n\tintercept: number;\n\tslope: number;\n} {\n\tconst n = values.length;\n\tif (n < 2) return { intercept: values[0] ?? 0, slope: 0 };\n\tlet sx = 0;\n\tlet sy = 0;\n\tlet sxx = 0;\n\tlet sxy = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tsx += i;\n\t\tsy += values[i];\n\t\tsxx += i * i;\n\t\tsxy += i * values[i];\n\t}\n\tconst denom = n * sxx - sx * sx;\n\tconst slope = denom !== 0 ? (n * sxy - sx * sy) / denom : 0;\n\treturn { intercept: (sy - slope * sx) / n, slope };\n}\n\n/** Combined onset strength: spectral change plus a local rise in level. */\nfunction onsetStrength(f: Frames): Float32Array {\n\tconst k = Math.max(1, msToFrame(12));\n\tconst out = new Float32Array(f.n);\n\tfor (let t = 0; t < f.n; t++) {\n\t\tconst rise =\n\t\t\tf.smoothDb[Math.min(f.n - 1, t + k)] - f.smoothDb[Math.max(0, t - k)];\n\t\tout[t] = f.flux[t] + Math.max(0, rise) / 3;\n\t}\n\treturn smooth(out, Math.max(1, msToFrame(8)));\n}\n\n/**\n * Fit `count` evenly spaced moras to the recording.\n *\n * 連続音 lists are sung to a guide BGM, so the moras land on a metronomic grid —\n * which is exactly why the wiki treats 連続音 oto as something you *generate*\n * and then touch up. Fitting a global tempo first, and only then snapping each\n * mora to the nearest real transition, keeps one mis-detected onset from\n * dragging the rest of the file out of alignment.\n */\nexport function detectGrid(f: Frames, count: number): Grid | null {\n\tif (count < 1) return null;\n\tconst strength = onsetStrength(f);\n\tconst uttStart = findSoundStart(f, 0, f.n);\n\tconst uttEnd = findSoundEnd(f, uttStart, f.n);\n\tconst span = uttEnd - uttStart;\n\tif (span < msToFrame(80)) return null;\n\n\tif (count === 1) {\n\t\treturn { start: uttStart, interval: span, onsets: [uttStart] };\n\t}\n\n\tconst candidates = intervalCandidates(\n\t\tstrength,\n\t\tuttStart,\n\t\tuttEnd,\n\t\tspan / count,\n\t);\n\tconst best = { score: -Infinity, start: uttStart, interval: span / count };\n\tconst search = (requireFit: boolean): void => {\n\t\tfor (const candidate of candidates) {\n\t\t\tfor (\n\t\t\t\tlet iv = candidate * 0.85;\n\t\t\t\tiv <= candidate * 1.18;\n\t\t\t\tiv += candidate * 0.02\n\t\t\t) {\n\t\t\t\t// Every grid point looks for its onset in a window of the same width,\n\t\t\t\t// so one sliding-window maximum serves the whole phase sweep.\n\t\t\t\tconst near = windowArgMax(strength, Math.round(iv * 0.22));\n\t\t\t\tconst tol = iv * 0.22;\n\t\t\t\tconst hardEnd = uttEnd + iv * 0.4;\n\t\t\t\tfor (\n\t\t\t\t\tlet phase = uttStart - iv * 0.25;\n\t\t\t\t\tphase <= uttStart + iv * 0.5;\n\t\t\t\t\tphase += 1\n\t\t\t\t) {\n\t\t\t\t\tif (requireFit && phase + (count - 1) * iv > hardEnd) break;\n\t\t\t\t\tlet total = 0;\n\t\t\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\t\t\tconst centre = phase + i * iv;\n\t\t\t\t\t\tconst at = near[clamp(Math.round(centre), 0, f.n - 1)];\n\t\t\t\t\t\ttotal += strength[at] - Math.abs(at - centre) / tol;\n\t\t\t\t\t}\n\t\t\t\t\tif (total > best.score) {\n\t\t\t\t\t\tbest.score = total;\n\t\t\t\t\t\tbest.start = phase;\n\t\t\t\t\t\tbest.interval = iv;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Normally every mora has to fit inside the utterance. When none of the\n\t// candidate tempos can manage that — a phrase sung faster at the end, or an\n\t// utterance whose tail the threshold clipped — a grid that overruns is still\n\t// far better than no entries at all for the file.\n\tsearch(true);\n\tif (!Number.isFinite(best.score)) search(false);\n\tif (!Number.isFinite(best.score)) return null;\n\n\tconst near = windowArgMax(strength, Math.round(best.interval * 0.25));\n\tconst snapped: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tsnapped.push(\n\t\t\tnear[clamp(Math.round(best.start + i * best.interval), 0, f.n - 1)],\n\t\t);\n\t}\n\n\t// Refit the tempo to where the onsets actually landed, then pull each one\n\t// back toward that line. A vowel-to-vowel join has no attack to lock onto and\n\t// its peak wanders; the singer's own timing does not.\n\tconst { intercept, slope } = fitLine(snapped);\n\tconst onsets: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst fitted = intercept + slope * i;\n\t\tconst blended = Math.round(\n\t\t\tfitted + (snapped[i] - fitted) * GRID_SNAP_WEIGHT,\n\t\t);\n\t\tonsets.push(i > 0 ? Math.max(blended, onsets[i - 1] + 4) : blended);\n\t}\n\n\treturn {\n\t\tstart: onsets[0],\n\t\tinterval: slope > 0 ? slope : best.interval,\n\t\tonsets,\n\t};\n}\n\n/**\n * For every index, the index of the largest value within ±`half` of it.\n * A monotonic deque keeps this linear regardless of the window width.\n */\nfunction windowArgMax(src: Float32Array, half: number): Int32Array {\n\tconst n = src.length;\n\tconst out = new Int32Array(n);\n\tconst deque = new Int32Array(n);\n\tlet head = 0;\n\tlet tail = 0;\n\tlet next = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst limit = Math.min(n - 1, i + half);\n\t\twhile (next <= limit) {\n\t\t\twhile (tail > head && src[deque[tail - 1]] <= src[next]) tail--;\n\t\t\tdeque[tail++] = next++;\n\t\t}\n\t\twhile (deque[head] < i - half) head++;\n\t\tout[i] = deque[head];\n\t}\n\treturn out;\n}\n\n/**\n * Plausible mora intervals, in frames.\n *\n * Dividing the utterance by the mora count only works when the recording stops\n * shortly after the last mora; plenty of lists hold the final vowel for a\n * second or more, which inflates the estimate past any sane tempo. Auto-\n * correlating the onset track measures the beat directly instead, and its\n * *shortest* strong peak is the beat rather than a multiple of it.\n */\nfunction intervalCandidates(\n\tstrength: Float32Array,\n\tfrom: number,\n\tto: number,\n\tfromSpan: number,\n): number[] {\n\tconst lo = msToFrame(180);\n\tconst hi = Math.min(msToFrame(1300), Math.floor((to - from) / 2));\n\tconst out: number[] = [];\n\tif (hi > lo) {\n\t\tlet mean = 0;\n\t\tfor (let t = from; t < to; t++) mean += strength[t];\n\t\tmean /= Math.max(1, to - from);\n\n\t\tconst r = new Float64Array(hi + 1);\n\t\tlet peak = 0;\n\t\tfor (let lag = lo; lag <= hi; lag++) {\n\t\t\tlet sum = 0;\n\t\t\tlet n = 0;\n\t\t\tfor (let t = from; t + lag < to; t++, n++) {\n\t\t\t\tsum += (strength[t] - mean) * (strength[t + lag] - mean);\n\t\t\t}\n\t\t\tr[lag] = n > 0 ? sum / n : 0;\n\t\t\tif (r[lag] > peak) peak = r[lag];\n\t\t}\n\t\tif (peak > 0) {\n\t\t\tfor (let lag = lo + 1; lag < hi; lag++) {\n\t\t\t\tif (r[lag] < peak * 0.7) continue;\n\t\t\t\tif (r[lag] < r[lag - 1] || r[lag] < r[lag + 1]) continue;\n\t\t\t\tout.push(lag);\n\t\t\t\tif (out.length >= 2) break;\n\t\t\t}\n\t\t}\n\t}\n\tout.push(fromSpan);\n\n\t// Every peak's halves and thirds go in too. A list where every other mora is\n\t// a weak ん correlates most strongly at *two* moras, and nothing but trying\n\t// the sub-multiple tells the two apart — the grid score then picks.\n\tconst withSubmultiples: number[] = [];\n\tconst seen = new Set<number>();\n\tconst shortest = msToFrame(150);\n\tfor (const c of out) {\n\t\tfor (const divisor of [1, 2, 3]) {\n\t\t\tconst key = Math.round(c / divisor);\n\t\t\tif (key < shortest || seen.has(key)) continue;\n\t\t\tseen.add(key);\n\t\t\twithSubmultiples.push(key);\n\t\t}\n\t}\n\t// An utterance too short for even one plausible interval still has to yield\n\t// a grid; the caller has moras to place either way.\n\tif (withSubmultiples.length === 0) withSubmultiples.push(shortest);\n\treturn withSubmultiples;\n}\n\n/**\n * Where a mora's vowel starts *inside* a phrase, where nothing is silent.\n *\n * A voiceless consonant still cuts the voicing, so the vowel begins when the\n * folds come back. Everything else — a vowel following a vowel, a nasal, a\n * glide — never stops phonating, and its boundary is the transition itself,\n * which is what the grid already snapped to.\n */\nfunction sequenceVowelOnset(\n\tf: Frames,\n\tcls: ConsonantClass,\n\tonset: number,\n\tnext: number,\n): number {\n\tif (ARTICULATION[cls].voicedConsonant) return onset + SEQUENCE_ONSET_BIAS;\n\n\tconst lo = Math.max(0, onset - msToFrame(100));\n\tconst hi = Math.min(next, onset + msToFrame(150));\n\tlet quietest = onset;\n\tfor (let t = lo; t < hi; t++) {\n\t\tif (f.voiced[t] < f.voiced[quietest]) quietest = t;\n\t}\n\tif (f.voiced[quietest] >= VOICED_THRESHOLD) return onset;\n\n\tconst resumed = findVoiceOnset(\n\t\tf,\n\t\tquietest,\n\t\tMath.min(next, hi + msToFrame(80)),\n\t);\n\treturn resumed >= 0 ? resumed : onset;\n}\n\n/**\n * 連続音: every mora in the file gets an entry, aliased against the vowel it\n * follows (`a か`), with the first written as a phrase head (`- あ`).\n *\n * The template — 先行発声 at half the mora interval, オーバーラップ at a third of\n * that, 固定範囲 half again as long, 右ブランク two thirds of an interval past the\n * note — is the one the established 連続音 banks ship, and it survives a mora\n * whose consonant is longer than average because half an interval is far more\n * room than any Japanese onset needs.\n */\nexport function estimateSequence(\n\twav: string,\n\tf: Frames,\n\tsyllables: Syllable[],\n\topts: { suffix?: string; prefix?: string; trailingRest?: boolean } = {},\n): OtoEntry[] {\n\tconst grid = detectGrid(f, syllables.length);\n\tif (!grid) return [];\n\n\tconst intervalMs = framesToMs(grid.interval);\n\t// Half an interval, but never more than 250 ms — which is both what every\n\t// reference bank writes and far more room than any Japanese onset needs.\n\tconst pre = clamp(intervalMs / 2, 60, MAX_SEQUENCE_PRE_MS);\n\tconst overlap = round(pre / 3);\n\tconst consonant = round(pre * 1.5);\n\tconst suffix = opts.suffix ?? \"\";\n\t// A head marker describes how the phrase *starts*, so it belongs on the\n\t// phrase-head alias and nowhere else.\n\tconst prefix = opts.prefix ?? \"\";\n\n\tconst entries: OtoEntry[] = [];\n\tfor (let i = 0; i < syllables.length; i++) {\n\t\tconst syl = syllables[i];\n\t\tconst onset = grid.onsets[i];\n\t\tconst next =\n\t\t\ti + 1 < syllables.length\n\t\t\t\t? grid.onsets[i + 1]\n\t\t\t\t: findSoundEnd(f, onset, f.n);\n\n\t\tlet vowelFrame: number;\n\t\tif (i === 0) {\n\t\t\t// The phrase head is the one mora with real silence in front of it, so\n\t\t\t// it can be measured the same way a 単独音 file is.\n\t\t\tvowelFrame = locateMora(f, syl.cls, 0, next).vowelOnset;\n\t\t} else {\n\t\t\tvowelFrame = sequenceVowelOnset(f, syl.cls, onset, next);\n\t\t}\n\n\t\tconst noteMs = frameTimeMs(vowelFrame);\n\t\tconst offsetMs = clamp(noteMs - pre, 0, Math.max(0, noteMs - 1));\n\t\tconst actualPre = noteMs - offsetMs;\n\t\t// 右ブランク reaches two thirds of an interval past the note, so each mora's\n\t\t// tail is still there for the next one to cross-fade into.\n\t\tconst endMs = Math.min(f.durationMs, noteMs + (intervalMs * 2) / 3);\n\n\t\tconst alias =\n\t\t\ti === 0\n\t\t\t\t? `- ${prefix}${syl.kana}${suffix}`\n\t\t\t\t: `${syllables[i - 1].vowel} ${syl.kana}${suffix}`;\n\n\t\tentries.push({\n\t\t\twav,\n\t\t\talias,\n\t\t\toffset: round(offsetMs),\n\t\t\tconsonant: Math.max(round(consonant), round(actualPre + 20)),\n\t\t\tcutoff: round(-Math.max(endMs - offsetMs, consonant + 40)),\n\t\t\tpre: round(actualPre),\n\t\t\toverlap: i === 0 ? 0 : Math.min(overlap, round(actualPre)),\n\t\t});\n\t}\n\n\tif (opts.trailingRest && syllables.length > 0) {\n\t\tconst last = syllables[syllables.length - 1];\n\t\tconst lastOnset = grid.onsets[syllables.length - 1];\n\t\tconst soundEnd = findSoundEnd(f, lastOnset, f.n);\n\t\tconst decay = findDecayStart(f, lastOnset, soundEnd);\n\t\tconst noteMs = frameTimeMs(decay);\n\t\tconst offsetMs = clamp(noteMs - pre, 0, Math.max(0, noteMs - 1));\n\t\tconst actualPre = noteMs - offsetMs;\n\t\tentries.push({\n\t\t\twav,\n\t\t\talias: `${last.vowel} R${suffix}`,\n\t\t\toffset: round(offsetMs),\n\t\t\tconsonant: round(consonant),\n\t\t\tcutoff: round(\n\t\t\t\t-(Math.min(f.durationMs, frameTimeMs(soundEnd)) - offsetMs),\n\t\t\t),\n\t\t\tpre: round(actualPre),\n\t\t\toverlap: Math.min(overlap, round(actualPre)),\n\t\t});\n\t}\n\n\treturn entries;\n}\n","/**\n * Kana → phoneme tables for oto.ini generation.\n *\n * A UTAU recording's filename *is* its phonetic transcript: `か.wav` holds one\n * mora, `_ああいあうえあ.wav` holds seven. Everything the estimator does — where\n * to look for the vowel, how wide to make the crossfade, whether the overlap\n * goes negative — follows from which consonant a mora starts with, so the kana\n * has to be resolved into (consonant, vowel) before any audio is touched.\n */\n\n/**\n * Articulation class of a mora's initial consonant. The estimator branches on\n * this to pick where the preutterance lands and what overlap the mora gets;\n * see `ARTICULATION` in `estimate.ts`.\n */\nexport type ConsonantClass =\n\t/** あ/い/う/え/お — no consonant at all. */\n\t| \"vowel\"\n\t/** ん — a syllabic nasal that is its own nucleus. */\n\t| \"nasalN\"\n\t/** な/ま行 — voiced throughout, vowel starts at the nasal release. */\n\t| \"nasal\"\n\t/** ら行 — a flap: brief closure, then the vowel. */\n\t| \"liquid\"\n\t/** や/わ行 and vowel glides (いぇ, うぉ) — barely a consonant at all. */\n\t| \"semivowel\"\n\t/** さ/は行 — voiceless noise, so voicing onset *is* the vowel onset. */\n\t| \"fricativeVoiceless\"\n\t/** ざ行, ヴ — voiced noise. */\n\t| \"fricativeVoiced\"\n\t/** つ/ち — a stop released into friction; behaves like a plosive. */\n\t| \"affricate\"\n\t/** か/た/ぱ行 — a silent closure precedes the burst. */\n\t| \"plosiveVoiceless\"\n\t/** が/だ/ば行 — may prevoice through the closure. */\n\t| \"plosiveVoiced\";\n\nexport interface Syllable {\n\t/** The kana as written, e.g. \"きゃ\". Used verbatim in the alias. */\n\tkana: string;\n\t/** Romanised onset, e.g. \"ky\". Empty for bare vowels and ん. */\n\tconsonant: string;\n\t/** Romanised nucleus: a/i/u/e/o, or \"n\" for ん. */\n\tvowel: string;\n\tcls: ConsonantClass;\n}\n\nconst CLASS_OF: Record<string, ConsonantClass> = {\n\t\"\": \"vowel\",\n\tk: \"plosiveVoiceless\",\n\tky: \"plosiveVoiceless\",\n\tt: \"plosiveVoiceless\",\n\tty: \"plosiveVoiceless\",\n\tp: \"plosiveVoiceless\",\n\tpy: \"plosiveVoiceless\",\n\tg: \"plosiveVoiced\",\n\tgy: \"plosiveVoiced\",\n\td: \"plosiveVoiced\",\n\tdy: \"plosiveVoiced\",\n\tb: \"plosiveVoiced\",\n\tby: \"plosiveVoiced\",\n\ts: \"fricativeVoiceless\",\n\tsh: \"fricativeVoiceless\",\n\th: \"fricativeVoiceless\",\n\thy: \"fricativeVoiceless\",\n\tf: \"fricativeVoiceless\",\n\tz: \"fricativeVoiced\",\n\tj: \"fricativeVoiced\",\n\tv: \"fricativeVoiced\",\n\tts: \"affricate\",\n\tch: \"affricate\",\n\tn: \"nasal\",\n\tny: \"nasal\",\n\tm: \"nasal\",\n\tmy: \"nasal\",\n\tr: \"liquid\",\n\try: \"liquid\",\n\ty: \"semivowel\",\n\tw: \"semivowel\",\n};\n\n/**\n * kana → \"consonant vowel\". A space-separated pair keeps the table readable;\n * a leading space means \"no consonant\".\n */\nconst KANA: Record<string, string> = {\n\tあ: \" a\",\n\tい: \" i\",\n\tう: \" u\",\n\tえ: \" e\",\n\tお: \" o\",\n\tん: \" n\",\n\tか: \"k a\",\n\tき: \"k i\",\n\tく: \"k u\",\n\tけ: \"k e\",\n\tこ: \"k o\",\n\tが: \"g a\",\n\tぎ: \"g i\",\n\tぐ: \"g u\",\n\tげ: \"g e\",\n\tご: \"g o\",\n\tさ: \"s a\",\n\tし: \"sh i\",\n\tす: \"s u\",\n\tせ: \"s e\",\n\tそ: \"s o\",\n\tざ: \"z a\",\n\tじ: \"j i\",\n\tず: \"z u\",\n\tぜ: \"z e\",\n\tぞ: \"z o\",\n\tた: \"t a\",\n\tち: \"ch i\",\n\tつ: \"ts u\",\n\tて: \"t e\",\n\tと: \"t o\",\n\tだ: \"d a\",\n\tぢ: \"j i\",\n\tづ: \"z u\",\n\tで: \"d e\",\n\tど: \"d o\",\n\tな: \"n a\",\n\tに: \"n i\",\n\tぬ: \"n u\",\n\tね: \"n e\",\n\tの: \"n o\",\n\tは: \"h a\",\n\tひ: \"h i\",\n\tふ: \"f u\",\n\tへ: \"h e\",\n\tほ: \"h o\",\n\tば: \"b a\",\n\tび: \"b i\",\n\tぶ: \"b u\",\n\tべ: \"b e\",\n\tぼ: \"b o\",\n\tぱ: \"p a\",\n\tぴ: \"p i\",\n\tぷ: \"p u\",\n\tぺ: \"p e\",\n\tぽ: \"p o\",\n\tま: \"m a\",\n\tみ: \"m i\",\n\tむ: \"m u\",\n\tめ: \"m e\",\n\tも: \"m o\",\n\tや: \"y a\",\n\tゆ: \"y u\",\n\tよ: \"y o\",\n\tら: \"r a\",\n\tり: \"r i\",\n\tる: \"r u\",\n\tれ: \"r e\",\n\tろ: \"r o\",\n\tわ: \"w a\",\n\tゐ: \"w i\",\n\tゑ: \"w e\",\n\tを: \"w o\",\n\tゔ: \"v u\",\n};\n\n/** Small kana that can only appear as the second half of a digraph. */\nconst SMALL: Record<string, string> = {\n\tぁ: \"a\",\n\tぃ: \"i\",\n\tぅ: \"u\",\n\tぇ: \"e\",\n\tぉ: \"o\",\n\tゃ: \"a\",\n\tゅ: \"u\",\n\tょ: \"o\",\n\tゎ: \"a\",\n};\n\n/** Digraphs whose onset is not simply \"base consonant + y\". */\nconst DIGRAPH: Record<string, string> = {\n\tしゃ: \"sh a\",\n\tしゅ: \"sh u\",\n\tしょ: \"sh o\",\n\tしぇ: \"sh e\",\n\tじゃ: \"j a\",\n\tじゅ: \"j u\",\n\tじょ: \"j o\",\n\tじぇ: \"j e\",\n\tちゃ: \"ch a\",\n\tちゅ: \"ch u\",\n\tちょ: \"ch o\",\n\tちぇ: \"ch e\",\n\tぢゃ: \"j a\",\n\tぢゅ: \"j u\",\n\tぢょ: \"j o\",\n\tつぁ: \"ts a\",\n\tつぃ: \"ts i\",\n\tつぇ: \"ts e\",\n\tつぉ: \"ts o\",\n\tてぃ: \"t i\",\n\tてゃ: \"ty a\",\n\tてゅ: \"ty u\",\n\tてょ: \"ty o\",\n\tでぃ: \"d i\",\n\tでゃ: \"dy a\",\n\tでゅ: \"dy u\",\n\tでょ: \"dy o\",\n\tとぅ: \"t u\",\n\tどぅ: \"d u\",\n\tふぁ: \"f a\",\n\tふぃ: \"f i\",\n\tふぇ: \"f e\",\n\tふぉ: \"f o\",\n\tふゅ: \"f u\",\n\tゔぁ: \"v a\",\n\tゔぃ: \"v i\",\n\tゔぇ: \"v e\",\n\tゔぉ: \"v o\",\n\tゔゅ: \"v u\",\n\tくぁ: \"k a\",\n\tくぃ: \"k i\",\n\tくぇ: \"k e\",\n\tくぉ: \"k o\",\n\tぐぁ: \"g a\",\n\tぐぃ: \"g i\",\n\tぐぇ: \"g e\",\n\tぐぉ: \"g o\",\n\tすぃ: \"s i\",\n\tずぃ: \"z i\",\n};\n\n/**\n * Katakana → hiragana, so ヴァ and ゔぁ resolve identically. Only the kana\n * block is folded; ー and everything else is left alone for the caller to\n * reject.\n */\nexport function toHiragana(s: string): string {\n\tlet out = \"\";\n\tfor (const ch of s) {\n\t\tconst c = ch.codePointAt(0) ?? 0;\n\t\t// Katakana ァ(30A1)–ヶ(30F6) map onto hiragana ぁ(3041)–ゖ(3096).\n\t\tout += c >= 0x30a1 && c <= 0x30f6 ? String.fromCodePoint(c - 0x60) : ch;\n\t}\n\treturn out;\n}\n\nfunction make(kana: string, pair: string): Syllable {\n\tconst sp = pair.indexOf(\" \");\n\tconst consonant = pair.slice(0, sp);\n\tconst vowel = pair.slice(sp + 1);\n\treturn { kana, consonant, vowel, cls: CLASS_OF[consonant] ?? \"vowel\" };\n}\n\n/**\n * Resolve one kana or digraph starting at `i`, returning the syllable and how\n * many characters it consumed — or null if the text is not kana we know.\n */\nfunction readSyllable(\n\tsrc: string,\n\thira: string,\n\ti: number,\n): { syl: Syllable; len: number } | null {\n\tconst two = hira.slice(i, i + 2);\n\tif (two.length === 2) {\n\t\tconst explicit = DIGRAPH[two];\n\t\tif (explicit) return { syl: make(src.slice(i, i + 2), explicit), len: 2 };\n\n\t\tconst small = SMALL[two[1]];\n\t\tconst base = KANA[two[0]];\n\t\tif (small && base) {\n\t\t\tconst sp = base.indexOf(\" \");\n\t\t\tconst baseConsonant = base.slice(0, sp);\n\t\t\tconst baseVowel = base.slice(sp + 1);\n\t\t\t// きゃ = k + i + a → a palatalised \"ky\" onset.\n\t\t\tif (baseVowel === \"i\" && CLASS_OF[`${baseConsonant}y`]) {\n\t\t\t\tconst pair = `${baseConsonant}y ${small}`;\n\t\t\t\treturn { syl: make(src.slice(i, i + 2), pair), len: 2 };\n\t\t\t}\n\t\t\t// いぇ / うぉ — a bare vowel gliding into another is a semivowel.\n\t\t\tif (!baseConsonant) {\n\t\t\t\tconst glide = baseVowel === \"i\" ? \"y\" : baseVowel === \"u\" ? \"w\" : \"\";\n\t\t\t\tconst syl = make(src.slice(i, i + 2), `${glide} ${small}`);\n\t\t\t\t// おぁ has no romanisable onset, but it still articulates like one.\n\t\t\t\treturn { syl: { ...syl, cls: \"semivowel\" }, len: 2 };\n\t\t\t}\n\t\t\t// Anything else keeps the base consonant and takes the small kana as\n\t\t\t// its vowel: ぢぇ is /je/, くゎ is a labialised /ka/, づぉ is /zo/. The\n\t\t\t// nucleus is what the estimator needs, and this gets it right for every\n\t\t\t// combination a recording list can invent.\n\t\t\treturn {\n\t\t\t\tsyl: make(src.slice(i, i + 2), `${baseConsonant} ${small}`),\n\t\t\t\tlen: 2,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst one = KANA[hira[i]];\n\tif (one) return { syl: make(src.slice(i, i + 1), one), len: 1 };\n\treturn null;\n}\n\n/**\n * Split a kana string into moras.\n *\n * Returns null if any character is not kana we can resolve — that is the\n * signal to skip the file entirely, which is what keeps a bank's karaoke\n * tracks and readme audio out of the generated oto.ini.\n */\nexport function splitKana(text: string): Syllable[] | null {\n\tconst src = text.normalize(\"NFC\");\n\tconst hira = toHiragana(src);\n\tconst out: Syllable[] = [];\n\n\tfor (let i = 0; i < hira.length; ) {\n\t\tconst ch = hira[i];\n\t\t// っ marks a geminate: the closure belongs to the following mora, and\n\t\t// there is nothing to voice on its own.\n\t\tif (ch === \"っ\" || ch === \"ー\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst read = readSyllable(src, hira, i);\n\t\tif (!read) return null;\n\t\tout.push(read.syl);\n\t\ti += read.len;\n\t}\n\n\treturn out.length > 0 ? out : null;\n}\n\n/**\n * Vowel a following mora connects to, as written in a 連続音 alias\n * (`a か`). ん connects as \"n\".\n */\nexport function connectingVowel(syl: Syllable): string {\n\treturn syl.vowel;\n}\n","/**\n * Folder → oto.ini, with no manual step in between.\n *\n * The filename carries the transcript, so the recording style falls out of it:\n * one mora per file is 単独音, several is 連続音. Everything else — which\n * aliases to emit, where the phrase head goes, whether a trailing R belongs on\n * the end — follows from the same parse.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\nimport { parseWav } from \"../converter/wav.js\";\nimport {\n\testimateSequence,\n\testimateSolo,\n\testimateVowelJoin,\n} from \"./estimate.js\";\nimport { analyze, type Frames } from \"./frames.js\";\nimport { type Syllable, splitKana, toHiragana } from \"./kana.js\";\n\nexport interface GenerateOptions {\n\t/**\n\t * Appended to every alias — the usual home for a multi-pitch or expression\n\t * marker (`_G4`, `強`). Defaults to the folder's own note name when it has\n\t * one; pass `\"\"` to suppress that.\n\t */\n\tsuffix?: string;\n\t/** Emit `- か` phrase-head aliases alongside the bare kana. Default true. */\n\theadAliases?: boolean;\n\t/** Emit `* あ` 母音結合 aliases for vowel-only files. Default true. */\n\tvowelJoinAliases?: boolean;\n}\n\n/** One file that could not be transcribed, and why. */\nexport interface SkippedFile {\n\twav: string;\n\treason: string;\n}\n\nexport interface GenerateResult {\n\tentries: OtoEntry[];\n\tskipped: SkippedFile[];\n\t/** Recording style inferred from the filenames. */\n\tstyle: \"solo\" | \"sequence\" | \"mixed\" | \"empty\";\n}\n\n/** What one recording produced. */\nexport interface FileResult {\n\tentries: OtoEntry[];\n\t/** Set instead of entries when the file could not be set up. */\n\tskipped: SkippedFile | null;\n\t/** Style this one file was read as, or null if it was skipped. */\n\tstyle: \"solo\" | \"sequence\" | null;\n}\n\nexport interface WavInput {\n\t/** Filename as it appears in oto.ini, e.g. `_ああいあう.wav`. */\n\tname: string;\n\tdata: ArrayBuffer;\n}\n\n/** A rest/breath marker that ends a 連続音 phrase. */\nconst REST = /[RrRr]$|息$|吸$/;\n\ninterface Transcript {\n\tsyllables: Syllable[];\n\ttrailingRest: boolean;\n\t/** Non-kana marker before the kana, e.g. the `x` of `_xか.wav`. */\n\tprefix: string;\n\t/** Non-kana marker after the kana, e.g. the `b` of `_あb.wav`. */\n\tmark: string;\n}\n\n/**\n * Read the transcript out of a filename.\n *\n * The leading `_` that marks a recording-list file, an extension, and a\n * trailing pitch tag are all noise; what is left has to be kana end to end, or\n * the file is not a voice sample we can set up (a karaoke track, a sample song,\n * a readme recording).\n */\nexport function transcribe(filename: string): Transcript | null {\n\tlet body = filename.replace(/\\.[^.]+$/, \"\");\n\tbody = body.replace(/^[_\\-\\s]+/, \"\");\n\t// Drop a per-file pitch tag such as `_C4` / `_A#3`.\n\tbody = body.replace(/_[A-G][#b]?-?\\d$/i, \"\");\n\tbody = body.trim();\n\tif (!body) return null;\n\n\t// Take markers ride along into the alias rather than being discarded: a bank\n\t// that recorded `_あb.wav` as a second take means its oto.ini to say `あb`,\n\t// and `_ううわうぉわ↑.wav` is a distinct entry from the unmarked one.\n\tlet mark = \"\";\n\tconst arrows = /[↑↓→]+$/.exec(body);\n\tif (arrows) {\n\t\tmark = arrows[0];\n\t\tbody = body.slice(0, -arrows[0].length);\n\t}\n\n\tlet trailingRest = false;\n\tif (REST.test(body)) {\n\t\ttrailingRest = true;\n\t\tbody = body.replace(REST, \"\");\n\t}\n\n\tconst take = /[A-Za-z0-9'][A-Za-z0-9']?$/.exec(body);\n\tif (take && body.length > take[0].length) {\n\t\tmark = take[0] + mark;\n\t\tbody = body.slice(0, -take[0].length);\n\t}\n\n\t// A leading ASCII marker only counts when kana follows it — `_xか.wav` is a\n\t// devoiced か, while `1646312012.wav` is not a recording at all.\n\tlet prefix = \"\";\n\tconst head = /^[A-Za-z]{1,2}(?=[ぁ-ゟァ-ヿ])/.exec(body);\n\tif (head) {\n\t\tprefix = head[0];\n\t\tbody = body.slice(head[0].length);\n\t}\n\tif (!body) return null;\n\n\tconst syllables = splitKana(body);\n\tif (!syllables) return null;\n\treturn { syllables, trailingRest, prefix, mark };\n}\n\n/**\n * Alias suffix implied by a folder's name.\n *\n * A multi-pitch bank keeps one folder per pitch and merges every oto.ini into\n * one alias namespace, so without the pitch tag each folder's `- あ` would\n * overwrite the last. The tag is taken either from a folder named for nothing\n * but the pitch (`G4`) or from an explicit `_G4` token inside a longer name\n * (`多音階03:_G4(連続音)`). A bare `G4` buried in a name is left alone — in\n * `表情音01:強(G4歌連続音)` it describes the take, and the suffix the bank\n * actually uses there is `強`, which no filename carries.\n */\nexport function suffixFromFolderName(folder: string): string {\n\tif (/^[A-G][#b]?-?\\d$/.test(folder)) return `_${folder}`;\n\tconst tagged = /_([A-G][#b]?-?\\d)(?![0-9A-Za-z])/.exec(folder);\n\treturn tagged ? `_${tagged[1]}` : \"\";\n}\n\nfunction aliasesFor(name: string, headAliases: boolean): string[] {\n\treturn headAliases ? [name, `- ${name}`] : [name];\n}\n\n/**\n * Estimate oto.ini entries for every WAV in one folder.\n *\n * Decoding and analysis are per-file and independent, so a bad WAV is reported\n * and skipped rather than failing the folder.\n */\nexport function generateOtoForFile(\n\tfile: WavInput,\n\toptions: GenerateOptions = {},\n): FileResult {\n\tconst suffix = options.suffix ?? \"\";\n\tconst headAliases = options.headAliases ?? true;\n\tconst vowelJoinAliases = options.vowelJoinAliases ?? true;\n\n\tconst transcript = transcribe(file.name);\n\tif (!transcript) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"filename is not kana\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\n\tlet frames: Frames;\n\ttry {\n\t\tframes = analyze(parseWav(file.data));\n\t} catch (err) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: {\n\t\t\t\twav: file.name,\n\t\t\t\treason: err instanceof Error ? err.message : String(err),\n\t\t\t},\n\t\t\tstyle: null,\n\t\t};\n\t}\n\tif (frames.n < 8) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"too short to analyse\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\n\tconst { syllables, trailingRest, prefix, mark } = transcript;\n\n\tif (syllables.length === 1 && !trailingRest) {\n\t\tconst syl = syllables[0];\n\t\tconst name = `${prefix}${syl.kana}${mark}${suffix}`;\n\t\tconst entries = estimateSolo(\n\t\t\tfile.name,\n\t\t\tframes,\n\t\t\tsyl,\n\t\t\taliasesFor(name, headAliases),\n\t\t);\n\n\t\t// あ/い/う/え/お/ん also get a 母音結合 entry, cut from the steady part of\n\t\t// the same note — the `* あ` aliases a 連続音-style phrase leans on.\n\t\tif (vowelJoinAliases && (syl.cls === \"vowel\" || syl.cls === \"nasalN\")) {\n\t\t\tconst join = estimateVowelJoin(file.name, frames, syl, `* ${name}`);\n\t\t\tif (join) entries.push(join);\n\t\t}\n\t\treturn { entries, skipped: null, style: \"solo\" };\n\t}\n\n\tconst entries = estimateSequence(file.name, frames, syllables, {\n\t\tsuffix: `${mark}${suffix}`,\n\t\tprefix,\n\t\ttrailingRest,\n\t});\n\tif (entries.length === 0) {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tskipped: { wav: file.name, reason: \"could not segment the phrase\" },\n\t\t\tstyle: null,\n\t\t};\n\t}\n\treturn { entries, skipped: null, style: \"sequence\" };\n}\n\n/**\n * Estimate oto.ini entries for every WAV in one folder.\n *\n * Decoding and analysis are per-file and independent, so a bad WAV is reported\n * and skipped rather than failing the folder. A caller that needs to stay\n * responsive — a browser UI, say — should drive {@link generateOtoForFile}\n * itself and yield between files.\n */\nexport function generateOto(\n\tfiles: readonly WavInput[],\n\toptions: GenerateOptions = {},\n): GenerateResult {\n\tconst entries: OtoEntry[] = [];\n\tconst skipped: SkippedFile[] = [];\n\tlet solo = 0;\n\tlet sequence = 0;\n\n\tfor (const file of files) {\n\t\tconst result = generateOtoForFile(file, options);\n\t\tentries.push(...result.entries);\n\t\tif (result.skipped) skipped.push(result.skipped);\n\t\tif (result.style === \"solo\") solo++;\n\t\tif (result.style === \"sequence\") sequence++;\n\t}\n\n\treturn { entries, skipped, style: summarise(solo, sequence) };\n}\n\n/** Fold per-file styles into the one label that describes the folder. */\nexport function summarise(\n\tsolo: number,\n\tsequence: number,\n): GenerateResult[\"style\"] {\n\tif (solo && sequence) return \"mixed\";\n\tif (sequence) return \"sequence\";\n\tif (solo) return \"solo\";\n\treturn \"empty\";\n}\n\n/** Exposed for callers that want to pre-flight a folder without decoding audio. */\nexport function looksLikeVoiceFolder(names: readonly string[]): boolean {\n\treturn names.some(\n\t\t(n) => /\\.wav$/i.test(n) && transcribe(n) !== null && toHiragana(n) !== \"\",\n\t);\n}\n","/**\n * oto.ini serialisation.\n *\n * UTAU reads oto.ini as Shift-JIS, and OpenUtau follows a bank's declared\n * encoding, so writing UTF-8 would leave every kana alias mojibake in the\n * original editor. There is no Shift-JIS *encoder* in the platform — only a\n * decoder — so the table is built by decoding every legal byte pair once and\n * inverting the result.\n */\n\nimport type { OtoEntry } from \"../converter/parse-oto.js\";\n\nlet reverseTable: Map<string, number> | null = null;\n\nfunction shiftJisTable(): Map<string, number> {\n\tif (reverseTable) return reverseTable;\n\tconst table = new Map<string, number>();\n\tconst decoder = new TextDecoder(\"shift_jis\", { fatal: false });\n\n\t// ASCII, plus the yen/overline substitutions Shift-JIS makes at 0x5C/0x7E.\n\tfor (let b = 0; b < 0x80; b++) {\n\t\ttable.set(decoder.decode(new Uint8Array([b])), b);\n\t}\n\t// Half-width katakana.\n\tfor (let b = 0xa1; b <= 0xdf; b++) {\n\t\ttable.set(decoder.decode(new Uint8Array([b])), b);\n\t}\n\t// Two-byte planes.\n\tconst pair = new Uint8Array(2);\n\tfor (let lead = 0x81; lead <= 0xfc; lead++) {\n\t\tif (lead > 0x9f && lead < 0xe0) continue;\n\t\tpair[0] = lead;\n\t\tfor (let trail = 0x40; trail <= 0xfc; trail++) {\n\t\t\tif (trail === 0x7f) continue;\n\t\t\tpair[1] = trail;\n\t\t\tconst ch = decoder.decode(pair);\n\t\t\t// A byte pair the decoder rejects comes back as U+FFFD, and a few map\n\t\t\t// to two characters; neither is usable as a round-trip entry.\n\t\t\tif (ch.length !== 1 || ch === \"�\") continue;\n\t\t\tif (!table.has(ch)) table.set(ch, (lead << 8) | trail);\n\t\t}\n\t}\n\n\treverseTable = table;\n\treturn table;\n}\n\n/**\n * Encode text as Shift-JIS. Characters with no Shift-JIS form become `?`,\n * matching what UTAU's own tools do rather than corrupting the line.\n */\nexport function encodeShiftJis(text: string): Uint8Array {\n\tconst table = shiftJisTable();\n\tconst out: number[] = [];\n\tfor (const ch of text) {\n\t\tconst code = table.get(ch);\n\t\tif (code === undefined) out.push(0x3f);\n\t\telse if (code > 0xff) out.push(code >> 8, code & 0xff);\n\t\telse out.push(code);\n\t}\n\treturn new Uint8Array(out);\n}\n\n/** Trim trailing zeros so `120.000` prints as `120`. */\nfunction num(v: number): string {\n\tconst s = v.toFixed(3);\n\treturn s.replace(/\\.?0+$/, \"\") || \"0\";\n}\n\n/** Render entries as oto.ini text (CRLF, as UTAU writes it). */\nexport function formatOto(entries: readonly OtoEntry[]): string {\n\treturn entries\n\t\t.map(\n\t\t\t(e) =>\n\t\t\t\t`${e.wav}=${e.alias},${num(e.offset)},${num(e.consonant)},${num(e.cutoff)},${num(e.pre)},${num(e.overlap)}`,\n\t\t)\n\t\t.join(\"\\r\\n\")\n\t\t.concat(\"\\r\\n\");\n}\n\n/** Render entries as Shift-JIS oto.ini bytes, ready to write to disk. */\nexport function encodeOto(entries: readonly OtoEntry[]): Uint8Array {\n\treturn encodeShiftJis(formatOto(entries));\n}\n","/**\n * Asset loading for the TTS stack: the Go UtauTTS wasm (~10 MB), the\n * jpreprocess wasm (~2 MB) and its naist-jdic dictionary (~29 MB gzipped,\n * ~80 MB inflated) and the TCN prosody model (~1 MB).\n *\n * Everything goes through {@link fetchAsset}, which streams the download with\n * progress callbacks and stores the raw response in the Cache API so the second\n * visit skips the network entirely (the browser HTTP cache alone is not\n * reliable for files this size).\n */\n\nexport interface AssetProgress {\n\turl: string;\n\t/** Bytes received so far (compressed bytes for gzipped files). */\n\tloaded: number;\n\t/** Total bytes when the server sent Content-Length, otherwise 0. */\n\ttotal: number;\n\t/** True when served from the Cache API (no network). */\n\tfromCache: boolean;\n}\n\nexport interface AssetFetchOptions {\n\t/**\n\t * Cache API bucket name. `null` disables caching. Defaults to\n\t * `\"koe-tts-assets-v1\"`.\n\t */\n\tcacheName?: string | null;\n\tonProgress?: (progress: AssetProgress) => void;\n\tsignal?: AbortSignal;\n\t/**\n\t * Check the cached copy against the server with a HEAD request (ETag,\n\t * Last-Modified or Content-Length) so a redeployed asset is refetched.\n\t * Offline or on error the cached copy is used. Default true.\n\t */\n\trevalidate?: boolean;\n}\n\nconst DEFAULT_CACHE = \"koe-tts-assets-v1\";\n\nasync function openCache(\n\tname: string | null | undefined,\n): Promise<Cache | null> {\n\tif (name === null) return null;\n\ttry {\n\t\tif (typeof caches === \"undefined\") return null;\n\t\treturn await caches.open(name ?? DEFAULT_CACHE);\n\t} catch {\n\t\t// file:// pages, private windows and insecure origins have no Cache API.\n\t\treturn null;\n\t}\n}\n\n/**\n * HEAD the asset and compare validators with the cached copy. Network errors\n * (offline) count as \"current\" so the cache keeps working without a server.\n */\nasync function cachedCopyIsCurrent(\n\turl: string,\n\tcached: Response,\n\tsignal?: AbortSignal,\n): Promise<boolean> {\n\tlet head: Response;\n\ttry {\n\t\thead = await fetch(url, { method: \"HEAD\", signal, cache: \"no-cache\" });\n\t} catch {\n\t\treturn true;\n\t}\n\tif (!head.ok) return true;\n\tfor (const name of [\"etag\", \"last-modified\", \"content-length\"]) {\n\t\tconst remote = head.headers.get(name);\n\t\tconst local = cached.headers.get(name);\n\t\tif (remote && local) return remote === local;\n\t}\n\treturn true;\n}\n\n/**\n * Fetch a static asset with download progress, backed by the Cache API.\n *\n * The returned Response has a fully buffered body, so it can be handed to\n * `WebAssembly.instantiateStreaming` / wasm-bindgen `init()` as-is.\n */\nexport async function fetchAsset(\n\turl: string,\n\toptions: AssetFetchOptions = {},\n): Promise<Response> {\n\tconst { onProgress, signal, revalidate = true } = options;\n\tconst cache = await openCache(options.cacheName);\n\tif (cache) {\n\t\ttry {\n\t\t\tconst hit = await cache.match(url);\n\t\t\tif (\n\t\t\t\thit &&\n\t\t\t\t(!revalidate || (await cachedCopyIsCurrent(url, hit, signal)))\n\t\t\t) {\n\t\t\t\tconst total = Number(hit.headers.get(\"content-length\")) || 0;\n\t\t\t\tonProgress?.({ url, loaded: total, total, fromCache: true });\n\t\t\t\treturn hit;\n\t\t\t}\n\t\t} catch {\n\t\t\t// fall through to the network\n\t\t}\n\t}\n\n\tconst response = await fetch(url, { signal });\n\tif (!response.ok) {\n\t\tthrow new Error(`fetch ${url}: HTTP ${response.status}`);\n\t}\n\tconst total = Number(response.headers.get(\"content-length\")) || 0;\n\tlet body: Uint8Array<ArrayBuffer>;\n\tif (response.body && onProgress) {\n\t\tconst reader = response.body.getReader();\n\t\tconst parts: Uint8Array[] = [];\n\t\tlet loaded = 0;\n\t\tonProgress({ url, loaded, total, fromCache: false });\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tparts.push(value);\n\t\t\tloaded += value.byteLength;\n\t\t\tonProgress({ url, loaded, total, fromCache: false });\n\t\t}\n\t\tbody = new Uint8Array(new ArrayBuffer(loaded));\n\t\tlet offset = 0;\n\t\tfor (const part of parts) {\n\t\t\tbody.set(part, offset);\n\t\t\toffset += part.byteLength;\n\t\t}\n\t} else {\n\t\tbody = new Uint8Array(await response.arrayBuffer());\n\t\tonProgress?.({\n\t\t\turl,\n\t\t\tloaded: body.byteLength,\n\t\t\ttotal: total || body.byteLength,\n\t\t\tfromCache: false,\n\t\t});\n\t}\n\n\tconst headers = new Headers();\n\tfor (const name of [\"content-type\", \"etag\", \"last-modified\"]) {\n\t\tconst value = response.headers.get(name);\n\t\tif (value) headers.set(name, value);\n\t}\n\theaders.set(\"content-length\", String(body.byteLength));\n\tconst buffered = new Response(body, { status: 200, headers });\n\tif (cache) {\n\t\ttry {\n\t\t\tawait cache.put(url, buffered.clone());\n\t\t} catch {\n\t\t\t// quota exceeded or opaque response: caching is best effort\n\t\t}\n\t}\n\treturn buffered;\n}\n\n/** {@link fetchAsset} and return the body bytes. */\nexport async function fetchAssetBytes(\n\turl: string,\n\toptions?: AssetFetchOptions,\n): Promise<Uint8Array> {\n\treturn new Uint8Array(await (await fetchAsset(url, options)).arrayBuffer());\n}\n\n/** {@link fetchAsset} and return the body as text. */\nexport async function fetchAssetText(\n\turl: string,\n\toptions?: AssetFetchOptions,\n): Promise<string> {\n\treturn (await fetchAsset(url, options)).text();\n}\n\n/** The naist-jdic files produced by jpreprocess's dictionary build, in `init_dictionary` order. */\nexport const NAIST_JDIC_FILES = [\n\t\"metadata.json\",\n\t\"char_def.bin\",\n\t\"matrix.mtx\",\n\t\"dict.da\",\n\t\"dict.vals\",\n\t\"unk.bin\",\n\t\"dict.wordsidx\",\n\t\"dict.words\",\n] as const;\n\nexport type NaistJdicFile = (typeof NAIST_JDIC_FILES)[number];\n\nexport type NaistJdicData = Record<NaistJdicFile, Uint8Array>;\n\n/** The subset of the wasm-bindgen module surface used by koe. */\nexport interface JpreprocessModule {\n\tinit_dictionary(\n\t\tmetadata: Uint8Array,\n\t\tcharDef: Uint8Array,\n\t\tmatrix: Uint8Array,\n\t\tdictDa: Uint8Array,\n\t\tdictVals: Uint8Array,\n\t\tunk: Uint8Array,\n\t\twordsIdx: Uint8Array,\n\t\twords: Uint8Array,\n\t): void;\n\tanalyze_text(text: string): string;\n\tis_ready(): boolean;\n\t/** Load an HTS voice (.htsvoice bytes) for `analyze_prosody`. */\n\tinit_voice?(htsvoice: Uint8Array): void;\n\tis_voice_ready?(): boolean;\n\t/** HTS phoneme durations + F0 for the text (JSON, see `HtsProsodyFrames`). */\n\tanalyze_prosody?(text: string, speed: number): string;\n}\n\nasync function inflate(bytes: Uint8Array): Promise<Uint8Array> {\n\tif (typeof DecompressionStream === \"undefined\") {\n\t\tthrow new Error(\n\t\t\t\"DecompressionStream is not available; serve the dictionary uncompressed\",\n\t\t);\n\t}\n\tconst stream = new Blob([bytes as BlobPart])\n\t\t.stream()\n\t\t.pipeThrough(new DecompressionStream(\"gzip\"));\n\treturn new Uint8Array(await new Response(stream).arrayBuffer());\n}\n\nexport interface LoadNaistJdicOptions extends AssetFetchOptions {\n\t/** Files are `<name>.gz` and inflated in the browser. Default true. */\n\tcompressed?: boolean;\n}\n\n/**\n * Download (or read from the Cache API) the naist-jdic dictionary files for\n * jpreprocess. `baseUrl` is the directory holding `dict.da.gz` etc.\n *\n * Progress is reported per file via `onProgress`; sum `loaded`/`total` across\n * the {@link NAIST_JDIC_FILES} URLs for an aggregate bar.\n */\nexport async function loadNaistJdic(\n\tbaseUrl: string,\n\toptions: LoadNaistJdicOptions = {},\n): Promise<NaistJdicData> {\n\tconst { compressed = true, ...fetchOptions } = options;\n\tconst base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\tconst entries = await Promise.all(\n\t\tNAIST_JDIC_FILES.map(async (name) => {\n\t\t\tconst raw = await fetchAssetBytes(\n\t\t\t\t`${base}${name}${compressed ? \".gz\" : \"\"}`,\n\t\t\t\tfetchOptions,\n\t\t\t);\n\t\t\treturn [name, compressed ? await inflate(raw) : raw] as const;\n\t\t}),\n\t);\n\treturn Object.fromEntries(entries) as NaistJdicData;\n}\n\n/** Hand the loaded dictionary to the jpreprocess wasm module (once per page). */\nexport function initJpreprocessDictionary(\n\tmodule: JpreprocessModule,\n\tdata: NaistJdicData,\n): void {\n\tmodule.init_dictionary(\n\t\tdata[\"metadata.json\"],\n\t\tdata[\"char_def.bin\"],\n\t\tdata[\"matrix.mtx\"],\n\t\tdata[\"dict.da\"],\n\t\tdata[\"dict.vals\"],\n\t\tdata[\"unk.bin\"],\n\t\tdata[\"dict.wordsidx\"],\n\t\tdata[\"dict.words\"],\n\t);\n}\n","import type { FeatureFrame } from \"./openjtalk_features.js\";\n\n/**\n * Prosody transplant from an HTS voice (Open JTalk's statistical model, run by\n * jbonsai inside the jpreprocess wasm): HTS decides *how long* each mora is and\n * *what pitch contour* the sentence has; the UTAU voice bank only supplies the\n * timbre. This is the same division of labour as Cantari (VOICEVOX prosody +\n * worldline) but with a 1-2 MB model that runs in the browser.\n */\n\n/** One phoneme of the HTS timeline (`analyze_prosody` output). */\nexport interface HtsPhoneme {\n\tphone: string;\n\tstart_ms: number;\n\tduration_ms: number;\n}\n\n/** Raw `analyze_prosody` result. */\nexport interface HtsProsodyFrames {\n\tframe_ms: number;\n\tsample_rate: number;\n\tphonemes: HtsPhoneme[];\n\t/** F0 in Hz per frame; 0 = unvoiced. */\n\tf0_hz: number[];\n}\n\n/** HTS prosody aligned to the UtauTTS mora sequence, ready for `plan()`. */\nexport interface HtsProsody {\n\t/** Per feature-frame (mora or pause) duration in ms, same order as the features. */\n\tmoraDurationsMs: number[];\n\t/** Cents relative to the speaker median, on the plan time axis (0 = first mora onset). */\n\tpitchCurve: { frame_ms: number; cents: number[] };\n\t/** Median voiced F0 of the HTS utterance in Hz. */\n\tmedianHz: number;\n\t/** Total planned duration in ms (sum of `moraDurationsMs`). */\n\tdurationMs: number;\n\t/**\n\t * Per feature-frame flag: HTS predicted the mora nucleus as a devoiced vowel\n\t * (Open JTalk's upper-case `I`/`U`, e.g. the \"su\" in \"desu\"). Pauses are false.\n\t */\n\tdevoiced: boolean[];\n\t/**\n\t * Per feature-frame HTS consonant length in ms (onset of the mora's first\n\t * phone to its vowel onset); 0 for pauses and vowel-initial morae. The\n\t * planner uses it to end the previous vowel where the consonant starts.\n\t */\n\tconsonantMs: number[];\n\t/** Per feature-frame flag: the mora starts with an unvoiced consonant (k, s, t, h, p …). */\n\tunvoicedOnset: boolean[];\n\t/**\n\t * Optional per feature-frame linear gain (1 = unity) applied to the units of\n\t * that mora on top of UtauTTS's own volume; filled by `shapeProsody`.\n\t */\n\tmoraGains?: number[];\n}\n\nexport interface AlignHtsOptions {\n\t/** Multiplier on the cents curve. 1 = HTS as-is. Default 1. */\n\tintonationStrength?: number;\n\t/** Output frame period for the pitch curve in ms. Default 10 (worldline's frame). */\n\tframeMs?: number;\n\t/** Pause length used when the features have a pause HTS did not produce. Default 150. */\n\tfallbackPauseMs?: number;\n\t/**\n\t * Soft limit for the cents curve: excursions beyond `kneeCents` are halved,\n\t * then hard-clamped at `maxCents`. HTS voices end phrases with a creaky\n\t * drop of close to an octave, which WORLD resynthesis of a singing sample\n\t * cannot follow cleanly. Defaults: knee 400, max 700.\n\t */\n\tkneeCents?: number;\n\tmaxCents?: number;\n\t/**\n\t * Longest unvoiced run (ms) that is bridged by interpolating F0 from the\n\t * voiced frame before it to the one after it. Unvoiced consonants (30–120\n\t * ms) are bridged; a longer run is a devoiced vowel plus a pause plus the\n\t * next phrase's consonant, and a ramp across it would carry the *next*\n\t * phrase's onset pitch back onto the devoiced mora (「ございます」 rendered\n\t * with a rising 「す」, since UTAU renders devoiced vowels voiced). Such\n\t * runs hold the previous value over their first half and the following\n\t * value over their second half. Default 120.\n\t */\n\tunvoicedBridgeMs?: number;\n}\n\n/** Mora nuclei in Open JTalk phoneme notation (upper case = devoiced vowel). */\nconst NUCLEUS = new Set([\n\t\"a\",\n\t\"i\",\n\t\"u\",\n\t\"e\",\n\t\"o\",\n\t\"A\",\n\t\"I\",\n\t\"U\",\n\t\"E\",\n\t\"O\",\n\t\"N\",\n\t\"cl\",\n]);\n\n/** Halve excursions beyond ±knee, then clamp at ±max (keeps the shape, tames the extremes). */\nfunction softLimit(value: number, knee: number, max: number): number {\n\tconst magnitude = Math.abs(value);\n\tconst limited =\n\t\tmagnitude <= knee ? magnitude : knee + (magnitude - knee) * 0.5;\n\treturn Math.sign(value) * Math.min(max, limited);\n}\n\ninterface Segment {\n\tpause: boolean;\n\t/** Consonant onset (pause start for pauses). */\n\tstartMs: number;\n\t/** Vowel (nucleus) onset; equals `startMs` for pauses and bare consonants. */\n\tnucleusMs: number;\n\tendMs: number;\n\t/** Nucleus was an upper-case (devoiced) vowel. */\n\tdevoiced: boolean;\n\t/** First phone of the mora (\"\" for pauses and vowel-initial morae). */\n\tonset: string;\n}\n\nconst DEVOICED = new Set([\"A\", \"I\", \"U\", \"E\", \"O\"]);\n\n/** Open JTalk consonants with no voicing: the F0 jump across them is inaudible in speech. */\nconst UNVOICED_ONSET = new Set([\n\t\"k\",\n\t\"ky\",\n\t\"s\",\n\t\"sh\",\n\t\"t\",\n\t\"ty\",\n\t\"ch\",\n\t\"ts\",\n\t\"h\",\n\t\"hy\",\n\t\"f\",\n\t\"p\",\n\t\"py\",\n]);\n\n/** Group HTS phonemes into morae / pauses. Leading `sil` is dropped, trailing `sil` becomes a pause. */\nfunction segmentPhonemes(phonemes: HtsPhoneme[]): Segment[] {\n\tconst segments: Segment[] = [];\n\tlet openStart: number | null = null;\n\tlet openOnset = \"\";\n\tfor (let i = 0; i < phonemes.length; i++) {\n\t\tconst { phone, start_ms, duration_ms } = phonemes[i];\n\t\tif (phone === \"sil\" || phone === \"pau\") {\n\t\t\tif (openStart !== null) {\n\t\t\t\t// Consonant without a nucleus (should not happen): fold into a mora.\n\t\t\t\tsegments.push({\n\t\t\t\t\tpause: false,\n\t\t\t\t\tstartMs: openStart,\n\t\t\t\t\tnucleusMs: openStart,\n\t\t\t\t\tendMs: start_ms,\n\t\t\t\t\tdevoiced: false,\n\t\t\t\t\tonset: openOnset,\n\t\t\t\t});\n\t\t\t\topenStart = null;\n\t\t\t}\n\t\t\tif (i === 0) continue;\n\t\t\tsegments.push({\n\t\t\t\tpause: true,\n\t\t\t\tstartMs: start_ms,\n\t\t\t\tnucleusMs: start_ms,\n\t\t\t\tendMs: start_ms + duration_ms,\n\t\t\t\tdevoiced: false,\n\t\t\t\tonset: \"\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (openStart === null) {\n\t\t\topenStart = start_ms;\n\t\t\topenOnset = NUCLEUS.has(phone) ? \"\" : phone;\n\t\t}\n\t\tif (NUCLEUS.has(phone)) {\n\t\t\tsegments.push({\n\t\t\t\tpause: false,\n\t\t\t\tstartMs: openStart,\n\t\t\t\tnucleusMs: start_ms,\n\t\t\t\tendMs: start_ms + duration_ms,\n\t\t\t\tdevoiced: DEVOICED.has(phone),\n\t\t\t\tonset: openOnset,\n\t\t\t});\n\t\t\topenStart = null;\n\t\t}\n\t}\n\tif (openStart !== null) {\n\t\tconst last = phonemes[phonemes.length - 1];\n\t\tsegments.push({\n\t\t\tpause: false,\n\t\t\tstartMs: openStart,\n\t\t\tnucleusMs: openStart,\n\t\t\tendMs: last.start_ms + last.duration_ms,\n\t\t\tonset: openOnset,\n\t\t\tdevoiced: false,\n\t\t});\n\t}\n\treturn segments;\n}\n\n/**\n * Where a segment sits on the mora grid: a mora's note starts at its vowel\n * onset (UTAU note semantics: the consonant is pre-uttered before the note),\n * a pause at its own start.\n */\nfunction anchorMs(segment: Segment): number {\n\treturn segment.pause ? segment.startMs : segment.nucleusMs;\n}\n\n/**\n * Align HTS phoneme timing and F0 to the mora/pause sequence in `features`\n * (from `openjtalkAnalyze`). Returns null when the two mora sequences cannot\n * be matched, in which case the caller should fall back to the TCN contour.\n *\n * Mora boundaries are the HTS *vowel onsets*: a mora's duration runs from its\n * vowel onset to the next mora's vowel onset (so the next consonant belongs to\n * the end of this mora), which is how UtauTTS places units (note start =\n * vowel onset, consonant pre-uttered). Cutting at consonant onsets instead\n * would delay the F0 contour by one consonant (40–120 ms) relative to the\n * rendered vowels and shift every accent fall onto the following mora.\n */\nexport function alignHtsProsody(\n\tframes: HtsProsodyFrames,\n\tfeatures: FeatureFrame[],\n\toptions: AlignHtsOptions = {},\n): HtsProsody | null {\n\tconst {\n\t\tintonationStrength = 1,\n\t\tframeMs = 10,\n\t\tfallbackPauseMs = 150,\n\t\tkneeCents = 400,\n\t\tmaxCents = 700,\n\t\tunvoicedBridgeMs = 120,\n\t} = options;\n\tconst segments = segmentPhonemes(frames.phonemes);\n\n\t// Two-pointer walk: morae must pair 1:1; pauses may be missing on either side.\n\tconst matched: (number | null)[] = new Array(features.length).fill(null);\n\tconst devoiced: boolean[] = new Array(features.length).fill(false);\n\tconst consonantMs: number[] = new Array(features.length).fill(0);\n\tconst unvoicedOnset: boolean[] = new Array(features.length).fill(false);\n\tlet s = 0;\n\tfor (let f = 0; f < features.length; f++) {\n\t\tconst feature = features[f];\n\t\twhile (s < segments.length && segments[s].pause && !feature.pause) s++; // HTS pause the features lack\n\t\tconst segment = segments[s];\n\t\tif (feature.pause) {\n\t\t\tif (segment?.pause) matched[f] = s++;\n\t\t\t// else: features pause HTS lacks (e.g. unreadable token) → fallback below\n\t\t\tcontinue;\n\t\t}\n\t\tif (!segment) return null;\n\t\tmatched[f] = s++;\n\t\tdevoiced[f] = segment.devoiced;\n\t\tconsonantMs[f] = Math.max(0, segment.nucleusMs - segment.startMs);\n\t\tunvoicedOnset[f] = UNVOICED_ONSET.has(segment.onset);\n\t}\n\tif (segments.slice(s).some((segment) => !segment.pause)) return null; // HTS has morae left over\n\n\t// Durations between consecutive anchors; HTS pauses the features skipped\n\t// are cut out so a mora does not stretch across them.\n\tconst durations: number[] = new Array(features.length).fill(0);\n\tconst htsStart: (number | null)[] = new Array(features.length).fill(null);\n\tfor (let f = 0; f < features.length; f++) {\n\t\tconst index = matched[f];\n\t\tif (index === null) {\n\t\t\tdurations[f] = fallbackPauseMs;\n\t\t\tcontinue;\n\t\t}\n\t\tconst here = anchorMs(segments[index]);\n\t\tlet next = f + 1;\n\t\twhile (next < features.length && matched[next] === null) next++;\n\t\tlet end = segments[index].endMs;\n\t\tif (next < features.length) {\n\t\t\tconst nextIndex = matched[next] as number;\n\t\t\tend = anchorMs(segments[nextIndex]);\n\t\t\tfor (let k = index + 1; k < nextIndex; k++) {\n\t\t\t\tif (segments[k].pause) end -= segments[k].endMs - segments[k].startMs;\n\t\t\t}\n\t\t}\n\t\tdurations[f] = Math.max(0, end - here);\n\t\thtsStart[f] = here;\n\t}\n\n\t// HTS voices often call unvoiced consonants voiced (tohoku-f01 gives 「h」\n\t// and 「t」 an F0 track), which would carry the pitch movement of the\n\t// consonant into the rendered vowel. Treat frames inside phonologically\n\t// unvoiced consonants as unvoiced so the hold-then-ramp bridging applies.\n\tconst f0 = frames.f0_hz.slice();\n\tfor (const phoneme of frames.phonemes) {\n\t\tif (!UNVOICED_ONSET.has(phoneme.phone) && phoneme.phone !== \"cl\") continue;\n\t\tconst from = Math.max(0, Math.round(phoneme.start_ms / frames.frame_ms));\n\t\tconst to = Math.min(\n\t\t\tf0.length,\n\t\t\tMath.round((phoneme.start_ms + phoneme.duration_ms) / frames.frame_ms),\n\t\t);\n\t\tfor (let i = from; i < to; i++) f0[i] = 0;\n\t}\n\n\t// Continuous F0 in log2 domain (interpolate across unvoiced runs, hold at edges).\n\tconst logF0 = new Float64Array(f0.length);\n\tconst voiced: number[] = [];\n\tfor (let i = 0; i < f0.length; i++) if (f0[i] > 0) voiced.push(i);\n\tif (voiced.length === 0) return null;\n\tconst sorted = voiced.map((i) => f0[i]).sort((a, b) => a - b);\n\tconst medianHz = sorted[Math.floor(sorted.length / 2)];\n\tfor (let i = 0, v = 0; i < f0.length; i++) {\n\t\tif (f0[i] > 0) {\n\t\t\tlogF0[i] = Math.log2(f0[i]);\n\t\t\tcontinue;\n\t\t}\n\t\twhile (v < voiced.length && voiced[v] < i) v++;\n\t\tconst right = voiced[v];\n\t\tconst left = v > 0 ? voiced[v - 1] : undefined;\n\t\tif (left === undefined) logF0[i] = Math.log2(f0[right]);\n\t\telse if (right === undefined) logF0[i] = Math.log2(f0[left]);\n\t\telse {\n\t\t\tif ((right - left) * frames.frame_ms > unvoicedBridgeMs) {\n\t\t\t\t// Pause-sized gap: no ramp; switch from the previous to the next value at the midpoint.\n\t\t\t\tlogF0[i] = Math.log2(\n\t\t\t\t\ti - left <= (right - left) / 2 ? f0[left] : f0[right],\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Unvoiced consonant: hold the previous value and move only in the\n\t\t\t// last ~20 ms before the next vowel. In speech the jump hides inside\n\t\t\t// the consonant; a ramp across the whole gap would be rendered as a\n\t\t\t// glide inside the preceding vowel (UTAU vowels run up to the next\n\t\t\t// consonant), which sounds sing-song.\n\t\t\tconst rampStart = Math.max(left, right - Math.ceil(20 / frames.frame_ms));\n\t\t\tif (i <= rampStart) {\n\t\t\t\tlogF0[i] = Math.log2(f0[left]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst t = (i - rampStart) / (right - rampStart);\n\t\t\tlogF0[i] = Math.log2(f0[left]) * (1 - t) + Math.log2(f0[right]) * t;\n\t\t}\n\t}\n\tconst logMedian = Math.log2(medianHz);\n\tconst htsCentsAt = (tMs: number): number => {\n\t\tconst position = Math.max(0, tMs) / frames.frame_ms;\n\t\tconst left = Math.min(logF0.length - 1, Math.floor(position));\n\t\tconst right = Math.min(logF0.length - 1, left + 1);\n\t\tconst t = position - Math.floor(position);\n\t\treturn (logF0[left] * (1 - t) + logF0[right] * t - logMedian) * 1200;\n\t};\n\n\t// Plan time axis: morae start at the cumulative sum of the assigned durations.\n\tconst planStart: number[] = [];\n\tlet cursor = 0;\n\tfor (let f = 0; f < features.length; f++) {\n\t\tplanStart.push(cursor);\n\t\tcursor += durations[f];\n\t}\n\tconst durationMs = cursor;\n\tconst count = Math.max(2, Math.ceil(durationMs / frameMs) + 2);\n\tconst cents = new Array<number>(count);\n\tlet f = 0;\n\tfor (let frame = 0; frame < count; frame++) {\n\t\tconst tMs = frame * frameMs;\n\t\twhile (f + 1 < features.length && tMs >= planStart[f + 1]) f++;\n\t\tconst start = htsStart[f];\n\t\t// Pauses HTS did not produce have no HTS time: hold the value at the next mora onset.\n\t\tlet htsMs: number;\n\t\tif (start !== null) htsMs = start + (tMs - planStart[f]);\n\t\telse {\n\t\t\tconst next = htsStart.slice(f + 1).find((value) => value !== null);\n\t\t\thtsMs = next ?? frames.phonemes.at(-1)?.start_ms ?? 0;\n\t\t}\n\t\tcents[frame] = softLimit(\n\t\t\thtsCentsAt(htsMs) * intonationStrength,\n\t\t\tkneeCents,\n\t\t\tmaxCents,\n\t\t);\n\t}\n\treturn {\n\t\tmoraDurationsMs: durations,\n\t\tpitchCurve: { frame_ms: frameMs, cents },\n\t\tmedianHz,\n\t\tdurationMs,\n\t\tdevoiced,\n\t\tconsonantMs,\n\t\tunvoicedOnset,\n\t};\n}\n","export interface NjdNode {\r\n string: string;\r\n pos: string;\r\n pos_group1: string;\r\n pron: string;\r\n read: string;\r\n acc: number;\r\n mora_size: number;\r\n chain_flag: number;\r\n}\r\n\r\nexport interface FeatureFrame {\r\n mora: string;\r\n pause: boolean;\r\n /**\r\n * For pause frames: the token that produced the pause (「。」「、」「?」, a\r\n * space, a bracket…). Lets prosody rules pick a pause length per kind.\r\n * Absent on pauses synthesised from a reading string.\r\n */\r\n punctuation?: string;\r\n accent_phrase_position?: number;\r\n accent_phrase_length?: number;\r\n accent_nucleus?: number;\r\n accent_high?: boolean;\r\n accent_phrase_start?: boolean;\r\n accent_phrase_end?: boolean;\r\n word_start?: boolean;\r\n word_end?: boolean;\r\n pos?: string;\r\n pos_group1?: string;\r\n}\r\n\r\nconst PUNCTUATION = new Set([\"、\", \"。\", \"?\", \"!\", \",\", \".\", \"?\", \"!\"]);\r\nconst SMALL_KANA = new Set([\"ぁ\", \"ぃ\", \"ぅ\", \"ぇ\", \"ぉ\", \"ゃ\", \"ゅ\", \"ょ\", \"ゎ\", \"ゕ\", \"ゖ\"]);\r\n\r\nfunction toHiragana(character: string): string {\r\n const code = character.charCodeAt(0);\r\n if (0x30A1 <= code && code <= 0x30F6) {\r\n return String.fromCharCode(code - 0x60);\r\n }\r\n return character;\r\n}\r\n\r\nfunction splitMorae(reading: string): FeatureFrame[] {\r\n const result: FeatureFrame[] = [];\r\n const normalized = reading.normalize(\"NFC\").replace(/'/g, \"\").replace(/’/g, \"\");\r\n for (const character of normalized) {\r\n if (/\\s/.test(character) || PUNCTUATION.has(character)) {\r\n if (result.length > 0 && !result[result.length - 1].pause) {\r\n result.push({ mora: \"\", pause: true });\r\n }\r\n continue;\r\n }\r\n const mora = toHiragana(character);\r\n if (SMALL_KANA.has(mora) && result.length > 0 && !result[result.length - 1].pause) {\r\n result[result.length - 1].mora += mora;\r\n } else {\r\n result.push({ mora, pause: false });\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nfunction isHigh(position: number, accent: number): boolean {\r\n if (accent === 1) return position === 1;\r\n if (accent > 1) return 2 <= position && position <= accent;\r\n return position >= 2;\r\n}\r\n\r\n/** Pause kinds a punctuation token maps to (see {@link pauseKind}). */\r\nexport type PauseKind = \"sentence\" | \"clause\" | \"space\";\r\n\r\nconst SENTENCE_END = /[。.!?!?.]/u;\r\nconst CLAUSE = /[、,,]/u;\r\n\r\n/**\r\n * Classify the token that produced a pause: sentence-final punctuation, a\r\n * clause comma, or whitespace / anything else (brackets, symbols).\r\n */\r\nexport function pauseKind(punctuation: string | undefined): PauseKind {\r\n if (punctuation === undefined) return \"clause\";\r\n if (SENTENCE_END.test(punctuation)) return \"sentence\";\r\n if (CLAUSE.test(punctuation)) return \"clause\";\r\n return \"space\";\r\n}\r\n\r\nfunction pauseRank(punctuation: string | undefined): number {\r\n if (punctuation === undefined) return 0;\r\n switch (pauseKind(punctuation)) {\r\n case \"sentence\": return 3;\r\n case \"clause\": return 2;\r\n default: return 1;\r\n }\r\n}\r\n\r\nexport function analyze(nodes: NjdNode[]): { reading: string, features: FeatureFrame[] } {\r\n const reading_parts: string[] = [];\r\n const result: FeatureFrame[] = [];\r\n let index = 0;\r\n \r\n while (index < nodes.length) {\r\n const node = nodes[index];\r\n const pronunciation = (node.pron || \"\").replace(/'/g, \"\").replace(/’/g, \"\");\r\n if (node.mora_size === 0 || PUNCTUATION.has(node.string)) {\r\n reading_parts.push(node.string || \"、\");\r\n const last = result[result.length - 1];\r\n if (result.length > 0 && !last.pause) {\r\n result.push({ mora: \"\", pause: true, punctuation: node.string || \"、\" });\r\n } else if (last?.pause && pauseRank(node.string) > pauseRank(last.punctuation)) {\r\n // 「。」 followed by a space or a closing bracket: keep the strongest token.\r\n last.punctuation = node.string;\r\n }\r\n index++;\r\n continue;\r\n }\r\n\r\n const phrase_nodes: { current: NjdNode, morae: FeatureFrame[] }[] = [];\r\n while (index < nodes.length) {\r\n const current = nodes[index];\r\n if (current.mora_size === 0 || PUNCTUATION.has(current.string)) {\r\n break;\r\n }\r\n if (phrase_nodes.length > 0 && current.chain_flag !== 1) {\r\n break;\r\n }\r\n const current_pronunciation = (current.pron || \"\").replace(/'/g, \"\").replace(/’/g, \"\");\r\n const morae = splitMorae(current_pronunciation).filter(item => !item.pause);\r\n phrase_nodes.push({ current, morae });\r\n reading_parts.push(current_pronunciation);\r\n index++;\r\n }\r\n\r\n const phrase_length = phrase_nodes.reduce((sum, item) => sum + item.morae.length, 0);\r\n const accent = phrase_nodes[0].current.acc || 0;\r\n let phrase_position = 0;\r\n\r\n for (const { current, morae } of phrase_nodes) {\r\n for (let word_position = 1; word_position <= morae.length; word_position++) {\r\n phrase_position++;\r\n result.push({\r\n mora: morae[word_position - 1].mora,\r\n pause: false,\r\n accent_phrase_position: phrase_position,\r\n accent_phrase_length: phrase_length,\r\n accent_nucleus: accent,\r\n accent_high: isHigh(phrase_position, accent),\r\n accent_phrase_start: phrase_position === 1,\r\n accent_phrase_end: phrase_position === phrase_length,\r\n word_start: word_position === 1,\r\n word_end: word_position === morae.length,\r\n pos: current.pos || \"*\",\r\n pos_group1: current.pos_group1 || \"*\",\r\n });\r\n }\r\n }\r\n }\r\n return { reading: reading_parts.join(\"\"), features: result };\r\n}\r\nexport function sparse_features(token: FeatureFrame): Record<string, number> {\r\n if (token.pause || token.accent_phrase_position === undefined || token.accent_phrase_length === undefined || token.accent_nucleus === undefined) {\r\n return {};\r\n }\r\n const phrase_length = Math.max(1, token.accent_phrase_length);\r\n const phrase_position = token.accent_phrase_position;\r\n const nucleus = token.accent_nucleus;\r\n \r\n const result: Record<string, number> = {\r\n \"accent_position\": phrase_position / phrase_length,\r\n \"accent_from_end\": (phrase_length - phrase_position) / phrase_length,\r\n \"accent_nucleus_position\": nucleus / phrase_length,\r\n \"accent_high\": token.accent_high ? 1.0 : 0.0,\r\n \"accent_phrase_start\": token.accent_phrase_start ? 1.0 : 0.0,\r\n \"accent_phrase_end\": token.accent_phrase_end ? 1.0 : 0.0,\r\n \"word_start\": token.word_start ? 1.0 : 0.0,\r\n \"word_end\": token.word_end ? 1.0 : 0.0,\r\n };\r\n \r\n result[`pos=${token.pos || \"*\"}`] = 1.0;\r\n result[`pos_group1=${token.pos_group1 || \"*\"}`] = 1.0;\r\n \r\n if (nucleus === 0) {\r\n result[\"accent_type=heiban\"] = 1.0;\r\n } else if (phrase_position < nucleus) {\r\n result[\"accent_type=before\"] = 1.0;\r\n } else if (phrase_position === nucleus) {\r\n result[\"accent_type=nucleus\"] = 1.0;\r\n } else {\r\n result[\"accent_type=after\"] = 1.0;\r\n }\r\n \r\n return result;\r\n}\r\n","import type { HtsProsody } from \"./hts.js\";\nimport {\n\ttype FeatureFrame,\n\ttype PauseKind,\n\tpauseKind,\n} from \"./openjtalk_features.js\";\n\n/**\n * Rule-based residuals on top of the HTS prosody (a cut-down Fujisaki-style\n * layer): the statistical model gives the accent shape, these rules add what\n * the HTS voices were not trained for and what a concatenative voice bank\n * lacks on its own.\n *\n * - question rise: a sentence ending in 「?」 gets at least a minimum rise\n * on its last mora; Open JTalk's interrogative label flag already makes\n * tohoku-f01 rise, so this only tops up voices/sentences that do not\n * - energy envelope (off by default, see `energyDbPerSemitone`): loudness\n * follows pitch per mora; the renderer now does this smoothly per frame\n * - devoiced vowels: morae HTS predicted as devoiced (「です」「ます」…) are\n * attenuated so the voiced sample does not shout a vowel the speaker\n * would whisper\n * - pause length by punctuation: the HTS voice was trained on single\n * sentences, so it gives 「。」 and 「、」 the same ~300 ms; a reading voice\n * pauses roughly twice as long at a sentence end\n * - duration contrast: HTS durations are variance-shrunk (over-smoothed);\n * stretching them around the utterance mean restores some of the\n * short-particle / long-final-mora rhythm of natural speech\n *\n * Zero assets, negligible compute; everything is mora-level arithmetic.\n */\nexport interface ShapeProsodyOptions {\n\t/**\n\t * Minimum pause length in ms per pause kind (see `pauseKind`); the HTS\n\t * pause is kept when it is already longer. The utterance-final pause is\n\t * left alone. `null` disables the rule. Defaults: sentence 650, clause 380,\n\t * space 500.\n\t */\n\tpauseMs?: Partial<Record<PauseKind, number>> | null;\n\t/**\n\t * Expansion of spoken-mora durations around the utterance mean:\n\t * `mean + (d − mean) × contrast`. 1 keeps HTS as-is. Default 1.3.\n\t */\n\tdurationContrast?: number;\n\t/** Floor for a spoken mora after contrast expansion, in ms. Default 60. */\n\tminMoraMs?: number;\n\t/**\n\t * A mora is never shortened below this fraction of its HTS duration by the\n\t * contrast expansion (short morae such as devoiced 「く」 are already at\n\t * their minimum). Default 0.85.\n\t */\n\tminShrink?: number;\n\t/** Baseline pitch shift added to the whole curve, in cents. Default 0. */\n\tpitchShiftCents?: number;\n\t/** Treat the utterance as a question (see {@link isQuestion}). Default false. */\n\tquestion?: boolean;\n\t/**\n\t * Minimum rise across the final mora of a question, in cents. Open JTalk\n\t * labels carry an interrogative flag and HTS voices trained with it (e.g.\n\t * tohoku-f01) already rise; the rule only tops up whatever is missing, so\n\t * it is a safety net for voices/sentences where the rise does not appear.\n\t * Default 350.\n\t */\n\tquestionRiseCents?: number;\n\t/**\n\t * Per-mora loudness coupling: dB per 100 cents of pitch relative to the\n\t * speaker median, applied as a step per mora through `moraGains`. Default\n\t * 0: `UtauTTSAdapter.renderChunks` applies the same coupling as a smooth\n\t * per-frame curve (`energyDbPerSemitone` there), which avoids level steps\n\t * at the mora joins. Set this when rendering through something else.\n\t */\n\tenergyDbPerSemitone?: number;\n\t/**\n\t * Linear gain for morae with a devoiced nucleus, applied to the whole unit\n\t * through `moraGains`. Default 1: `UtauTTSAdapter.renderChunks` attenuates\n\t * only the vowel part of a devoiced mora (`devoicedDb`), keeping the\n\t * consonant burst audible; set this when rendering through something else.\n\t */\n\tdevoicedGain?: number;\n\t/** Clamp for the per-mora gain. Defaults 0.35 … 1.8. */\n\tminGain?: number;\n\tmaxGain?: number;\n}\n\n/** Closing brackets/quotes/spaces that may follow the final punctuation. */\nconst TRAILING = /[\\s」』))〕】>>\"'”’]+$/u;\n\n/** True when the text ends with a question mark (「?」 or \"?\"), ignoring closing quotes. */\nexport function isQuestion(text: string): boolean {\n\treturn /[??]$/u.test(text.replace(TRAILING, \"\"));\n}\n\nfunction smoothstep(t: number): number {\n\tconst x = Math.min(1, Math.max(0, t));\n\treturn x * x * (3 - 2 * x);\n}\n\nconst DEFAULT_PAUSE_MS: Record<PauseKind, number> = {\n\tsentence: 650,\n\tclause: 380,\n\tspace: 500,\n};\n\n/**\n * New per-frame durations: pauses lengthened by kind, spoken morae expanded\n * around the mean. Pure; returns `durations` itself when nothing changes.\n */\nexport function shapeDurations(\n\tdurations: number[],\n\tfeatures: FeatureFrame[],\n\toptions: Pick<\n\t\tShapeProsodyOptions,\n\t\t\"pauseMs\" | \"durationContrast\" | \"minMoraMs\" | \"minShrink\"\n\t> = {},\n): number[] {\n\tconst {\n\t\tpauseMs = DEFAULT_PAUSE_MS,\n\t\tdurationContrast = 1.3,\n\t\tminMoraMs = 60,\n\t\tminShrink = 0.85,\n\t} = options;\n\tconst count = Math.min(features.length, durations.length);\n\tlet sum = 0;\n\tlet spoken = 0;\n\tfor (let f = 0; f < count; f++) {\n\t\tif (features[f].pause) continue;\n\t\tsum += durations[f];\n\t\tspoken++;\n\t}\n\tconst mean = spoken > 0 ? sum / spoken : 0;\n\tconst result = durations.slice();\n\tlet changed = false;\n\tfor (let f = 0; f < count; f++) {\n\t\tconst feature = features[f];\n\t\tlet next = durations[f];\n\t\tif (feature.pause) {\n\t\t\tif (pauseMs && f < count - 1) {\n\t\t\t\tconst kind = pauseKind(feature.punctuation);\n\t\t\t\tnext = Math.max(next, pauseMs[kind] ?? DEFAULT_PAUSE_MS[kind]);\n\t\t\t}\n\t\t} else if (durationContrast !== 1 && next > 0) {\n\t\t\tnext = Math.max(\n\t\t\t\tMath.min(next, minMoraMs),\n\t\t\t\tnext * minShrink,\n\t\t\t\tmean + (next - mean) * durationContrast,\n\t\t\t);\n\t\t}\n\t\tif (next !== durations[f]) {\n\t\t\tresult[f] = next;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\treturn changed ? result : durations;\n}\n\n/**\n * Re-time a cents curve from the `from` durations to the `to` durations with\n * a piecewise-linear warp (each frame keeps its own contour, stretched or\n * squeezed to its new length). Frame period unchanged.\n */\nexport function warpPitchCurve(\n\tcents: number[],\n\tframeMs: number,\n\tfrom: number[],\n\tto: number[],\n): number[] {\n\tconst count = Math.min(from.length, to.length);\n\tconst fromStart: number[] = [];\n\tconst toStart: number[] = [];\n\tlet a = 0;\n\tlet b = 0;\n\tfor (let f = 0; f < count; f++) {\n\t\tfromStart.push(a);\n\t\ttoStart.push(b);\n\t\ta += from[f];\n\t\tb += to[f];\n\t}\n\tconst frames = Math.max(2, Math.ceil(b / frameMs) + 2);\n\tconst result = new Array<number>(frames);\n\tconst last = cents.length - 1;\n\tif (last < 0) return result.fill(0);\n\tlet f = 0;\n\tfor (let frame = 0; frame < frames; frame++) {\n\t\tconst tMs = frame * frameMs;\n\t\twhile (f + 1 < count && tMs >= toStart[f + 1]) f++;\n\t\tconst progress = to[f] > 0 ? (tMs - toStart[f]) / to[f] : 0;\n\t\tconst source = (fromStart[f] + progress * from[f]) / frameMs;\n\t\tconst left = Math.min(last, Math.max(0, Math.floor(source)));\n\t\tconst right = Math.min(last, left + 1);\n\t\tconst t = Math.min(1, Math.max(0, source - Math.floor(source)));\n\t\tresult[frame] = cents[left] * (1 - t) + cents[right] * t;\n\t}\n\treturn result;\n}\n\n/**\n * Apply the residual rules to an aligned HTS prosody. Returns a new object;\n * `prosody` is not modified. Pass the result to `plan({ prosody })`: the pitch\n * curve carries the question rise, `moraGains` the energy envelope.\n */\nexport function shapeProsody(\n\tprosody: HtsProsody,\n\tfeatures: FeatureFrame[],\n\toptions: ShapeProsodyOptions = {},\n): HtsProsody {\n\tconst {\n\t\tquestion = false,\n\t\tquestionRiseCents = 350,\n\t\tenergyDbPerSemitone = 0,\n\t\tdevoicedGain = 1,\n\t\tminGain = 0.35,\n\t\tmaxGain = 1.8,\n\t\tpitchShiftCents = 0,\n\t} = options;\n\tconst { frame_ms: frameMs } = prosody.pitchCurve;\n\n\t// ── Durations: pause by punctuation kind, contrast expansion; warp the curve to match ──\n\tconst durations = shapeDurations(prosody.moraDurationsMs, features, options);\n\tconst cents =\n\t\tdurations === prosody.moraDurationsMs\n\t\t\t? prosody.pitchCurve.cents.slice()\n\t\t\t: warpPitchCurve(\n\t\t\t\t\tprosody.pitchCurve.cents,\n\t\t\t\t\tframeMs,\n\t\t\t\t\tprosody.moraDurationsMs,\n\t\t\t\t\tdurations,\n\t\t\t\t);\n\tconst count = Math.min(features.length, durations.length);\n\n\t// Mora boundaries on the plan time axis, in frames.\n\tconst startFrame: number[] = [];\n\tconst endFrame: number[] = [];\n\tlet cursor = 0;\n\tfor (let f = 0; f < count; f++) {\n\t\tstartFrame.push(cursor / frameMs);\n\t\tcursor += durations[f];\n\t\tendFrame.push(cursor / frameMs);\n\t}\n\tfor (let f = count; f < durations.length; f++) cursor += durations[f];\n\tconst durationMs = cursor;\n\tif (pitchShiftCents !== 0) {\n\t\tfor (let frame = 0; frame < cents.length; frame++)\n\t\t\tcents[frame] += pitchShiftCents;\n\t}\n\tconst frameRange = (f: number): [number, number] => [\n\t\tMath.max(0, Math.min(cents.length, Math.round(startFrame[f]))),\n\t\tMath.max(0, Math.min(cents.length, Math.round(endFrame[f]))),\n\t];\n\n\t// ── Question rise on the last spoken mora (top-up only) ──\n\tif (question && questionRiseCents > 0) {\n\t\tlet last = -1;\n\t\tfor (let f = count - 1; f >= 0; f--) {\n\t\t\tif (!features[f].pause) {\n\t\t\t\tlast = f;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (last >= 0) {\n\t\t\tconst [from, to] = frameRange(last);\n\t\t\tif (to > from) {\n\t\t\t\tconst existing = cents[to - 1] - cents[from];\n\t\t\t\tconst shortfall = questionRiseCents - existing;\n\t\t\t\tif (shortfall > 0) {\n\t\t\t\t\t// Hold the first quarter, then add the missing rise; keep the peak\n\t\t\t\t\t// through whatever follows (trailing pause / release).\n\t\t\t\t\tfor (let frame = from; frame < cents.length; frame++) {\n\t\t\t\t\t\tconst t = (frame - from) / (to - from);\n\t\t\t\t\t\tcents[frame] += shortfall * smoothstep((t - 0.25) / 0.75);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Per-mora gain: pitch-coupled loudness × devoicing ──\n\tconst moraGains: number[] = new Array(features.length).fill(1);\n\tfor (let f = 0; f < count; f++) {\n\t\tif (features[f].pause) continue;\n\t\tlet gainDb = 0;\n\t\tif (energyDbPerSemitone !== 0) {\n\t\t\tconst [from, to] = frameRange(f);\n\t\t\tif (to > from) {\n\t\t\t\tlet sum = 0;\n\t\t\t\tfor (let frame = from; frame < to; frame++) sum += cents[frame];\n\t\t\t\tgainDb += (sum / (to - from) / 100) * energyDbPerSemitone;\n\t\t\t}\n\t\t}\n\t\tlet gain = 10 ** (gainDb / 20);\n\t\tif (prosody.devoiced[f]) gain *= devoicedGain;\n\t\tmoraGains[f] = Math.min(maxGain, Math.max(minGain, gain));\n\t}\n\n\treturn {\n\t\t...prosody,\n\t\tmoraDurationsMs: durations,\n\t\tdurationMs,\n\t\tpitchCurve: { frame_ms: frameMs, cents },\n\t\tmoraGains,\n\t};\n}\n","import type { AlignHtsOptions } from \"./hts.js\";\nimport type { ShapeProsodyOptions } from \"./prosody_rules.js\";\nimport type { UtauTTSRenderOptions } from \"./UtauTTSAdapter.js\";\n\n/**\n * Speaking style: the handful of global knobs the pipeline already has,\n * bundled so an application can offer \"calm / neutral / lively\" (or map an\n * emotion label onto them) without knowing which stage each knob lives in.\n *\n * Nothing here needs assets or compute: `speed` goes to\n * `analyze_prosody(text, speed)`, `intonation` to `alignHtsProsody`,\n * `pauseScale` / `durationContrast` / `pitchShiftCents` to `shapeProsody`,\n * `energyDbPerSemitone` to `renderChunks`. A different HTS voice (tohoku-f01\n * ships happy / sad / angry variants next to neutral) changes the phoneme\n * durations and F0 themselves and composes with these knobs.\n */\nexport interface SpeakingStyle {\n\t/** HTS speaking rate; 1 = the voice model's own rate (~7 morae/s for tohoku-f01). */\n\tspeed: number;\n\t/** F0 excursion scale (`AlignHtsOptions.intonationStrength`). */\n\tintonation: number;\n\t/** Baseline pitch shift in cents, added to the whole F0 curve. */\n\tpitchShiftCents: number;\n\t/** Multiplier on the punctuation pause minimums (「。」650 / 「、」380 / space 500 ms at 1). */\n\tpauseScale: number;\n\t/** Mora-duration contrast expansion around the mean (`ShapeProsodyOptions.durationContrast`). */\n\tdurationContrast: number;\n\t/** Loudness contour strength in dB per semitone (`UtauTTSRenderOptions.energyDbPerSemitone`). */\n\tenergyDbPerSemitone: number;\n}\n\nexport type SpeakingStyleName = \"neutral\" | \"calm\" | \"lively\";\n\n/**\n * Presets. `neutral` is the pipeline's defaults; `calm` is a reading /\n * narration pace (slower, longer sentence pauses, gentler dynamics, slightly\n * lower baseline); `lively` is the opposite. Values are starting points meant\n * to be tuned by ear.\n */\nexport const SPEAKING_STYLES: Record<SpeakingStyleName, SpeakingStyle> = {\n\tneutral: {\n\t\tspeed: 1,\n\t\tintonation: 1,\n\t\tpitchShiftCents: 0,\n\t\tpauseScale: 1,\n\t\tdurationContrast: 1.3,\n\t\tenergyDbPerSemitone: 0.8,\n\t},\n\tcalm: {\n\t\tspeed: 0.9,\n\t\tintonation: 0.9,\n\t\tpitchShiftCents: -100,\n\t\tpauseScale: 1.4,\n\t\tdurationContrast: 1.2,\n\t\tenergyDbPerSemitone: 0.6,\n\t},\n\tlively: {\n\t\tspeed: 1.08,\n\t\tintonation: 1.3,\n\t\tpitchShiftCents: 100,\n\t\tpauseScale: 0.85,\n\t\tdurationContrast: 1.4,\n\t\tenergyDbPerSemitone: 1,\n\t},\n};\n\nconst BASE_PAUSE_MS = { sentence: 650, clause: 380, space: 500 } as const;\n\n/** A preset name, or a preset name plus overrides, or a full/partial style over `neutral`. */\nexport type SpeakingStyleInput =\n\t| SpeakingStyleName\n\t| (Partial<SpeakingStyle> & { preset?: SpeakingStyleName });\n\n/** Resolve a style input to a complete {@link SpeakingStyle}. */\nexport function resolveSpeakingStyle(\n\tinput: SpeakingStyleInput = \"neutral\",\n): SpeakingStyle {\n\tif (typeof input === \"string\") return { ...SPEAKING_STYLES[input] };\n\tconst { preset = \"neutral\", ...overrides } = input;\n\treturn { ...SPEAKING_STYLES[preset], ...overrides };\n}\n\n/** Options for `alignHtsProsody` that follow the style. */\nexport function styleAlignOptions(style: SpeakingStyle): AlignHtsOptions {\n\treturn { intonationStrength: style.intonation };\n}\n\n/** Options for `shapeProsody` that follow the style (merge your own, e.g. `question`, on top). */\nexport function styleShapeOptions(style: SpeakingStyle): ShapeProsodyOptions {\n\treturn {\n\t\tpauseMs: {\n\t\t\tsentence: BASE_PAUSE_MS.sentence * style.pauseScale,\n\t\t\tclause: BASE_PAUSE_MS.clause * style.pauseScale,\n\t\t\tspace: BASE_PAUSE_MS.space * style.pauseScale,\n\t\t},\n\t\tdurationContrast: style.durationContrast,\n\t\tpitchShiftCents: style.pitchShiftCents,\n\t};\n}\n\n/** Options for `renderChunks` / `synthesizeText` that follow the style. */\nexport function styleRenderOptions(style: SpeakingStyle): UtauTTSRenderOptions {\n\treturn { energyDbPerSemitone: style.energyDbPerSemitone };\n}\n","import type { VoiceBank } from \"../engine/voice-bank.js\";\nimport {\n\tMIN_WORLDLINE_SAMPLES,\n\ttype PhraseUnit,\n\tWORLDLINE_SAMPLE_RATE,\n\ttype Worldline,\n} from \"../engine/worldline.js\";\nimport type { HtsProsody } from \"./hts.js\";\nimport { type FeatureFrame, sparse_features } from \"./openjtalk_features.js\";\n\n// ── Plan JSON produced by cmd/utautts-wasm ──────────────────────────────────\n\n/** One unit of the UtauTTS synthesis plan (`internal/plan.Unit`). */\nexport interface UtauTTSUnit {\n\tposition: number;\n\trole: string;\n\tmora: string;\n\talias: string;\n\tnote_start_ms: number;\n\tduration_ms: number;\n\toffset_ms: number;\n\tconsonant_ms: number;\n\tcutoff_ms: number;\n\tpreutterance_ms: number;\n\toverlap_ms: number;\n\tsilent?: boolean;\n\tpitch_factor: number;\n\tenergy_factor: number;\n\teffective_preutterance_ms: number;\n\teffective_consonant_ms: number;\n\teffective_overlap_ms: number;\n\tsource_f0_hz?: number;\n\ttarget_f0_hz?: number;\n\t[extra: string]: unknown;\n}\n\n/** Placement of one unit on the worldline phrase timeline (`render.WorldlineTimelineUnit`). */\nexport interface UtauTTSTimelineUnit {\n\tindex: number;\n\tposition: number;\n\trole: string;\n\tmora: string;\n\talias: string;\n\tnote_start_ms: number;\n\tduration_ms: number;\n\tposition_ms: number;\n\tskip_ms: number;\n\tlength_ms: number;\n\tfade_in_ms: number;\n\tfade_out_ms: number;\n\toffset_ms: number;\n\trequired_length_ms: number;\n\tconsonant_ms: number;\n\tcutoff_ms: number;\n\ttone: number;\n\tconsonant_velocity: number;\n\tvolume: number;\n\tenergy_factor: number;\n\tsource_f0_hz: number;\n\ttarget_f0_hz: number;\n\tenvelope?: { x_ms: number; y: number }[];\n\t/** Set by `UtauTTSAdapter.plan` from `HtsProsody.devoiced`: the nucleus is a devoiced vowel. */\n\tdevoiced?: boolean;\n}\n\n/** Whole-phrase placement + F0 curve (`render.WorldlineTimeline`). */\nexport interface UtauTTSTimeline {\n\tframe_ms: number;\n\tleading_ms: number;\n\t/** Timeline length in ms (plan duration + release + leading margin). */\n\tduration_ms: number;\n\treference_hz: number;\n\t/** Target F0 in Hz per `frame_ms` frame, starting at timeline 0. */\n\tf0_curve: number[];\n\tunits: UtauTTSTimelineUnit[];\n}\n\nexport interface UtauTTSPlan {\n\treading: string;\n\tlanguage: string;\n\tmorae: { Text: string; Consonant: string; Vowel: string; Pause: boolean }[];\n\tplan: {\n\t\tduration_ms: number;\n\t\tsingle_cv?: boolean;\n\t\tleading_margin_ms?: number;\n\t\tunits: UtauTTSUnit[];\n\t\t[extra: string]: unknown;\n\t};\n\t/** Frame pitch curve in cents relative to each unit's own pitch (plan time base). */\n\tpitch_curve?: { frame_ms: number; cents: number[] };\n\tmora_timings: { StartMS: number; DurationMS: number }[];\n\ttimeline: UtauTTSTimeline;\n\t/** @deprecated use `plan.duration_ms` */\n\tduration_ms: number;\n\t/** @deprecated use `plan.units` */\n\tunits: UtauTTSUnit[];\n\t/** @deprecated use `pitch_curve` */\n\tpitch_cents?: number[];\n\t/** @deprecated use `pitch_curve` */\n\tpitch_frame_ms?: number;\n}\n\ninterface WasmResult {\n\tsuccess: boolean;\n\terror?: string;\n\tplan?: string;\n\tid?: string;\n\taliases?: number;\n}\n\ndeclare function utautts_plan(requestJSON: string): WasmResult;\ndeclare function utautts_set_model(modelJSON: string): WasmResult;\ndeclare function utautts_set_bank(bankJSON: string): WasmResult;\ndeclare class Go {\n\timportObject: WebAssembly.Imports;\n\trun(instance: WebAssembly.Instance): Promise<void>;\n}\n\n// ── Options ─────────────────────────────────────────────────────────────────\n\n/** Synthesis parameters, same meaning and defaults as `utautts-cli` / the UtauTTS GUI. */\nexport interface UtauTTSOptions {\n\t/** Voicebank tone for prefix.map lookups. Default \"C4\". */\n\ttone?: string;\n\t/** Base mora length in ms (0 = UtauTTS default 140). */\n\tmoraDurationMs?: number;\n\t/** Pause length for punctuation in ms (0 = UtauTTS default 180). */\n\tpauseDurationMs?: number;\n\t/** Release envelope in ms. Default 20. */\n\treleaseMs?: number;\n\t/** Cap on the leading preutterance margin before the first mora (0 = no cap). */\n\tleadingPreutteranceMs?: number;\n\t/** Apply the TCN frame pitch contour and source pitch stabilisation. Default true. */\n\tapplyPitch?: boolean;\n\t/** Contour strength 0..4. Default 1. */\n\tintonationStrength?: number;\n\t/** UtauTTS experimental speech timing (voicebank calibration). Default false. */\n\tspeechTiming?: boolean;\n\twordBoundaryEnvelope?: boolean;\n\t/**\n\t * External prosody (mora durations + cents curve) from `alignHtsProsody`.\n\t * When set, UtauTTS uses these instead of its own durations and TCN contour;\n\t * `intonationStrength` is applied by `alignHtsProsody`, not here.\n\t */\n\tprosody?: HtsProsody;\n}\n\n/** One rendered piece of audio. Sum overlapping chunks: seams are equal-power crossfades. */\nexport interface UtauTTSChunk {\n\t/** Float32 PCM at 48 kHz. */\n\tpcm: Float32Array;\n\t/** Where the chunk starts on the timeline (ms from timeline 0). */\n\tstartMs: number;\n\tindex: number;\n\t/** Timeline units rendered into this chunk (context units for seams excluded). */\n\tunits: UtauTTSTimelineUnit[];\n}\n\nexport interface UtauTTSRenderOptions {\n\t/** Units in the first chunk (small → audio starts sooner). Default 3. */\n\tfirstChunkUnits?: number;\n\t/** Units per later chunk. Default 6. */\n\tchunkUnits?: number;\n\t/** Crossfade length at a mid-phrase seam in ms. Default 20. */\n\tseamCrossfadeMs?: number;\n\t/**\n\t * Even out the loudness of the rendered units. worldline normalises every\n\t * unit's level internally (the sample's own level does not reach the\n\t * output), but the vowel RMS that comes out still differs by several dB\n\t * from unit to unit, which a listener hears as an uneven, choppy line.\n\t * Each unit's vowel RMS (middle 35–90 % of its mora) is measured on the\n\t * rendered audio and pulled towards `unitLoudnessDb` by a gain curve\n\t * interpolated between mora centres, so there is no step at the joins. The\n\t * prosodic volume of the unit (accent loudness, devoicing) is kept.\n\t * Default true.\n\t */\n\tnormalizeUnitLoudness?: boolean;\n\t/**\n\t * Reference vowel RMS in dBFS. Because worldline normalises every unit,\n\t * the rendered vowel level is bank-independent (≈ −15 dBFS median for a\n\t * 単独音 bank at volume 100), so an absolute reference works and keeps the\n\t * chunks of a streamed utterance consistent. Default −16.\n\t */\n\tunitLoudnessDb?: number;\n\t/** Largest correction applied to a unit, in dB. Default 6. */\n\tunitLoudnessMaxDb?: number;\n\t/**\n\t * Energy contour: loudness follows the F0 curve, in dB per semitone from\n\t * the utterance's median F0, applied as a smooth per-frame gain on the\n\t * rendered audio (the accent peak is louder, the phrase end softer, as in\n\t * natural speech, where a read sentence loses 10–15 dB over the phrase).\n\t * A plain unit concatenation renders every mora at the same level, which\n\t * is heard as a bumpy, mechanical line. 0 disables. Default 0.8.\n\t */\n\tenergyDbPerSemitone?: number;\n\t/** Clamp for the energy contour, in dB. Default 6. */\n\tenergyMaxDb?: number;\n\t/**\n\t * Attenuation of the vowel part of a devoiced mora (Open JTalk's 「です」\n\t * 「ます」 「あくた」…), in dB, applied from the vowel onset to the next\n\t * unit's consonant so the consonant burst of the devoiced mora itself stays\n\t * at full level (attenuating the whole unit made 「あくた」 sound like\n\t * 「あた」). 0 disables. Default −9.\n\t */\n\tdevoicedDb?: number;\n\t/**\n\t * Soft limiter on the rendered audio: samples above this linear level are\n\t * compressed smoothly towards full scale (tanh knee). worldline's output\n\t * already peaks close to 0 dBFS with a plain plan, and the prosodic gains\n\t * push single vowels over; this keeps them from hard-clipping in the\n\t * AudioContext. 0 disables. Default 0.8.\n\t */\n\toutputLimit?: number;\n\tsignal?: AbortSignal;\n\tgender?: number;\n\ttension?: number;\n\tbreathiness?: number;\n\tvoicing?: number;\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n/**\n * Build the kana reading UtauTTS parses from the jpreprocess token features,\n * so the mora sequence and the feature frames line up 1:1 by construction.\n */\nexport function readingFromFeatures(features: FeatureFrame[]): string {\n\treturn features.map((frame) => (frame.pause ? \"、\" : frame.mora)).join(\"\");\n}\n\nconst FS = WORLDLINE_SAMPLE_RATE;\nconst msToSamples = (ms: number): number => Math.round((ms / 1000) * FS);\n\n/** RMS of `pcm[from, to)` in dBFS; NaN when the window is empty. */\nfunction rmsDb(pcm: Float32Array, from: number, to: number): number {\n\tconst a = Math.max(0, from);\n\tconst b = Math.min(pcm.length, to);\n\tif (b <= a) return Number.NaN;\n\tlet sum = 0;\n\tfor (let k = a; k < b; k++) sum += pcm[k] * pcm[k];\n\treturn 10 * Math.log10(sum / (b - a) + 1e-12);\n}\n\n/**\n * Multiply `pcm` by a per-frame gain curve in dB (`frameSamples` samples per\n * frame), linearly interpolated between frame centres.\n */\nfunction applyGainFrames(\n\tpcm: Float32Array,\n\tframesDb: Float64Array,\n\tframeSamples: number,\n): void {\n\tconst last = framesDb.length - 1;\n\tif (last < 0) return;\n\tfor (let k = 0; k < pcm.length; k++) {\n\t\tconst position = k / frameSamples - 0.5;\n\t\tconst left = Math.min(last, Math.max(0, Math.floor(position)));\n\t\tconst right = Math.min(last, left + 1);\n\t\tconst t = Math.min(1, Math.max(0, position - left));\n\t\tpcm[k] *= 10 ** ((framesDb[left] * (1 - t) + framesDb[right] * t) / 20);\n\t}\n}\n\n/** Soft-knee limiter: identity below `threshold`, tanh compression towards ±1 above it. */\nfunction softLimit(pcm: Float32Array, threshold: number): void {\n\tconst range = 1 - threshold;\n\tif (range <= 0) return;\n\tfor (let k = 0; k < pcm.length; k++) {\n\t\tconst x = pcm[k];\n\t\tconst a = Math.abs(x);\n\t\tif (a <= threshold) continue;\n\t\tconst y = threshold + range * Math.tanh((a - threshold) / range);\n\t\tpcm[k] = x < 0 ? -y : y;\n\t}\n}\n\n/** Sample the timeline F0 curve (Hz) at an absolute timeline time with linear interpolation. */\nfunction f0At(timeline: UtauTTSTimeline, tMs: number): number {\n\tconst curve = timeline.f0_curve;\n\tif (curve.length === 0) return timeline.reference_hz || 220;\n\tconst position = Math.max(0, tMs) / timeline.frame_ms;\n\tconst left = Math.floor(position);\n\tif (left >= curve.length - 1) return curve[curve.length - 1];\n\tconst progress = position - left;\n\treturn curve[left] * (1 - progress) + curve[left + 1] * progress;\n}\n\ninterface ChunkRange {\n\t/** First own unit (inclusive). */\n\tstart: number;\n\t/** Last own unit (exclusive). */\n\tend: number;\n\t/** Chunk starts mid-phrase (needs the previous unit as context + a seam fade-in). */\n\theadSeam: boolean;\n\t/** Chunk ends mid-phrase (needs the next unit as context + a seam fade-out). */\n\ttailSeam: boolean;\n}\n\n/**\n * Scale each timeline unit's volume by the gain of the mora it belongs to\n * (`HtsProsody.moraGains`, one entry per feature frame / plan mora). Units are\n * matched by their mora index when the counts agree, else by start time.\n */\nfunction applyMoraGains(plan: UtauTTSPlan, gains: number[]): void {\n\tconst morae = plan.morae ?? [];\n\tconst timings = plan.mora_timings ?? [];\n\tconst byIndex = morae.length === gains.length;\n\tconst moraAt = (unit: UtauTTSTimelineUnit): number => {\n\t\tif (byIndex) return unit.position;\n\t\tlet found = -1;\n\t\tfor (let i = 0; i < timings.length && i < gains.length; i++) {\n\t\t\tif (timings[i].StartMS <= unit.note_start_ms + 1e-6) found = i;\n\t\t\telse break;\n\t\t}\n\t\treturn found;\n\t};\n\tfor (const unit of plan.timeline.units) {\n\t\tconst index = moraAt(unit);\n\t\tconst gain = gains[index];\n\t\tif (index < 0 || gain === undefined || !Number.isFinite(gain)) continue;\n\t\tunit.volume *= gain;\n\t}\n}\n\n/**\n * End each vowel where HTS puts the next mora's unvoiced consonant. A 単独音\n * unit is placed at its vowel onset with only the sample's own short\n * consonant (its preutterance) in front, so the previous vowel would\n * otherwise sound right up to that point: a 100 ms HTS 「h」 becomes 30 ms\n * of 「h」 and 70 ms of extra vowel, and any pitch movement HTS put inside the\n * consonant is heard as a glide in the vowel. Shortening the previous unit\n * to the HTS consonant onset leaves a natural gap instead. Voiced consonants\n * (n, m, r, g …) keep the continuous voicing.\n */\nfunction applyConsonantGaps(plan: UtauTTSPlan, prosody: HtsProsody): void {\n\tconst { consonantMs, unvoicedOnset } = prosody;\n\tif (!consonantMs || !unvoicedOnset) return;\n\tif (consonantMs.length !== (plan.morae?.length ?? -1)) return;\n\tconst leading = plan.timeline.leading_ms;\n\tconst units = plan.timeline.units;\n\tfor (let i = 0; i + 1 < units.length; i++) {\n\t\tconst unit = units[i];\n\t\tconst next = units[i + 1];\n\t\tif (next.position !== unit.position + 1) continue; // pause or transition in between\n\t\tif (!unvoicedOnset[next.position]) continue;\n\t\tconst consonant = consonantMs[next.position];\n\t\tif (!(consonant > 0)) continue;\n\t\tconst gapStart = next.note_start_ms + leading - consonant;\n\t\tconst currentEnd = unit.position_ms + unit.length_ms;\n\t\tif (gapStart >= currentEnd) continue;\n\t\tconst minimumLength = Math.max(\n\t\t\t40,\n\t\t\tunit.fade_in_ms + unit.fade_out_ms + 10,\n\t\t\tunit.note_start_ms + leading - unit.position_ms + 30,\n\t\t);\n\t\tunit.length_ms = Math.max(minimumLength, gapStart - unit.position_ms);\n\t}\n}\n\n/**\n * Split timeline units into chunks. Breaks are free where units do not overlap\n * (pauses); inside a phrase a break every N units costs one seam crossfade.\n */\nfunction planChunks(\n\tunits: UtauTTSTimelineUnit[],\n\tfirstChunkUnits: number,\n\tchunkUnits: number,\n): ChunkRange[] {\n\tconst ranges: ChunkRange[] = [];\n\tif (units.length === 0) return ranges;\n\tlet start = 0;\n\tlet coveredEndMs = units[0].position_ms + units[0].length_ms;\n\tlet headSeam = false;\n\tfor (let i = 1; i <= units.length; i++) {\n\t\tconst limit = ranges.length === 0 ? firstChunkUnits : chunkUnits;\n\t\tconst atEnd = i === units.length;\n\t\tconst clean = !atEnd && units[i].position_ms >= coveredEndMs - 1e-6;\n\t\tconst full = !atEnd && i - start >= limit;\n\t\tif (atEnd || clean || full) {\n\t\t\tconst tailSeam = !atEnd && !clean;\n\t\t\tranges.push({ start, end: i, headSeam, tailSeam });\n\t\t\tstart = i;\n\t\t\theadSeam = tailSeam;\n\t\t\tif (!atEnd) coveredEndMs = units[i].position_ms + units[i].length_ms;\n\t\t\tcontinue;\n\t\t}\n\t\tcoveredEndMs = Math.max(\n\t\t\tcoveredEndMs,\n\t\t\tunits[i].position_ms + units[i].length_ms,\n\t\t);\n\t}\n\treturn ranges;\n}\n\n/**\n * Where to cut between two chunks that share the boundary before `next`: just\n * after `next`'s fade-in, in its steady vowel, so both renders agree spectrally.\n */\nfunction seamTimeMs(next: UtauTTSTimelineUnit, crossfadeMs: number): number {\n\tconst earliest = next.position_ms + next.fade_in_ms + crossfadeMs / 2;\n\tconst latest = next.position_ms + next.length_ms - crossfadeMs / 2;\n\treturn Math.min(\n\t\tearliest,\n\t\tMath.max(next.position_ms + crossfadeMs / 2, latest),\n\t);\n}\n\nfunction applyFade(\n\tpcm: Float32Array,\n\tfromSample: number,\n\tsamples: number,\n\tfadeIn: boolean,\n): void {\n\tconst n = Math.max(1, Math.min(samples, pcm.length - fromSample));\n\tfor (let k = 0; k < n; k++) {\n\t\tconst t = (k + 0.5) / n;\n\t\tconst gain = fadeIn\n\t\t\t? Math.sin((Math.PI / 2) * t)\n\t\t\t: Math.cos((Math.PI / 2) * t);\n\t\tpcm[fromSample + k] *= gain;\n\t}\n}\n\n/** Median of a non-empty array (sorted copy). */\nfunction median(values: number[]): number {\n\tconst sorted = values.slice().sort((a, b) => a - b);\n\treturn sorted[Math.floor(sorted.length / 2)];\n}\n\ninterface LoudnessShapeOptions {\n\t/** Equalise unit levels towards the reference (see `normalizeUnitLoudness`). */\n\tequalize: boolean;\n\t/** Reference vowel RMS in dBFS. */\n\ttargetDb: number;\n\tmaxDb: number;\n\t/** Energy contour strength in dB per semitone from `referenceHz`; 0 = off. */\n\tenergyDbPerSemitone: number;\n\tenergyMaxDb: number;\n\t/** Vowel-part attenuation of devoiced morae in dB (≤ 0); 0 = off. */\n\tdevoicedDb: number;\n\t/** Utterance median F0 in Hz (centre of the energy contour). */\n\treferenceHz: number;\n}\n\n/**\n * Post-render loudness shaping of one rendered phrase: per-unit\n * equalisation (vowel RMS measured on the rendered audio, prosodic volume\n * kept, gain interpolated between mora centres) plus the F0-coupled energy\n * contour, both as one smooth per-frame gain curve. `units` are the timeline\n * units rendered into `audio` (context units included, so a unit shared by\n * two chunks gets the same correction in both), `baseMs` the timeline time\n * of `audio[0]`.\n */\nfunction shapeLoudness(\n\taudio: Float32Array,\n\tunits: UtauTTSTimelineUnit[],\n\ttimeline: UtauTTSTimeline,\n\tbaseMs: number,\n\toptions: LoudnessShapeOptions,\n): void {\n\tconst frameMs = timeline.frame_ms > 0 ? timeline.frame_ms : 10;\n\tconst frameSamples = Math.max(1, msToSamples(frameMs));\n\tconst frames = Math.ceil(audio.length / frameSamples) + 1;\n\tconst curve = new Float64Array(frames);\n\n\tif (options.equalize) {\n\t\tconst anchors: { frame: number; db: number }[] = [];\n\t\tconst measured: { frame: number; intrinsicDb: number }[] = [];\n\t\tfor (const unit of units) {\n\t\t\tif (!(unit.volume > 0) || unit.duration_ms < 30) continue;\n\t\t\tconst start = unit.note_start_ms + timeline.leading_ms - baseMs;\n\t\t\tconst soundEnd =\n\t\t\t\tunit.position_ms - baseMs + unit.length_ms - unit.fade_out_ms;\n\t\t\tconst from = msToSamples(start + unit.duration_ms * 0.35);\n\t\t\tconst to = msToSamples(\n\t\t\t\tMath.min(start + unit.duration_ms * 0.9, soundEnd),\n\t\t\t);\n\t\t\tif (to - from < msToSamples(20)) continue;\n\t\t\tconst db = rmsDb(audio, from, to);\n\t\t\tif (!Number.isFinite(db) || db < -70) continue;\n\t\t\tmeasured.push({\n\t\t\t\tframe: (start + unit.duration_ms * 0.6) / frameMs,\n\t\t\t\tintrinsicDb: db - 20 * Math.log10(unit.volume / 100),\n\t\t\t});\n\t\t}\n\t\tif (measured.length > 0) {\n\t\t\tconst reference = options.targetDb;\n\t\t\tfor (const m of measured) {\n\t\t\t\tanchors.push({\n\t\t\t\t\tframe: m.frame,\n\t\t\t\t\tdb: Math.max(\n\t\t\t\t\t\t-options.maxDb,\n\t\t\t\t\t\tMath.min(options.maxDb, reference - m.intrinsicDb),\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet a = 0;\n\t\t\tfor (let frame = 0; frame < frames; frame++) {\n\t\t\t\twhile (a + 1 < anchors.length && frame >= anchors[a + 1].frame) a++;\n\t\t\t\tconst left = anchors[a];\n\t\t\t\tconst right = anchors[Math.min(anchors.length - 1, a + 1)];\n\t\t\t\tif (frame <= left.frame || right === left) curve[frame] = left.db;\n\t\t\t\telse if (frame >= right.frame) curve[frame] = right.db;\n\t\t\t\telse {\n\t\t\t\t\tconst t = (frame - left.frame) / (right.frame - left.frame);\n\t\t\t\t\tcurve[frame] = left.db * (1 - t) + right.db * t;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (options.energyDbPerSemitone !== 0 && options.referenceHz > 0) {\n\t\tfor (let frame = 0; frame < frames; frame++) {\n\t\t\tconst f0 = f0At(timeline, baseMs + frame * frameMs);\n\t\t\tif (!(f0 > 0)) continue;\n\t\t\tconst semitones = 12 * Math.log2(f0 / options.referenceHz);\n\t\t\tcurve[frame] += Math.max(\n\t\t\t\t-options.energyMaxDb,\n\t\t\t\tMath.min(options.energyMaxDb, semitones * options.energyDbPerSemitone),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (options.devoicedDb < 0) {\n\t\tconst rampFrames = Math.max(1, Math.round(20 / frameMs));\n\t\tfor (let i = 0; i < units.length; i++) {\n\t\t\tconst unit = units[i];\n\t\t\tif (!unit.devoiced) continue;\n\t\t\tconst start = unit.note_start_ms + timeline.leading_ms - baseMs;\n\t\t\tlet endMs = start + unit.duration_ms;\n\t\t\tconst next = units[i + 1];\n\t\t\tif (next) endMs = Math.min(endMs, next.position_ms - baseMs);\n\t\t\tconst from = start / frameMs;\n\t\t\tconst to = endMs / frameMs;\n\t\t\tfor (\n\t\t\t\tlet frame = Math.max(0, Math.floor(from));\n\t\t\t\tframe < frames && frame < to + rampFrames;\n\t\t\t\tframe++\n\t\t\t) {\n\t\t\t\tconst fadeIn = Math.min(1, Math.max(0, (frame - from) / rampFrames));\n\t\t\t\tconst fadeOut = Math.min(\n\t\t\t\t\t1,\n\t\t\t\t\tMath.max(0, (to + rampFrames - frame) / rampFrames),\n\t\t\t\t);\n\t\t\t\tcurve[frame] += options.devoicedDb * Math.min(fadeIn, fadeOut);\n\t\t\t}\n\t\t}\n\t}\n\n\tapplyGainFrames(audio, curve, frameSamples);\n}\n\n// ── Adapter ─────────────────────────────────────────────────────────────────\n\n/**\n * Text-to-speech with UtauTTS's planner (Go wasm) and koe's worldline renderer.\n *\n * Pipeline per utterance:\n * 1. jpreprocess (caller) → NJD nodes → {@link FeatureFrame}s via `openjtalkAnalyze`\n * 2. {@link plan}: UtauTTS resolves units (Viterbi), builds the timing plan,\n * predicts the TCN pitch contour and lays the units on the worldline timeline\n * exactly as its native worldline bridge would\n * 3. {@link renderChunks}: worldline renders the timeline in small chunks so\n * playback can start after the first few morae\n *\n * Load order: `initializeWasm()` once per page, `setModel()` once per model,\n * `setBank()` once per voice bank.\n */\nexport class UtauTTSAdapter {\n\tprivate static modelId: string | null = null;\n\tprivate bankAliases = new WeakMap<VoiceBank, number>();\n\tprivate currentBank: VoiceBank | null = null;\n\tprivate pcmCache = new Map<string, Promise<Float64Array | null>>();\n\n\tconstructor(private worldline: Worldline) {}\n\n\t/**\n\t * Load the UtauTTS Go wasm. `wasm_exec.js` must already be on the page.\n\t * Pass `fetch` (e.g. koe's `fetchAsset`) to stream from the Cache API.\n\t */\n\tstatic async initializeWasm(\n\t\twasmUrl = \"utautts.wasm\",\n\t\toptions: { fetch?: (url: string) => Promise<Response> } = {},\n\t): Promise<void> {\n\t\tif (typeof utautts_plan === \"function\") return;\n\t\tif (typeof Go === \"undefined\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"wasm_exec.js must be loaded before calling initializeWasm.\",\n\t\t\t);\n\t\t}\n\t\tconst go = new Go();\n\t\tconst responsePromise = (options.fetch ?? fetch)(wasmUrl);\n\t\tlet instance: WebAssembly.Instance;\n\t\ttry {\n\t\t\tinstance = (\n\t\t\t\tawait WebAssembly.instantiateStreaming(responsePromise, go.importObject)\n\t\t\t).instance;\n\t\t} catch {\n\t\t\t// Servers without the application/wasm MIME type.\n\t\t\tconst bytes = await (\n\t\t\t\tawait (options.fetch ?? fetch)(wasmUrl)\n\t\t\t).arrayBuffer();\n\t\t\tinstance = (await WebAssembly.instantiate(bytes, go.importObject))\n\t\t\t\t.instance;\n\t\t}\n\t\tvoid go.run(instance);\n\t\tfor (\n\t\t\tlet attempt = 0;\n\t\t\tattempt < 100 && typeof utautts_plan !== \"function\";\n\t\t\tattempt++\n\t\t) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t}\n\t\tif (typeof utautts_plan !== \"function\") {\n\t\t\tthrow new Error(\"utautts_plan failed to initialize in global scope.\");\n\t\t}\n\t}\n\n\tstatic get ready(): boolean {\n\t\treturn typeof utautts_plan === \"function\";\n\t}\n\n\t/** Parse and cache a prosody model (e.g. `frame-intonation-v8.json`) inside the wasm. */\n\tstatic setModel(modelJSON: string): string | null {\n\t\tUtauTTSAdapter.assertReady();\n\t\tconst result = utautts_set_model(modelJSON);\n\t\tif (!result.success)\n\t\t\tthrow new Error(`UtauTTS model error: ${result.error}`);\n\t\tUtauTTSAdapter.modelId = result.id ?? null;\n\t\treturn UtauTTSAdapter.modelId;\n\t}\n\n\tstatic get currentModelId(): string | null {\n\t\treturn UtauTTSAdapter.modelId;\n\t}\n\n\tprivate static assertReady(): void {\n\t\tif (typeof utautts_plan !== \"function\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"UtauTTS wasm is not initialized; call UtauTTSAdapter.initializeWasm() first.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Register a koe voice bank with the planner: the manifest becomes a virtual\n\t * oto.ini (koe PCM is pre-trimmed, so offset is 0) plus each sample's\n\t * recorded pitch. Called automatically by {@link plan}; cheap when unchanged.\n\t */\n\tsetBank(bank: VoiceBank): void {\n\t\tUtauTTSAdapter.assertReady();\n\t\tif (this.currentBank === bank && this.bankAliases.has(bank)) return;\n\t\tconst entries: Record<string, unknown[]> = {};\n\t\tconst pitch: Record<string, number> = {};\n\t\tfor (const [alias, phoneme] of Object.entries(bank.manifest.phonemes)) {\n\t\t\tentries[alias] = [\n\t\t\t\t{\n\t\t\t\t\tFilename: `koe:${alias}`,\n\t\t\t\t\tAlias: alias,\n\t\t\t\t\tOffset: 0,\n\t\t\t\t\tFixed: phoneme.consonant / 48,\n\t\t\t\t\tBlank: 0,\n\t\t\t\t\tPreutterance: phoneme.pre / 48,\n\t\t\t\t\tOverlap: phoneme.overlap / 48,\n\t\t\t\t\tSourceGroup: \"koe\",\n\t\t\t\t},\n\t\t\t];\n\t\t\tif (phoneme.pitch > 0) pitch[alias] = phoneme.pitch;\n\t\t}\n\t\tconst result = utautts_set_bank(\n\t\t\tJSON.stringify({\n\t\t\t\tname: \"koe\",\n\t\t\t\toto_entries: entries,\n\t\t\t\tsource_pitch_hz: pitch,\n\t\t\t}),\n\t\t);\n\t\tif (!result.success) throw new Error(`UtauTTS bank error: ${result.error}`);\n\t\tthis.bankAliases.set(bank, result.aliases ?? 0);\n\t\tthis.currentBank = bank;\n\t\tthis.pcmCache.clear();\n\t}\n\n\t/**\n\t * Plan an utterance: unit selection, timing, pitch contour and worldline\n\t * placement. `features` are the mora-level frames from `openjtalkAnalyze`\n\t * (pauses included); the kana reading is derived from them.\n\t */\n\tplan(\n\t\tbank: VoiceBank,\n\t\ttext: string,\n\t\tfeatures: FeatureFrame[],\n\t\toptions: UtauTTSOptions = {},\n\t): UtauTTSPlan {\n\t\tthis.setBank(bank);\n\t\tconst request = {\n\t\t\ttext,\n\t\t\treading: readingFromFeatures(features),\n\t\t\tframes: features.map((frame) => sparse_features(frame)),\n\t\t\ttone: options.tone ?? \"C4\",\n\t\t\tmora_duration_ms: options.moraDurationMs ?? 0,\n\t\t\tpause_duration_ms: options.pauseDurationMs ?? 0,\n\t\t\trelease_ms: options.releaseMs ?? 20,\n\t\t\tleading_preutterance_ms: options.leadingPreutteranceMs ?? 0,\n\t\t\tapply_pitch: options.applyPitch ?? true,\n\t\t\tintonation_strength: options.intonationStrength ?? 1,\n\t\t\tspeech_timing: options.speechTiming ?? false,\n\t\t\tword_boundary_envelope: options.wordBoundaryEnvelope ?? false,\n\t\t\tmora_durations_ms: options.prosody?.moraDurationsMs,\n\t\t\tpitch_curve: options.prosody?.pitchCurve,\n\t\t};\n\t\tconst response = utautts_plan(JSON.stringify(request));\n\t\tif (!response.success || !response.plan) {\n\t\t\tthrow new Error(`UtauTTS error: ${response.error ?? \"no plan\"}`);\n\t\t}\n\t\tconst plan = JSON.parse(response.plan) as UtauTTSPlan;\n\t\tconst gains = options.prosody?.moraGains;\n\t\tif (gains) applyMoraGains(plan, gains);\n\t\tconst devoiced = options.prosody?.devoiced;\n\t\tif (devoiced && devoiced.length === (plan.morae?.length ?? -1)) {\n\t\t\tfor (const unit of plan.timeline.units) {\n\t\t\t\tif (devoiced[unit.position]) unit.devoiced = true;\n\t\t\t}\n\t\t}\n\t\tif (options.prosody) applyConsonantGaps(plan, options.prosody);\n\t\treturn plan;\n\t}\n\n\tprivate getPcm(bank: VoiceBank, alias: string): Promise<Float64Array | null> {\n\t\tlet cached = this.pcmCache.get(alias);\n\t\tif (!cached) {\n\t\t\tcached = bank.getPcm(alias);\n\t\t\tthis.pcmCache.set(alias, cached);\n\t\t}\n\t\treturn cached;\n\t}\n\n\t/**\n\t * Render a plan chunk by chunk. Each chunk is independent audio positioned\n\t * at `startMs`; schedule them as they arrive (see the demo) or sum them.\n\t *\n\t * Chunk breaks fall on pauses when possible. Inside a phrase a break renders\n\t * one neighbouring unit of context on each side so the unit crossfade stays\n\t * WORLD's spectral one, then the two renders are joined with a short\n\t * equal-power crossfade in the following vowel.\n\t */\n\tasync *renderChunks(\n\t\tbank: VoiceBank,\n\t\tplan: UtauTTSPlan,\n\t\toptions: UtauTTSRenderOptions = {},\n\t): AsyncGenerator<UtauTTSChunk> {\n\t\tconst {\n\t\t\tfirstChunkUnits = 3,\n\t\t\tchunkUnits = 6,\n\t\t\tseamCrossfadeMs = 20,\n\t\t\tnormalizeUnitLoudness = true,\n\t\t\tunitLoudnessDb = -16,\n\t\t\tunitLoudnessMaxDb = 6,\n\t\t\tenergyDbPerSemitone = 0.8,\n\t\t\tenergyMaxDb = 6,\n\t\t\tdevoicedDb = -9,\n\t\t\toutputLimit = 0.8,\n\t\t\tsignal,\n\t\t} = options;\n\t\tconst timeline = plan.timeline;\n\t\tconst units = timeline.units.filter((unit) => unit.length_ms > 0);\n\t\tconst voicedF0 = timeline.f0_curve.filter((hz) => hz > 0);\n\t\tconst referenceHz = voicedF0.length > 0 ? median(voicedF0) : 0;\n\t\tconst ranges = planChunks(\n\t\t\tunits,\n\t\t\tMath.max(1, firstChunkUnits),\n\t\t\tMath.max(1, chunkUnits),\n\t\t);\n\t\tconst crossfadeSamples = Math.max(2, msToSamples(seamCrossfadeMs));\n\n\t\tfor (let index = 0; index < ranges.length; index++) {\n\t\t\tif (signal?.aborted) return;\n\t\t\tconst range = ranges[index];\n\t\t\tconst renderStart = range.headSeam ? range.start - 1 : range.start;\n\t\t\tconst renderEnd = range.tailSeam ? range.end + 1 : range.end;\n\t\t\tconst rendered = units.slice(renderStart, renderEnd);\n\t\t\tconst baseMs = Math.min(...rendered.map((unit) => unit.position_ms));\n\n\t\t\tconst phraseUnits: PhraseUnit[] = [];\n\t\t\tfor (const unit of rendered) {\n\t\t\t\tconst pcm = await this.getPcm(bank, unit.alias);\n\t\t\t\tif (!pcm || pcm.length < MIN_WORLDLINE_SAMPLES) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[utautts] no usable PCM for alias \"${unit.alias}\"; skipped`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tphraseUnits.push({\n\t\t\t\t\tpcm,\n\t\t\t\t\tposMs: unit.position_ms - baseMs,\n\t\t\t\t\tskipMs: unit.skip_ms,\n\t\t\t\t\tlengthMs: unit.length_ms,\n\t\t\t\t\tfadeInMs: unit.fade_in_ms,\n\t\t\t\t\tfadeOutMs: unit.fade_out_ms,\n\t\t\t\t\tconsonantMs: unit.consonant_ms,\n\t\t\t\t\trequiredLengthMs: unit.required_length_ms,\n\t\t\t\t\tvolume: unit.volume,\n\t\t\t\t\ttone: unit.tone,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (signal?.aborted) return;\n\t\t\tif (phraseUnits.length === 0) continue;\n\n\t\t\tconst audio = this.worldline.renderPhrase({\n\t\t\t\tunits: phraseUnits,\n\t\t\t\tpitch: (tMs) => f0At(timeline, baseMs + tMs),\n\t\t\t\tgender: options.gender,\n\t\t\t\ttension: options.tension,\n\t\t\t\tbreathiness: options.breathiness,\n\t\t\t\tvoicing: options.voicing,\n\t\t\t});\n\t\t\tif (!audio || audio.length === 0) continue;\n\t\t\tif (\n\t\t\t\tnormalizeUnitLoudness ||\n\t\t\t\tenergyDbPerSemitone !== 0 ||\n\t\t\t\tdevoicedDb < 0\n\t\t\t) {\n\t\t\t\tshapeLoudness(audio, rendered, timeline, baseMs, {\n\t\t\t\t\tequalize: normalizeUnitLoudness,\n\t\t\t\t\ttargetDb: unitLoudnessDb,\n\t\t\t\t\tmaxDb: unitLoudnessMaxDb,\n\t\t\t\t\tenergyDbPerSemitone,\n\t\t\t\t\tenergyMaxDb,\n\t\t\t\t\tdevoicedDb,\n\t\t\t\t\treferenceHz,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Trim to [head seam − xf/2, tail seam + xf/2] and fade the seams.\n\t\t\tlet fromSample = 0;\n\t\t\tlet toSample = audio.length;\n\t\t\tlet startMs = baseMs;\n\t\t\tif (range.headSeam) {\n\t\t\t\tconst seamMs = seamTimeMs(units[range.start], seamCrossfadeMs);\n\t\t\t\tfromSample = Math.max(\n\t\t\t\t\t0,\n\t\t\t\t\tmsToSamples(seamMs - baseMs) - crossfadeSamples / 2,\n\t\t\t\t);\n\t\t\t\tstartMs = baseMs + (fromSample / FS) * 1000;\n\t\t\t}\n\t\t\tif (range.tailSeam) {\n\t\t\t\tconst seamMs = seamTimeMs(units[range.end], seamCrossfadeMs);\n\t\t\t\ttoSample = Math.min(\n\t\t\t\t\taudio.length,\n\t\t\t\t\tmsToSamples(seamMs - baseMs) + crossfadeSamples / 2,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (toSample <= fromSample) continue;\n\t\t\tconst pcm = audio.slice(fromSample, toSample);\n\t\t\tif (outputLimit > 0) softLimit(pcm, outputLimit);\n\t\t\tif (range.headSeam) applyFade(pcm, 0, crossfadeSamples, true);\n\t\t\tif (range.tailSeam)\n\t\t\t\tapplyFade(\n\t\t\t\t\tpcm,\n\t\t\t\t\tMath.max(0, pcm.length - crossfadeSamples),\n\t\t\t\t\tcrossfadeSamples,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\n\t\t\tyield { pcm, startMs, index, units: units.slice(range.start, range.end) };\n\t\t\t// Let the event loop breathe (audio scheduling, UI) between chunks.\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 0));\n\t\t}\n\t}\n\n\t/**\n\t * Plan + render an utterance into one buffer (Float32, 48 kHz) covering the\n\t * whole timeline. Use {@link plan} + {@link renderChunks} for streaming.\n\t */\n\tasync synthesizeText(\n\t\tbank: VoiceBank,\n\t\ttext: string,\n\t\tfeatures: FeatureFrame[],\n\t\toptions: UtauTTSOptions & UtauTTSRenderOptions = {},\n\t): Promise<Float32Array | null> {\n\t\tconst plan = this.plan(bank, text, features, options);\n\t\tconst total = msToSamples(plan.timeline.duration_ms) + msToSamples(200);\n\t\tconst out = new Float32Array(total);\n\t\tlet any = false;\n\t\tfor await (const chunk of this.renderChunks(bank, plan, options)) {\n\t\t\tany = true;\n\t\t\tconst offset = msToSamples(chunk.startMs);\n\t\t\tconst n = Math.min(chunk.pcm.length, out.length - offset);\n\t\t\tfor (let k = 0; k < n; k++) out[offset + k] += chunk.pcm[k];\n\t\t}\n\t\t// Seams are equal-power crossfades of two limited chunks; limit the sum too.\n\t\tconst limit = options.outputLimit ?? 0.8;\n\t\tif (any && limit > 0) softLimit(out, limit);\n\t\treturn any ? out : null;\n\t}\n}\n"],"mappings":"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","names":["num","l","_a","_b","i","_a","_a","fl","_a","_a","FS","rmsDb","clamp","near","err","entries","total","max","f","toHiragana","analyze","f","msToSamples","softLimit","pcm"]}