@waveform-playlist/spectrogram 7.0.0 → 7.1.1
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 +0 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +0 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/computation/fft.ts","../src/computation/windowFunctions.ts","../src/computation/computeSpectrogram.ts","../src/computation/colorMaps.ts","../src/computation/frequencyScales.ts","../src/components/SpectrogramMenuItems.tsx","../src/components/SpectrogramSettingsModal.tsx","../src/worker/createSpectrogramWorker.ts","../src/SpectrogramProvider.tsx"],"sourcesContent":["import FFT from 'fft.js';\n\n/**\n * Cache fft.js instances per size (pre-computes twiddle factors).\n */\nconst fftInstances = new Map<number, FFT>();\nconst complexBuffers = new Map<number, number[]>();\n\nfunction getFftInstance(size: number): FFT {\n let instance = fftInstances.get(size);\n if (!instance) {\n instance = new FFT(size);\n fftInstances.set(size, instance);\n complexBuffers.set(size, instance.createComplexArray());\n }\n return instance;\n}\n\nfunction getComplexBuffer(size: number): number[] {\n const buffer = complexBuffers.get(size);\n if (!buffer) {\n throw new Error(`No complex buffer for size ${size}. Call getFftInstance first.`);\n }\n return buffer;\n}\n\n/**\n * In-place FFT using fft.js (radix-4).\n * @param real - Real part (modified in place)\n * @param imag - Imaginary part (modified in place)\n */\nexport function fft(real: Float32Array, imag: Float32Array): void {\n const n = real.length;\n const f = getFftInstance(n);\n const input = f.createComplexArray();\n const out = getComplexBuffer(n);\n\n for (let i = 0; i < n; i++) {\n input[i * 2] = real[i];\n input[i * 2 + 1] = imag[i];\n }\n\n f.transform(out, input);\n\n for (let i = 0; i < n; i++) {\n real[i] = out[i * 2];\n imag[i] = out[i * 2 + 1];\n }\n}\n\n/**\n * Fused FFT → magnitude → decibels for real-valued input.\n * Uses fft.js realTransform (radix-4, ~25% faster for real input).\n * Writes dB values for positive frequencies (n/2 bins) into `out`.\n *\n * @param real - Real input (windowed audio frame, length n)\n * @param out - Output array for dB values (length >= n/2)\n */\nexport function fftMagnitudeDb(real: Float32Array, out: Float32Array): void {\n const n = real.length;\n const f = getFftInstance(n);\n const complexOut = getComplexBuffer(n);\n\n f.realTransform(complexOut, real);\n\n const half = n >> 1;\n for (let i = 0; i < half; i++) {\n const re = complexOut[i * 2];\n const im = complexOut[i * 2 + 1];\n let db = 20 * Math.log10(Math.sqrt(re * re + im * im) + 1e-10);\n if (db < -160) db = -160;\n out[i] = db;\n }\n}\n\n/**\n * Compute magnitude spectrum from FFT output.\n * Returns only the first half (positive frequencies).\n */\nexport function magnitudeSpectrum(real: Float32Array, imag: Float32Array): Float32Array {\n const n = real.length >> 1;\n const magnitudes = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n magnitudes[i] = Math.sqrt(real[i] * real[i] + imag[i] * imag[i]);\n }\n return magnitudes;\n}\n\n/**\n * Convert magnitudes to decibels with a fixed -160 dB floor.\n * Gain is applied at render time, not during FFT.\n */\nexport function toDecibels(magnitudes: Float32Array): Float32Array {\n const result = new Float32Array(magnitudes.length);\n for (let i = 0; i < magnitudes.length; i++) {\n let db = 20 * Math.log10(magnitudes[i] + 1e-10);\n if (db < -160) db = -160;\n result[i] = db;\n }\n return result;\n}\n","/**\n * Window functions for spectral analysis.\n */\n\nexport function getWindowFunction(\n name: string,\n size: number,\n alpha?: number\n): Float32Array {\n const window = new Float32Array(size);\n const N = size;\n\n switch (name) {\n case 'rectangular':\n for (let i = 0; i < size; i++) window[i] = 1;\n break;\n\n case 'bartlett':\n for (let i = 0; i < size; i++) {\n window[i] = 1 - Math.abs((2 * i - N) / N);\n }\n break;\n\n case 'hann':\n for (let i = 0; i < size; i++) {\n window[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / N));\n }\n break;\n\n case 'hamming':\n for (let i = 0; i < size; i++) {\n const a = alpha ?? 0.54;\n window[i] = a - (1 - a) * Math.cos((2 * Math.PI * i) / N);\n }\n break;\n\n case 'blackman': {\n const a0 = 0.42;\n const a1 = 0.5;\n const a2 = 0.08;\n for (let i = 0; i < size; i++) {\n window[i] =\n a0 -\n a1 * Math.cos((2 * Math.PI * i) / N) +\n a2 * Math.cos((4 * Math.PI * i) / N);\n }\n break;\n }\n\n case 'blackman-harris': {\n const c0 = 0.35875;\n const c1 = 0.48829;\n const c2 = 0.14128;\n const c3 = 0.01168;\n for (let i = 0; i < size; i++) {\n window[i] =\n c0 -\n c1 * Math.cos((2 * Math.PI * i) / N) +\n c2 * Math.cos((4 * Math.PI * i) / N) -\n c3 * Math.cos((6 * Math.PI * i) / N);\n }\n break;\n }\n\n default:\n console.warn(`[spectrogram] Unknown window function \"${name}\", falling back to hann`);\n for (let i = 0; i < size; i++) {\n window[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / N));\n }\n }\n\n // Amplitude normalization: scale so a 0 dB sine produces a 0 dB spectrum peak.\n // Matches Audacity: scale = 2.0 / sum(window)\n let sum = 0;\n for (let i = 0; i < size; i++) sum += window[i];\n if (sum > 0) {\n const scale = 2.0 / sum;\n for (let i = 0; i < size; i++) window[i] *= scale;\n }\n\n return window;\n}\n","/**\n * Compute spectrogram data from an AudioBuffer.\n */\n\nimport type { SpectrogramConfig, SpectrogramData } from '@waveform-playlist/core';\nimport { fftMagnitudeDb } from './fft';\nimport { getWindowFunction } from './windowFunctions';\n\n/**\n * Compute spectrogram for a single channel of audio.\n *\n * @param audioBuffer - Source audio buffer\n * @param config - Spectrogram configuration\n * @param offsetSamples - Start offset into the audio buffer\n * @param durationSamples - Number of samples to process\n * @param channel - Channel index (0 = left, 1 = right). Default: 0\n */\nexport function computeSpectrogram(\n audioBuffer: AudioBuffer,\n config: SpectrogramConfig = {},\n offsetSamples: number = 0,\n durationSamples?: number,\n channel: number = 0\n): SpectrogramData {\n const windowSize = config.fftSize ?? 2048;\n const zeroPaddingFactor = config.zeroPaddingFactor ?? 2;\n const actualFftSize = windowSize * zeroPaddingFactor;\n const hopSize = config.hopSize ?? Math.floor(windowSize / 4);\n const windowName = config.windowFunction ?? 'hann';\n const gainDb = config.gainDb ?? 20;\n const rangeDb = config.rangeDb ?? 80;\n const alpha = config.alpha;\n\n const sampleRate = audioBuffer.sampleRate;\n const frequencyBinCount = actualFftSize >> 1;\n const totalSamples = durationSamples ?? (audioBuffer.length - offsetSamples);\n\n // Get channel data\n const channelIdx = Math.min(channel, audioBuffer.numberOfChannels - 1);\n const channelData = audioBuffer.getChannelData(channelIdx);\n\n // Pre-compute window (at windowSize, not actualFftSize)\n const window = getWindowFunction(windowName, windowSize, alpha);\n\n // Calculate frame count (step by windowSize, not actualFftSize)\n const frameCount = Math.max(1, Math.floor((totalSamples - windowSize) / hopSize) + 1);\n\n // Output: frameCount × frequencyBinCount\n const data = new Float32Array(frameCount * frequencyBinCount);\n\n // Reusable buffers at actualFftSize\n const real = new Float32Array(actualFftSize);\n const dbBuf = new Float32Array(frequencyBinCount);\n\n for (let frame = 0; frame < frameCount; frame++) {\n const start = offsetSamples + frame * hopSize;\n\n // Fill first windowSize samples with windowed audio, rest stays zero\n for (let i = 0; i < windowSize; i++) {\n const sampleIdx = start + i;\n real[i] = sampleIdx < channelData.length ? channelData[sampleIdx] * window[i] : 0;\n }\n // Zero-pad the rest\n for (let i = windowSize; i < actualFftSize; i++) {\n real[i] = 0;\n }\n\n fftMagnitudeDb(real, dbBuf);\n data.set(dbBuf, frame * frequencyBinCount);\n }\n\n return {\n fftSize: actualFftSize,\n windowSize,\n frequencyBinCount,\n sampleRate,\n hopSize,\n frameCount,\n data,\n gainDb,\n rangeDb,\n };\n}\n\n/**\n * Compute a mono (mixed-down) spectrogram from all channels.\n */\nexport function computeSpectrogramMono(\n audioBuffer: AudioBuffer,\n config: SpectrogramConfig = {},\n offsetSamples: number = 0,\n durationSamples?: number\n): SpectrogramData {\n if (audioBuffer.numberOfChannels === 1) {\n return computeSpectrogram(audioBuffer, config, offsetSamples, durationSamples, 0);\n }\n\n // Mix down channels\n const windowSize = config.fftSize ?? 2048;\n const zeroPaddingFactor = config.zeroPaddingFactor ?? 2;\n const actualFftSize = windowSize * zeroPaddingFactor;\n const hopSize = config.hopSize ?? Math.floor(windowSize / 4);\n const windowName = config.windowFunction ?? 'hann';\n const gainDb = config.gainDb ?? 20;\n const rangeDb = config.rangeDb ?? 80;\n const alpha = config.alpha;\n\n const sampleRate = audioBuffer.sampleRate;\n const frequencyBinCount = actualFftSize >> 1;\n const totalSamples = durationSamples ?? (audioBuffer.length - offsetSamples);\n const numChannels = audioBuffer.numberOfChannels;\n\n const window = getWindowFunction(windowName, windowSize, alpha);\n const frameCount = Math.max(1, Math.floor((totalSamples - windowSize) / hopSize) + 1);\n const data = new Float32Array(frameCount * frequencyBinCount);\n const real = new Float32Array(actualFftSize);\n const dbBuf = new Float32Array(frequencyBinCount);\n\n // Get all channel data\n const channels: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(audioBuffer.getChannelData(ch));\n }\n\n for (let frame = 0; frame < frameCount; frame++) {\n const start = offsetSamples + frame * hopSize;\n\n // Mix channels and apply window\n for (let i = 0; i < windowSize; i++) {\n const sampleIdx = start + i;\n let sum = 0;\n for (let ch = 0; ch < numChannels; ch++) {\n sum += sampleIdx < channels[ch].length ? channels[ch][sampleIdx] : 0;\n }\n real[i] = (sum / numChannels) * window[i];\n }\n // Zero-pad the rest\n for (let i = windowSize; i < actualFftSize; i++) {\n real[i] = 0;\n }\n\n fftMagnitudeDb(real, dbBuf);\n data.set(dbBuf, frame * frequencyBinCount);\n }\n\n return {\n fftSize: actualFftSize,\n windowSize,\n frequencyBinCount,\n sampleRate,\n hopSize,\n frameCount,\n data,\n gainDb,\n rangeDb,\n };\n}\n","/**\n * Color maps for spectrogram rendering.\n * Each map is a 256-entry RGB lookup table (768 bytes).\n *\n * Viridis, Magma, Inferno: Perceptually uniform colormaps from matplotlib.\n * By Stéfan van der Walt, Nathaniel Smith, and Eric Firing. Released under CC0.\n * Data from https://github.com/BIDS/colormap\n *\n * Roseus: Perceptually uniform colormap from https://github.com/dofuuz/roseus\n * By dofuuz, licensed under CC0 1.0 Universal.\n */\n\nimport type { ColorMapName, ColorMapValue } from '@waveform-playlist/core';\n\n// Pre-computed 256-entry LUT: Uint8Array of length 768 (256 * 3 RGB)\ntype ColorLUT = Uint8Array;\n\nfunction interpolateLUT(stops: number[][]): ColorLUT {\n const lut = new Uint8Array(256 * 3);\n const n = stops.length;\n for (let i = 0; i < 256; i++) {\n const t = i / 255;\n const pos = t * (n - 1);\n const lo = Math.floor(pos);\n const hi = Math.min(lo + 1, n - 1);\n const frac = pos - lo;\n lut[i * 3] = Math.round(stops[lo][0] * (1 - frac) + stops[hi][0] * frac);\n lut[i * 3 + 1] = Math.round(stops[lo][1] * (1 - frac) + stops[hi][1] * frac);\n lut[i * 3 + 2] = Math.round(stops[lo][2] * (1 - frac) + stops[hi][2] * frac);\n }\n return lut;\n}\n\n// prettier-ignore\nconst VIRIDIS_LUT = new Uint8Array([\n 68, 1, 84, 68, 2, 86, 69, 4, 87, 69, 5, 89, 70, 7, 90, 70, 8, 92, 70, 10, 93, 70, 11, 94,\n 71, 13, 96, 71, 14, 97, 71, 16, 99, 71, 17, 100, 71, 19, 101, 72, 20, 103, 72, 22, 104, 72, 23, 105,\n 72, 24, 106, 72, 26, 108, 72, 27, 109, 72, 28, 110, 72, 29, 111, 72, 31, 112, 72, 32, 113, 72, 33, 115,\n 72, 35, 116, 72, 36, 117, 72, 37, 118, 72, 38, 119, 72, 40, 120, 72, 41, 121, 71, 42, 122, 71, 44, 122,\n 71, 45, 123, 71, 46, 124, 71, 47, 125, 70, 48, 126, 70, 50, 126, 70, 51, 127, 70, 52, 128, 69, 53, 129,\n 69, 55, 129, 69, 56, 130, 68, 57, 131, 68, 58, 131, 68, 59, 132, 67, 61, 132, 67, 62, 133, 66, 63, 133,\n 66, 64, 134, 66, 65, 134, 65, 66, 135, 65, 68, 135, 64, 69, 136, 64, 70, 136, 63, 71, 136, 63, 72, 137,\n 62, 73, 137, 62, 74, 137, 62, 76, 138, 61, 77, 138, 61, 78, 138, 60, 79, 138, 60, 80, 139, 59, 81, 139,\n 59, 82, 139, 58, 83, 139, 58, 84, 140, 57, 85, 140, 57, 86, 140, 56, 88, 140, 56, 89, 140, 55, 90, 140,\n 55, 91, 141, 54, 92, 141, 54, 93, 141, 53, 94, 141, 53, 95, 141, 52, 96, 141, 52, 97, 141, 51, 98, 141,\n 51, 99, 141, 50, 100, 142, 50, 101, 142, 49, 102, 142, 49, 103, 142, 49, 104, 142, 48, 105, 142, 48, 106, 142,\n 47, 107, 142, 47, 108, 142, 46, 109, 142, 46, 110, 142, 46, 111, 142, 45, 112, 142, 45, 113, 142, 44, 113, 142,\n 44, 114, 142, 44, 115, 142, 43, 116, 142, 43, 117, 142, 42, 118, 142, 42, 119, 142, 42, 120, 142, 41, 121, 142,\n 41, 122, 142, 41, 123, 142, 40, 124, 142, 40, 125, 142, 39, 126, 142, 39, 127, 142, 39, 128, 142, 38, 129, 142,\n 38, 130, 142, 38, 130, 142, 37, 131, 142, 37, 132, 142, 37, 133, 142, 36, 134, 142, 36, 135, 142, 35, 136, 142,\n 35, 137, 142, 35, 138, 141, 34, 139, 141, 34, 140, 141, 34, 141, 141, 33, 142, 141, 33, 143, 141, 33, 144, 141,\n 33, 145, 140, 32, 146, 140, 32, 146, 140, 32, 147, 140, 31, 148, 140, 31, 149, 139, 31, 150, 139, 31, 151, 139,\n 31, 152, 139, 31, 153, 138, 31, 154, 138, 30, 155, 138, 30, 156, 137, 30, 157, 137, 31, 158, 137, 31, 159, 136,\n 31, 160, 136, 31, 161, 136, 31, 161, 135, 31, 162, 135, 32, 163, 134, 32, 164, 134, 33, 165, 133, 33, 166, 133,\n 34, 167, 133, 34, 168, 132, 35, 169, 131, 36, 170, 131, 37, 171, 130, 37, 172, 130, 38, 173, 129, 39, 173, 129,\n 40, 174, 128, 41, 175, 127, 42, 176, 127, 44, 177, 126, 45, 178, 125, 46, 179, 124, 47, 180, 124, 49, 181, 123,\n 50, 182, 122, 52, 182, 121, 53, 183, 121, 55, 184, 120, 56, 185, 119, 58, 186, 118, 59, 187, 117, 61, 188, 116,\n 63, 188, 115, 64, 189, 114, 66, 190, 113, 68, 191, 112, 70, 192, 111, 72, 193, 110, 74, 193, 109, 76, 194, 108,\n 78, 195, 107, 80, 196, 106, 82, 197, 105, 84, 197, 104, 86, 198, 103, 88, 199, 101, 90, 200, 100, 92, 200, 99,\n 94, 201, 98, 96, 202, 96, 99, 203, 95, 101, 203, 94, 103, 204, 92, 105, 205, 91, 108, 205, 90, 110, 206, 88,\n 112, 207, 87, 115, 208, 86, 117, 208, 84, 119, 209, 83, 122, 209, 81, 124, 210, 80, 127, 211, 78, 129, 211, 77,\n 132, 212, 75, 134, 213, 73, 137, 213, 72, 139, 214, 70, 142, 214, 69, 144, 215, 67, 147, 215, 65, 149, 216, 64,\n 152, 216, 62, 155, 217, 60, 157, 217, 59, 160, 218, 57, 162, 218, 55, 165, 219, 54, 168, 219, 52, 170, 220, 50,\n 173, 220, 48, 176, 221, 47, 178, 221, 45, 181, 222, 43, 184, 222, 41, 186, 222, 40, 189, 223, 38, 192, 223, 37,\n 194, 223, 35, 197, 224, 33, 200, 224, 32, 202, 225, 31, 205, 225, 29, 208, 225, 28, 210, 226, 27, 213, 226, 26,\n 216, 226, 25, 218, 227, 25, 221, 227, 24, 223, 227, 24, 226, 228, 24, 229, 228, 25, 231, 228, 25, 234, 229, 26,\n 236, 229, 27, 239, 229, 28, 241, 229, 29, 244, 230, 30, 246, 230, 32, 248, 230, 33, 251, 231, 35, 253, 231, 37,\n]);\n\n// prettier-ignore\nconst MAGMA_LUT = new Uint8Array([\n 0, 0, 4, 1, 0, 5, 1, 1, 6, 1, 1, 8, 2, 1, 9, 2, 2, 11, 2, 2, 13, 3, 3, 15,\n 3, 3, 18, 4, 4, 20, 5, 4, 22, 6, 5, 24, 6, 5, 26, 7, 6, 28, 8, 7, 30, 9, 7, 32,\n 10, 8, 34, 11, 9, 36, 12, 9, 38, 13, 10, 41, 14, 11, 43, 16, 11, 45, 17, 12, 47, 18, 13, 49,\n 19, 13, 52, 20, 14, 54, 21, 14, 56, 22, 15, 59, 24, 15, 61, 25, 16, 63, 26, 16, 66, 28, 16, 68,\n 29, 17, 71, 30, 17, 73, 32, 17, 75, 33, 17, 78, 34, 17, 80, 36, 18, 83, 37, 18, 85, 39, 18, 88,\n 41, 17, 90, 42, 17, 92, 44, 17, 95, 45, 17, 97, 47, 17, 99, 49, 17, 101, 51, 16, 103, 52, 16, 105,\n 54, 16, 107, 56, 16, 108, 57, 15, 110, 59, 15, 112, 61, 15, 113, 63, 15, 114, 64, 15, 116, 66, 15, 117,\n 68, 15, 118, 69, 16, 119, 71, 16, 120, 73, 16, 120, 74, 16, 121, 76, 17, 122, 78, 17, 123, 79, 18, 123,\n 81, 18, 124, 82, 19, 124, 84, 19, 125, 86, 20, 125, 87, 21, 126, 89, 21, 126, 90, 22, 126, 92, 22, 127,\n 93, 23, 127, 95, 24, 127, 96, 24, 128, 98, 25, 128, 100, 26, 128, 101, 26, 128, 103, 27, 128, 104, 28, 129,\n 106, 28, 129, 107, 29, 129, 109, 29, 129, 110, 30, 129, 112, 31, 129, 114, 31, 129, 115, 32, 129, 117, 33, 129,\n 118, 33, 129, 120, 34, 129, 121, 34, 130, 123, 35, 130, 124, 35, 130, 126, 36, 130, 128, 37, 130, 129, 37, 129,\n 131, 38, 129, 132, 38, 129, 134, 39, 129, 136, 39, 129, 137, 40, 129, 139, 41, 129, 140, 41, 129, 142, 42, 129,\n 144, 42, 129, 145, 43, 129, 147, 43, 128, 148, 44, 128, 150, 44, 128, 152, 45, 128, 153, 45, 128, 155, 46, 127,\n 156, 46, 127, 158, 47, 127, 160, 47, 127, 161, 48, 126, 163, 48, 126, 165, 49, 126, 166, 49, 125, 168, 50, 125,\n 170, 51, 125, 171, 51, 124, 173, 52, 124, 174, 52, 123, 176, 53, 123, 178, 53, 123, 179, 54, 122, 181, 54, 122,\n 183, 55, 121, 184, 55, 121, 186, 56, 120, 188, 57, 120, 189, 57, 119, 191, 58, 119, 192, 58, 118, 194, 59, 117,\n 196, 60, 117, 197, 60, 116, 199, 61, 115, 200, 62, 115, 202, 62, 114, 204, 63, 113, 205, 64, 113, 207, 64, 112,\n 208, 65, 111, 210, 66, 111, 211, 67, 110, 213, 68, 109, 214, 69, 108, 216, 69, 108, 217, 70, 107, 219, 71, 106,\n 220, 72, 105, 222, 73, 104, 223, 74, 104, 224, 76, 103, 226, 77, 102, 227, 78, 101, 228, 79, 100, 229, 80, 100,\n 231, 82, 99, 232, 83, 98, 233, 84, 98, 234, 86, 97, 235, 87, 96, 236, 88, 96, 237, 90, 95, 238, 91, 94,\n 239, 93, 94, 240, 95, 94, 241, 96, 93, 242, 98, 93, 242, 100, 92, 243, 101, 92, 244, 103, 92, 244, 105, 92,\n 245, 107, 92, 246, 108, 92, 246, 110, 92, 247, 112, 92, 247, 114, 92, 248, 116, 92, 248, 118, 92, 249, 120, 93,\n 249, 121, 93, 249, 123, 93, 250, 125, 94, 250, 127, 94, 250, 129, 95, 251, 131, 95, 251, 133, 96, 251, 135, 97,\n 252, 137, 97, 252, 138, 98, 252, 140, 99, 252, 142, 100, 252, 144, 101, 253, 146, 102, 253, 148, 103, 253, 150, 104,\n 253, 152, 105, 253, 154, 106, 253, 155, 107, 254, 157, 108, 254, 159, 109, 254, 161, 110, 254, 163, 111, 254, 165, 113,\n 254, 167, 114, 254, 169, 115, 254, 170, 116, 254, 172, 118, 254, 174, 119, 254, 176, 120, 254, 178, 122, 254, 180, 123,\n 254, 182, 124, 254, 183, 126, 254, 185, 127, 254, 187, 129, 254, 189, 130, 254, 191, 132, 254, 193, 133, 254, 194, 135,\n 254, 196, 136, 254, 198, 138, 254, 200, 140, 254, 202, 141, 254, 204, 143, 254, 205, 144, 254, 207, 146, 254, 209, 148,\n 254, 211, 149, 254, 213, 151, 254, 215, 153, 254, 216, 154, 253, 218, 156, 253, 220, 158, 253, 222, 160, 253, 224, 161,\n 253, 226, 163, 253, 227, 165, 253, 229, 167, 253, 231, 169, 253, 233, 170, 253, 235, 172, 252, 236, 174, 252, 238, 176,\n 252, 240, 178, 252, 242, 180, 252, 244, 182, 252, 246, 184, 252, 247, 185, 252, 249, 187, 252, 251, 189, 252, 253, 191,\n]);\n\n// prettier-ignore\nconst INFERNO_LUT = new Uint8Array([\n 0, 0, 4, 1, 0, 5, 1, 1, 6, 1, 1, 8, 2, 1, 10, 2, 2, 12, 2, 2, 14, 3, 2, 16,\n 4, 3, 18, 4, 3, 20, 5, 4, 23, 6, 4, 25, 7, 5, 27, 8, 5, 29, 9, 6, 31, 10, 7, 34,\n 11, 7, 36, 12, 8, 38, 13, 8, 41, 14, 9, 43, 16, 9, 45, 17, 10, 48, 18, 10, 50, 20, 11, 52,\n 21, 11, 55, 22, 11, 57, 24, 12, 60, 25, 12, 62, 27, 12, 65, 28, 12, 67, 30, 12, 69, 31, 12, 72,\n 33, 12, 74, 35, 12, 76, 36, 12, 79, 38, 12, 81, 40, 11, 83, 41, 11, 85, 43, 11, 87, 45, 11, 89,\n 47, 10, 91, 49, 10, 92, 50, 10, 94, 52, 10, 95, 54, 9, 97, 56, 9, 98, 57, 9, 99, 59, 9, 100,\n 61, 9, 101, 62, 9, 102, 64, 10, 103, 66, 10, 104, 68, 10, 104, 69, 10, 105, 71, 11, 106, 73, 11, 106,\n 74, 12, 107, 76, 12, 107, 77, 13, 108, 79, 13, 108, 81, 14, 108, 82, 14, 109, 84, 15, 109, 85, 15, 109,\n 87, 16, 110, 89, 16, 110, 90, 17, 110, 92, 18, 110, 93, 18, 110, 95, 19, 110, 97, 19, 110, 98, 20, 110,\n 100, 21, 110, 101, 21, 110, 103, 22, 110, 105, 22, 110, 106, 23, 110, 108, 24, 110, 109, 24, 110, 111, 25, 110,\n 113, 25, 110, 114, 26, 110, 116, 26, 110, 117, 27, 110, 119, 28, 109, 120, 28, 109, 122, 29, 109, 124, 29, 109,\n 125, 30, 109, 127, 30, 108, 128, 31, 108, 130, 32, 108, 132, 32, 107, 133, 33, 107, 135, 33, 107, 136, 34, 106,\n 138, 34, 106, 140, 35, 105, 141, 35, 105, 143, 36, 105, 144, 37, 104, 146, 37, 104, 147, 38, 103, 149, 38, 103,\n 151, 39, 102, 152, 39, 102, 154, 40, 101, 155, 41, 100, 157, 41, 100, 159, 42, 99, 160, 42, 99, 162, 43, 98,\n 163, 44, 97, 165, 44, 96, 166, 45, 96, 168, 46, 95, 169, 46, 94, 171, 47, 94, 173, 48, 93, 174, 48, 92,\n 176, 49, 91, 177, 50, 90, 179, 50, 90, 180, 51, 89, 182, 52, 88, 183, 53, 87, 185, 53, 86, 186, 54, 85,\n 188, 55, 84, 189, 56, 83, 191, 57, 82, 192, 58, 81, 193, 58, 80, 195, 59, 79, 196, 60, 78, 198, 61, 77,\n 199, 62, 76, 200, 63, 75, 202, 64, 74, 203, 65, 73, 204, 66, 72, 206, 67, 71, 207, 68, 70, 208, 69, 69,\n 210, 70, 68, 211, 71, 67, 212, 72, 66, 213, 74, 65, 215, 75, 63, 216, 76, 62, 217, 77, 61, 218, 78, 60,\n 219, 80, 59, 221, 81, 58, 222, 82, 56, 223, 83, 55, 224, 85, 54, 225, 86, 53, 226, 87, 52, 227, 89, 51,\n 228, 90, 49, 229, 92, 48, 230, 93, 47, 231, 94, 46, 232, 96, 45, 233, 97, 43, 234, 99, 42, 235, 100, 41,\n 235, 102, 40, 236, 103, 38, 237, 105, 37, 238, 106, 36, 239, 108, 35, 239, 110, 33, 240, 111, 32, 241, 113, 31,\n 241, 115, 29, 242, 116, 28, 243, 118, 27, 243, 120, 25, 244, 121, 24, 245, 123, 23, 245, 125, 21, 246, 126, 20,\n 246, 128, 19, 247, 130, 18, 247, 132, 16, 248, 133, 15, 248, 135, 14, 248, 137, 12, 249, 139, 11, 249, 140, 10,\n 249, 142, 9, 250, 144, 8, 250, 146, 7, 250, 148, 7, 251, 150, 6, 251, 151, 6, 251, 153, 6, 251, 155, 6,\n 251, 157, 7, 252, 159, 7, 252, 161, 8, 252, 163, 9, 252, 165, 10, 252, 166, 12, 252, 168, 13, 252, 170, 15,\n 252, 172, 17, 252, 174, 18, 252, 176, 20, 252, 178, 22, 252, 180, 24, 251, 182, 26, 251, 184, 29, 251, 186, 31,\n 251, 188, 33, 251, 190, 35, 250, 192, 38, 250, 194, 40, 250, 196, 42, 250, 198, 45, 249, 199, 47, 249, 201, 50,\n 249, 203, 53, 248, 205, 55, 248, 207, 58, 247, 209, 61, 247, 211, 64, 246, 213, 67, 246, 215, 70, 245, 217, 73,\n 245, 219, 76, 244, 221, 79, 244, 223, 83, 244, 225, 86, 243, 227, 90, 243, 229, 93, 242, 230, 97, 242, 232, 101,\n 242, 234, 105, 241, 236, 109, 241, 237, 113, 241, 239, 117, 241, 241, 121, 242, 242, 125, 242, 244, 130, 243, 245, 134,\n 243, 246, 138, 244, 248, 142, 245, 249, 146, 246, 250, 150, 248, 251, 154, 249, 252, 157, 250, 253, 161, 252, 255, 164,\n]);\n\n// prettier-ignore\nconst ROSEUS_LUT = new Uint8Array([\n 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 3, 4, 2, 4, 5, 2, 5, 6, 3, 6, 7,\n 3, 7, 8, 3, 8, 10, 3, 9, 12, 3, 10, 14, 3, 12, 16, 3, 13, 17, 3, 14, 19, 2, 15, 21,\n 2, 16, 23, 2, 17, 25, 2, 18, 27, 2, 19, 30, 1, 20, 32, 1, 21, 34, 1, 22, 36, 1, 23, 38,\n 1, 24, 40, 0, 25, 43, 0, 26, 45, 0, 27, 47, 0, 27, 50, 0, 28, 52, 0, 29, 54, 0, 30, 57,\n 0, 30, 59, 1, 31, 62, 1, 32, 64, 1, 32, 67, 2, 33, 69, 3, 33, 72, 4, 34, 74, 5, 35, 77,\n 6, 35, 79, 8, 35, 82, 9, 36, 84, 11, 36, 86, 13, 37, 89, 15, 37, 91, 17, 37, 94, 19, 37, 96,\n 21, 38, 99, 23, 38, 101, 25, 38, 104, 27, 38, 106, 29, 38, 108, 31, 38, 111, 33, 38, 113, 35, 38, 115,\n 38, 38, 118, 40, 38, 120, 42, 38, 122, 44, 38, 124, 46, 38, 126, 49, 38, 128, 51, 38, 130, 53, 37, 132,\n 55, 37, 134, 58, 37, 136, 60, 36, 138, 62, 36, 139, 65, 36, 141, 67, 35, 143, 69, 35, 144, 72, 35, 146,\n 74, 34, 147, 76, 34, 149, 79, 33, 150, 81, 33, 151, 84, 32, 152, 86, 32, 153, 88, 31, 154, 91, 31, 155,\n 93, 30, 156, 95, 29, 157, 98, 29, 158, 100, 28, 159, 103, 28, 159, 105, 27, 160, 107, 27, 160, 110, 26, 161,\n 112, 26, 161, 114, 25, 161, 117, 25, 162, 119, 24, 162, 121, 24, 162, 124, 23, 162, 126, 23, 162, 128, 23, 162,\n 131, 22, 161, 133, 22, 161, 135, 22, 161, 137, 22, 161, 140, 22, 160, 142, 22, 160, 144, 22, 159, 146, 22, 159,\n 148, 22, 158, 150, 22, 157, 153, 22, 157, 155, 23, 156, 157, 23, 155, 159, 23, 154, 161, 24, 153, 163, 24, 152,\n 165, 25, 151, 167, 26, 150, 169, 26, 149, 171, 27, 148, 173, 28, 147, 175, 29, 146, 177, 29, 145, 179, 30, 144,\n 181, 31, 142, 183, 32, 141, 184, 33, 140, 186, 34, 139, 188, 35, 137, 190, 36, 136, 192, 37, 135, 193, 39, 133,\n 195, 40, 132, 197, 41, 130, 198, 42, 129, 200, 43, 128, 202, 45, 126, 203, 46, 125, 205, 47, 123, 206, 48, 122,\n 208, 50, 120, 209, 51, 119, 211, 52, 117, 212, 54, 116, 214, 55, 114, 215, 57, 113, 217, 58, 111, 218, 60, 110,\n 219, 61, 109, 221, 63, 107, 222, 64, 106, 223, 66, 104, 225, 67, 103, 226, 69, 101, 227, 70, 100, 228, 72, 99,\n 229, 73, 97, 230, 75, 96, 231, 77, 94, 233, 78, 93, 234, 80, 92, 235, 82, 91, 236, 83, 89, 237, 85, 88,\n 237, 87, 87, 238, 89, 86, 239, 90, 84, 240, 92, 83, 241, 94, 82, 242, 96, 81, 242, 97, 80, 243, 99, 79,\n 244, 101, 78, 245, 103, 77, 245, 105, 76, 246, 107, 75, 246, 108, 74, 247, 110, 74, 248, 112, 73, 248, 114, 72,\n 248, 116, 72, 249, 118, 71, 249, 120, 71, 250, 122, 70, 250, 124, 70, 250, 126, 70, 251, 128, 70, 251, 130, 69,\n 251, 132, 70, 251, 134, 70, 251, 136, 70, 252, 138, 70, 252, 140, 70, 252, 142, 71, 252, 144, 72, 252, 146, 72,\n 252, 148, 73, 252, 150, 74, 251, 152, 75, 251, 154, 76, 251, 156, 77, 251, 158, 78, 251, 160, 80, 251, 162, 81,\n 250, 164, 83, 250, 166, 85, 250, 168, 87, 249, 170, 88, 249, 172, 90, 248, 174, 93, 248, 176, 95, 248, 178, 97,\n 247, 180, 99, 247, 182, 102, 246, 184, 104, 246, 186, 107, 245, 188, 110, 244, 190, 112, 244, 192, 115, 243, 194, 118,\n 243, 195, 121, 242, 197, 124, 242, 199, 127, 241, 201, 131, 240, 203, 134, 240, 205, 137, 239, 207, 140, 239, 208, 144,\n 238, 210, 147, 238, 212, 151, 237, 213, 154, 237, 215, 158, 236, 217, 161, 236, 218, 165, 236, 220, 169, 236, 222, 172,\n 235, 223, 176, 235, 225, 180, 235, 226, 183, 235, 228, 187, 235, 229, 191, 235, 230, 194, 236, 232, 198, 236, 233, 201,\n 236, 234, 205, 237, 236, 208, 237, 237, 212, 238, 238, 215, 239, 239, 219, 240, 240, 222, 241, 242, 225, 242, 243, 228,\n 243, 244, 231, 244, 245, 234, 246, 246, 237, 247, 247, 240, 249, 248, 242, 251, 249, 245, 253, 250, 247, 254, 251, 249,\n]);\n\nconst lutCache = new Map<string, ColorLUT>();\n\nfunction grayscaleLUT(): ColorLUT {\n let lut = lutCache.get('grayscale');\n if (!lut) {\n lut = new Uint8Array(256 * 3);\n for (let i = 0; i < 256; i++) {\n lut[i * 3] = lut[i * 3 + 1] = lut[i * 3 + 2] = i;\n }\n lutCache.set('grayscale', lut);\n }\n return lut;\n}\n\nfunction igrayLUT(): ColorLUT {\n let lut = lutCache.get('igray');\n if (!lut) {\n lut = new Uint8Array(256 * 3);\n for (let i = 0; i < 256; i++) {\n const v = 255 - i;\n lut[i * 3] = lut[i * 3 + 1] = lut[i * 3 + 2] = v;\n }\n lutCache.set('igray', lut);\n }\n return lut;\n}\n\n/**\n * Get a 256-entry RGB LUT for the given color map.\n */\nexport function getColorMap(value: ColorMapValue): ColorLUT {\n if (Array.isArray(value)) {\n return interpolateLUT(value);\n }\n\n switch (value) {\n case 'viridis': return VIRIDIS_LUT;\n case 'magma': return MAGMA_LUT;\n case 'inferno': return INFERNO_LUT;\n case 'roseus': return ROSEUS_LUT;\n case 'grayscale': return grayscaleLUT();\n case 'igray': return igrayLUT();\n default: return VIRIDIS_LUT;\n }\n}\n","/**\n * Frequency scale mapping functions.\n * Each maps a frequency (Hz) to a normalized position [0, 1].\n */\n\nfunction linearScale(f: number, minF: number, maxF: number): number {\n if (maxF === minF) return 0;\n return (f - minF) / (maxF - minF);\n}\n\nfunction logarithmicScale(f: number, minF: number, maxF: number): number {\n const logMin = Math.log2(Math.max(minF, 1));\n const logMax = Math.log2(maxF);\n if (logMax === logMin) return 0;\n return (Math.log2(Math.max(f, 1)) - logMin) / (logMax - logMin);\n}\n\nfunction hzToMel(f: number): number {\n return 2595 * Math.log10(1 + f / 700);\n}\n\nfunction melScale(f: number, minF: number, maxF: number): number {\n const melMin = hzToMel(minF);\n const melMax = hzToMel(maxF);\n if (melMax === melMin) return 0;\n return (hzToMel(f) - melMin) / (melMax - melMin);\n}\n\nfunction hzToBark(f: number): number {\n return 13 * Math.atan(0.00076 * f) + 3.5 * Math.atan((f / 7500) ** 2);\n}\n\nfunction barkScale(f: number, minF: number, maxF: number): number {\n const barkMin = hzToBark(minF);\n const barkMax = hzToBark(maxF);\n if (barkMax === barkMin) return 0;\n return (hzToBark(f) - barkMin) / (barkMax - barkMin);\n}\n\nfunction hzToErb(f: number): number {\n return 21.4 * Math.log10(1 + 0.00437 * f);\n}\n\nfunction erbScale(f: number, minF: number, maxF: number): number {\n const erbMin = hzToErb(minF);\n const erbMax = hzToErb(maxF);\n if (erbMax === erbMin) return 0;\n return (hzToErb(f) - erbMin) / (erbMax - erbMin);\n}\n\nexport type FrequencyScaleName = 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb';\n\n/**\n * Returns a mapping function: (frequencyHz, minFrequency, maxFrequency) → [0, 1]\n */\nexport function getFrequencyScale(\n name: FrequencyScaleName\n): (f: number, minF: number, maxF: number) => number {\n switch (name) {\n case 'logarithmic': return logarithmicScale;\n case 'mel': return melScale;\n case 'bark': return barkScale;\n case 'erb': return erbScale;\n case 'linear':\n return linearScale;\n default:\n console.warn(`[spectrogram] Unknown frequency scale \"${name}\", falling back to linear`);\n return linearScale;\n }\n}\n","import React from 'react';\nimport styled from 'styled-components';\nimport type { RenderMode } from '@waveform-playlist/core';\nimport type { TrackMenuItem } from './types';\n\nconst SectionLabel = styled.div`\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n opacity: 0.5;\n margin-bottom: 0.25rem;\n`;\n\nconst RadioLabel = styled.label`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.2rem 0;\n font-size: 0.8rem;\n cursor: pointer;\n\n &:hover {\n opacity: 0.8;\n }\n`;\n\nconst SettingsButton = styled.button`\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n font-size: 0.8rem;\n padding: 0.35rem 0.75rem;\n width: 100%;\n text-align: left;\n\n &:hover {\n background: rgba(128, 128, 128, 0.15);\n }\n`;\n\nconst DropdownSection = styled.div`\n padding: 0.25rem 0.75rem;\n`;\n\nconst RENDER_MODES: { value: RenderMode; label: string }[] = [\n { value: 'waveform', label: 'Waveform' },\n { value: 'spectrogram', label: 'Spectrogram' },\n { value: 'both', label: 'Both' },\n];\n\nexport interface SpectrogramMenuItemsProps {\n renderMode: RenderMode;\n onRenderModeChange: (mode: RenderMode) => void;\n onOpenSettings: () => void;\n onClose?: () => void;\n}\n\n/**\n * Returns TrackMenuItem[] for the spectrogram display mode radios and settings button.\n */\nexport function SpectrogramMenuItems({\n renderMode,\n onRenderModeChange,\n onOpenSettings,\n onClose,\n}: SpectrogramMenuItemsProps): TrackMenuItem[] {\n return [\n {\n id: 'spectrogram-display',\n label: 'Display',\n content: (\n <DropdownSection>\n <SectionLabel>Display</SectionLabel>\n {RENDER_MODES.map(({ value, label }) => (\n <RadioLabel key={value}>\n <input\n type=\"radio\"\n name=\"render-mode\"\n checked={renderMode === value}\n onChange={() => { onRenderModeChange(value); onClose?.(); }}\n />\n {label}\n </RadioLabel>\n ))}\n </DropdownSection>\n ),\n },\n {\n id: 'spectrogram-settings',\n content: (\n <SettingsButton\n onClick={(e) => {\n e.stopPropagation();\n onClose?.();\n onOpenSettings();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n Spectrogram Settings...\n </SettingsButton>\n ),\n },\n ];\n}\n","import React, { useRef, useEffect, useState } from 'react';\nimport styled from 'styled-components';\nimport type { SpectrogramConfig, ColorMapValue, ColorMapName, FFTSize } from '@waveform-playlist/core';\n\nexport interface SpectrogramSettingsModalProps {\n open: boolean;\n onClose: () => void;\n config: SpectrogramConfig;\n colorMap: ColorMapValue;\n onApply: (config: SpectrogramConfig, colorMap: ColorMapValue) => void;\n}\n\nconst StyledDialog = styled.dialog`\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 8px;\n padding: 1.5rem;\n background: ${p => p.theme.timescaleBackgroundColor ?? '#222'};\n color: ${p => p.theme.textColor ?? 'inherit'};\n min-width: 380px;\n max-width: 500px;\n\n &::backdrop {\n background: rgba(0, 0, 0, 0.5);\n }\n`;\n\nconst Title = styled.h3`\n margin: 0 0 1rem;\n font-size: 1rem;\n`;\n\nconst FormGrid = styled.div`\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0.75rem;\n`;\n\nconst Field = styled.div<{ $span?: boolean }>`\n display: flex;\n flex-direction: column;\n gap: 0.2rem;\n grid-column: ${p => p.$span ? '1 / -1' : 'auto'};\n`;\n\nconst Label = styled.label`\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n opacity: 0.6;\n`;\n\nconst Select = styled.select`\n padding: 0.3rem 0.4rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n background: rgba(128, 128, 128, 0.15);\n color: inherit;\n font-size: 0.85rem;\n`;\n\nconst NumberInput = styled.input`\n padding: 0.3rem 0.4rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n background: rgba(128, 128, 128, 0.15);\n color: inherit;\n font-size: 0.85rem;\n width: 100%;\n box-sizing: border-box;\n`;\n\nconst RangeRow = styled.div`\n display: flex;\n align-items: center;\n gap: 0.5rem;\n`;\n\nconst RangeValue = styled.span`\n font-size: 0.75rem;\n font-family: monospace;\n opacity: 0.6;\n min-width: 3ch;\n text-align: right;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.85rem;\n cursor: pointer;\n`;\n\nconst ButtonRow = styled.div`\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 1.25rem;\n`;\n\nconst ModalButton = styled.button<{ $primary?: boolean }>`\n padding: 0.4rem 1rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.85rem;\n background: ${p => p.$primary ? 'var(--ifm-color-primary, #4a9)' : 'transparent'};\n color: ${p => p.$primary ? '#fff' : 'inherit'};\n\n &:hover {\n opacity: 0.85;\n }\n`;\n\nconst FFT_SIZES = [256, 512, 1024, 2048, 4096, 8192];\nconst WINDOW_FUNCTIONS = ['hann', 'hamming', 'blackman', 'blackman-harris', 'bartlett', 'rectangular'] as const;\nconst FREQ_SCALES = ['linear', 'logarithmic', 'mel', 'bark', 'erb'] as const;\nconst COLOR_MAPS: ColorMapName[] = ['viridis', 'magma', 'inferno', 'grayscale', 'igray', 'roseus'];\n\nexport const SpectrogramSettingsModal: React.FC<SpectrogramSettingsModalProps> = ({\n open,\n onClose,\n config,\n colorMap,\n onApply,\n}) => {\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n // Local form state\n const [fftSize, setFftSize] = useState(config.fftSize ?? 2048);\n const [windowFn, setWindowFn] = useState(config.windowFunction ?? 'hann');\n const [freqScale, setFreqScale] = useState(config.frequencyScale ?? 'mel');\n const [localColorMap, setLocalColorMap] = useState<ColorMapName>(\n typeof colorMap === 'string' ? colorMap : 'viridis'\n );\n const [minFreq, setMinFreq] = useState(config.minFrequency ?? 0);\n const [maxFreq, setMaxFreq] = useState(config.maxFrequency ?? 20000);\n const [gainDb, setGainDb] = useState(config.gainDb ?? 20);\n const [rangeDb, setRangeDb] = useState(config.rangeDb ?? 80);\n const [zeroPadding, setZeroPadding] = useState(config.zeroPaddingFactor ?? 2);\n const [hopSize, setHopSize] = useState(config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4));\n const [showLabels, setShowLabels] = useState(config.labels ?? false);\n\n // Sync local state when props change\n useEffect(() => {\n setFftSize(config.fftSize ?? 2048);\n setWindowFn(config.windowFunction ?? 'hann');\n setFreqScale(config.frequencyScale ?? 'mel');\n setLocalColorMap(typeof colorMap === 'string' ? colorMap : 'viridis');\n setMinFreq(config.minFrequency ?? 0);\n setMaxFreq(config.maxFrequency ?? 20000);\n setGainDb(config.gainDb ?? 20);\n setRangeDb(config.rangeDb ?? 80);\n setZeroPadding(config.zeroPaddingFactor ?? 2);\n setHopSize(config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4));\n setShowLabels(config.labels ?? false);\n }, [config, colorMap]);\n\n // Open/close dialog + handle native close (Escape key)\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (open && !dialog.open) {\n dialog.showModal();\n } else if (!open && dialog.open) {\n dialog.close();\n }\n\n const handleClose = () => {\n // Only call onClose if dialog was open (avoids double-fire)\n if (open) {\n onClose();\n }\n };\n dialog.addEventListener('close', handleClose);\n return () => dialog.removeEventListener('close', handleClose);\n }, [open, onClose]);\n\n const handleApply = () => {\n onApply(\n {\n fftSize,\n windowFunction: windowFn as SpectrogramConfig['windowFunction'],\n frequencyScale: freqScale as SpectrogramConfig['frequencyScale'],\n minFrequency: minFreq,\n maxFrequency: maxFreq,\n gainDb,\n rangeDb,\n zeroPaddingFactor: zeroPadding,\n hopSize,\n labels: showLabels,\n },\n localColorMap\n );\n onClose();\n };\n\n return (\n <StyledDialog ref={dialogRef}>\n <Title>Spectrogram Settings</Title>\n <FormGrid>\n <Field>\n <Label>FFT Size</Label>\n <Select value={fftSize} onChange={e => { const v = Number(e.target.value) as FFTSize; setFftSize(v); setHopSize(Math.floor(v / 4)); }}>\n {FFT_SIZES.map(s => <option key={s} value={s}>{s}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Hop Size</Label>\n <Select value={hopSize} onChange={e => setHopSize(Number(e.target.value))}>\n {[\n { label: `${fftSize} (no overlap)`, value: fftSize },\n { label: `${Math.floor(fftSize / 2)} (50%)`, value: Math.floor(fftSize / 2) },\n { label: `${Math.floor(fftSize / 4)} (75%)`, value: Math.floor(fftSize / 4) },\n { label: `${Math.floor(fftSize / 8)} (87.5%)`, value: Math.floor(fftSize / 8) },\n ].map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Zero Padding</Label>\n <Select value={zeroPadding} onChange={e => setZeroPadding(Number(e.target.value))}>\n {[1, 2, 4, 8, 16].map(v => <option key={v} value={v}>{v}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Window Function</Label>\n <Select value={windowFn} onChange={e => setWindowFn(e.target.value as typeof windowFn)}>\n {WINDOW_FUNCTIONS.map(w => <option key={w} value={w}>{w}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Frequency Scale</Label>\n <Select value={freqScale} onChange={e => setFreqScale(e.target.value as typeof freqScale)}>\n {FREQ_SCALES.map(s => <option key={s} value={s}>{s}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Color Map</Label>\n <Select value={localColorMap} onChange={e => setLocalColorMap(e.target.value as ColorMapName)}>\n {COLOR_MAPS.map(c => <option key={c} value={c}>{c}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Min Frequency (Hz)</Label>\n <NumberInput type=\"number\" min={0} max={5000} step={50} value={minFreq}\n onChange={e => setMinFreq(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Max Frequency (Hz)</Label>\n <NumberInput type=\"number\" min={1000} max={22050} step={50} value={maxFreq}\n onChange={e => setMaxFreq(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Range (dB)</Label>\n <NumberInput type=\"number\" min={1} max={120} step={1} value={rangeDb}\n onChange={e => setRangeDb(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Gain (dB)</Label>\n <NumberInput type=\"number\" min={-20} max={60} step={1} value={gainDb}\n onChange={e => setGainDb(Number(e.target.value))} />\n </Field>\n\n <Field $span>\n <CheckboxLabel>\n <input type=\"checkbox\" checked={showLabels} onChange={e => setShowLabels(e.target.checked)} />\n Show Frequency Labels\n </CheckboxLabel>\n </Field>\n </FormGrid>\n\n <ButtonRow>\n <ModalButton onClick={onClose}>Cancel</ModalButton>\n <ModalButton $primary onClick={handleApply}>Apply</ModalButton>\n </ButtonRow>\n </StyledDialog>\n );\n};\n","import type { SpectrogramConfig, SpectrogramData } from '@waveform-playlist/core';\n\nexport interface SpectrogramWorkerComputeParams {\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n mono: boolean;\n}\n\nexport interface SpectrogramWorkerRenderParams extends SpectrogramWorkerComputeParams {\n render: {\n canvasIds: string[][];\n canvasWidths: number[];\n canvasHeight: number;\n devicePixelRatio: number;\n samplesPerPixel: number;\n colorLUT: Uint8Array;\n frequencyScale: string;\n minFrequency: number;\n maxFrequency: number;\n };\n}\n\nexport interface SpectrogramWorkerFFTParams {\n clipId: string;\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n mono: boolean;\n sampleRange?: { start: number; end: number };\n}\n\nexport interface SpectrogramWorkerRenderChunksParams {\n cacheKey: string;\n canvasIds: string[];\n canvasWidths: number[];\n globalPixelOffsets: number[];\n canvasHeight: number;\n devicePixelRatio: number;\n samplesPerPixel: number;\n colorLUT: Uint8Array;\n frequencyScale: string;\n minFrequency: number;\n maxFrequency: number;\n gainDb: number;\n rangeDb: number;\n channelIndex: number;\n}\n\ntype ComputeResponse =\n | { id: string; type: 'spectrograms'; spectrograms: SpectrogramData[] }\n | { id: string; type: 'cache-key'; cacheKey: string }\n | { id: string; type: 'done' }\n | { id: string; type: 'error'; error: string };\n\n/** Union of all values that worker resolve callbacks receive. */\ntype PendingResolveValue = SpectrogramData[] | { cacheKey: string } | void;\n\ninterface PendingEntry {\n resolve: (value: PendingResolveValue) => void;\n reject: (reason: unknown) => void;\n}\n\n/** Add a pending promise entry, centralizing the single unavoidable resolve cast. */\nfunction addPending<T>(\n map: Map<string, PendingEntry>,\n id: string,\n resolve: (value: T) => void,\n reject: (reason: unknown) => void,\n): void {\n map.set(id, { resolve: resolve as PendingEntry['resolve'], reject });\n}\n\nexport interface SpectrogramWorkerApi {\n compute(params: SpectrogramWorkerComputeParams): Promise<SpectrogramData[]>;\n computeFFT(params: SpectrogramWorkerFFTParams): Promise<{ cacheKey: string }>;\n renderChunks(params: SpectrogramWorkerRenderChunksParams): Promise<void>;\n registerCanvas(canvasId: string, canvas: OffscreenCanvas): void;\n unregisterCanvas(canvasId: string): void;\n registerAudioData(clipId: string, channelDataArrays: Float32Array[], sampleRate: number): void;\n unregisterAudioData(clipId: string): void;\n computeAndRender(params: SpectrogramWorkerRenderParams): Promise<void>;\n terminate(): void;\n}\n\nlet idCounter = 0;\n\n/**\n * Wraps a Web Worker running `spectrogram.worker.ts` with a promise-based API.\n *\n * The caller is responsible for creating the Worker, e.g.:\n * ```ts\n * const worker = new Worker(\n * new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n * { type: 'module' }\n * );\n * const api = createSpectrogramWorker(worker);\n * ```\n */\nexport function createSpectrogramWorker(worker: Worker): SpectrogramWorkerApi {\n const pending = new Map<string, PendingEntry>();\n\n // Track which clipIds have pre-registered audio data in the worker\n const registeredClipIds = new Set<string>();\n let terminated = false;\n\n worker.onmessage = (e: MessageEvent<ComputeResponse>) => {\n const msg = e.data;\n const entry = pending.get(msg.id);\n if (entry) {\n pending.delete(msg.id);\n switch (msg.type) {\n case 'error':\n entry.reject(new Error(msg.error));\n break;\n case 'cache-key':\n entry.resolve({ cacheKey: msg.cacheKey });\n break;\n case 'done':\n entry.resolve(undefined);\n break;\n case 'spectrograms':\n entry.resolve(msg.spectrograms);\n break;\n }\n } else if (msg.id) {\n console.warn(`[spectrogram] Received response for unknown message ID: ${msg.id}`);\n }\n };\n\n worker.onerror = (e: ErrorEvent) => {\n terminated = true;\n for (const [, entry] of pending) {\n entry.reject(e.error ?? new Error(e.message));\n }\n pending.clear();\n };\n\n return {\n compute(params: SpectrogramWorkerComputeParams): Promise<SpectrogramData[]> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<SpectrogramData[]>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n // Slice channel data so we can transfer without detaching the original AudioBuffer views\n const transferableArrays = params.channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n id,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n },\n transferables,\n );\n });\n },\n\n computeFFT(params: SpectrogramWorkerFFTParams): Promise<{ cacheKey: string }> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<{ cacheKey: string }>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n // Skip transfer if audio data is pre-registered in the worker\n const isPreRegistered = registeredClipIds.has(params.clipId);\n const transferableArrays = isPreRegistered ? [] : params.channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n type: 'compute-fft',\n id,\n clipId: params.clipId,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n ...(params.sampleRange ? { sampleRange: params.sampleRange } : {}),\n },\n transferables,\n );\n });\n },\n\n renderChunks(params: SpectrogramWorkerRenderChunksParams): Promise<void> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<void>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n worker.postMessage({\n type: 'render-chunks',\n id,\n cacheKey: params.cacheKey,\n canvasIds: params.canvasIds,\n canvasWidths: params.canvasWidths,\n globalPixelOffsets: params.globalPixelOffsets,\n canvasHeight: params.canvasHeight,\n devicePixelRatio: params.devicePixelRatio,\n samplesPerPixel: params.samplesPerPixel,\n colorLUT: params.colorLUT,\n frequencyScale: params.frequencyScale,\n minFrequency: params.minFrequency,\n maxFrequency: params.maxFrequency,\n gainDb: params.gainDb,\n rangeDb: params.rangeDb,\n channelIndex: params.channelIndex,\n });\n });\n },\n\n registerCanvas(canvasId: string, canvas: OffscreenCanvas): void {\n worker.postMessage(\n { type: 'register-canvas', canvasId, canvas },\n [canvas],\n );\n },\n\n unregisterCanvas(canvasId: string): void {\n worker.postMessage({ type: 'unregister-canvas', canvasId });\n },\n\n registerAudioData(clipId: string, channelDataArrays: Float32Array[], sampleRate: number): void {\n const transferableArrays = channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n worker.postMessage(\n { type: 'register-audio-data', clipId, channelDataArrays: transferableArrays, sampleRate },\n transferables,\n );\n registeredClipIds.add(clipId);\n },\n\n unregisterAudioData(clipId: string): void {\n worker.postMessage({ type: 'unregister-audio-data', clipId });\n registeredClipIds.delete(clipId);\n },\n\n computeAndRender(params: SpectrogramWorkerRenderParams): Promise<void> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<void>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n const transferableArrays = params.channelDataArrays.map(arr => arr.slice());\n const transferables: Transferable[] = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n type: 'compute-render',\n id,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n render: params.render,\n },\n transferables,\n );\n });\n },\n\n terminate() {\n terminated = true;\n worker.terminate();\n for (const [, entry] of pending) {\n entry.reject(new Error('Worker terminated'));\n }\n pending.clear();\n },\n };\n}\n","import React, { useState, useEffect, useRef, useCallback, useMemo, type ReactNode } from 'react';\nimport type { SpectrogramData, SpectrogramConfig, SpectrogramComputeConfig, ColorMapValue, RenderMode, TrackSpectrogramOverrides } from '@waveform-playlist/core';\nimport { computeSpectrogram, computeSpectrogramMono, getColorMap, getFrequencyScale } from './computation';\nimport { createSpectrogramWorker, type SpectrogramWorkerApi } from './worker';\nimport { SpectrogramMenuItems } from './components';\nimport { SpectrogramSettingsModal } from './components';\nimport { SpectrogramIntegrationProvider, type SpectrogramIntegration } from '@waveform-playlist/browser';\nimport { usePlaylistData, usePlaylistControls } from '@waveform-playlist/browser';\n\nexport interface SpectrogramProviderProps {\n config?: SpectrogramConfig;\n colorMap?: ColorMapValue;\n children: ReactNode;\n}\n\nexport const SpectrogramProvider: React.FC<SpectrogramProviderProps> = ({\n config: spectrogramConfig,\n colorMap: spectrogramColorMap,\n children,\n}) => {\n const {\n tracks,\n waveHeight,\n samplesPerPixel,\n isReady,\n mono,\n controls,\n } = usePlaylistData();\n const { scrollContainerRef } = usePlaylistControls();\n\n // State\n const [spectrogramDataMap, setSpectrogramDataMap] = useState<Map<string, SpectrogramData[]>>(new Map());\n const [trackSpectrogramOverrides, setTrackSpectrogramOverrides] = useState<Map<string, TrackSpectrogramOverrides>>(new Map());\n\n // OffscreenCanvas registry for worker-rendered spectrograms\n const spectrogramCanvasRegistryRef = useRef<Map<string, Map<number, { canvasIds: string[]; canvasWidths: number[] }>>>(new Map());\n const [spectrogramCanvasVersion, setSpectrogramCanvasVersion] = useState(0);\n\n // Spectrogram refs\n const prevSpectrogramConfigRef = useRef<Map<string, string>>(new Map());\n const prevSpectrogramFFTKeyRef = useRef<Map<string, string>>(new Map());\n const spectrogramWorkerRef = useRef<SpectrogramWorkerApi | null>(null);\n const spectrogramGenerationRef = useRef(0);\n const prevCanvasVersionRef = useRef(0);\n const [spectrogramWorkerReady, setSpectrogramWorkerReady] = useState(false);\n const clipCacheKeysRef = useRef<Map<string, string>>(new Map());\n const backgroundRenderAbortRef = useRef<{ aborted: boolean } | null>(null);\n const registeredAudioClipIdsRef = useRef<Set<string>>(new Set());\n\n // Terminate worker on unmount\n useEffect(() => {\n return () => {\n spectrogramWorkerRef.current?.terminate();\n spectrogramWorkerRef.current = null;\n };\n }, []);\n\n // Eagerly transfer audio data to worker when tracks load\n useEffect(() => {\n if (!isReady || tracks.length === 0) return;\n\n let workerApi = spectrogramWorkerRef.current;\n if (!workerApi) {\n try {\n const rawWorker = new Worker(\n new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n { type: 'module' }\n );\n workerApi = createSpectrogramWorker(rawWorker);\n spectrogramWorkerRef.current = workerApi;\n setSpectrogramWorkerReady(true);\n } catch {\n console.warn('Spectrogram Web Worker unavailable for pre-transfer');\n return;\n }\n }\n\n const currentClipIds = new Set<string>();\n\n for (const track of tracks) {\n for (const clip of track.clips) {\n if (!clip.audioBuffer) continue;\n currentClipIds.add(clip.id);\n\n if (!registeredAudioClipIdsRef.current.has(clip.id)) {\n const channelDataArrays: Float32Array[] = [];\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelDataArrays.push(clip.audioBuffer.getChannelData(ch));\n }\n workerApi.registerAudioData(clip.id, channelDataArrays, clip.audioBuffer.sampleRate);\n registeredAudioClipIdsRef.current.add(clip.id);\n }\n }\n }\n\n for (const clipId of registeredAudioClipIdsRef.current) {\n if (!currentClipIds.has(clipId)) {\n workerApi.unregisterAudioData(clipId);\n registeredAudioClipIdsRef.current.delete(clipId);\n }\n }\n }, [isReady, tracks]);\n\n // Main spectrogram computation effect\n useEffect(() => {\n if (tracks.length === 0) return;\n\n const currentKeys = new Map<string, string>();\n const currentFFTKeys = new Map<string, string>();\n tracks.forEach((track) => {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'waveform') return;\n const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig;\n const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap;\n currentKeys.set(track.id, JSON.stringify({ mode, cfg, cm, mono }));\n const computeConfig: SpectrogramComputeConfig = {\n fftSize: cfg?.fftSize, hopSize: cfg?.hopSize,\n windowFunction: cfg?.windowFunction, alpha: cfg?.alpha,\n zeroPaddingFactor: cfg?.zeroPaddingFactor,\n };\n currentFFTKeys.set(track.id, JSON.stringify({ mode, mono, ...computeConfig }));\n });\n\n const prevKeys = prevSpectrogramConfigRef.current;\n const prevFFTKeys = prevSpectrogramFFTKeyRef.current;\n\n let configChanged = currentKeys.size !== prevKeys.size;\n if (!configChanged) {\n for (const [idx, key] of currentKeys) {\n if (prevKeys.get(idx) !== key) { configChanged = true; break; }\n }\n }\n\n let fftKeyChanged = currentFFTKeys.size !== prevFFTKeys.size;\n if (!fftKeyChanged) {\n for (const [idx, key] of currentFFTKeys) {\n if (prevFFTKeys.get(idx) !== key) { fftKeyChanged = true; break; }\n }\n }\n\n const canvasVersionChanged = spectrogramCanvasVersion !== prevCanvasVersionRef.current;\n prevCanvasVersionRef.current = spectrogramCanvasVersion;\n\n if (!configChanged && !canvasVersionChanged) return;\n\n if (configChanged) {\n prevSpectrogramConfigRef.current = currentKeys;\n prevSpectrogramFFTKeyRef.current = currentFFTKeys;\n }\n\n if (configChanged) {\n setSpectrogramDataMap(prevMap => {\n const activeClipIds = new Set<string>();\n for (const track of tracks) {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'spectrogram' || mode === 'both') {\n for (const clip of track.clips) {\n activeClipIds.add(clip.id);\n }\n }\n }\n const newMap = new Map(prevMap);\n for (const clipId of newMap.keys()) {\n if (!activeClipIds.has(clipId)) {\n newMap.delete(clipId);\n }\n }\n return newMap;\n });\n }\n\n if (backgroundRenderAbortRef.current) {\n backgroundRenderAbortRef.current.aborted = true;\n }\n\n const generation = ++spectrogramGenerationRef.current;\n\n let workerApi = spectrogramWorkerRef.current;\n if (!workerApi) {\n try {\n const rawWorker = new Worker(\n new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n { type: 'module' }\n );\n workerApi = createSpectrogramWorker(rawWorker);\n spectrogramWorkerRef.current = workerApi;\n setSpectrogramWorkerReady(true);\n } catch {\n console.warn('Spectrogram Web Worker unavailable, falling back to synchronous computation');\n }\n }\n\n const clipsNeedingFFT: Array<{\n clipId: string;\n trackIndex: number;\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n clipStartSample: number;\n monoFlag: boolean;\n colorMap: ColorMapValue;\n }> = [];\n const clipsNeedingDisplayOnly: Array<{\n clipId: string;\n trackIndex: number;\n config: SpectrogramConfig;\n clipStartSample: number;\n monoFlag: boolean;\n colorMap: ColorMapValue;\n numChannels: number;\n }> = [];\n\n tracks.forEach((track, i) => {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'waveform') return;\n\n const trackConfigChanged = configChanged && (currentKeys.get(track.id) !== prevKeys.get(track.id));\n const trackFFTChanged = fftKeyChanged && (currentFFTKeys.get(track.id) !== prevFFTKeys.get(track.id));\n const hasRegisteredCanvases = canvasVersionChanged && track.clips.some(\n clip => spectrogramCanvasRegistryRef.current.has(clip.id)\n );\n if (!trackConfigChanged && !hasRegisteredCanvases) return;\n\n const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig ?? {};\n const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap ?? 'viridis';\n\n for (const clip of track.clips) {\n if (!clip.audioBuffer) continue;\n\n const monoFlag = mono || clip.audioBuffer.numberOfChannels === 1;\n\n if (!trackFFTChanged && !hasRegisteredCanvases && clipCacheKeysRef.current.has(clip.id)) {\n clipsNeedingDisplayOnly.push({\n clipId: clip.id,\n trackIndex: i,\n config: cfg,\n clipStartSample: clip.startSample,\n monoFlag,\n colorMap: cm,\n numChannels: monoFlag ? 1 : clip.audioBuffer.numberOfChannels,\n });\n continue;\n }\n\n const channelDataArrays: Float32Array[] = [];\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelDataArrays.push(clip.audioBuffer.getChannelData(ch));\n }\n\n clipsNeedingFFT.push({\n clipId: clip.id,\n trackIndex: i,\n channelDataArrays,\n config: cfg,\n sampleRate: clip.audioBuffer.sampleRate,\n offsetSamples: clip.offsetSamples,\n durationSamples: clip.durationSamples,\n clipStartSample: clip.startSample,\n monoFlag,\n colorMap: cm,\n });\n }\n });\n\n if (clipsNeedingFFT.length === 0 && clipsNeedingDisplayOnly.length === 0) return;\n\n if (!workerApi) {\n try {\n setSpectrogramDataMap(prevMap => {\n const newMap = new Map(prevMap);\n for (const item of clipsNeedingFFT) {\n const clip = tracks.flatMap(t => t.clips).find(c => c.id === item.clipId);\n if (!clip?.audioBuffer) continue;\n const channelSpectrograms: SpectrogramData[] = [];\n if (item.monoFlag) {\n channelSpectrograms.push(\n computeSpectrogramMono(\n clip.audioBuffer,\n item.config, item.offsetSamples, item.durationSamples\n )\n );\n } else {\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelSpectrograms.push(\n computeSpectrogram(clip.audioBuffer, item.config, item.offsetSamples, item.durationSamples, ch)\n );\n }\n }\n newMap.set(item.clipId, channelSpectrograms);\n }\n return newMap;\n });\n } catch (err) {\n console.error('[waveform-playlist] Synchronous spectrogram computation failed:', err);\n }\n return;\n }\n\n const getVisibleChunkRange = (canvasWidths: number[], clipPixelOffset = 0): { visibleIndices: number[]; remainingIndices: number[] } => {\n const container = scrollContainerRef.current;\n if (!container) {\n return { visibleIndices: canvasWidths.map((_, i) => i), remainingIndices: [] };\n }\n\n const scrollLeft = container.scrollLeft;\n const viewportWidth = container.clientWidth;\n const controlWidth = controls.show ? controls.width : 0;\n\n const visibleIndices: number[] = [];\n const remainingIndices: number[] = [];\n let offset = 0;\n\n for (let i = 0; i < canvasWidths.length; i++) {\n const chunkLeft = offset + controlWidth + clipPixelOffset;\n const chunkRight = chunkLeft + canvasWidths[i];\n if (chunkRight > scrollLeft && chunkLeft < scrollLeft + viewportWidth) {\n visibleIndices.push(i);\n } else {\n remainingIndices.push(i);\n }\n offset += canvasWidths[i];\n }\n\n return { visibleIndices, remainingIndices };\n };\n\n const renderChunkSubset = async (\n api: SpectrogramWorkerApi,\n cacheKey: string,\n channelInfo: { canvasIds: string[]; canvasWidths: number[] },\n indices: number[],\n item: { config: SpectrogramConfig; colorMap: ColorMapValue },\n channelIndex: number,\n ) => {\n if (indices.length === 0) return;\n\n const canvasIds = indices.map(i => channelInfo.canvasIds[i]);\n const canvasWidths = indices.map(i => channelInfo.canvasWidths[i]);\n\n const globalPixelOffsets: number[] = [];\n for (const idx of indices) {\n let offset = 0;\n for (let j = 0; j < idx; j++) {\n offset += channelInfo.canvasWidths[j];\n }\n globalPixelOffsets.push(offset);\n }\n\n const colorLUT = getColorMap(item.colorMap);\n\n await api.renderChunks({\n cacheKey,\n canvasIds,\n canvasWidths,\n globalPixelOffsets,\n canvasHeight: waveHeight,\n devicePixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio : 1,\n samplesPerPixel,\n colorLUT,\n frequencyScale: item.config.frequencyScale ?? 'mel',\n minFrequency: item.config.minFrequency ?? 0,\n maxFrequency: item.config.maxFrequency ?? 0,\n gainDb: item.config.gainDb ?? 20,\n rangeDb: item.config.rangeDb ?? 80,\n channelIndex,\n });\n };\n\n const computeAsync = async () => {\n const abortToken = { aborted: false };\n backgroundRenderAbortRef.current = abortToken;\n\n for (const item of clipsNeedingFFT) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n try {\n const clipCanvasInfo = spectrogramCanvasRegistryRef.current.get(item.clipId);\n if (clipCanvasInfo && clipCanvasInfo.size > 0) {\n const numChannels = item.monoFlag ? 1 : item.channelDataArrays.length;\n const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);\n\n const container = scrollContainerRef.current;\n const windowSize = item.config.fftSize ?? 2048;\n let visibleRange: { start: number; end: number } | undefined;\n\n if (container) {\n const scrollLeft = container.scrollLeft;\n const viewportWidth = container.clientWidth;\n const controlWidth = controls.show ? controls.width : 0;\n\n const vpStartPx = Math.max(0, scrollLeft - controlWidth);\n const vpEndPx = vpStartPx + viewportWidth;\n\n const clipStartPx = clipPixelOffset;\n const clipEndPx = clipStartPx + Math.ceil(item.durationSamples / samplesPerPixel);\n\n const overlapStartPx = Math.max(vpStartPx, clipStartPx);\n const overlapEndPx = Math.min(vpEndPx, clipEndPx);\n\n if (overlapEndPx > overlapStartPx) {\n const localStartPx = overlapStartPx - clipStartPx;\n const localEndPx = overlapEndPx - clipStartPx;\n const visStartSample = item.offsetSamples + Math.floor(localStartPx * samplesPerPixel);\n const visEndSample = Math.min(\n item.offsetSamples + item.durationSamples,\n item.offsetSamples + Math.ceil(localEndPx * samplesPerPixel)\n );\n const paddedStart = Math.max(item.offsetSamples, visStartSample - windowSize);\n const paddedEnd = Math.min(item.offsetSamples + item.durationSamples, visEndSample + windowSize);\n\n if ((paddedEnd - paddedStart) < item.durationSamples * 0.8) {\n visibleRange = { start: paddedStart, end: paddedEnd };\n }\n }\n }\n\n const fullClipAlreadyCached = clipCacheKeysRef.current.has(item.clipId);\n if (visibleRange && !fullClipAlreadyCached) {\n const { cacheKey: visibleCacheKey } = await workerApi!.computeFFT({\n clipId: item.clipId,\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n sampleRange: visibleRange,\n });\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n for (let ch = 0; ch < numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n await renderChunkSubset(workerApi!, visibleCacheKey, channelInfo, visibleIndices, item, ch);\n }\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n }\n\n const { cacheKey } = await workerApi!.computeFFT({\n clipId: item.clipId,\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n clipCacheKeysRef.current.set(item.clipId, cacheKey);\n\n for (let ch = 0; ch < numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, visibleIndices, item, ch);\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const BATCH_SIZE = 4;\n for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);\n\n await new Promise<void>(resolve => {\n if (typeof requestIdleCallback === 'function') {\n requestIdleCallback(() => resolve());\n } else {\n setTimeout(resolve, 0);\n }\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, batch, item, ch);\n }\n }\n } else {\n const spectrograms = await workerApi!.compute({\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n });\n\n if (spectrogramGenerationRef.current !== generation) return;\n\n setSpectrogramDataMap(prevMap => {\n const newMap = new Map(prevMap);\n newMap.set(item.clipId, spectrograms);\n return newMap;\n });\n }\n } catch (err) {\n console.warn('Spectrogram worker error for clip', item.clipId, err);\n }\n }\n\n for (const item of clipsNeedingDisplayOnly) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const cacheKey = clipCacheKeysRef.current.get(item.clipId);\n if (!cacheKey) continue;\n\n const clipCanvasInfo = spectrogramCanvasRegistryRef.current.get(item.clipId);\n if (!clipCanvasInfo || clipCanvasInfo.size === 0) continue;\n\n try {\n const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);\n for (let ch = 0; ch < item.numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, visibleIndices, item, ch);\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const BATCH_SIZE = 4;\n for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);\n\n await new Promise<void>(resolve => {\n if (typeof requestIdleCallback === 'function') {\n requestIdleCallback(() => resolve());\n } else {\n setTimeout(resolve, 0);\n }\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, batch, item, ch);\n }\n }\n } catch (err) {\n console.warn('Spectrogram display re-render error for clip', item.clipId, err);\n }\n }\n };\n\n computeAsync().catch(err => {\n console.error('[waveform-playlist] Spectrogram computation failed:', err);\n });\n }, [tracks, mono, spectrogramConfig, spectrogramColorMap, trackSpectrogramOverrides, waveHeight, samplesPerPixel, spectrogramCanvasVersion, controls, scrollContainerRef]);\n\n // Setters\n const setTrackRenderMode = useCallback((trackId: string, mode: RenderMode) => {\n setTrackSpectrogramOverrides(prev => {\n const next = new Map(prev);\n const existing = next.get(trackId);\n next.set(trackId, { ...existing, renderMode: mode });\n return next;\n });\n }, []);\n\n const setTrackSpectrogramConfig = useCallback((trackId: string, config: SpectrogramConfig, colorMap?: ColorMapValue) => {\n setTrackSpectrogramOverrides(prev => {\n const next = new Map(prev);\n const existing = next.get(trackId);\n next.set(trackId, {\n renderMode: existing?.renderMode ?? 'waveform',\n config,\n ...(colorMap !== undefined ? { colorMap } : { colorMap: existing?.colorMap }),\n });\n return next;\n });\n }, []);\n\n const registerSpectrogramCanvases = useCallback((clipId: string, channelIndex: number, canvasIds: string[], canvasWidths: number[]) => {\n const registry = spectrogramCanvasRegistryRef.current;\n if (!registry.has(clipId)) {\n registry.set(clipId, new Map());\n }\n registry.get(clipId)!.set(channelIndex, { canvasIds, canvasWidths });\n setSpectrogramCanvasVersion(v => v + 1);\n }, []);\n\n const unregisterSpectrogramCanvases = useCallback((clipId: string, channelIndex: number) => {\n const registry = spectrogramCanvasRegistryRef.current;\n const clipChannels = registry.get(clipId);\n if (clipChannels) {\n clipChannels.delete(channelIndex);\n if (clipChannels.size === 0) {\n registry.delete(clipId);\n }\n }\n }, []);\n\n const renderMenuItems = useCallback((props: { renderMode: string; onRenderModeChange: (mode: RenderMode) => void; onOpenSettings: () => void; onClose?: () => void }) => {\n return SpectrogramMenuItems({\n renderMode: props.renderMode as RenderMode,\n onRenderModeChange: props.onRenderModeChange,\n onOpenSettings: props.onOpenSettings,\n onClose: props.onClose,\n });\n }, []);\n\n const value: SpectrogramIntegration = useMemo(() => ({\n spectrogramDataMap,\n trackSpectrogramOverrides,\n spectrogramWorkerApi: spectrogramWorkerReady ? spectrogramWorkerRef.current : null,\n spectrogramConfig,\n spectrogramColorMap,\n setTrackRenderMode,\n setTrackSpectrogramConfig,\n registerSpectrogramCanvases,\n unregisterSpectrogramCanvases,\n renderMenuItems,\n SettingsModal: SpectrogramSettingsModal,\n getColorMap,\n getFrequencyScale: getFrequencyScale as (name: string) => (f: number, minF: number, maxF: number) => number,\n }), [\n spectrogramDataMap,\n trackSpectrogramOverrides,\n spectrogramWorkerReady,\n spectrogramConfig,\n spectrogramColorMap,\n setTrackRenderMode,\n setTrackSpectrogramConfig,\n registerSpectrogramCanvases,\n unregisterSpectrogramCanvases,\n renderMenuItems,\n ]);\n\n return (\n <SpectrogramIntegrationProvider value={value}>\n {children}\n </SpectrogramIntegrationProvider>\n );\n};\n"],"mappings":"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AAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC1G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACzG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAC9G,CAAC;AAGD,IAAM,YAAY,IAAI,WAAW;AAAA,EAC/B;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,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EACvE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACzF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAC9F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EACvG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACxG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAChH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACrH,CAAC;AAGD,IAAM,cAAc,IAAI,WAAW;AAAA,EACjC;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,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EACxE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAC7E;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACvF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EACxF;AAAA,EAAI;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACjG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACzG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACrG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EACrG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACxG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACrH,CAAC;AAGD,IAAM,aAAa,IAAI,WAAW;AAAA,EAChC;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,EACrE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAChF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACzF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAClG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EACxG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAClH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA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","names":["window","window","styled","jsx","jsxs","useState","useEffect","useRef","jsx","useState","useRef","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/computation/fft.ts","../src/computation/windowFunctions.ts","../src/computation/computeSpectrogram.ts","../src/computation/colorMaps.ts","../src/computation/frequencyScales.ts","../src/components/SpectrogramMenuItems.tsx","../src/components/SpectrogramSettingsModal.tsx","../src/worker/createSpectrogramWorker.ts","../src/SpectrogramProvider.tsx"],"sourcesContent":["import FFT from 'fft.js';\n\n/**\n * Cache fft.js instances per size (pre-computes twiddle factors).\n */\nconst fftInstances = new Map<number, FFT>();\nconst complexBuffers = new Map<number, number[]>();\n\nfunction getFftInstance(size: number): FFT {\n let instance = fftInstances.get(size);\n if (!instance) {\n instance = new FFT(size);\n fftInstances.set(size, instance);\n complexBuffers.set(size, instance.createComplexArray());\n }\n return instance;\n}\n\nfunction getComplexBuffer(size: number): number[] {\n const buffer = complexBuffers.get(size);\n if (!buffer) {\n throw new Error(`No complex buffer for size ${size}. Call getFftInstance first.`);\n }\n return buffer;\n}\n\n/**\n * In-place FFT using fft.js (radix-4).\n * @param real - Real part (modified in place)\n * @param imag - Imaginary part (modified in place)\n */\nexport function fft(real: Float32Array, imag: Float32Array): void {\n const n = real.length;\n const f = getFftInstance(n);\n const input = f.createComplexArray();\n const out = getComplexBuffer(n);\n\n for (let i = 0; i < n; i++) {\n input[i * 2] = real[i];\n input[i * 2 + 1] = imag[i];\n }\n\n f.transform(out, input);\n\n for (let i = 0; i < n; i++) {\n real[i] = out[i * 2];\n imag[i] = out[i * 2 + 1];\n }\n}\n\n/**\n * Fused FFT → magnitude → decibels for real-valued input.\n * Uses fft.js realTransform (radix-4, ~25% faster for real input).\n * Writes dB values for positive frequencies (n/2 bins) into `out`.\n *\n * @param real - Real input (windowed audio frame, length n)\n * @param out - Output array for dB values (length >= n/2)\n */\nexport function fftMagnitudeDb(real: Float32Array, out: Float32Array): void {\n const n = real.length;\n const f = getFftInstance(n);\n const complexOut = getComplexBuffer(n);\n\n f.realTransform(complexOut, real);\n\n const half = n >> 1;\n for (let i = 0; i < half; i++) {\n const re = complexOut[i * 2];\n const im = complexOut[i * 2 + 1];\n let db = 20 * Math.log10(Math.sqrt(re * re + im * im) + 1e-10);\n if (db < -160) db = -160;\n out[i] = db;\n }\n}\n\n/**\n * Compute magnitude spectrum from FFT output.\n * Returns only the first half (positive frequencies).\n */\nexport function magnitudeSpectrum(real: Float32Array, imag: Float32Array): Float32Array {\n const n = real.length >> 1;\n const magnitudes = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n magnitudes[i] = Math.sqrt(real[i] * real[i] + imag[i] * imag[i]);\n }\n return magnitudes;\n}\n\n/**\n * Convert magnitudes to decibels with a fixed -160 dB floor.\n * Gain is applied at render time, not during FFT.\n */\nexport function toDecibels(magnitudes: Float32Array): Float32Array {\n const result = new Float32Array(magnitudes.length);\n for (let i = 0; i < magnitudes.length; i++) {\n let db = 20 * Math.log10(magnitudes[i] + 1e-10);\n if (db < -160) db = -160;\n result[i] = db;\n }\n return result;\n}\n","/**\n * Window functions for spectral analysis.\n */\n\nexport function getWindowFunction(\n name: string,\n size: number,\n alpha?: number\n): Float32Array {\n const window = new Float32Array(size);\n const N = size;\n\n switch (name) {\n case 'rectangular':\n for (let i = 0; i < size; i++) window[i] = 1;\n break;\n\n case 'bartlett':\n for (let i = 0; i < size; i++) {\n window[i] = 1 - Math.abs((2 * i - N) / N);\n }\n break;\n\n case 'hann':\n for (let i = 0; i < size; i++) {\n window[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / N));\n }\n break;\n\n case 'hamming':\n for (let i = 0; i < size; i++) {\n const a = alpha ?? 0.54;\n window[i] = a - (1 - a) * Math.cos((2 * Math.PI * i) / N);\n }\n break;\n\n case 'blackman': {\n const a0 = 0.42;\n const a1 = 0.5;\n const a2 = 0.08;\n for (let i = 0; i < size; i++) {\n window[i] =\n a0 -\n a1 * Math.cos((2 * Math.PI * i) / N) +\n a2 * Math.cos((4 * Math.PI * i) / N);\n }\n break;\n }\n\n case 'blackman-harris': {\n const c0 = 0.35875;\n const c1 = 0.48829;\n const c2 = 0.14128;\n const c3 = 0.01168;\n for (let i = 0; i < size; i++) {\n window[i] =\n c0 -\n c1 * Math.cos((2 * Math.PI * i) / N) +\n c2 * Math.cos((4 * Math.PI * i) / N) -\n c3 * Math.cos((6 * Math.PI * i) / N);\n }\n break;\n }\n\n default:\n console.warn(`[spectrogram] Unknown window function \"${name}\", falling back to hann`);\n for (let i = 0; i < size; i++) {\n window[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / N));\n }\n }\n\n // Amplitude normalization: scale so a 0 dB sine produces a 0 dB spectrum peak.\n // Matches Audacity: scale = 2.0 / sum(window)\n let sum = 0;\n for (let i = 0; i < size; i++) sum += window[i];\n if (sum > 0) {\n const scale = 2.0 / sum;\n for (let i = 0; i < size; i++) window[i] *= scale;\n }\n\n return window;\n}\n","/**\n * Compute spectrogram data from an AudioBuffer.\n */\n\nimport type { SpectrogramConfig, SpectrogramData } from '@waveform-playlist/core';\nimport { fftMagnitudeDb } from './fft';\nimport { getWindowFunction } from './windowFunctions';\n\n/**\n * Compute spectrogram for a single channel of audio.\n *\n * @param audioBuffer - Source audio buffer\n * @param config - Spectrogram configuration\n * @param offsetSamples - Start offset into the audio buffer\n * @param durationSamples - Number of samples to process\n * @param channel - Channel index (0 = left, 1 = right). Default: 0\n */\nexport function computeSpectrogram(\n audioBuffer: AudioBuffer,\n config: SpectrogramConfig = {},\n offsetSamples: number = 0,\n durationSamples?: number,\n channel: number = 0\n): SpectrogramData {\n const windowSize = config.fftSize ?? 2048;\n const zeroPaddingFactor = config.zeroPaddingFactor ?? 2;\n const actualFftSize = windowSize * zeroPaddingFactor;\n const hopSize = config.hopSize ?? Math.floor(windowSize / 4);\n const windowName = config.windowFunction ?? 'hann';\n const gainDb = config.gainDb ?? 20;\n const rangeDb = config.rangeDb ?? 80;\n const alpha = config.alpha;\n\n const sampleRate = audioBuffer.sampleRate;\n const frequencyBinCount = actualFftSize >> 1;\n const totalSamples = durationSamples ?? (audioBuffer.length - offsetSamples);\n\n // Get channel data\n const channelIdx = Math.min(channel, audioBuffer.numberOfChannels - 1);\n const channelData = audioBuffer.getChannelData(channelIdx);\n\n // Pre-compute window (at windowSize, not actualFftSize)\n const window = getWindowFunction(windowName, windowSize, alpha);\n\n // Calculate frame count (step by windowSize, not actualFftSize)\n const frameCount = Math.max(1, Math.floor((totalSamples - windowSize) / hopSize) + 1);\n\n // Output: frameCount × frequencyBinCount\n const data = new Float32Array(frameCount * frequencyBinCount);\n\n // Reusable buffers at actualFftSize\n const real = new Float32Array(actualFftSize);\n const dbBuf = new Float32Array(frequencyBinCount);\n\n for (let frame = 0; frame < frameCount; frame++) {\n const start = offsetSamples + frame * hopSize;\n\n // Fill first windowSize samples with windowed audio, rest stays zero\n for (let i = 0; i < windowSize; i++) {\n const sampleIdx = start + i;\n real[i] = sampleIdx < channelData.length ? channelData[sampleIdx] * window[i] : 0;\n }\n // Zero-pad the rest\n for (let i = windowSize; i < actualFftSize; i++) {\n real[i] = 0;\n }\n\n fftMagnitudeDb(real, dbBuf);\n data.set(dbBuf, frame * frequencyBinCount);\n }\n\n return {\n fftSize: actualFftSize,\n windowSize,\n frequencyBinCount,\n sampleRate,\n hopSize,\n frameCount,\n data,\n gainDb,\n rangeDb,\n };\n}\n\n/**\n * Compute a mono (mixed-down) spectrogram from all channels.\n */\nexport function computeSpectrogramMono(\n audioBuffer: AudioBuffer,\n config: SpectrogramConfig = {},\n offsetSamples: number = 0,\n durationSamples?: number\n): SpectrogramData {\n if (audioBuffer.numberOfChannels === 1) {\n return computeSpectrogram(audioBuffer, config, offsetSamples, durationSamples, 0);\n }\n\n // Mix down channels\n const windowSize = config.fftSize ?? 2048;\n const zeroPaddingFactor = config.zeroPaddingFactor ?? 2;\n const actualFftSize = windowSize * zeroPaddingFactor;\n const hopSize = config.hopSize ?? Math.floor(windowSize / 4);\n const windowName = config.windowFunction ?? 'hann';\n const gainDb = config.gainDb ?? 20;\n const rangeDb = config.rangeDb ?? 80;\n const alpha = config.alpha;\n\n const sampleRate = audioBuffer.sampleRate;\n const frequencyBinCount = actualFftSize >> 1;\n const totalSamples = durationSamples ?? (audioBuffer.length - offsetSamples);\n const numChannels = audioBuffer.numberOfChannels;\n\n const window = getWindowFunction(windowName, windowSize, alpha);\n const frameCount = Math.max(1, Math.floor((totalSamples - windowSize) / hopSize) + 1);\n const data = new Float32Array(frameCount * frequencyBinCount);\n const real = new Float32Array(actualFftSize);\n const dbBuf = new Float32Array(frequencyBinCount);\n\n // Get all channel data\n const channels: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(audioBuffer.getChannelData(ch));\n }\n\n for (let frame = 0; frame < frameCount; frame++) {\n const start = offsetSamples + frame * hopSize;\n\n // Mix channels and apply window\n for (let i = 0; i < windowSize; i++) {\n const sampleIdx = start + i;\n let sum = 0;\n for (let ch = 0; ch < numChannels; ch++) {\n sum += sampleIdx < channels[ch].length ? channels[ch][sampleIdx] : 0;\n }\n real[i] = (sum / numChannels) * window[i];\n }\n // Zero-pad the rest\n for (let i = windowSize; i < actualFftSize; i++) {\n real[i] = 0;\n }\n\n fftMagnitudeDb(real, dbBuf);\n data.set(dbBuf, frame * frequencyBinCount);\n }\n\n return {\n fftSize: actualFftSize,\n windowSize,\n frequencyBinCount,\n sampleRate,\n hopSize,\n frameCount,\n data,\n gainDb,\n rangeDb,\n };\n}\n","/**\n * Color maps for spectrogram rendering.\n * Each map is a 256-entry RGB lookup table (768 bytes).\n *\n * Viridis, Magma, Inferno: Perceptually uniform colormaps from matplotlib.\n * By Stéfan van der Walt, Nathaniel Smith, and Eric Firing. Released under CC0.\n * Data from https://github.com/BIDS/colormap\n *\n * Roseus: Perceptually uniform colormap from https://github.com/dofuuz/roseus\n * By dofuuz, licensed under CC0 1.0 Universal.\n */\n\nimport type { ColorMapValue } from '@waveform-playlist/core';\n\n// Pre-computed 256-entry LUT: Uint8Array of length 768 (256 * 3 RGB)\ntype ColorLUT = Uint8Array;\n\nfunction interpolateLUT(stops: number[][]): ColorLUT {\n const lut = new Uint8Array(256 * 3);\n const n = stops.length;\n for (let i = 0; i < 256; i++) {\n const t = i / 255;\n const pos = t * (n - 1);\n const lo = Math.floor(pos);\n const hi = Math.min(lo + 1, n - 1);\n const frac = pos - lo;\n lut[i * 3] = Math.round(stops[lo][0] * (1 - frac) + stops[hi][0] * frac);\n lut[i * 3 + 1] = Math.round(stops[lo][1] * (1 - frac) + stops[hi][1] * frac);\n lut[i * 3 + 2] = Math.round(stops[lo][2] * (1 - frac) + stops[hi][2] * frac);\n }\n return lut;\n}\n\n// prettier-ignore\nconst VIRIDIS_LUT = new Uint8Array([\n 68, 1, 84, 68, 2, 86, 69, 4, 87, 69, 5, 89, 70, 7, 90, 70, 8, 92, 70, 10, 93, 70, 11, 94,\n 71, 13, 96, 71, 14, 97, 71, 16, 99, 71, 17, 100, 71, 19, 101, 72, 20, 103, 72, 22, 104, 72, 23, 105,\n 72, 24, 106, 72, 26, 108, 72, 27, 109, 72, 28, 110, 72, 29, 111, 72, 31, 112, 72, 32, 113, 72, 33, 115,\n 72, 35, 116, 72, 36, 117, 72, 37, 118, 72, 38, 119, 72, 40, 120, 72, 41, 121, 71, 42, 122, 71, 44, 122,\n 71, 45, 123, 71, 46, 124, 71, 47, 125, 70, 48, 126, 70, 50, 126, 70, 51, 127, 70, 52, 128, 69, 53, 129,\n 69, 55, 129, 69, 56, 130, 68, 57, 131, 68, 58, 131, 68, 59, 132, 67, 61, 132, 67, 62, 133, 66, 63, 133,\n 66, 64, 134, 66, 65, 134, 65, 66, 135, 65, 68, 135, 64, 69, 136, 64, 70, 136, 63, 71, 136, 63, 72, 137,\n 62, 73, 137, 62, 74, 137, 62, 76, 138, 61, 77, 138, 61, 78, 138, 60, 79, 138, 60, 80, 139, 59, 81, 139,\n 59, 82, 139, 58, 83, 139, 58, 84, 140, 57, 85, 140, 57, 86, 140, 56, 88, 140, 56, 89, 140, 55, 90, 140,\n 55, 91, 141, 54, 92, 141, 54, 93, 141, 53, 94, 141, 53, 95, 141, 52, 96, 141, 52, 97, 141, 51, 98, 141,\n 51, 99, 141, 50, 100, 142, 50, 101, 142, 49, 102, 142, 49, 103, 142, 49, 104, 142, 48, 105, 142, 48, 106, 142,\n 47, 107, 142, 47, 108, 142, 46, 109, 142, 46, 110, 142, 46, 111, 142, 45, 112, 142, 45, 113, 142, 44, 113, 142,\n 44, 114, 142, 44, 115, 142, 43, 116, 142, 43, 117, 142, 42, 118, 142, 42, 119, 142, 42, 120, 142, 41, 121, 142,\n 41, 122, 142, 41, 123, 142, 40, 124, 142, 40, 125, 142, 39, 126, 142, 39, 127, 142, 39, 128, 142, 38, 129, 142,\n 38, 130, 142, 38, 130, 142, 37, 131, 142, 37, 132, 142, 37, 133, 142, 36, 134, 142, 36, 135, 142, 35, 136, 142,\n 35, 137, 142, 35, 138, 141, 34, 139, 141, 34, 140, 141, 34, 141, 141, 33, 142, 141, 33, 143, 141, 33, 144, 141,\n 33, 145, 140, 32, 146, 140, 32, 146, 140, 32, 147, 140, 31, 148, 140, 31, 149, 139, 31, 150, 139, 31, 151, 139,\n 31, 152, 139, 31, 153, 138, 31, 154, 138, 30, 155, 138, 30, 156, 137, 30, 157, 137, 31, 158, 137, 31, 159, 136,\n 31, 160, 136, 31, 161, 136, 31, 161, 135, 31, 162, 135, 32, 163, 134, 32, 164, 134, 33, 165, 133, 33, 166, 133,\n 34, 167, 133, 34, 168, 132, 35, 169, 131, 36, 170, 131, 37, 171, 130, 37, 172, 130, 38, 173, 129, 39, 173, 129,\n 40, 174, 128, 41, 175, 127, 42, 176, 127, 44, 177, 126, 45, 178, 125, 46, 179, 124, 47, 180, 124, 49, 181, 123,\n 50, 182, 122, 52, 182, 121, 53, 183, 121, 55, 184, 120, 56, 185, 119, 58, 186, 118, 59, 187, 117, 61, 188, 116,\n 63, 188, 115, 64, 189, 114, 66, 190, 113, 68, 191, 112, 70, 192, 111, 72, 193, 110, 74, 193, 109, 76, 194, 108,\n 78, 195, 107, 80, 196, 106, 82, 197, 105, 84, 197, 104, 86, 198, 103, 88, 199, 101, 90, 200, 100, 92, 200, 99,\n 94, 201, 98, 96, 202, 96, 99, 203, 95, 101, 203, 94, 103, 204, 92, 105, 205, 91, 108, 205, 90, 110, 206, 88,\n 112, 207, 87, 115, 208, 86, 117, 208, 84, 119, 209, 83, 122, 209, 81, 124, 210, 80, 127, 211, 78, 129, 211, 77,\n 132, 212, 75, 134, 213, 73, 137, 213, 72, 139, 214, 70, 142, 214, 69, 144, 215, 67, 147, 215, 65, 149, 216, 64,\n 152, 216, 62, 155, 217, 60, 157, 217, 59, 160, 218, 57, 162, 218, 55, 165, 219, 54, 168, 219, 52, 170, 220, 50,\n 173, 220, 48, 176, 221, 47, 178, 221, 45, 181, 222, 43, 184, 222, 41, 186, 222, 40, 189, 223, 38, 192, 223, 37,\n 194, 223, 35, 197, 224, 33, 200, 224, 32, 202, 225, 31, 205, 225, 29, 208, 225, 28, 210, 226, 27, 213, 226, 26,\n 216, 226, 25, 218, 227, 25, 221, 227, 24, 223, 227, 24, 226, 228, 24, 229, 228, 25, 231, 228, 25, 234, 229, 26,\n 236, 229, 27, 239, 229, 28, 241, 229, 29, 244, 230, 30, 246, 230, 32, 248, 230, 33, 251, 231, 35, 253, 231, 37,\n]);\n\n// prettier-ignore\nconst MAGMA_LUT = new Uint8Array([\n 0, 0, 4, 1, 0, 5, 1, 1, 6, 1, 1, 8, 2, 1, 9, 2, 2, 11, 2, 2, 13, 3, 3, 15,\n 3, 3, 18, 4, 4, 20, 5, 4, 22, 6, 5, 24, 6, 5, 26, 7, 6, 28, 8, 7, 30, 9, 7, 32,\n 10, 8, 34, 11, 9, 36, 12, 9, 38, 13, 10, 41, 14, 11, 43, 16, 11, 45, 17, 12, 47, 18, 13, 49,\n 19, 13, 52, 20, 14, 54, 21, 14, 56, 22, 15, 59, 24, 15, 61, 25, 16, 63, 26, 16, 66, 28, 16, 68,\n 29, 17, 71, 30, 17, 73, 32, 17, 75, 33, 17, 78, 34, 17, 80, 36, 18, 83, 37, 18, 85, 39, 18, 88,\n 41, 17, 90, 42, 17, 92, 44, 17, 95, 45, 17, 97, 47, 17, 99, 49, 17, 101, 51, 16, 103, 52, 16, 105,\n 54, 16, 107, 56, 16, 108, 57, 15, 110, 59, 15, 112, 61, 15, 113, 63, 15, 114, 64, 15, 116, 66, 15, 117,\n 68, 15, 118, 69, 16, 119, 71, 16, 120, 73, 16, 120, 74, 16, 121, 76, 17, 122, 78, 17, 123, 79, 18, 123,\n 81, 18, 124, 82, 19, 124, 84, 19, 125, 86, 20, 125, 87, 21, 126, 89, 21, 126, 90, 22, 126, 92, 22, 127,\n 93, 23, 127, 95, 24, 127, 96, 24, 128, 98, 25, 128, 100, 26, 128, 101, 26, 128, 103, 27, 128, 104, 28, 129,\n 106, 28, 129, 107, 29, 129, 109, 29, 129, 110, 30, 129, 112, 31, 129, 114, 31, 129, 115, 32, 129, 117, 33, 129,\n 118, 33, 129, 120, 34, 129, 121, 34, 130, 123, 35, 130, 124, 35, 130, 126, 36, 130, 128, 37, 130, 129, 37, 129,\n 131, 38, 129, 132, 38, 129, 134, 39, 129, 136, 39, 129, 137, 40, 129, 139, 41, 129, 140, 41, 129, 142, 42, 129,\n 144, 42, 129, 145, 43, 129, 147, 43, 128, 148, 44, 128, 150, 44, 128, 152, 45, 128, 153, 45, 128, 155, 46, 127,\n 156, 46, 127, 158, 47, 127, 160, 47, 127, 161, 48, 126, 163, 48, 126, 165, 49, 126, 166, 49, 125, 168, 50, 125,\n 170, 51, 125, 171, 51, 124, 173, 52, 124, 174, 52, 123, 176, 53, 123, 178, 53, 123, 179, 54, 122, 181, 54, 122,\n 183, 55, 121, 184, 55, 121, 186, 56, 120, 188, 57, 120, 189, 57, 119, 191, 58, 119, 192, 58, 118, 194, 59, 117,\n 196, 60, 117, 197, 60, 116, 199, 61, 115, 200, 62, 115, 202, 62, 114, 204, 63, 113, 205, 64, 113, 207, 64, 112,\n 208, 65, 111, 210, 66, 111, 211, 67, 110, 213, 68, 109, 214, 69, 108, 216, 69, 108, 217, 70, 107, 219, 71, 106,\n 220, 72, 105, 222, 73, 104, 223, 74, 104, 224, 76, 103, 226, 77, 102, 227, 78, 101, 228, 79, 100, 229, 80, 100,\n 231, 82, 99, 232, 83, 98, 233, 84, 98, 234, 86, 97, 235, 87, 96, 236, 88, 96, 237, 90, 95, 238, 91, 94,\n 239, 93, 94, 240, 95, 94, 241, 96, 93, 242, 98, 93, 242, 100, 92, 243, 101, 92, 244, 103, 92, 244, 105, 92,\n 245, 107, 92, 246, 108, 92, 246, 110, 92, 247, 112, 92, 247, 114, 92, 248, 116, 92, 248, 118, 92, 249, 120, 93,\n 249, 121, 93, 249, 123, 93, 250, 125, 94, 250, 127, 94, 250, 129, 95, 251, 131, 95, 251, 133, 96, 251, 135, 97,\n 252, 137, 97, 252, 138, 98, 252, 140, 99, 252, 142, 100, 252, 144, 101, 253, 146, 102, 253, 148, 103, 253, 150, 104,\n 253, 152, 105, 253, 154, 106, 253, 155, 107, 254, 157, 108, 254, 159, 109, 254, 161, 110, 254, 163, 111, 254, 165, 113,\n 254, 167, 114, 254, 169, 115, 254, 170, 116, 254, 172, 118, 254, 174, 119, 254, 176, 120, 254, 178, 122, 254, 180, 123,\n 254, 182, 124, 254, 183, 126, 254, 185, 127, 254, 187, 129, 254, 189, 130, 254, 191, 132, 254, 193, 133, 254, 194, 135,\n 254, 196, 136, 254, 198, 138, 254, 200, 140, 254, 202, 141, 254, 204, 143, 254, 205, 144, 254, 207, 146, 254, 209, 148,\n 254, 211, 149, 254, 213, 151, 254, 215, 153, 254, 216, 154, 253, 218, 156, 253, 220, 158, 253, 222, 160, 253, 224, 161,\n 253, 226, 163, 253, 227, 165, 253, 229, 167, 253, 231, 169, 253, 233, 170, 253, 235, 172, 252, 236, 174, 252, 238, 176,\n 252, 240, 178, 252, 242, 180, 252, 244, 182, 252, 246, 184, 252, 247, 185, 252, 249, 187, 252, 251, 189, 252, 253, 191,\n]);\n\n// prettier-ignore\nconst INFERNO_LUT = new Uint8Array([\n 0, 0, 4, 1, 0, 5, 1, 1, 6, 1, 1, 8, 2, 1, 10, 2, 2, 12, 2, 2, 14, 3, 2, 16,\n 4, 3, 18, 4, 3, 20, 5, 4, 23, 6, 4, 25, 7, 5, 27, 8, 5, 29, 9, 6, 31, 10, 7, 34,\n 11, 7, 36, 12, 8, 38, 13, 8, 41, 14, 9, 43, 16, 9, 45, 17, 10, 48, 18, 10, 50, 20, 11, 52,\n 21, 11, 55, 22, 11, 57, 24, 12, 60, 25, 12, 62, 27, 12, 65, 28, 12, 67, 30, 12, 69, 31, 12, 72,\n 33, 12, 74, 35, 12, 76, 36, 12, 79, 38, 12, 81, 40, 11, 83, 41, 11, 85, 43, 11, 87, 45, 11, 89,\n 47, 10, 91, 49, 10, 92, 50, 10, 94, 52, 10, 95, 54, 9, 97, 56, 9, 98, 57, 9, 99, 59, 9, 100,\n 61, 9, 101, 62, 9, 102, 64, 10, 103, 66, 10, 104, 68, 10, 104, 69, 10, 105, 71, 11, 106, 73, 11, 106,\n 74, 12, 107, 76, 12, 107, 77, 13, 108, 79, 13, 108, 81, 14, 108, 82, 14, 109, 84, 15, 109, 85, 15, 109,\n 87, 16, 110, 89, 16, 110, 90, 17, 110, 92, 18, 110, 93, 18, 110, 95, 19, 110, 97, 19, 110, 98, 20, 110,\n 100, 21, 110, 101, 21, 110, 103, 22, 110, 105, 22, 110, 106, 23, 110, 108, 24, 110, 109, 24, 110, 111, 25, 110,\n 113, 25, 110, 114, 26, 110, 116, 26, 110, 117, 27, 110, 119, 28, 109, 120, 28, 109, 122, 29, 109, 124, 29, 109,\n 125, 30, 109, 127, 30, 108, 128, 31, 108, 130, 32, 108, 132, 32, 107, 133, 33, 107, 135, 33, 107, 136, 34, 106,\n 138, 34, 106, 140, 35, 105, 141, 35, 105, 143, 36, 105, 144, 37, 104, 146, 37, 104, 147, 38, 103, 149, 38, 103,\n 151, 39, 102, 152, 39, 102, 154, 40, 101, 155, 41, 100, 157, 41, 100, 159, 42, 99, 160, 42, 99, 162, 43, 98,\n 163, 44, 97, 165, 44, 96, 166, 45, 96, 168, 46, 95, 169, 46, 94, 171, 47, 94, 173, 48, 93, 174, 48, 92,\n 176, 49, 91, 177, 50, 90, 179, 50, 90, 180, 51, 89, 182, 52, 88, 183, 53, 87, 185, 53, 86, 186, 54, 85,\n 188, 55, 84, 189, 56, 83, 191, 57, 82, 192, 58, 81, 193, 58, 80, 195, 59, 79, 196, 60, 78, 198, 61, 77,\n 199, 62, 76, 200, 63, 75, 202, 64, 74, 203, 65, 73, 204, 66, 72, 206, 67, 71, 207, 68, 70, 208, 69, 69,\n 210, 70, 68, 211, 71, 67, 212, 72, 66, 213, 74, 65, 215, 75, 63, 216, 76, 62, 217, 77, 61, 218, 78, 60,\n 219, 80, 59, 221, 81, 58, 222, 82, 56, 223, 83, 55, 224, 85, 54, 225, 86, 53, 226, 87, 52, 227, 89, 51,\n 228, 90, 49, 229, 92, 48, 230, 93, 47, 231, 94, 46, 232, 96, 45, 233, 97, 43, 234, 99, 42, 235, 100, 41,\n 235, 102, 40, 236, 103, 38, 237, 105, 37, 238, 106, 36, 239, 108, 35, 239, 110, 33, 240, 111, 32, 241, 113, 31,\n 241, 115, 29, 242, 116, 28, 243, 118, 27, 243, 120, 25, 244, 121, 24, 245, 123, 23, 245, 125, 21, 246, 126, 20,\n 246, 128, 19, 247, 130, 18, 247, 132, 16, 248, 133, 15, 248, 135, 14, 248, 137, 12, 249, 139, 11, 249, 140, 10,\n 249, 142, 9, 250, 144, 8, 250, 146, 7, 250, 148, 7, 251, 150, 6, 251, 151, 6, 251, 153, 6, 251, 155, 6,\n 251, 157, 7, 252, 159, 7, 252, 161, 8, 252, 163, 9, 252, 165, 10, 252, 166, 12, 252, 168, 13, 252, 170, 15,\n 252, 172, 17, 252, 174, 18, 252, 176, 20, 252, 178, 22, 252, 180, 24, 251, 182, 26, 251, 184, 29, 251, 186, 31,\n 251, 188, 33, 251, 190, 35, 250, 192, 38, 250, 194, 40, 250, 196, 42, 250, 198, 45, 249, 199, 47, 249, 201, 50,\n 249, 203, 53, 248, 205, 55, 248, 207, 58, 247, 209, 61, 247, 211, 64, 246, 213, 67, 246, 215, 70, 245, 217, 73,\n 245, 219, 76, 244, 221, 79, 244, 223, 83, 244, 225, 86, 243, 227, 90, 243, 229, 93, 242, 230, 97, 242, 232, 101,\n 242, 234, 105, 241, 236, 109, 241, 237, 113, 241, 239, 117, 241, 241, 121, 242, 242, 125, 242, 244, 130, 243, 245, 134,\n 243, 246, 138, 244, 248, 142, 245, 249, 146, 246, 250, 150, 248, 251, 154, 249, 252, 157, 250, 253, 161, 252, 255, 164,\n]);\n\n// prettier-ignore\nconst ROSEUS_LUT = new Uint8Array([\n 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 3, 4, 2, 4, 5, 2, 5, 6, 3, 6, 7,\n 3, 7, 8, 3, 8, 10, 3, 9, 12, 3, 10, 14, 3, 12, 16, 3, 13, 17, 3, 14, 19, 2, 15, 21,\n 2, 16, 23, 2, 17, 25, 2, 18, 27, 2, 19, 30, 1, 20, 32, 1, 21, 34, 1, 22, 36, 1, 23, 38,\n 1, 24, 40, 0, 25, 43, 0, 26, 45, 0, 27, 47, 0, 27, 50, 0, 28, 52, 0, 29, 54, 0, 30, 57,\n 0, 30, 59, 1, 31, 62, 1, 32, 64, 1, 32, 67, 2, 33, 69, 3, 33, 72, 4, 34, 74, 5, 35, 77,\n 6, 35, 79, 8, 35, 82, 9, 36, 84, 11, 36, 86, 13, 37, 89, 15, 37, 91, 17, 37, 94, 19, 37, 96,\n 21, 38, 99, 23, 38, 101, 25, 38, 104, 27, 38, 106, 29, 38, 108, 31, 38, 111, 33, 38, 113, 35, 38, 115,\n 38, 38, 118, 40, 38, 120, 42, 38, 122, 44, 38, 124, 46, 38, 126, 49, 38, 128, 51, 38, 130, 53, 37, 132,\n 55, 37, 134, 58, 37, 136, 60, 36, 138, 62, 36, 139, 65, 36, 141, 67, 35, 143, 69, 35, 144, 72, 35, 146,\n 74, 34, 147, 76, 34, 149, 79, 33, 150, 81, 33, 151, 84, 32, 152, 86, 32, 153, 88, 31, 154, 91, 31, 155,\n 93, 30, 156, 95, 29, 157, 98, 29, 158, 100, 28, 159, 103, 28, 159, 105, 27, 160, 107, 27, 160, 110, 26, 161,\n 112, 26, 161, 114, 25, 161, 117, 25, 162, 119, 24, 162, 121, 24, 162, 124, 23, 162, 126, 23, 162, 128, 23, 162,\n 131, 22, 161, 133, 22, 161, 135, 22, 161, 137, 22, 161, 140, 22, 160, 142, 22, 160, 144, 22, 159, 146, 22, 159,\n 148, 22, 158, 150, 22, 157, 153, 22, 157, 155, 23, 156, 157, 23, 155, 159, 23, 154, 161, 24, 153, 163, 24, 152,\n 165, 25, 151, 167, 26, 150, 169, 26, 149, 171, 27, 148, 173, 28, 147, 175, 29, 146, 177, 29, 145, 179, 30, 144,\n 181, 31, 142, 183, 32, 141, 184, 33, 140, 186, 34, 139, 188, 35, 137, 190, 36, 136, 192, 37, 135, 193, 39, 133,\n 195, 40, 132, 197, 41, 130, 198, 42, 129, 200, 43, 128, 202, 45, 126, 203, 46, 125, 205, 47, 123, 206, 48, 122,\n 208, 50, 120, 209, 51, 119, 211, 52, 117, 212, 54, 116, 214, 55, 114, 215, 57, 113, 217, 58, 111, 218, 60, 110,\n 219, 61, 109, 221, 63, 107, 222, 64, 106, 223, 66, 104, 225, 67, 103, 226, 69, 101, 227, 70, 100, 228, 72, 99,\n 229, 73, 97, 230, 75, 96, 231, 77, 94, 233, 78, 93, 234, 80, 92, 235, 82, 91, 236, 83, 89, 237, 85, 88,\n 237, 87, 87, 238, 89, 86, 239, 90, 84, 240, 92, 83, 241, 94, 82, 242, 96, 81, 242, 97, 80, 243, 99, 79,\n 244, 101, 78, 245, 103, 77, 245, 105, 76, 246, 107, 75, 246, 108, 74, 247, 110, 74, 248, 112, 73, 248, 114, 72,\n 248, 116, 72, 249, 118, 71, 249, 120, 71, 250, 122, 70, 250, 124, 70, 250, 126, 70, 251, 128, 70, 251, 130, 69,\n 251, 132, 70, 251, 134, 70, 251, 136, 70, 252, 138, 70, 252, 140, 70, 252, 142, 71, 252, 144, 72, 252, 146, 72,\n 252, 148, 73, 252, 150, 74, 251, 152, 75, 251, 154, 76, 251, 156, 77, 251, 158, 78, 251, 160, 80, 251, 162, 81,\n 250, 164, 83, 250, 166, 85, 250, 168, 87, 249, 170, 88, 249, 172, 90, 248, 174, 93, 248, 176, 95, 248, 178, 97,\n 247, 180, 99, 247, 182, 102, 246, 184, 104, 246, 186, 107, 245, 188, 110, 244, 190, 112, 244, 192, 115, 243, 194, 118,\n 243, 195, 121, 242, 197, 124, 242, 199, 127, 241, 201, 131, 240, 203, 134, 240, 205, 137, 239, 207, 140, 239, 208, 144,\n 238, 210, 147, 238, 212, 151, 237, 213, 154, 237, 215, 158, 236, 217, 161, 236, 218, 165, 236, 220, 169, 236, 222, 172,\n 235, 223, 176, 235, 225, 180, 235, 226, 183, 235, 228, 187, 235, 229, 191, 235, 230, 194, 236, 232, 198, 236, 233, 201,\n 236, 234, 205, 237, 236, 208, 237, 237, 212, 238, 238, 215, 239, 239, 219, 240, 240, 222, 241, 242, 225, 242, 243, 228,\n 243, 244, 231, 244, 245, 234, 246, 246, 237, 247, 247, 240, 249, 248, 242, 251, 249, 245, 253, 250, 247, 254, 251, 249,\n]);\n\nconst lutCache = new Map<string, ColorLUT>();\n\nfunction grayscaleLUT(): ColorLUT {\n let lut = lutCache.get('grayscale');\n if (!lut) {\n lut = new Uint8Array(256 * 3);\n for (let i = 0; i < 256; i++) {\n lut[i * 3] = lut[i * 3 + 1] = lut[i * 3 + 2] = i;\n }\n lutCache.set('grayscale', lut);\n }\n return lut;\n}\n\nfunction igrayLUT(): ColorLUT {\n let lut = lutCache.get('igray');\n if (!lut) {\n lut = new Uint8Array(256 * 3);\n for (let i = 0; i < 256; i++) {\n const v = 255 - i;\n lut[i * 3] = lut[i * 3 + 1] = lut[i * 3 + 2] = v;\n }\n lutCache.set('igray', lut);\n }\n return lut;\n}\n\n/**\n * Get a 256-entry RGB LUT for the given color map.\n */\nexport function getColorMap(value: ColorMapValue): ColorLUT {\n if (Array.isArray(value)) {\n return interpolateLUT(value);\n }\n\n switch (value) {\n case 'viridis': return VIRIDIS_LUT;\n case 'magma': return MAGMA_LUT;\n case 'inferno': return INFERNO_LUT;\n case 'roseus': return ROSEUS_LUT;\n case 'grayscale': return grayscaleLUT();\n case 'igray': return igrayLUT();\n default: return VIRIDIS_LUT;\n }\n}\n","/**\n * Frequency scale mapping functions.\n * Each maps a frequency (Hz) to a normalized position [0, 1].\n */\n\nfunction linearScale(f: number, minF: number, maxF: number): number {\n if (maxF === minF) return 0;\n return (f - minF) / (maxF - minF);\n}\n\nfunction logarithmicScale(f: number, minF: number, maxF: number): number {\n const logMin = Math.log2(Math.max(minF, 1));\n const logMax = Math.log2(maxF);\n if (logMax === logMin) return 0;\n return (Math.log2(Math.max(f, 1)) - logMin) / (logMax - logMin);\n}\n\nfunction hzToMel(f: number): number {\n return 2595 * Math.log10(1 + f / 700);\n}\n\nfunction melScale(f: number, minF: number, maxF: number): number {\n const melMin = hzToMel(minF);\n const melMax = hzToMel(maxF);\n if (melMax === melMin) return 0;\n return (hzToMel(f) - melMin) / (melMax - melMin);\n}\n\nfunction hzToBark(f: number): number {\n return 13 * Math.atan(0.00076 * f) + 3.5 * Math.atan((f / 7500) ** 2);\n}\n\nfunction barkScale(f: number, minF: number, maxF: number): number {\n const barkMin = hzToBark(minF);\n const barkMax = hzToBark(maxF);\n if (barkMax === barkMin) return 0;\n return (hzToBark(f) - barkMin) / (barkMax - barkMin);\n}\n\nfunction hzToErb(f: number): number {\n return 21.4 * Math.log10(1 + 0.00437 * f);\n}\n\nfunction erbScale(f: number, minF: number, maxF: number): number {\n const erbMin = hzToErb(minF);\n const erbMax = hzToErb(maxF);\n if (erbMax === erbMin) return 0;\n return (hzToErb(f) - erbMin) / (erbMax - erbMin);\n}\n\nexport type FrequencyScaleName = 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb';\n\n/**\n * Returns a mapping function: (frequencyHz, minFrequency, maxFrequency) → [0, 1]\n */\nexport function getFrequencyScale(\n name: FrequencyScaleName\n): (f: number, minF: number, maxF: number) => number {\n switch (name) {\n case 'logarithmic': return logarithmicScale;\n case 'mel': return melScale;\n case 'bark': return barkScale;\n case 'erb': return erbScale;\n case 'linear':\n return linearScale;\n default:\n console.warn(`[spectrogram] Unknown frequency scale \"${name}\", falling back to linear`);\n return linearScale;\n }\n}\n","import React from 'react';\nimport styled from 'styled-components';\nimport type { RenderMode } from '@waveform-playlist/core';\nimport type { TrackMenuItem } from './types';\n\nconst SectionLabel = styled.div`\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n opacity: 0.5;\n margin-bottom: 0.25rem;\n`;\n\nconst RadioLabel = styled.label`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.2rem 0;\n font-size: 0.8rem;\n cursor: pointer;\n\n &:hover {\n opacity: 0.8;\n }\n`;\n\nconst SettingsButton = styled.button`\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n font-size: 0.8rem;\n padding: 0.35rem 0.75rem;\n width: 100%;\n text-align: left;\n\n &:hover {\n background: rgba(128, 128, 128, 0.15);\n }\n`;\n\nconst DropdownSection = styled.div`\n padding: 0.25rem 0.75rem;\n`;\n\nconst RENDER_MODES: { value: RenderMode; label: string }[] = [\n { value: 'waveform', label: 'Waveform' },\n { value: 'spectrogram', label: 'Spectrogram' },\n { value: 'both', label: 'Both' },\n];\n\nexport interface SpectrogramMenuItemsProps {\n renderMode: RenderMode;\n onRenderModeChange: (mode: RenderMode) => void;\n onOpenSettings: () => void;\n onClose?: () => void;\n}\n\n/**\n * Returns TrackMenuItem[] for the spectrogram display mode radios and settings button.\n */\nexport function SpectrogramMenuItems({\n renderMode,\n onRenderModeChange,\n onOpenSettings,\n onClose,\n}: SpectrogramMenuItemsProps): TrackMenuItem[] {\n return [\n {\n id: 'spectrogram-display',\n label: 'Display',\n content: (\n <DropdownSection>\n <SectionLabel>Display</SectionLabel>\n {RENDER_MODES.map(({ value, label }) => (\n <RadioLabel key={value}>\n <input\n type=\"radio\"\n name=\"render-mode\"\n checked={renderMode === value}\n onChange={() => { onRenderModeChange(value); onClose?.(); }}\n />\n {label}\n </RadioLabel>\n ))}\n </DropdownSection>\n ),\n },\n {\n id: 'spectrogram-settings',\n content: (\n <SettingsButton\n onClick={(e) => {\n e.stopPropagation();\n onClose?.();\n onOpenSettings();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n Spectrogram Settings...\n </SettingsButton>\n ),\n },\n ];\n}\n","import React, { useRef, useEffect, useState } from 'react';\nimport styled from 'styled-components';\nimport type { SpectrogramConfig, ColorMapValue, ColorMapName, FFTSize } from '@waveform-playlist/core';\n\nexport interface SpectrogramSettingsModalProps {\n open: boolean;\n onClose: () => void;\n config: SpectrogramConfig;\n colorMap: ColorMapValue;\n onApply: (config: SpectrogramConfig, colorMap: ColorMapValue) => void;\n}\n\nconst StyledDialog = styled.dialog`\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 8px;\n padding: 1.5rem;\n background: ${p => p.theme.timescaleBackgroundColor ?? '#222'};\n color: ${p => p.theme.textColor ?? 'inherit'};\n min-width: 380px;\n max-width: 500px;\n\n &::backdrop {\n background: rgba(0, 0, 0, 0.5);\n }\n`;\n\nconst Title = styled.h3`\n margin: 0 0 1rem;\n font-size: 1rem;\n`;\n\nconst FormGrid = styled.div`\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0.75rem;\n`;\n\nconst Field = styled.div<{ $span?: boolean }>`\n display: flex;\n flex-direction: column;\n gap: 0.2rem;\n grid-column: ${p => p.$span ? '1 / -1' : 'auto'};\n`;\n\nconst Label = styled.label`\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n opacity: 0.6;\n`;\n\nconst Select = styled.select`\n padding: 0.3rem 0.4rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n background: rgba(128, 128, 128, 0.15);\n color: inherit;\n font-size: 0.85rem;\n`;\n\nconst NumberInput = styled.input`\n padding: 0.3rem 0.4rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n background: rgba(128, 128, 128, 0.15);\n color: inherit;\n font-size: 0.85rem;\n width: 100%;\n box-sizing: border-box;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.85rem;\n cursor: pointer;\n`;\n\nconst ButtonRow = styled.div`\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 1.25rem;\n`;\n\nconst ModalButton = styled.button<{ $primary?: boolean }>`\n padding: 0.4rem 1rem;\n border: 1px solid rgba(128, 128, 128, 0.4);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.85rem;\n background: ${p => p.$primary ? 'var(--ifm-color-primary, #4a9)' : 'transparent'};\n color: ${p => p.$primary ? '#fff' : 'inherit'};\n\n &:hover {\n opacity: 0.85;\n }\n`;\n\nconst FFT_SIZES = [256, 512, 1024, 2048, 4096, 8192];\nconst WINDOW_FUNCTIONS = ['hann', 'hamming', 'blackman', 'blackman-harris', 'bartlett', 'rectangular'] as const;\nconst FREQ_SCALES = ['linear', 'logarithmic', 'mel', 'bark', 'erb'] as const;\nconst COLOR_MAPS: ColorMapName[] = ['viridis', 'magma', 'inferno', 'grayscale', 'igray', 'roseus'];\n\nexport const SpectrogramSettingsModal: React.FC<SpectrogramSettingsModalProps> = ({\n open,\n onClose,\n config,\n colorMap,\n onApply,\n}) => {\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n // Local form state\n const [fftSize, setFftSize] = useState(config.fftSize ?? 2048);\n const [windowFn, setWindowFn] = useState(config.windowFunction ?? 'hann');\n const [freqScale, setFreqScale] = useState(config.frequencyScale ?? 'mel');\n const [localColorMap, setLocalColorMap] = useState<ColorMapName>(\n typeof colorMap === 'string' ? colorMap : 'viridis'\n );\n const [minFreq, setMinFreq] = useState(config.minFrequency ?? 0);\n const [maxFreq, setMaxFreq] = useState(config.maxFrequency ?? 20000);\n const [gainDb, setGainDb] = useState(config.gainDb ?? 20);\n const [rangeDb, setRangeDb] = useState(config.rangeDb ?? 80);\n const [zeroPadding, setZeroPadding] = useState(config.zeroPaddingFactor ?? 2);\n const [hopSize, setHopSize] = useState(config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4));\n const [showLabels, setShowLabels] = useState(config.labels ?? false);\n\n // Sync local state when props change\n useEffect(() => {\n setFftSize(config.fftSize ?? 2048);\n setWindowFn(config.windowFunction ?? 'hann');\n setFreqScale(config.frequencyScale ?? 'mel');\n setLocalColorMap(typeof colorMap === 'string' ? colorMap : 'viridis');\n setMinFreq(config.minFrequency ?? 0);\n setMaxFreq(config.maxFrequency ?? 20000);\n setGainDb(config.gainDb ?? 20);\n setRangeDb(config.rangeDb ?? 80);\n setZeroPadding(config.zeroPaddingFactor ?? 2);\n setHopSize(config.hopSize ?? Math.floor((config.fftSize ?? 2048) / 4));\n setShowLabels(config.labels ?? false);\n }, [config, colorMap]);\n\n // Open/close dialog + handle native close (Escape key)\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (open && !dialog.open) {\n dialog.showModal();\n } else if (!open && dialog.open) {\n dialog.close();\n }\n\n const handleClose = () => {\n // Only call onClose if dialog was open (avoids double-fire)\n if (open) {\n onClose();\n }\n };\n dialog.addEventListener('close', handleClose);\n return () => dialog.removeEventListener('close', handleClose);\n }, [open, onClose]);\n\n const handleApply = () => {\n onApply(\n {\n fftSize,\n windowFunction: windowFn as SpectrogramConfig['windowFunction'],\n frequencyScale: freqScale as SpectrogramConfig['frequencyScale'],\n minFrequency: minFreq,\n maxFrequency: maxFreq,\n gainDb,\n rangeDb,\n zeroPaddingFactor: zeroPadding,\n hopSize,\n labels: showLabels,\n },\n localColorMap\n );\n onClose();\n };\n\n return (\n <StyledDialog ref={dialogRef}>\n <Title>Spectrogram Settings</Title>\n <FormGrid>\n <Field>\n <Label>FFT Size</Label>\n <Select value={fftSize} onChange={e => { const v = Number(e.target.value) as FFTSize; setFftSize(v); setHopSize(Math.floor(v / 4)); }}>\n {FFT_SIZES.map(s => <option key={s} value={s}>{s}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Hop Size</Label>\n <Select value={hopSize} onChange={e => setHopSize(Number(e.target.value))}>\n {[\n { label: `${fftSize} (no overlap)`, value: fftSize },\n { label: `${Math.floor(fftSize / 2)} (50%)`, value: Math.floor(fftSize / 2) },\n { label: `${Math.floor(fftSize / 4)} (75%)`, value: Math.floor(fftSize / 4) },\n { label: `${Math.floor(fftSize / 8)} (87.5%)`, value: Math.floor(fftSize / 8) },\n ].map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Zero Padding</Label>\n <Select value={zeroPadding} onChange={e => setZeroPadding(Number(e.target.value))}>\n {[1, 2, 4, 8, 16].map(v => <option key={v} value={v}>{v}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Window Function</Label>\n <Select value={windowFn} onChange={e => setWindowFn(e.target.value as typeof windowFn)}>\n {WINDOW_FUNCTIONS.map(w => <option key={w} value={w}>{w}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Frequency Scale</Label>\n <Select value={freqScale} onChange={e => setFreqScale(e.target.value as typeof freqScale)}>\n {FREQ_SCALES.map(s => <option key={s} value={s}>{s}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Color Map</Label>\n <Select value={localColorMap} onChange={e => setLocalColorMap(e.target.value as ColorMapName)}>\n {COLOR_MAPS.map(c => <option key={c} value={c}>{c}</option>)}\n </Select>\n </Field>\n\n <Field>\n <Label>Min Frequency (Hz)</Label>\n <NumberInput type=\"number\" min={0} max={5000} step={50} value={minFreq}\n onChange={e => setMinFreq(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Max Frequency (Hz)</Label>\n <NumberInput type=\"number\" min={1000} max={22050} step={50} value={maxFreq}\n onChange={e => setMaxFreq(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Range (dB)</Label>\n <NumberInput type=\"number\" min={1} max={120} step={1} value={rangeDb}\n onChange={e => setRangeDb(Number(e.target.value))} />\n </Field>\n\n <Field>\n <Label>Gain (dB)</Label>\n <NumberInput type=\"number\" min={-20} max={60} step={1} value={gainDb}\n onChange={e => setGainDb(Number(e.target.value))} />\n </Field>\n\n <Field $span>\n <CheckboxLabel>\n <input type=\"checkbox\" checked={showLabels} onChange={e => setShowLabels(e.target.checked)} />\n Show Frequency Labels\n </CheckboxLabel>\n </Field>\n </FormGrid>\n\n <ButtonRow>\n <ModalButton onClick={onClose}>Cancel</ModalButton>\n <ModalButton $primary onClick={handleApply}>Apply</ModalButton>\n </ButtonRow>\n </StyledDialog>\n );\n};\n","import type { SpectrogramConfig, SpectrogramData } from '@waveform-playlist/core';\n\nexport interface SpectrogramWorkerComputeParams {\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n mono: boolean;\n}\n\nexport interface SpectrogramWorkerRenderParams extends SpectrogramWorkerComputeParams {\n render: {\n canvasIds: string[][];\n canvasWidths: number[];\n canvasHeight: number;\n devicePixelRatio: number;\n samplesPerPixel: number;\n colorLUT: Uint8Array;\n frequencyScale: string;\n minFrequency: number;\n maxFrequency: number;\n };\n}\n\nexport interface SpectrogramWorkerFFTParams {\n clipId: string;\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n mono: boolean;\n sampleRange?: { start: number; end: number };\n}\n\nexport interface SpectrogramWorkerRenderChunksParams {\n cacheKey: string;\n canvasIds: string[];\n canvasWidths: number[];\n globalPixelOffsets: number[];\n canvasHeight: number;\n devicePixelRatio: number;\n samplesPerPixel: number;\n colorLUT: Uint8Array;\n frequencyScale: string;\n minFrequency: number;\n maxFrequency: number;\n gainDb: number;\n rangeDb: number;\n channelIndex: number;\n}\n\ntype ComputeResponse =\n | { id: string; type: 'spectrograms'; spectrograms: SpectrogramData[] }\n | { id: string; type: 'cache-key'; cacheKey: string }\n | { id: string; type: 'done' }\n | { id: string; type: 'error'; error: string };\n\n/** Union of all values that worker resolve callbacks receive. */\ntype PendingResolveValue = SpectrogramData[] | { cacheKey: string } | void;\n\ninterface PendingEntry {\n resolve: (value: PendingResolveValue) => void;\n reject: (reason: unknown) => void;\n}\n\n/** Add a pending promise entry, centralizing the single unavoidable resolve cast. */\nfunction addPending<T>(\n map: Map<string, PendingEntry>,\n id: string,\n resolve: (value: T) => void,\n reject: (reason: unknown) => void,\n): void {\n map.set(id, { resolve: resolve as PendingEntry['resolve'], reject });\n}\n\nexport interface SpectrogramWorkerApi {\n compute(params: SpectrogramWorkerComputeParams): Promise<SpectrogramData[]>;\n computeFFT(params: SpectrogramWorkerFFTParams): Promise<{ cacheKey: string }>;\n renderChunks(params: SpectrogramWorkerRenderChunksParams): Promise<void>;\n registerCanvas(canvasId: string, canvas: OffscreenCanvas): void;\n unregisterCanvas(canvasId: string): void;\n registerAudioData(clipId: string, channelDataArrays: Float32Array[], sampleRate: number): void;\n unregisterAudioData(clipId: string): void;\n computeAndRender(params: SpectrogramWorkerRenderParams): Promise<void>;\n terminate(): void;\n}\n\nlet idCounter = 0;\n\n/**\n * Wraps a Web Worker running `spectrogram.worker.ts` with a promise-based API.\n *\n * The caller is responsible for creating the Worker, e.g.:\n * ```ts\n * const worker = new Worker(\n * new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n * { type: 'module' }\n * );\n * const api = createSpectrogramWorker(worker);\n * ```\n */\nexport function createSpectrogramWorker(worker: Worker): SpectrogramWorkerApi {\n const pending = new Map<string, PendingEntry>();\n\n // Track which clipIds have pre-registered audio data in the worker\n const registeredClipIds = new Set<string>();\n let terminated = false;\n\n worker.onmessage = (e: MessageEvent<ComputeResponse>) => {\n const msg = e.data;\n const entry = pending.get(msg.id);\n if (entry) {\n pending.delete(msg.id);\n switch (msg.type) {\n case 'error':\n entry.reject(new Error(msg.error));\n break;\n case 'cache-key':\n entry.resolve({ cacheKey: msg.cacheKey });\n break;\n case 'done':\n entry.resolve(undefined);\n break;\n case 'spectrograms':\n entry.resolve(msg.spectrograms);\n break;\n }\n } else if (msg.id) {\n console.warn(`[spectrogram] Received response for unknown message ID: ${msg.id}`);\n }\n };\n\n worker.onerror = (e: ErrorEvent) => {\n terminated = true;\n for (const [, entry] of pending) {\n entry.reject(e.error ?? new Error(e.message));\n }\n pending.clear();\n };\n\n return {\n compute(params: SpectrogramWorkerComputeParams): Promise<SpectrogramData[]> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<SpectrogramData[]>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n // Slice channel data so we can transfer without detaching the original AudioBuffer views\n const transferableArrays = params.channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n id,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n },\n transferables,\n );\n });\n },\n\n computeFFT(params: SpectrogramWorkerFFTParams): Promise<{ cacheKey: string }> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<{ cacheKey: string }>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n // Skip transfer if audio data is pre-registered in the worker\n const isPreRegistered = registeredClipIds.has(params.clipId);\n const transferableArrays = isPreRegistered ? [] : params.channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n type: 'compute-fft',\n id,\n clipId: params.clipId,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n ...(params.sampleRange ? { sampleRange: params.sampleRange } : {}),\n },\n transferables,\n );\n });\n },\n\n renderChunks(params: SpectrogramWorkerRenderChunksParams): Promise<void> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<void>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n worker.postMessage({\n type: 'render-chunks',\n id,\n cacheKey: params.cacheKey,\n canvasIds: params.canvasIds,\n canvasWidths: params.canvasWidths,\n globalPixelOffsets: params.globalPixelOffsets,\n canvasHeight: params.canvasHeight,\n devicePixelRatio: params.devicePixelRatio,\n samplesPerPixel: params.samplesPerPixel,\n colorLUT: params.colorLUT,\n frequencyScale: params.frequencyScale,\n minFrequency: params.minFrequency,\n maxFrequency: params.maxFrequency,\n gainDb: params.gainDb,\n rangeDb: params.rangeDb,\n channelIndex: params.channelIndex,\n });\n });\n },\n\n registerCanvas(canvasId: string, canvas: OffscreenCanvas): void {\n worker.postMessage(\n { type: 'register-canvas', canvasId, canvas },\n [canvas],\n );\n },\n\n unregisterCanvas(canvasId: string): void {\n worker.postMessage({ type: 'unregister-canvas', canvasId });\n },\n\n registerAudioData(clipId: string, channelDataArrays: Float32Array[], sampleRate: number): void {\n const transferableArrays = channelDataArrays.map(arr => arr.slice());\n const transferables = transferableArrays.map(arr => arr.buffer);\n worker.postMessage(\n { type: 'register-audio-data', clipId, channelDataArrays: transferableArrays, sampleRate },\n transferables,\n );\n registeredClipIds.add(clipId);\n },\n\n unregisterAudioData(clipId: string): void {\n worker.postMessage({ type: 'unregister-audio-data', clipId });\n registeredClipIds.delete(clipId);\n },\n\n computeAndRender(params: SpectrogramWorkerRenderParams): Promise<void> {\n if (terminated) return Promise.reject(new Error('Worker terminated'));\n const id = String(++idCounter);\n\n return new Promise<void>((resolve, reject) => {\n addPending(pending, id, resolve, reject);\n\n const transferableArrays = params.channelDataArrays.map(arr => arr.slice());\n const transferables: Transferable[] = transferableArrays.map(arr => arr.buffer);\n\n worker.postMessage(\n {\n type: 'compute-render',\n id,\n channelDataArrays: transferableArrays,\n config: params.config,\n sampleRate: params.sampleRate,\n offsetSamples: params.offsetSamples,\n durationSamples: params.durationSamples,\n mono: params.mono,\n render: params.render,\n },\n transferables,\n );\n });\n },\n\n terminate() {\n terminated = true;\n worker.terminate();\n for (const [, entry] of pending) {\n entry.reject(new Error('Worker terminated'));\n }\n pending.clear();\n },\n };\n}\n","import React, { useState, useEffect, useRef, useCallback, useMemo, type ReactNode } from 'react';\nimport type { SpectrogramData, SpectrogramConfig, SpectrogramComputeConfig, ColorMapValue, RenderMode, TrackSpectrogramOverrides } from '@waveform-playlist/core';\nimport { computeSpectrogram, computeSpectrogramMono, getColorMap, getFrequencyScale } from './computation';\nimport { createSpectrogramWorker, type SpectrogramWorkerApi } from './worker';\nimport { SpectrogramMenuItems } from './components';\nimport { SpectrogramSettingsModal } from './components';\nimport { SpectrogramIntegrationProvider, type SpectrogramIntegration } from '@waveform-playlist/browser';\nimport { usePlaylistData, usePlaylistControls } from '@waveform-playlist/browser';\n\nexport interface SpectrogramProviderProps {\n config?: SpectrogramConfig;\n colorMap?: ColorMapValue;\n children: ReactNode;\n}\n\nexport const SpectrogramProvider: React.FC<SpectrogramProviderProps> = ({\n config: spectrogramConfig,\n colorMap: spectrogramColorMap,\n children,\n}) => {\n const {\n tracks,\n waveHeight,\n samplesPerPixel,\n isReady,\n mono,\n controls,\n } = usePlaylistData();\n const { scrollContainerRef } = usePlaylistControls();\n\n // State\n const [spectrogramDataMap, setSpectrogramDataMap] = useState<Map<string, SpectrogramData[]>>(new Map());\n const [trackSpectrogramOverrides, setTrackSpectrogramOverrides] = useState<Map<string, TrackSpectrogramOverrides>>(new Map());\n\n // OffscreenCanvas registry for worker-rendered spectrograms\n const spectrogramCanvasRegistryRef = useRef<Map<string, Map<number, { canvasIds: string[]; canvasWidths: number[] }>>>(new Map());\n const [spectrogramCanvasVersion, setSpectrogramCanvasVersion] = useState(0);\n\n // Spectrogram refs\n const prevSpectrogramConfigRef = useRef<Map<string, string>>(new Map());\n const prevSpectrogramFFTKeyRef = useRef<Map<string, string>>(new Map());\n const spectrogramWorkerRef = useRef<SpectrogramWorkerApi | null>(null);\n const spectrogramGenerationRef = useRef(0);\n const prevCanvasVersionRef = useRef(0);\n const [spectrogramWorkerReady, setSpectrogramWorkerReady] = useState(false);\n const clipCacheKeysRef = useRef<Map<string, string>>(new Map());\n const backgroundRenderAbortRef = useRef<{ aborted: boolean } | null>(null);\n const registeredAudioClipIdsRef = useRef<Set<string>>(new Set());\n\n // Terminate worker on unmount\n useEffect(() => {\n return () => {\n spectrogramWorkerRef.current?.terminate();\n spectrogramWorkerRef.current = null;\n };\n }, []);\n\n // Eagerly transfer audio data to worker when tracks load\n useEffect(() => {\n if (!isReady || tracks.length === 0) return;\n\n let workerApi = spectrogramWorkerRef.current;\n if (!workerApi) {\n try {\n const rawWorker = new Worker(\n new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n { type: 'module' }\n );\n workerApi = createSpectrogramWorker(rawWorker);\n spectrogramWorkerRef.current = workerApi;\n setSpectrogramWorkerReady(true);\n } catch {\n console.warn('Spectrogram Web Worker unavailable for pre-transfer');\n return;\n }\n }\n\n const currentClipIds = new Set<string>();\n\n for (const track of tracks) {\n for (const clip of track.clips) {\n if (!clip.audioBuffer) continue;\n currentClipIds.add(clip.id);\n\n if (!registeredAudioClipIdsRef.current.has(clip.id)) {\n const channelDataArrays: Float32Array[] = [];\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelDataArrays.push(clip.audioBuffer.getChannelData(ch));\n }\n workerApi.registerAudioData(clip.id, channelDataArrays, clip.audioBuffer.sampleRate);\n registeredAudioClipIdsRef.current.add(clip.id);\n }\n }\n }\n\n for (const clipId of registeredAudioClipIdsRef.current) {\n if (!currentClipIds.has(clipId)) {\n workerApi.unregisterAudioData(clipId);\n registeredAudioClipIdsRef.current.delete(clipId);\n }\n }\n }, [isReady, tracks]);\n\n // Main spectrogram computation effect\n useEffect(() => {\n if (tracks.length === 0) return;\n\n const currentKeys = new Map<string, string>();\n const currentFFTKeys = new Map<string, string>();\n tracks.forEach((track) => {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'waveform') return;\n const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig;\n const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap;\n currentKeys.set(track.id, JSON.stringify({ mode, cfg, cm, mono }));\n const computeConfig: SpectrogramComputeConfig = {\n fftSize: cfg?.fftSize, hopSize: cfg?.hopSize,\n windowFunction: cfg?.windowFunction, alpha: cfg?.alpha,\n zeroPaddingFactor: cfg?.zeroPaddingFactor,\n };\n currentFFTKeys.set(track.id, JSON.stringify({ mode, mono, ...computeConfig }));\n });\n\n const prevKeys = prevSpectrogramConfigRef.current;\n const prevFFTKeys = prevSpectrogramFFTKeyRef.current;\n\n let configChanged = currentKeys.size !== prevKeys.size;\n if (!configChanged) {\n for (const [idx, key] of currentKeys) {\n if (prevKeys.get(idx) !== key) { configChanged = true; break; }\n }\n }\n\n let fftKeyChanged = currentFFTKeys.size !== prevFFTKeys.size;\n if (!fftKeyChanged) {\n for (const [idx, key] of currentFFTKeys) {\n if (prevFFTKeys.get(idx) !== key) { fftKeyChanged = true; break; }\n }\n }\n\n const canvasVersionChanged = spectrogramCanvasVersion !== prevCanvasVersionRef.current;\n prevCanvasVersionRef.current = spectrogramCanvasVersion;\n\n if (!configChanged && !canvasVersionChanged) return;\n\n if (configChanged) {\n prevSpectrogramConfigRef.current = currentKeys;\n prevSpectrogramFFTKeyRef.current = currentFFTKeys;\n }\n\n if (configChanged) {\n setSpectrogramDataMap(prevMap => {\n const activeClipIds = new Set<string>();\n for (const track of tracks) {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'spectrogram' || mode === 'both') {\n for (const clip of track.clips) {\n activeClipIds.add(clip.id);\n }\n }\n }\n const newMap = new Map(prevMap);\n for (const clipId of newMap.keys()) {\n if (!activeClipIds.has(clipId)) {\n newMap.delete(clipId);\n }\n }\n return newMap;\n });\n }\n\n if (backgroundRenderAbortRef.current) {\n backgroundRenderAbortRef.current.aborted = true;\n }\n\n const generation = ++spectrogramGenerationRef.current;\n\n let workerApi = spectrogramWorkerRef.current;\n if (!workerApi) {\n try {\n const rawWorker = new Worker(\n new URL('@waveform-playlist/spectrogram/worker/spectrogram.worker', import.meta.url),\n { type: 'module' }\n );\n workerApi = createSpectrogramWorker(rawWorker);\n spectrogramWorkerRef.current = workerApi;\n setSpectrogramWorkerReady(true);\n } catch {\n console.warn('Spectrogram Web Worker unavailable, falling back to synchronous computation');\n }\n }\n\n const clipsNeedingFFT: Array<{\n clipId: string;\n trackIndex: number;\n channelDataArrays: Float32Array[];\n config: SpectrogramConfig;\n sampleRate: number;\n offsetSamples: number;\n durationSamples: number;\n clipStartSample: number;\n monoFlag: boolean;\n colorMap: ColorMapValue;\n }> = [];\n const clipsNeedingDisplayOnly: Array<{\n clipId: string;\n trackIndex: number;\n config: SpectrogramConfig;\n clipStartSample: number;\n monoFlag: boolean;\n colorMap: ColorMapValue;\n numChannels: number;\n }> = [];\n\n tracks.forEach((track, i) => {\n const mode = trackSpectrogramOverrides.get(track.id)?.renderMode ?? track.renderMode ?? 'waveform';\n if (mode === 'waveform') return;\n\n const trackConfigChanged = configChanged && (currentKeys.get(track.id) !== prevKeys.get(track.id));\n const trackFFTChanged = fftKeyChanged && (currentFFTKeys.get(track.id) !== prevFFTKeys.get(track.id));\n const hasRegisteredCanvases = canvasVersionChanged && track.clips.some(\n clip => spectrogramCanvasRegistryRef.current.has(clip.id)\n );\n if (!trackConfigChanged && !hasRegisteredCanvases) return;\n\n const cfg = trackSpectrogramOverrides.get(track.id)?.config ?? track.spectrogramConfig ?? spectrogramConfig ?? {};\n const cm = trackSpectrogramOverrides.get(track.id)?.colorMap ?? track.spectrogramColorMap ?? spectrogramColorMap ?? 'viridis';\n\n for (const clip of track.clips) {\n if (!clip.audioBuffer) continue;\n\n const monoFlag = mono || clip.audioBuffer.numberOfChannels === 1;\n\n if (!trackFFTChanged && !hasRegisteredCanvases && clipCacheKeysRef.current.has(clip.id)) {\n clipsNeedingDisplayOnly.push({\n clipId: clip.id,\n trackIndex: i,\n config: cfg,\n clipStartSample: clip.startSample,\n monoFlag,\n colorMap: cm,\n numChannels: monoFlag ? 1 : clip.audioBuffer.numberOfChannels,\n });\n continue;\n }\n\n const channelDataArrays: Float32Array[] = [];\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelDataArrays.push(clip.audioBuffer.getChannelData(ch));\n }\n\n clipsNeedingFFT.push({\n clipId: clip.id,\n trackIndex: i,\n channelDataArrays,\n config: cfg,\n sampleRate: clip.audioBuffer.sampleRate,\n offsetSamples: clip.offsetSamples,\n durationSamples: clip.durationSamples,\n clipStartSample: clip.startSample,\n monoFlag,\n colorMap: cm,\n });\n }\n });\n\n if (clipsNeedingFFT.length === 0 && clipsNeedingDisplayOnly.length === 0) return;\n\n if (!workerApi) {\n try {\n setSpectrogramDataMap(prevMap => {\n const newMap = new Map(prevMap);\n for (const item of clipsNeedingFFT) {\n const clip = tracks.flatMap(t => t.clips).find(c => c.id === item.clipId);\n if (!clip?.audioBuffer) continue;\n const channelSpectrograms: SpectrogramData[] = [];\n if (item.monoFlag) {\n channelSpectrograms.push(\n computeSpectrogramMono(\n clip.audioBuffer,\n item.config, item.offsetSamples, item.durationSamples\n )\n );\n } else {\n for (let ch = 0; ch < clip.audioBuffer.numberOfChannels; ch++) {\n channelSpectrograms.push(\n computeSpectrogram(clip.audioBuffer, item.config, item.offsetSamples, item.durationSamples, ch)\n );\n }\n }\n newMap.set(item.clipId, channelSpectrograms);\n }\n return newMap;\n });\n } catch (err) {\n console.error('[waveform-playlist] Synchronous spectrogram computation failed:', err);\n }\n return;\n }\n\n const getVisibleChunkRange = (canvasWidths: number[], clipPixelOffset = 0): { visibleIndices: number[]; remainingIndices: number[] } => {\n const container = scrollContainerRef.current;\n if (!container) {\n return { visibleIndices: canvasWidths.map((_, i) => i), remainingIndices: [] };\n }\n\n const scrollLeft = container.scrollLeft;\n const viewportWidth = container.clientWidth;\n const controlWidth = controls.show ? controls.width : 0;\n\n const visibleIndices: number[] = [];\n const remainingIndices: number[] = [];\n let offset = 0;\n\n for (let i = 0; i < canvasWidths.length; i++) {\n const chunkLeft = offset + controlWidth + clipPixelOffset;\n const chunkRight = chunkLeft + canvasWidths[i];\n if (chunkRight > scrollLeft && chunkLeft < scrollLeft + viewportWidth) {\n visibleIndices.push(i);\n } else {\n remainingIndices.push(i);\n }\n offset += canvasWidths[i];\n }\n\n return { visibleIndices, remainingIndices };\n };\n\n const renderChunkSubset = async (\n api: SpectrogramWorkerApi,\n cacheKey: string,\n channelInfo: { canvasIds: string[]; canvasWidths: number[] },\n indices: number[],\n item: { config: SpectrogramConfig; colorMap: ColorMapValue },\n channelIndex: number,\n ) => {\n if (indices.length === 0) return;\n\n const canvasIds = indices.map(i => channelInfo.canvasIds[i]);\n const canvasWidths = indices.map(i => channelInfo.canvasWidths[i]);\n\n const globalPixelOffsets: number[] = [];\n for (const idx of indices) {\n let offset = 0;\n for (let j = 0; j < idx; j++) {\n offset += channelInfo.canvasWidths[j];\n }\n globalPixelOffsets.push(offset);\n }\n\n const colorLUT = getColorMap(item.colorMap);\n\n await api.renderChunks({\n cacheKey,\n canvasIds,\n canvasWidths,\n globalPixelOffsets,\n canvasHeight: waveHeight,\n devicePixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio : 1,\n samplesPerPixel,\n colorLUT,\n frequencyScale: item.config.frequencyScale ?? 'mel',\n minFrequency: item.config.minFrequency ?? 0,\n maxFrequency: item.config.maxFrequency ?? 0,\n gainDb: item.config.gainDb ?? 20,\n rangeDb: item.config.rangeDb ?? 80,\n channelIndex,\n });\n };\n\n const computeAsync = async () => {\n const abortToken = { aborted: false };\n backgroundRenderAbortRef.current = abortToken;\n\n for (const item of clipsNeedingFFT) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n try {\n const clipCanvasInfo = spectrogramCanvasRegistryRef.current.get(item.clipId);\n if (clipCanvasInfo && clipCanvasInfo.size > 0) {\n const numChannels = item.monoFlag ? 1 : item.channelDataArrays.length;\n const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);\n\n const container = scrollContainerRef.current;\n const windowSize = item.config.fftSize ?? 2048;\n let visibleRange: { start: number; end: number } | undefined;\n\n if (container) {\n const scrollLeft = container.scrollLeft;\n const viewportWidth = container.clientWidth;\n const controlWidth = controls.show ? controls.width : 0;\n\n const vpStartPx = Math.max(0, scrollLeft - controlWidth);\n const vpEndPx = vpStartPx + viewportWidth;\n\n const clipStartPx = clipPixelOffset;\n const clipEndPx = clipStartPx + Math.ceil(item.durationSamples / samplesPerPixel);\n\n const overlapStartPx = Math.max(vpStartPx, clipStartPx);\n const overlapEndPx = Math.min(vpEndPx, clipEndPx);\n\n if (overlapEndPx > overlapStartPx) {\n const localStartPx = overlapStartPx - clipStartPx;\n const localEndPx = overlapEndPx - clipStartPx;\n const visStartSample = item.offsetSamples + Math.floor(localStartPx * samplesPerPixel);\n const visEndSample = Math.min(\n item.offsetSamples + item.durationSamples,\n item.offsetSamples + Math.ceil(localEndPx * samplesPerPixel)\n );\n const paddedStart = Math.max(item.offsetSamples, visStartSample - windowSize);\n const paddedEnd = Math.min(item.offsetSamples + item.durationSamples, visEndSample + windowSize);\n\n if ((paddedEnd - paddedStart) < item.durationSamples * 0.8) {\n visibleRange = { start: paddedStart, end: paddedEnd };\n }\n }\n }\n\n const fullClipAlreadyCached = clipCacheKeysRef.current.has(item.clipId);\n if (visibleRange && !fullClipAlreadyCached) {\n const { cacheKey: visibleCacheKey } = await workerApi!.computeFFT({\n clipId: item.clipId,\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n sampleRange: visibleRange,\n });\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n for (let ch = 0; ch < numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n await renderChunkSubset(workerApi!, visibleCacheKey, channelInfo, visibleIndices, item, ch);\n }\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n }\n\n const { cacheKey } = await workerApi!.computeFFT({\n clipId: item.clipId,\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n clipCacheKeysRef.current.set(item.clipId, cacheKey);\n\n for (let ch = 0; ch < numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, visibleIndices, item, ch);\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const BATCH_SIZE = 4;\n for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);\n\n await new Promise<void>(resolve => {\n if (typeof requestIdleCallback === 'function') {\n requestIdleCallback(() => resolve());\n } else {\n setTimeout(resolve, 0);\n }\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, batch, item, ch);\n }\n }\n } else {\n const spectrograms = await workerApi!.compute({\n channelDataArrays: item.channelDataArrays,\n config: item.config,\n sampleRate: item.sampleRate,\n offsetSamples: item.offsetSamples,\n durationSamples: item.durationSamples,\n mono: item.monoFlag,\n });\n\n if (spectrogramGenerationRef.current !== generation) return;\n\n setSpectrogramDataMap(prevMap => {\n const newMap = new Map(prevMap);\n newMap.set(item.clipId, spectrograms);\n return newMap;\n });\n }\n } catch (err) {\n console.warn('Spectrogram worker error for clip', item.clipId, err);\n }\n }\n\n for (const item of clipsNeedingDisplayOnly) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const cacheKey = clipCacheKeysRef.current.get(item.clipId);\n if (!cacheKey) continue;\n\n const clipCanvasInfo = spectrogramCanvasRegistryRef.current.get(item.clipId);\n if (!clipCanvasInfo || clipCanvasInfo.size === 0) continue;\n\n try {\n const clipPixelOffset = Math.floor(item.clipStartSample / samplesPerPixel);\n for (let ch = 0; ch < item.numChannels; ch++) {\n const channelInfo = clipCanvasInfo.get(ch);\n if (!channelInfo) continue;\n\n const { visibleIndices, remainingIndices } = getVisibleChunkRange(channelInfo.canvasWidths, clipPixelOffset);\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, visibleIndices, item, ch);\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const BATCH_SIZE = 4;\n for (let batchStart = 0; batchStart < remainingIndices.length; batchStart += BATCH_SIZE) {\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n const batch = remainingIndices.slice(batchStart, batchStart + BATCH_SIZE);\n\n await new Promise<void>(resolve => {\n if (typeof requestIdleCallback === 'function') {\n requestIdleCallback(() => resolve());\n } else {\n setTimeout(resolve, 0);\n }\n });\n\n if (spectrogramGenerationRef.current !== generation || abortToken.aborted) return;\n\n await renderChunkSubset(workerApi!, cacheKey, channelInfo, batch, item, ch);\n }\n }\n } catch (err) {\n console.warn('Spectrogram display re-render error for clip', item.clipId, err);\n }\n }\n };\n\n computeAsync().catch(err => {\n console.error('[waveform-playlist] Spectrogram computation failed:', err);\n });\n }, [tracks, mono, spectrogramConfig, spectrogramColorMap, trackSpectrogramOverrides, waveHeight, samplesPerPixel, spectrogramCanvasVersion, controls, scrollContainerRef]);\n\n // Setters\n const setTrackRenderMode = useCallback((trackId: string, mode: RenderMode) => {\n setTrackSpectrogramOverrides(prev => {\n const next = new Map(prev);\n const existing = next.get(trackId);\n next.set(trackId, { ...existing, renderMode: mode });\n return next;\n });\n }, []);\n\n const setTrackSpectrogramConfig = useCallback((trackId: string, config: SpectrogramConfig, colorMap?: ColorMapValue) => {\n setTrackSpectrogramOverrides(prev => {\n const next = new Map(prev);\n const existing = next.get(trackId);\n next.set(trackId, {\n renderMode: existing?.renderMode ?? 'waveform',\n config,\n ...(colorMap !== undefined ? { colorMap } : { colorMap: existing?.colorMap }),\n });\n return next;\n });\n }, []);\n\n const registerSpectrogramCanvases = useCallback((clipId: string, channelIndex: number, canvasIds: string[], canvasWidths: number[]) => {\n const registry = spectrogramCanvasRegistryRef.current;\n if (!registry.has(clipId)) {\n registry.set(clipId, new Map());\n }\n registry.get(clipId)!.set(channelIndex, { canvasIds, canvasWidths });\n setSpectrogramCanvasVersion(v => v + 1);\n }, []);\n\n const unregisterSpectrogramCanvases = useCallback((clipId: string, channelIndex: number) => {\n const registry = spectrogramCanvasRegistryRef.current;\n const clipChannels = registry.get(clipId);\n if (clipChannels) {\n clipChannels.delete(channelIndex);\n if (clipChannels.size === 0) {\n registry.delete(clipId);\n }\n }\n }, []);\n\n const renderMenuItems = useCallback((props: { renderMode: string; onRenderModeChange: (mode: RenderMode) => void; onOpenSettings: () => void; onClose?: () => void }) => {\n return SpectrogramMenuItems({\n renderMode: props.renderMode as RenderMode,\n onRenderModeChange: props.onRenderModeChange,\n onOpenSettings: props.onOpenSettings,\n onClose: props.onClose,\n });\n }, []);\n\n const value: SpectrogramIntegration = useMemo(() => ({\n spectrogramDataMap,\n trackSpectrogramOverrides,\n spectrogramWorkerApi: spectrogramWorkerReady ? spectrogramWorkerRef.current : null,\n spectrogramConfig,\n spectrogramColorMap,\n setTrackRenderMode,\n setTrackSpectrogramConfig,\n registerSpectrogramCanvases,\n unregisterSpectrogramCanvases,\n renderMenuItems,\n SettingsModal: SpectrogramSettingsModal,\n getColorMap,\n getFrequencyScale: getFrequencyScale as (name: string) => (f: number, minF: number, maxF: number) => number,\n }), [\n spectrogramDataMap,\n trackSpectrogramOverrides,\n spectrogramWorkerReady,\n spectrogramConfig,\n spectrogramColorMap,\n setTrackRenderMode,\n setTrackSpectrogramConfig,\n registerSpectrogramCanvases,\n unregisterSpectrogramCanvases,\n renderMenuItems,\n ]);\n\n return (\n <SpectrogramIntegrationProvider value={value}>\n {children}\n </SpectrogramIntegrationProvider>\n );\n};\n"],"mappings":"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AAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC1G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAC3G;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACzG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAC9G,CAAC;AAGD,IAAM,YAAY,IAAI,WAAW;AAAA,EAC/B;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,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EACvE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACzF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAC9F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EACvG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACxG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAChH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACrH,CAAC;AAGD,IAAM,cAAc,IAAI,WAAW;AAAA,EACjC;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,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EACxE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAC7E;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACvF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EACxF;AAAA,EAAI;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACjG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACzG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACrG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EACrG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACxG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACrH,CAAC;AAGD,IAAM,aAAa,IAAI,WAAW;AAAA,EAChC;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,EACrE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAChF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EACpF;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACzF;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAClG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EACnG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EACxG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3G;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EACpG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5G;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAClH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACnH;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA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","names":["window","window","styled","jsx","jsxs","useState","useEffect","useRef","jsx","useState","useRef","useEffect"]}
|