wavesurfer.js 7.1.1 → 7.1.3

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.
@@ -1,484 +1 @@
1
- /**
2
- * Spectrogram plugin
3
- *
4
- * Render a spectrogram visualisation of the audio.
5
- *
6
- * @author Pavel Denisov (https://github.com/akreal)
7
- * @see https://github.com/wavesurfer-js/wavesurfer.js/pull/337
8
- *
9
- * @example
10
- * // ... initialising wavesurfer with the plugin
11
- * var wavesurfer = WaveSurfer.create({
12
- * // wavesurfer options ...
13
- * plugins: [
14
- * SpectrogramPlugin.create({
15
- * // plugin options ...
16
- * })
17
- * ]
18
- * });
19
- */
20
- // @ts-nocheck
21
- /**
22
- * Calculate FFT - Based on https://github.com/corbanbrook/dsp.js
23
- *
24
- * @param {Number} bufferSize Buffer size
25
- * @param {Number} sampleRate Sample rate
26
- * @param {Function} windowFunc Window function
27
- * @param {Number} alpha Alpha channel
28
- */
29
- function FFT(bufferSize, sampleRate, windowFunc, alpha) {
30
- this.bufferSize = bufferSize;
31
- this.sampleRate = sampleRate;
32
- this.bandwidth = (2 / bufferSize) * (sampleRate / 2);
33
- this.sinTable = new Float32Array(bufferSize);
34
- this.cosTable = new Float32Array(bufferSize);
35
- this.windowValues = new Float32Array(bufferSize);
36
- this.reverseTable = new Uint32Array(bufferSize);
37
- this.peakBand = 0;
38
- this.peak = 0;
39
- var i;
40
- switch (windowFunc) {
41
- case 'bartlett':
42
- for (i = 0; i < bufferSize; i++) {
43
- this.windowValues[i] = (2 / (bufferSize - 1)) * ((bufferSize - 1) / 2 - Math.abs(i - (bufferSize - 1) / 2));
44
- }
45
- break;
46
- case 'bartlettHann':
47
- for (i = 0; i < bufferSize; i++) {
48
- this.windowValues[i] =
49
- 0.62 - 0.48 * Math.abs(i / (bufferSize - 1) - 0.5) - 0.38 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
50
- }
51
- break;
52
- case 'blackman':
53
- alpha = alpha || 0.16;
54
- for (i = 0; i < bufferSize; i++) {
55
- this.windowValues[i] =
56
- (1 - alpha) / 2 -
57
- 0.5 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1)) +
58
- (alpha / 2) * Math.cos((4 * Math.PI * i) / (bufferSize - 1));
59
- }
60
- break;
61
- case 'cosine':
62
- for (i = 0; i < bufferSize; i++) {
63
- this.windowValues[i] = Math.cos((Math.PI * i) / (bufferSize - 1) - Math.PI / 2);
64
- }
65
- break;
66
- case 'gauss':
67
- alpha = alpha || 0.25;
68
- for (i = 0; i < bufferSize; i++) {
69
- this.windowValues[i] = Math.pow(Math.E, -0.5 * Math.pow((i - (bufferSize - 1) / 2) / ((alpha * (bufferSize - 1)) / 2), 2));
70
- }
71
- break;
72
- case 'hamming':
73
- for (i = 0; i < bufferSize; i++) {
74
- this.windowValues[i] = 0.54 - 0.46 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
75
- }
76
- break;
77
- case 'hann':
78
- case undefined:
79
- for (i = 0; i < bufferSize; i++) {
80
- this.windowValues[i] = 0.5 * (1 - Math.cos((Math.PI * 2 * i) / (bufferSize - 1)));
81
- }
82
- break;
83
- case 'lanczoz':
84
- for (i = 0; i < bufferSize; i++) {
85
- this.windowValues[i] =
86
- Math.sin(Math.PI * ((2 * i) / (bufferSize - 1) - 1)) / (Math.PI * ((2 * i) / (bufferSize - 1) - 1));
87
- }
88
- break;
89
- case 'rectangular':
90
- for (i = 0; i < bufferSize; i++) {
91
- this.windowValues[i] = 1;
92
- }
93
- break;
94
- case 'triangular':
95
- for (i = 0; i < bufferSize; i++) {
96
- this.windowValues[i] = (2 / bufferSize) * (bufferSize / 2 - Math.abs(i - (bufferSize - 1) / 2));
97
- }
98
- break;
99
- default:
100
- throw Error("No such window function '" + windowFunc + "'");
101
- }
102
- var limit = 1;
103
- var bit = bufferSize >> 1;
104
- var i;
105
- while (limit < bufferSize) {
106
- for (i = 0; i < limit; i++) {
107
- this.reverseTable[i + limit] = this.reverseTable[i] + bit;
108
- }
109
- limit = limit << 1;
110
- bit = bit >> 1;
111
- }
112
- for (i = 0; i < bufferSize; i++) {
113
- this.sinTable[i] = Math.sin(-Math.PI / i);
114
- this.cosTable[i] = Math.cos(-Math.PI / i);
115
- }
116
- this.calculateSpectrum = function (buffer) {
117
- // Locally scope variables for speed up
118
- var bufferSize = this.bufferSize, cosTable = this.cosTable, sinTable = this.sinTable, reverseTable = this.reverseTable, real = new Float32Array(bufferSize), imag = new Float32Array(bufferSize), bSi = 2 / this.bufferSize, sqrt = Math.sqrt, rval, ival, mag, spectrum = new Float32Array(bufferSize / 2);
119
- var k = Math.floor(Math.log(bufferSize) / Math.LN2);
120
- if (Math.pow(2, k) !== bufferSize) {
121
- throw 'Invalid buffer size, must be a power of 2.';
122
- }
123
- if (bufferSize !== buffer.length) {
124
- throw ('Supplied buffer is not the same size as defined FFT. FFT Size: ' +
125
- bufferSize +
126
- ' Buffer Size: ' +
127
- buffer.length);
128
- }
129
- var halfSize = 1, phaseShiftStepReal, phaseShiftStepImag, currentPhaseShiftReal, currentPhaseShiftImag, off, tr, ti, tmpReal;
130
- for (var i = 0; i < bufferSize; i++) {
131
- real[i] = buffer[reverseTable[i]] * this.windowValues[reverseTable[i]];
132
- imag[i] = 0;
133
- }
134
- while (halfSize < bufferSize) {
135
- phaseShiftStepReal = cosTable[halfSize];
136
- phaseShiftStepImag = sinTable[halfSize];
137
- currentPhaseShiftReal = 1;
138
- currentPhaseShiftImag = 0;
139
- for (var fftStep = 0; fftStep < halfSize; fftStep++) {
140
- var i = fftStep;
141
- while (i < bufferSize) {
142
- off = i + halfSize;
143
- tr = currentPhaseShiftReal * real[off] - currentPhaseShiftImag * imag[off];
144
- ti = currentPhaseShiftReal * imag[off] + currentPhaseShiftImag * real[off];
145
- real[off] = real[i] - tr;
146
- imag[off] = imag[i] - ti;
147
- real[i] += tr;
148
- imag[i] += ti;
149
- i += halfSize << 1;
150
- }
151
- tmpReal = currentPhaseShiftReal;
152
- currentPhaseShiftReal = tmpReal * phaseShiftStepReal - currentPhaseShiftImag * phaseShiftStepImag;
153
- currentPhaseShiftImag = tmpReal * phaseShiftStepImag + currentPhaseShiftImag * phaseShiftStepReal;
154
- }
155
- halfSize = halfSize << 1;
156
- }
157
- for (var i = 0, N = bufferSize / 2; i < N; i++) {
158
- rval = real[i];
159
- ival = imag[i];
160
- mag = bSi * sqrt(rval * rval + ival * ival);
161
- if (mag > this.peak) {
162
- this.peakBand = i;
163
- this.peak = mag;
164
- }
165
- spectrum[i] = mag;
166
- }
167
- return spectrum;
168
- };
169
- }
170
- /**
171
- * Spectrogram plugin for wavesurfer.
172
- */
173
- import BasePlugin from '../base-plugin.js';
174
- class SpectrogramPlugin extends BasePlugin {
175
- static create(options) {
176
- return new SpectrogramPlugin(options || {});
177
- }
178
- constructor(options) {
179
- super(options);
180
- this.utils = {
181
- style: (el, styles) => Object.assign(el.style, styles),
182
- };
183
- this.drawSpectrogram = (frequenciesData) => {
184
- if (!isNaN(frequenciesData[0][0])) {
185
- // data is 1ch [sample, freq] format
186
- // to [channel, sample, freq] format
187
- frequenciesData = [frequenciesData];
188
- }
189
- // Set the height to fit all channels
190
- this.wrapper.style.height = this.height * frequenciesData.length + 'px';
191
- this.canvas.width = this.width;
192
- this.canvas.height = this.height * frequenciesData.length;
193
- const spectrCc = this.spectrCc;
194
- const height = this.height;
195
- const width = this.width;
196
- const freqFrom = this.buffer.sampleRate / 2;
197
- const freqMin = this.frequencyMin;
198
- const freqMax = this.frequencyMax;
199
- if (!spectrCc) {
200
- return;
201
- }
202
- for (let c = 0; c < frequenciesData.length; c++) {
203
- // for each channel
204
- const pixels = this.resample(frequenciesData[c]);
205
- const imageData = new ImageData(width, height);
206
- for (let i = 0; i < pixels.length; i++) {
207
- for (let j = 0; j < pixels[i].length; j++) {
208
- const colorMap = this.colorMap[pixels[i][j]];
209
- const redIndex = ((height - j) * width + i) * 4;
210
- imageData.data[redIndex] = colorMap[0] * 255;
211
- imageData.data[redIndex + 1] = colorMap[1] * 255;
212
- imageData.data[redIndex + 2] = colorMap[2] * 255;
213
- imageData.data[redIndex + 3] = colorMap[3] * 255;
214
- }
215
- }
216
- // scale and stack spectrograms
217
- createImageBitmap(imageData).then((renderer) => {
218
- spectrCc.drawImage(renderer, 0, height * (1 - freqMax / freqFrom), // source x, y
219
- width, (height * (freqMax - freqMin)) / freqFrom, // source width, height
220
- 0, height * c, // destination x, y
221
- width, height);
222
- });
223
- }
224
- this.loadLabels(this.options.labelsBackground, '12px', '12px', '', this.options.labelsColor, this.options.labelsHzColor || this.options.labelsColor, 'center', '#specLabels', frequenciesData.length);
225
- this.emit('ready');
226
- };
227
- this.frequenciesDataUrl = options.frequenciesDataUrl;
228
- this.container =
229
- 'string' == typeof options.container ? document.querySelector(options.container) : options.container;
230
- if (options.colorMap) {
231
- if (options.colorMap.length < 256) {
232
- throw new Error('Colormap must contain 256 elements');
233
- }
234
- for (let i = 0; i < options.colorMap.length; i++) {
235
- const cmEntry = options.colorMap[i];
236
- if (cmEntry.length !== 4) {
237
- throw new Error('ColorMap entries must contain 4 values');
238
- }
239
- }
240
- this.colorMap = options.colorMap;
241
- }
242
- else {
243
- this.colorMap = [];
244
- for (let i = 0; i < 256; i++) {
245
- const val = (255 - i) / 256;
246
- this.colorMap.push([val, val, val, 1]);
247
- }
248
- }
249
- this.fftSamples = options.fftSamples || 512;
250
- this.height = options.height || this.fftSamples / 2;
251
- this.noverlap = options.noverlap;
252
- this.windowFunc = options.windowFunc;
253
- this.alpha = options.alpha;
254
- // Getting file's original samplerate is difficult(#1248).
255
- // So set 12kHz default to render like wavesurfer.js 5.x.
256
- this.frequencyMin = options.frequencyMin || 0;
257
- this.frequencyMax = options.frequencyMax || 0;
258
- this.createWrapper();
259
- this.createCanvas();
260
- }
261
- onInit() {
262
- this.container = this.container || this.wavesurfer.getWrapper();
263
- this.container.appendChild(this.wrapper);
264
- if (this.wavesurfer.options.fillParent) {
265
- this.utils.style(this.wrapper, {
266
- width: '100%',
267
- overflowX: 'hidden',
268
- overflowY: 'hidden',
269
- });
270
- }
271
- this.width = this.wavesurfer.getWrapper().offsetWidth;
272
- this.subscriptions.push(this.wavesurfer.on('redraw', () => this.render()));
273
- }
274
- destroy() {
275
- this.unAll();
276
- this.wavesurfer.un('ready', this._onReady);
277
- this.wavesurfer.un('redraw', this._onRender);
278
- this.wavesurfer = null;
279
- this.util = null;
280
- this.options = null;
281
- if (this.wrapper) {
282
- this.wrapper.remove();
283
- this.wrapper = null;
284
- }
285
- super.destroy();
286
- }
287
- createWrapper() {
288
- this.wrapper = document.createElement('div');
289
- this.utils.style(this.wrapper, {
290
- display: 'block',
291
- position: 'relative',
292
- userSelect: 'none',
293
- });
294
- // if labels are active
295
- if (this.options.labels) {
296
- const labelsEl = document.createElement('canvas');
297
- labelsEl.setAttribute('part', 'spec-labels');
298
- this.utils.style(labelsEl, {
299
- position: 'absolute',
300
- zIndex: 9,
301
- width: '55px',
302
- height: '100%',
303
- });
304
- this.wrapper.appendChild(labelsEl);
305
- this.labelsEl = labelsEl;
306
- }
307
- this.wrapper.addEventListener('click', this._onWrapperClick);
308
- }
309
- _wrapperClickHandler(event) {
310
- event.preventDefault();
311
- const relX = 'offsetX' in event ? event.offsetX : event.layerX;
312
- this.emit('click', relX / this.width || 0);
313
- }
314
- createCanvas() {
315
- const canvas = document.createElement('canvas');
316
- this.wrapper.appendChild(canvas);
317
- this.spectrCc = canvas.getContext('2d');
318
- this.utils.style(canvas, {
319
- position: 'absolute',
320
- left: 0,
321
- top: 0,
322
- width: '100%',
323
- height: '100%',
324
- zIndex: 4,
325
- });
326
- this.canvas = canvas;
327
- }
328
- render() {
329
- var _a;
330
- if (this.frequenciesDataUrl) {
331
- this.loadFrequenciesData(this.frequenciesDataUrl);
332
- }
333
- else {
334
- this.drawSpectrogram(this.getFrequencies((_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.getDecodedData()));
335
- }
336
- }
337
- getFrequencies(buffer) {
338
- var _a, _b;
339
- const fftSamples = this.fftSamples;
340
- const channels = ((_a = this.options.splitChannels) !== null && _a !== void 0 ? _a : (_b = this.wavesurfer) === null || _b === void 0 ? void 0 : _b.options.splitChannels) ? buffer.numberOfChannels : 1;
341
- this.frequencyMax = this.frequencyMax || buffer.sampleRate / 2;
342
- if (!buffer)
343
- return;
344
- this.buffer = buffer;
345
- // This may differ from file samplerate. Browser resamples audio.
346
- const sampleRate = buffer.sampleRate;
347
- const frequencies = [];
348
- let noverlap = this.noverlap;
349
- if (!noverlap) {
350
- const uniqueSamplesPerPx = buffer.length / this.canvas.width;
351
- noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
352
- }
353
- const fft = new FFT(fftSamples, sampleRate, this.windowFunc, this.alpha);
354
- for (let c = 0; c < channels; c++) {
355
- // for each channel
356
- const channelData = buffer.getChannelData(c);
357
- const channelFreq = [];
358
- let currentOffset = 0;
359
- while (currentOffset + fftSamples < channelData.length) {
360
- const segment = channelData.slice(currentOffset, currentOffset + fftSamples);
361
- const spectrum = fft.calculateSpectrum(segment);
362
- const array = new Uint8Array(fftSamples / 2);
363
- for (let j = 0; j < fftSamples / 2; j++) {
364
- array[j] = Math.max(-255, Math.log10(spectrum[j]) * 45);
365
- }
366
- channelFreq.push(array);
367
- // channelFreq: [sample, freq]
368
- currentOffset += fftSamples - noverlap;
369
- }
370
- frequencies.push(channelFreq);
371
- // frequencies: [channel, sample, freq]
372
- }
373
- return frequencies;
374
- }
375
- loadFrequenciesData(url) {
376
- return fetch(url)
377
- .then((response) => response.json())
378
- .then(this.drawSpectrogram);
379
- }
380
- freqType(freq) {
381
- return freq >= 1000 ? (freq / 1000).toFixed(1) : Math.round(freq);
382
- }
383
- unitType(freq) {
384
- return freq >= 1000 ? 'KHz' : 'Hz';
385
- }
386
- loadLabels(bgFill, fontSizeFreq, fontSizeUnit, fontType, textColorFreq, textColorUnit, textAlign, container, channels) {
387
- const frequenciesHeight = this.height;
388
- bgFill = bgFill || 'rgba(68,68,68,0)';
389
- fontSizeFreq = fontSizeFreq || '12px';
390
- fontSizeUnit = fontSizeUnit || '12px';
391
- fontType = fontType || 'Helvetica';
392
- textColorFreq = textColorFreq || '#fff';
393
- textColorUnit = textColorUnit || '#fff';
394
- textAlign = textAlign || 'center';
395
- container = container || '#specLabels';
396
- const bgWidth = 55;
397
- const getMaxY = frequenciesHeight || 512;
398
- const labelIndex = 5 * (getMaxY / 256);
399
- const freqStart = this.frequencyMin;
400
- const step = (this.frequencyMax - freqStart) / labelIndex;
401
- // prepare canvas element for labels
402
- const ctx = this.labelsEl.getContext('2d');
403
- const dispScale = window.devicePixelRatio;
404
- this.labelsEl.height = this.height * channels * dispScale;
405
- this.labelsEl.width = bgWidth * dispScale;
406
- ctx.scale(dispScale, dispScale);
407
- if (!ctx) {
408
- return;
409
- }
410
- for (let c = 0; c < channels; c++) {
411
- // for each channel
412
- // fill background
413
- ctx.fillStyle = bgFill;
414
- ctx.fillRect(0, c * getMaxY, bgWidth, (1 + c) * getMaxY);
415
- ctx.fill();
416
- let i;
417
- // render labels
418
- for (i = 0; i <= labelIndex; i++) {
419
- ctx.textAlign = textAlign;
420
- ctx.textBaseline = 'middle';
421
- const freq = freqStart + step * i;
422
- const label = this.freqType(freq);
423
- const units = this.unitType(freq);
424
- const yLabelOffset = 2;
425
- const x = 16;
426
- let y;
427
- if (i == 0) {
428
- y = (1 + c) * getMaxY + i - 10;
429
- }
430
- else {
431
- y = (1 + c) * getMaxY - i * 50 + yLabelOffset;
432
- }
433
- // unit label
434
- ctx.fillStyle = textColorUnit;
435
- ctx.font = fontSizeUnit + ' ' + fontType;
436
- ctx.fillText(units, x + 24, y);
437
- // freq label
438
- ctx.fillStyle = textColorFreq;
439
- ctx.font = fontSizeFreq + ' ' + fontType;
440
- ctx.fillText(label, x, y);
441
- }
442
- }
443
- }
444
- resample(oldMatrix) {
445
- const columnsNumber = this.width;
446
- const newMatrix = [];
447
- const oldPiece = 1 / oldMatrix.length;
448
- const newPiece = 1 / columnsNumber;
449
- let i;
450
- for (i = 0; i < columnsNumber; i++) {
451
- const column = new Array(oldMatrix[0].length);
452
- let j;
453
- for (j = 0; j < oldMatrix.length; j++) {
454
- const oldStart = j * oldPiece;
455
- const oldEnd = oldStart + oldPiece;
456
- const newStart = i * newPiece;
457
- const newEnd = newStart + newPiece;
458
- const overlap = oldEnd <= newStart || newEnd <= oldStart
459
- ? 0
460
- : Math.min(Math.max(oldEnd, newStart), Math.max(newEnd, oldStart)) -
461
- Math.max(Math.min(oldEnd, newStart), Math.min(newEnd, oldStart));
462
- let k;
463
- /* eslint-disable max-depth */
464
- if (overlap > 0) {
465
- for (k = 0; k < oldMatrix[0].length; k++) {
466
- if (column[k] == null) {
467
- column[k] = 0;
468
- }
469
- column[k] += (overlap / newPiece) * oldMatrix[j][k];
470
- }
471
- }
472
- /* eslint-enable max-depth */
473
- }
474
- const intColumn = new Uint8Array(oldMatrix[0].length);
475
- let m;
476
- for (m = 0; m < oldMatrix[0].length; m++) {
477
- intColumn[m] = column[m];
478
- }
479
- newMatrix.push(intColumn);
480
- }
481
- return newMatrix;
482
- }
483
- }
484
- export default SpectrogramPlugin;
1
+ class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function s(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,h=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+h;r<<=1,h>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,h=this.sinTable,n=this.reverseTable,l=new Float32Array(a),o=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,p=new Float32Array(a/2),u=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,u)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,M,b,g,m,v,y,x=1,k=0;k<a;k++)l[k]=t[n[k]]*this.windowValues[n[k]],o[k]=0;for(;x<a;){d=r[x],w=h[x],M=1,b=0;for(var q=0;q<x;q++){for(k=q;k<a;)m=M*l[g=k+x]-b*o[g],v=M*o[g]+b*l[g],l[g]=l[k]-m,o[g]=o[k]-v,l[k]+=m,o[k]+=v,k+=x<<1;M=(y=M)*d-b*w,b=y*w+b*d}x<<=1}k=0;for(var S=a/2;k<S;k++)(i=c*f((e=l[k])*e+(s=o[k])*s))>this.peak&&(this.peakBand=k,this.peak=i),p[k]=i;return p}}class i extends e{static create(t){return new i(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]),this.wrapper.style.height=this.height*t.length+"px",this.canvas.width=this.width,this.canvas.height=this.height*t.length;const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,h=this.frequencyMax;if(e){for(let n=0;n<t.length;n++){const l=this.resample(t[n]),o=new ImageData(i,s);for(let t=0;t<l.length;t++)for(let e=0;e<l[t].length;e++){const a=this.colorMap[l[t][e]],r=4*((s-e)*i+t);o.data[r]=255*a[0],o.data[r+1]=255*a[1],o.data[r+2]=255*a[2],o.data[r+3]=255*a[3]}createImageBitmap(o).then((t=>{e.drawImage(t,0,s*(1-h/a),i,s*(h-r)/a,0,s*n,i,s)}))}this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels",t.length),this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++){if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values")}this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null),super.destroy()}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){var t;this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.drawSpectrogram(this.getFrequencies(null===(t=this.wavesurfer)||void 0===t?void 0:t.getDecodedData()))}getFrequencies(t){var e,i;const a=this.fftSamples,r=(null!==(e=this.options.splitChannels)&&void 0!==e?e:null===(i=this.wavesurfer)||void 0===i?void 0:i.options.splitChannels)?t.numberOfChannels:1;if(this.frequencyMax=this.frequencyMax||t.sampleRate/2,!t)return;this.buffer=t;const h=t.sampleRate,n=[];let l=this.noverlap;if(!l){const e=t.length/this.canvas.width;l=Math.max(0,Math.round(a-e))}const o=new s(a,h,this.windowFunc,this.alpha);for(let e=0;e<r;e++){const s=t.getChannelData(e),i=[];let r=0;for(;r+a<s.length;){const t=s.slice(r,r+a),e=o.calculateSpectrum(t),h=new Uint8Array(a/2);for(let t=0;t<a/2;t++)h[t]=Math.max(-255,45*Math.log10(e[t]));i.push(h),r+=a-l}n.push(i)}return n}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,h,n,l){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",h=h||"center";const o=this.height||512,c=o/256*5,f=this.frequencyMin,p=(this.frequencyMax-f)/c,u=this.labelsEl.getContext("2d"),d=window.devicePixelRatio;if(this.labelsEl.height=this.height*l*d,this.labelsEl.width=55*d,u.scale(d,d),u)for(let n=0;n<l;n++){let l;for(u.fillStyle=t,u.fillRect(0,n*o,55,(1+n)*o),u.fill(),l=0;l<=c;l++){u.textAlign=h,u.textBaseline="middle";const t=f+p*l,c=this.freqType(t),d=this.unitType(t),w=16;let M;M=0==l?(1+n)*o+l-10:(1+n)*o-50*l+2,u.fillStyle=r,u.font=s+" "+i,u.fillText(d,w+24,M),u.fillStyle=a,u.font=e+" "+i,u.fillText(c,w,M)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let h;for(h=0;h<t.length;h++){const s=h*i,n=s+i,l=r*a,o=l+a,c=n<=l||o<=s?0:Math.min(Math.max(n,l),Math.max(o,s))-Math.max(Math.min(n,l),Math.min(o,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[h][f]}const n=new Uint8Array(t[0].length);let l;for(l=0;l<t[0].length;l++)n[l]=e[l];s.push(n)}return s}}export{i as default};
@@ -1 +1 @@
1
- "use strict";class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class s extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new s(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=null!==(t=this.options.container)&&void 0!==t?t:this.wavesurfer.getWrapper();this.options.insertPosition?(e.firstElementChild||e).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):e.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,s;const n=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(n),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(n),l=null!==(s=this.options.secondaryLabelInterval)&&void 0!==s?s:this.defaultSecondaryLabelInterval(n),a="beforebegin"===this.options.insertPosition,h=document.createElement("div");if(h.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),a){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";h.setAttribute("style",h.getAttribute("style")+t)}"string"==typeof this.options.style?h.setAttribute("style",h.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(h.style,this.options.style);const p=document.createElement("div");p.setAttribute("part","timeline-notch"),p.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${a?"flex-start":"flex-end"};\n ${a?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0;e<t;e+=r){const t=p.cloneNode(),i=Math.round(100*e)/100%o==0,s=Math.round(100*e)/100%l==0;(i||s)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),i&&(t.style.opacity="1")),t.style.left=e*n+"px",h.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(h),this.emit("ready")}}module.exports=s;
1
+ "use strict";class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class n extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new n(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");let t=this.wavesurfer.getWrapper();if(this.options.container instanceof HTMLElement)t=this.options.container;else if("string"==typeof this.options.container){const e=document.querySelector(this.options.container);if(!e)throw Error(`No Timeline container found matching ${this.options.container}`);t=e}this.options.insertPosition?(t.firstElementChild||t).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):t.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,n;const s=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(s),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(s),l=this.options.primaryLabelSpacing,a=null!==(n=this.options.secondaryLabelInterval)&&void 0!==n?n:this.defaultSecondaryLabelInterval(s),h=this.options.secondaryLabelSpacing,p="beforebegin"===this.options.insertPosition,u=document.createElement("div");if(u.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),p){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";u.setAttribute("style",u.getAttribute("style")+t)}"string"==typeof this.options.style?u.setAttribute("style",u.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(u.style,this.options.style);const c=document.createElement("div");c.setAttribute("part","timeline-notch"),c.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${p?"flex-start":"flex-end"};\n ${p?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0,i=0;e<t;e+=r,i++){const t=c.cloneNode(),n=Math.round(100*e)/100%o==0||l&&i%l==0,r=Math.round(100*e)/100%a==0||h&&i%h==0;(n||r)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),n&&(t.style.opacity="1")),t.style.left=e*s+"px",u.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(u),this.emit("ready")}}module.exports=n;
@@ -5,18 +5,22 @@ import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
5
5
  export type TimelinePluginOptions = {
6
6
  /** The height of the timeline in pixels, defaults to 20 */
7
7
  height?: number;
8
- /** HTML container for the timeline, defaults to wavesufer's container */
9
- container?: HTMLElement;
8
+ /** HTML element or selector for a timeline container, defaults to wavesufer's container */
9
+ container?: HTMLElement | string;
10
10
  /** Pass 'beforebegin' to insert the timeline on top of the waveform */
11
11
  insertPosition?: InsertPosition;
12
12
  /** The duration of the timeline in seconds, defaults to wavesurfer's duration */
13
13
  duration?: number;
14
14
  /** Interval between ticks in seconds */
15
15
  timeInterval?: number;
16
- /** Interval between numeric labels */
16
+ /** Interval between numeric labels in seconds */
17
17
  primaryLabelInterval?: number;
18
- /** Interval between secondary numeric labels */
18
+ /** Interval between secondary numeric labels in seconds */
19
19
  secondaryLabelInterval?: number;
20
+ /** Interval between numeric labels in timeIntervals (i.e notch count) */
21
+ primaryLabelSpacing?: number;
22
+ /** Interval between secondary numeric labels in timeIntervals (i.e notch count) */
23
+ secondaryLabelSpacing?: number;
20
24
  /** Custom inline style to apply to the container */
21
25
  style?: Partial<CSSStyleDeclaration> | string;
22
26
  /** Turn the time into a suitable label for the time. */
@@ -1 +1 @@
1
- class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class n extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new n(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=null!==(t=this.options.container)&&void 0!==t?t:this.wavesurfer.getWrapper();this.options.insertPosition?(e.firstElementChild||e).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):e.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,n;const s=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(s),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(s),l=null!==(n=this.options.secondaryLabelInterval)&&void 0!==n?n:this.defaultSecondaryLabelInterval(s),a="beforebegin"===this.options.insertPosition,h=document.createElement("div");if(h.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),a){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";h.setAttribute("style",h.getAttribute("style")+t)}"string"==typeof this.options.style?h.setAttribute("style",h.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(h.style,this.options.style);const p=document.createElement("div");p.setAttribute("part","timeline-notch"),p.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${a?"flex-start":"flex-end"};\n ${a?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0;e<t;e+=r){const t=p.cloneNode(),i=Math.round(100*e)/100%o==0,n=Math.round(100*e)/100%l==0;(i||n)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),i&&(t.style.opacity="1")),t.style.left=e*s+"px",h.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(h),this.emit("ready")}}export{n as default};
1
+ class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class n extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new n(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");let t=this.wavesurfer.getWrapper();if(this.options.container instanceof HTMLElement)t=this.options.container;else if("string"==typeof this.options.container){const e=document.querySelector(this.options.container);if(!e)throw Error(`No Timeline container found matching ${this.options.container}`);t=e}this.options.insertPosition?(t.firstElementChild||t).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):t.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,n;const s=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(s),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(s),l=this.options.primaryLabelSpacing,a=null!==(n=this.options.secondaryLabelInterval)&&void 0!==n?n:this.defaultSecondaryLabelInterval(s),h=this.options.secondaryLabelSpacing,p="beforebegin"===this.options.insertPosition,u=document.createElement("div");if(u.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),p){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";u.setAttribute("style",u.getAttribute("style")+t)}"string"==typeof this.options.style?u.setAttribute("style",u.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(u.style,this.options.style);const c=document.createElement("div");c.setAttribute("part","timeline-notch"),c.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${p?"flex-start":"flex-end"};\n ${p?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0,i=0;e<t;e+=r,i++){const t=c.cloneNode(),n=Math.round(100*e)/100%o==0||l&&i%l==0,r=Math.round(100*e)/100%a==0||h&&i%h==0;(n||r)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),n&&(t.style.opacity="1")),t.style.left=e*s+"px",u.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(u),this.emit("ready")}}export{n as default};