@checksub_team/peaks_timeline 1.16.0-alpha.2 → 2.0.0-alpha.0

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.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/peaks.js +4160 -3938
  3. package/peaks.js.d.ts +5 -5
  4. package/src/{timeline-axis.js → components/axis.js} +244 -244
  5. package/src/{data-retriever.js → components/data-retriever.js} +117 -117
  6. package/src/{default-segment-marker.js → components/default-segment-marker.js} +132 -132
  7. package/src/{invoker.js → components/invoker.js} +81 -81
  8. package/src/{line.js → components/line-group.js} +192 -187
  9. package/src/components/line-groups.js +584 -0
  10. package/src/{line-indicator.js → components/line-indicator.js} +308 -293
  11. package/src/{marker-factories.js → components/marker-factories.js} +1 -1
  12. package/src/{mode-layer.js → components/mode-layer.js} +8 -12
  13. package/src/{playhead-layer.js → components/playhead-layer.js} +3 -3
  14. package/src/{segment-marker.js → components/segment-marker.js} +2 -2
  15. package/src/{segment-shape.js → components/segment-shape.js} +508 -508
  16. package/src/{segments-group.js → components/segments-group.js} +805 -805
  17. package/src/{source-group.js → components/source-group.js} +1641 -1645
  18. package/src/{sources-layer.js → components/sources-layer.js} +716 -704
  19. package/src/{waveform-builder.js → components/waveform-builder.js} +2 -2
  20. package/src/{waveform-shape.js → components/waveform-shape.js} +214 -214
  21. package/src/keyboard-handler.js +9 -9
  22. package/src/line-handler.js +179 -0
  23. package/src/main.js +99 -64
  24. package/src/models/line.js +156 -0
  25. package/src/{segment.js → models/segment.js} +420 -419
  26. package/src/{source.js → models/source.js} +1262 -1269
  27. package/src/player.js +2 -2
  28. package/src/{timeline-segments.js → segment-handler.js} +427 -435
  29. package/src/{timeline-sources.js → source-handler.js} +510 -512
  30. package/src/utils.js +5 -1
  31. package/src/{timeline-zoomview.js → view.js} +133 -138
  32. package/src/lines.js +0 -533
  33. /package/src/{data.js → components/data.js} +0 -0
  34. /package/src/{loader.js → components/loader.js} +0 -0
  35. /package/src/{mouse-drag-handler.js → components/mouse-drag-handler.js} +0 -0
  36. /package/src/{svgs.js → components/svgs.js} +0 -0
@@ -1,1269 +1,1262 @@
1
- /**
2
- * @file
3
- *
4
- * Defines the {@link source} class.
5
- *
6
- * @module source
7
- */
8
-
9
- define([
10
- './utils'
11
- ], function(Utils) {
12
- 'use strict';
13
-
14
- function validateSource(peaks, options, context) {
15
- if (!Utils.isValidTime(options.startTime)) {
16
- throw new TypeError('peaks.sources.' + context + ': startTime should be a valid number');
17
- }
18
-
19
- if (!Utils.isValidTime(options.endTime)) {
20
- throw new TypeError('peaks.sources.' + context + ': endTime should be a valid number');
21
- }
22
-
23
- if (!Utils.isValidTime(options.duration) || options.duration <= 0) {
24
- options.duration = 0;
25
- }
26
- else if (options.duration < peaks.options.minSourceSize) {
27
- options.duration = peaks.options.minSourceSize;
28
- }
29
-
30
- options.duration = Utils.roundTime(options.duration);
31
-
32
- if (options.startTime < 0) {
33
- throw new RangeError('peaks.sources.' + context + ': startTime should be positive');
34
- }
35
-
36
- if (options.endTime < 0) {
37
- throw new RangeError('peaks.sources.' + context + ': endTime should be positive');
38
- }
39
-
40
- if (options.endTime <= options.startTime) {
41
- throw new RangeError(
42
- 'peaks.sources.' + context + ': endTime should be greater than startTime'
43
- );
44
- }
45
-
46
- if (options.endTime - options.startTime < peaks.options.minSourceSize) {
47
- options.endTime = options.startTime + peaks.options.minSourceSize;
48
- }
49
-
50
- if (!Utils.isValidTime(options.mediaStartTime) || options.mediaStartTime < 0) {
51
- options.mediaStartTime = 0;
52
- }
53
-
54
- if (!Utils.isValidTime(options.mediaEndTime)
55
- || (options.mediaEndTime < options.mediaStartTime)
56
- || (options.mediaEndTime - options.mediaStartTime !== options.endTime - options.startTime)) {
57
- options.mediaEndTime = options.mediaStartTime + (options.endTime - options.startTime);
58
- }
59
-
60
- if (options.duration && options.mediaEndTime > options.duration) {
61
- var timeWidth = options.mediaEndTime - options.mediaStartTime;
62
-
63
- options.mediaEndTime = options.duration;
64
- if (options.duration > timeWidth) {
65
- options.mediaStartTime = options.mediaEndTime - timeWidth;
66
- options.endTime = options.startTime + timeWidth;
67
- }
68
- else {
69
- options.mediaStartTime = 0;
70
- options.endTime = options.startTime + options.duration;
71
- }
72
- }
73
-
74
- options.startTime = Utils.roundTime(options.startTime);
75
- options.endTime = Utils.roundTime(options.endTime);
76
- options.mediaStartTime = Utils.roundTime(options.mediaStartTime);
77
- options.mediaEndTime = Utils.roundTime(options.mediaEndTime);
78
-
79
- if (Utils.isNullOrUndefined(options.title)) {
80
- options.title = '';
81
- }
82
- else if (!Utils.isString(options.title)) {
83
- throw new TypeError('peaks.sources.' + context + ': title must be a string');
84
- }
85
-
86
- if (Utils.isNullOrUndefined(options.titleAlignments)) {
87
- options.titleAlignments = [];
88
- }
89
- else if (!Array.isArray(options.titleAlignments)) {
90
- throw new TypeError('peaks.sources.' + context + ': titleAlignments must be an array');
91
- }
92
-
93
- if (Utils.isNullOrUndefined(options.url)) {
94
- options.url = '';
95
- }
96
- else if (!Utils.isString(options.url)) {
97
- throw new TypeError('peaks.sources.' + context + ': url must be a string');
98
- }
99
-
100
- if (Utils.isNullOrUndefined(options.previewUrl)) {
101
- options.previewUrl = '';
102
- }
103
- else if (!Utils.isString(options.previewUrl)) {
104
- throw new TypeError('peaks.sources.' + context + ': previewUrl must be a string');
105
- }
106
-
107
- if (Utils.isNullOrUndefined(options.binaryUrl)) {
108
- options.binaryUrl = '';
109
- }
110
- else if (!Utils.isString(options.binaryUrl)) {
111
- throw new TypeError('peaks.sources.' + context + ': binaryUrl must be a string');
112
- }
113
-
114
- if (!Utils.isValidColor(options.color)) {
115
- options.color = peaks.options.zoomWaveformColor;
116
- }
117
-
118
- if (!Utils.isValidColor(options.backgroundColor)) {
119
- throw new TypeError(
120
- 'peaks.sources.' + context + ': backgroundColor should be a valid CSS color'
121
- );
122
- }
123
-
124
- if (!Utils.isValidColor(options.borderColor)) {
125
- options.borderColor = options.color;
126
- }
127
-
128
- if (Utils.isNullOrUndefined(options.selectedColor)) {
129
- options.selectedColor = null;
130
- }
131
- else if (!Utils.isValidColor(options.selectedColor)) {
132
- throw new TypeError(
133
- 'peaks.sources.' + context + ': selectedColor should be a valid CSS color'
134
- );
135
- }
136
-
137
- if (Utils.isNullOrUndefined(options.warningColor)) {
138
- options.warningColor = null;
139
- }
140
- else if (!Utils.isValidColor(options.warningColor)) {
141
- throw new TypeError(
142
- 'peaks.sources.' + context + ': warningColor should be a valid CSS color'
143
- );
144
- }
145
-
146
- if (Utils.isNullOrUndefined(options.warningWidth)) {
147
- options.warningWidth = 10;
148
- }
149
- else if (!Utils.isNumber(options.warningWidth)) {
150
- throw new TypeError('peaks.sources.' + context + ': warningWidth should be a number');
151
- }
152
-
153
- if (Utils.isNullOrUndefined(options.volumeSliderColor)) {
154
- options.volumeSliderColor = '#000000';
155
- }
156
- else if (!Utils.isValidColor(options.volumeSliderColor)) {
157
- throw new TypeError(
158
- 'peaks.sources.' + context + ': volumeSliderColor should be a valid CSS color'
159
- );
160
- }
161
-
162
- if (Utils.isNullOrUndefined(options.volumeSliderWidth)) {
163
- options.volumeSliderWidth = 2;
164
- }
165
- else if (!Utils.isNumber(options.volumeSliderWidth)) {
166
- throw new TypeError('peaks.sources.' + context + ': volumeSliderWidth should be a number');
167
- }
168
-
169
- if (Utils.isNullOrUndefined(options.volumeSliderDraggingWidth)) {
170
- options.volumeSliderDraggingWidth = options.volumeSliderWidth;
171
- }
172
- else if (!Utils.isNumber(options.volumeSliderDraggingWidth)) {
173
- throw new TypeError(
174
- 'peaks.sources.' + context + ': volumeSliderDraggingWidth should be a number'
175
- );
176
- }
177
-
178
- if (Utils.isNullOrUndefined(options.textFont)) {
179
- options.textFont = 'Arial';
180
- }
181
-
182
- if (Utils.isNullOrUndefined(options.textFontSize)) {
183
- options.textFontSize = 12;
184
- }
185
-
186
- if (Utils.isNullOrUndefined(options.textColor)) {
187
- options.textColor = '#000000';
188
- }
189
- else if (!Utils.isValidColor(options.textColor)) {
190
- throw new TypeError('peaks.sources.' + context + ': textColor should be a valid CSS color');
191
- }
192
-
193
- if (!Utils.isNullOrUndefined(options.textBackgroundColor)
194
- && !Utils.isValidColor(options.textBackgroundColor)) {
195
- throw new TypeError(
196
- 'peaks.sources.' + context + ': textBackgroundColor should be a valid CSS color'
197
- );
198
- }
199
-
200
- if (Utils.isNullOrUndefined(options.textPosition)) {
201
- options.textPosition = 'bottom';
202
- }
203
- else if (!Utils.isString(options.textPosition)) {
204
- throw new TypeError('peaks.sources.' + context + ': textPosition must be a string');
205
- }
206
-
207
- if (Utils.isNullOrUndefined(options.textAutoScroll)) {
208
- options.textAutoScroll = false;
209
- }
210
-
211
- if (Utils.isNullOrUndefined(options.borderWidth)) {
212
- options.borderWidth = 0;
213
- }
214
-
215
- if (Utils.isNullOrUndefined(options.wrapped)) {
216
- options.wrapped = false;
217
- }
218
- else if (!Utils.isBoolean(options.wrapped)) {
219
- throw new TypeError('peaks.sources.' + context + ': wrapped must be a boolean');
220
- }
221
-
222
- if (!Utils.isInteger(options.position)) {
223
- throw new TypeError('peaks.sources.' + context + ': position must be an integer');
224
- }
225
-
226
- if (Utils.isNullOrUndefined(options.draggable)) {
227
- options.draggable = true;
228
- }
229
- else if (!Utils.isBoolean(options.draggable)) {
230
- throw new TypeError('peaks.sources.' + context + ': draggable must be a boolean');
231
- }
232
-
233
- if (Utils.isNullOrUndefined(options.orderable)) {
234
- options.orderable = true;
235
- }
236
- else if (!Utils.isBoolean(options.orderable)) {
237
- throw new TypeError('peaks.sources.' + context + ': orderable must be a boolean');
238
- }
239
-
240
- if (Utils.isNullOrUndefined(options.resizable)) {
241
- options.resizable = true;
242
- }
243
- else if (!Utils.isBoolean(options.resizable)) {
244
- throw new TypeError('peaks.sources.' + context + ': resizable must be a boolean');
245
- }
246
-
247
- if (Utils.isNullOrUndefined(options.cuttable)) {
248
- options.cuttable = true;
249
- }
250
- else if (!Utils.isBoolean(options.cuttable)) {
251
- throw new TypeError('peaks.sources.' + context + ': cuttable must be a boolean');
252
- }
253
-
254
- if (Utils.isNullOrUndefined(options.deletable)) {
255
- options.deletable = true;
256
- }
257
- else if (!Utils.isBoolean(options.deletable)) {
258
- throw new TypeError('peaks.sources.' + context + ': deletable must be a boolean');
259
- }
260
-
261
- if (Utils.isNullOrUndefined(options.wrapping)) {
262
- options.wrapping = 'both';
263
- }
264
- else if (!Utils.isString(options.wrapping)) {
265
- throw new TypeError('peaks.sources.' + context + ': wrapping must be a string');
266
- }
267
-
268
- if (Utils.isNullOrUndefined(options.previewHeight)) {
269
- options.previewHeight = 0;
270
- }
271
- else if (!Utils.isNumber(options.previewHeight)) {
272
- throw new TypeError('peaks.sources.' + context + ': previewHeight must be a number');
273
- }
274
-
275
- if (Utils.isNullOrUndefined(options.binaryHeight)) {
276
- options.binaryHeight = 0;
277
- }
278
- else if (!Utils.isNumber(options.binaryHeight)) {
279
- throw new TypeError('peaks.sources.' + context + ': binaryHeight must be a number');
280
- }
281
-
282
- if (options.previewUrl && !options.previewHeight) {
283
- if (options.binaryHeight) {
284
- options.previewHeight = Math.max(peaks.options.lineHeight - options.binaryHeight, 0);
285
- }
286
- else {
287
- options.previewHeight = peaks.options.lineHeight / 2;
288
- }
289
- }
290
-
291
- if (options.binaryUrl && !options.binaryHeight) {
292
- options.binaryHeight = Math.max(peaks.options.lineHeight - options.previewHeight, 0);
293
- }
294
-
295
- if (options.wrapping === 'reduced') {
296
- options.wrapped = true;
297
- }
298
- else if (options.wrapping === 'complete') {
299
- options.wrapped = false;
300
- }
301
-
302
- if (Utils.isNullOrUndefined(options.indicators)) {
303
- options.indicators = [];
304
- }
305
-
306
- if (Utils.isNullOrUndefined(options.markers)) {
307
- options.markers = [];
308
- }
309
-
310
- if (Utils.isNullOrUndefined(options.buttons)) {
311
- options.buttons = [];
312
- }
313
- else if (!Array.isArray(options.buttons)) {
314
- throw new TypeError('peaks.sources.' + context + ': buttons must be an array');
315
- }
316
-
317
- if (Utils.isNullOrUndefined(options.markerColor)
318
- || !Utils.isValidColor(options.markerColor)) {
319
- options.markerColor = options.color;
320
- }
321
-
322
- if (Utils.isNullOrUndefined(options.markerWidth)) {
323
- options.markerWidth = 2;
324
- }
325
-
326
- if (!Utils.isNullOrUndefined(options.volumeRange)) {
327
- if (!Array.isArray(options.volumeRange)
328
- || options.volumeRange.length !== 2
329
- || !options.volumeRange.every(Utils.isNumber)) {
330
- throw new TypeError('peaks.sources.' + context + ': volumeRange must be an array of two numbers');
331
- }
332
- else if (options.volumeRange[0] > options.volumeRange[1]) {
333
- throw new RangeError('peaks.sources.' + context + ': volumeRange[0] should be less than volumeRange[1]');
334
- }
335
- }
336
-
337
- if (!Utils.isNullOrUndefined(options.volume)) {
338
- if (!Utils.isNumber(options.volume)) {
339
- throw new TypeError('peaks.sources.' + context + ': volume must be a number');
340
- }
341
- else {
342
- options.volume = Utils.clamp(options.volume, options.volumeRange[0], options.volumeRange[1]);
343
- }
344
- }
345
-
346
- if (Utils.isNullOrUndefined(options.loading)) {
347
- options.loading = false;
348
- }
349
- else if (!Utils.isBoolean(options.loading)) {
350
- throw new TypeError('peaks.sources.' + context + ': loading must be a boolean');
351
- }
352
- }
353
-
354
- /**
355
- * A source is an external media resource, represented on the timeline.
356
- *
357
- * @class
358
- * @alias Source
359
- *
360
- * @param {Peaks} peaks A reference to the Peaks instance.
361
- * @param {String} id A unique identifier for the source.
362
- * @param {String} originId The original identifier of the source before any cuts.
363
- * @param {String} elementId The HTML element identifier associated with this source.
364
- * @param {String} title Name of the source.
365
- * @param {Array<Object>} titleAlignments Array of objects with structure:
366
- * [{text: String, start: Number, end: Number}, ...]
367
- * @param {String} url Reference to the media element this source is representing.
368
- * @param {String} previewUrl URL for preview media content.
369
- * @param {String} binaryUrl URL for binary data associated with the source.
370
- * @param {String} kind Type/category of the source.
371
- * @param {String} subkind Sub-category of the source.
372
- * @param {Number} duration Total duration of the source media, in seconds.
373
- * @param {Number} startTime Source start time on the timeline, in seconds.
374
- * @param {Number} endTime Source end time on the timeline, in seconds.
375
- * @param {Number} mediaStartTime Start time within the source media, in seconds.
376
- * @param {Number} mediaEndTime End time within the source media, in seconds.
377
- * @param {String} color Primary color of the source representation.
378
- * @param {String} backgroundColor Background color of the source.
379
- * @param {String} borderColor Border color of the source.
380
- * @param {String} selectedColor Color when the source is selected.
381
- * @param {String} warningColor Color used for warning states.
382
- * @param {String} volumeSliderColor Color of the volume slider.
383
- * @param {Number} volumeSliderWidth Width of the volume slider.
384
- * @param {Number} volumeSliderDraggingWidth Width of the volume slider when dragging.
385
- * @param {String} textFont Font family for text display.
386
- * @param {Number} textFontSize Font size for text display.
387
- * @param {String} textColor Color of the text.
388
- * @param {String} textBackgroundColor Background color of the text.
389
- * @param {String} textPosition Position of text relative to the source.
390
- * @param {Boolean} textAutoScroll If <code>true</code> text will auto-scroll.
391
- * @param {Number} borderWidth Width of the source border.
392
- * @param {Number} borderRadius Radius for rounded corners.
393
- * @param {Boolean} wrapped If <code>true</code> the source representation will be smaller.
394
- * @param {Number} position Position of the source on the timeline. Corresponds to the index of the line.
395
- * @param {Boolean} draggable If <code>true</code> the source can be dragged.
396
- * @param {Boolean} orderable If <code>true</code> the source can be reordered.
397
- * @param {Boolean} resizable If <code>true</code> the source can be resized.
398
- * @param {Boolean} cuttable If <code>true</code> the source can be cut.
399
- * @param {Boolean} deletable If <code>true</code> the source can be deleted.
400
- * @param {String} wrapping Wrapping mode for the source display.
401
- * @param {Number} previewHeight Height of the preview area.
402
- * @param {Number} binaryHeight Height of the binary data visualization.
403
- * @param {Array} indicators Array containing indicator data for the source.
404
- * @param {Array} markers Array containing marker data for the source.
405
- * @param {Array} buttons Array containing button data for the source.
406
- * @param {String} markerColor Color of the markers.
407
- * @param {Number} markerWidth Width of the markers.
408
- * @param {Number} volume Current volume level of the source.
409
- * @param {Array<Number>} volumeRange Array containing min and max volume values.
410
- * @param {Boolean} loading If <code>true</code> the source is currently loading.
411
- */
412
-
413
- function Source(peaks, id, originId, elementId, title, titleAlignments, url, previewUrl, binaryUrl, kind,
414
- subkind, duration, startTime, endTime, mediaStartTime, mediaEndTime, color, backgroundColor,
415
- borderColor, selectedColor, warningColor, warningWidth, volumeSliderColor, volumeSliderWidth,
416
- volumeSliderDraggingWidth, textFont, textFontSize, textColor, textBackgroundColor, textPosition,
417
- textAutoScroll, borderWidth, borderRadius, wrapped, position, draggable, orderable, resizable,
418
- cuttable, deletable, wrapping, previewHeight, binaryHeight, indicators, markers, buttons, markerColor,
419
- markerWidth, volume, volumeRange, loading, ...customParams) {
420
- var opts = {
421
- title: title,
422
- titleAlignments: titleAlignments,
423
- url: url,
424
- previewUrl: previewUrl,
425
- binaryUrl: binaryUrl,
426
- kind: kind,
427
- subkind: subkind,
428
- duration: duration,
429
- startTime: startTime,
430
- endTime: endTime,
431
- mediaStartTime: mediaStartTime,
432
- mediaEndTime: mediaEndTime,
433
- color: color,
434
- backgroundColor: backgroundColor,
435
- borderColor: borderColor,
436
- selectedColor: selectedColor,
437
- warningColor: warningColor,
438
- warningWidth: warningWidth,
439
- textFont: textFont,
440
- textFontSize: textFontSize,
441
- textColor: textColor,
442
- textBackgroundColor: textBackgroundColor,
443
- volumeSliderColor: volumeSliderColor,
444
- volumeSliderWidth: volumeSliderWidth,
445
- volumeSliderDraggingWidth: volumeSliderDraggingWidth,
446
- textPosition: textPosition,
447
- textAutoScroll: textAutoScroll,
448
- borderWidth: borderWidth,
449
- borderRadius: borderRadius,
450
- wrapped: wrapped,
451
- position: position,
452
- draggable: draggable,
453
- orderable: orderable,
454
- resizable: resizable,
455
- cuttable: cuttable,
456
- deletable: deletable,
457
- wrapping: wrapping,
458
- previewHeight: previewHeight,
459
- binaryHeight: binaryHeight,
460
- indicators: indicators,
461
- markers: markers,
462
- buttons: buttons,
463
- markerColor: markerColor,
464
- markerWidth: markerWidth,
465
- volume: volume,
466
- volumeRange: volumeRange,
467
- loading: loading
468
- };
469
-
470
- validateSource(peaks, opts, 'add()');
471
-
472
- this._peaks = peaks;
473
- this._id = id;
474
- this._originId = originId || id;
475
- this._elementId = elementId;
476
- this._title = opts.title;
477
- this._titleAlignments = opts.titleAlignments;
478
- this._url = opts.url;
479
- this._previewUrl = opts.previewUrl;
480
- this._binaryUrl = opts.binaryUrl;
481
- this._kind = opts.kind;
482
- this._subkind = opts.subkind;
483
- this._duration = opts.duration;
484
- this._startTime = opts.startTime;
485
- this._endTime = opts.endTime;
486
- this._mediaStartTime = opts.mediaStartTime;
487
- this._mediaEndTime = opts.mediaEndTime;
488
- this._color = opts.color;
489
- this._backgroundColor = opts.backgroundColor;
490
- this._borderColor = opts.borderColor;
491
- this._selectedColor = opts.selectedColor || Utils.shadeColor(opts.backgroundColor, 30);
492
- this._warningColor = opts.warningColor;
493
- this._warningWidth = opts.warningWidth;
494
- this._volumeSliderColor = opts.volumeSliderColor;
495
- this._volumeSliderWidth = opts.volumeSliderWidth;
496
- this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
497
- this._textFont = opts.textFont;
498
- this._textFontSize = opts.textFontSize;
499
- this._textColor = opts.textColor;
500
- this._textBackgroundColor = opts.textBackgroundColor;
501
- this._textPosition = opts.textPosition;
502
- this._textAutoScroll = opts.textAutoScroll;
503
- this._borderWidth = opts.borderWidth;
504
- this._borderRadius = opts.borderRadius;
505
- this._wrapped = opts.wrapped;
506
- this._position = opts.position;
507
- this._draggable = opts.draggable;
508
- this._orderable = opts.orderable;
509
- this._resizable = opts.resizable;
510
- this._cuttable = opts.cuttable;
511
- this._deletable = opts.deletable;
512
- this._wrapping = opts.wrapping;
513
- this._previewHeight = opts.previewHeight;
514
- this._binaryHeight = opts.binaryHeight;
515
- this._indicators = opts.indicators;
516
- this._markers = opts.markers;
517
- this._buttons = opts.buttons;
518
- this._markerColor = opts.markerColor;
519
- this._markerWidth = opts.markerWidth;
520
- this._volume = opts.volume;
521
- this._volumeRange = opts.volumeRange;
522
- this._loading = opts.loading;
523
- this._minSize = peaks.options.minSourceSize;
524
- this._selected = false;
525
-
526
- for (var i = 0; i < customParams.length; i += 2) {
527
- var key = customParams[i];
528
- var value = customParams[i + 1];
529
-
530
- if (key && key.startsWith('custom_')) {
531
- this[key] = value;
532
- }
533
- }
534
- }
535
-
536
- Object.defineProperties(Source.prototype, {
537
- id: {
538
- enumerable: true,
539
- get: function() {
540
- return this._id;
541
- }
542
- },
543
- originId: {
544
- enumerable: true,
545
- get: function() {
546
- return this._originId;
547
- }
548
- },
549
- elementId: {
550
- enumerable: true,
551
- get: function() {
552
- return this._elementId;
553
- }
554
- },
555
- title: {
556
- enumerable: true,
557
- get: function() {
558
- return this._title;
559
- },
560
-
561
- set: function(title) {
562
- this._title = title;
563
- }
564
- },
565
- titleAlignments: {
566
- enumerable: true,
567
- get: function() {
568
- return this._titleAlignments;
569
- }
570
- },
571
- url: {
572
- enumerable: true,
573
- get: function() {
574
- return this._url;
575
- }
576
- },
577
- previewUrl: {
578
- enumerable: true,
579
- get: function() {
580
- return this._previewUrl;
581
- }
582
- },
583
- binaryUrl: {
584
- enumerable: true,
585
- get: function() {
586
- return this._binaryUrl;
587
- }
588
- },
589
- kind: {
590
- enumerable: true,
591
- get: function() {
592
- return this._kind;
593
- },
594
-
595
- set: function(kind) {
596
- this._kind = kind;
597
- }
598
- },
599
- subkind: {
600
- enumerable: true,
601
- get: function() {
602
- return this._subkind;
603
- },
604
-
605
- set: function(subkind) {
606
- this._subkind = subkind;
607
- }
608
- },
609
- duration: {
610
- enumerable: true,
611
- get: function() {
612
- return this._duration;
613
- }
614
- },
615
- startTime: {
616
- enumerable: true,
617
- get: function() {
618
- return this._startTime;
619
- }
620
- },
621
- endTime: {
622
- enumerable: true,
623
- get: function() {
624
- return this._endTime;
625
- }
626
- },
627
- mediaStartTime: {
628
- enumerable: true,
629
- get: function() {
630
- return this._mediaStartTime;
631
- },
632
-
633
- set: function(mediaStartTime) {
634
- this._mediaStartTime = mediaStartTime;
635
- }
636
- },
637
- mediaEndTime: {
638
- enumerable: true,
639
- get: function() {
640
- return this._mediaEndTime;
641
- },
642
-
643
- set: function(mediaEndTime) {
644
- this._mediaEndTime = mediaEndTime;
645
- }
646
- },
647
- color: {
648
- enumerable: true,
649
- get: function() {
650
- return this._color;
651
- },
652
-
653
- set: function(color) {
654
- this._color = color;
655
- }
656
- },
657
- backgroundColor: {
658
- enumerable: true,
659
- get: function() {
660
- return this._backgroundColor;
661
- },
662
-
663
- set: function(backgroundColor) {
664
- this._backgroundColor = backgroundColor;
665
- }
666
- },
667
- borderColor: {
668
- enumerable: true,
669
- get: function() {
670
- return this._borderColor;
671
- },
672
-
673
- set: function(borderColor) {
674
- this._borderColor = borderColor;
675
- }
676
- },
677
- selectedColor: {
678
- enumerable: true,
679
- get: function() {
680
- return this._selectedColor;
681
- },
682
-
683
- set: function(selectedColor) {
684
- this._selectedColor = selectedColor;
685
- }
686
- },
687
- warningColor: {
688
- enumerable: true,
689
- get: function() {
690
- return this._warningColor;
691
- },
692
-
693
- set: function(warningColor) {
694
- this._warningColor = warningColor;
695
- }
696
- },
697
- warningWidth: {
698
- enumerable: true,
699
- get: function() {
700
- return this._warningWidth;
701
- },
702
-
703
- set: function(warningWidth) {
704
- this._warningWidth = warningWidth;
705
- }
706
- },
707
- volumeSliderColor: {
708
- enumerable: true,
709
- get: function() {
710
- return this._volumeSliderColor;
711
- }
712
- },
713
- volumeSliderWidth: {
714
- enumerable: true,
715
- get: function() {
716
- return this._volumeSliderWidth;
717
- }
718
- },
719
- volumeSliderDraggingWidth: {
720
- enumerable: true,
721
- get: function() {
722
- return this._volumeSliderDraggingWidth;
723
- }
724
- },
725
- textFont: {
726
- enumerable: true,
727
- get: function() {
728
- return this._textFont;
729
- },
730
-
731
- set: function(textFont) {
732
- this._textFont = textFont;
733
- }
734
- },
735
- textFontSize: {
736
- enumerable: true,
737
- get: function() {
738
- return this._textFontSize;
739
- },
740
-
741
- set: function(textFontSize) {
742
- this._textFontSize = textFontSize;
743
- }
744
- },
745
- textColor: {
746
- enumerable: true,
747
- get: function() {
748
- return this._textColor;
749
- },
750
-
751
- set: function(textColor) {
752
- this._textColor = textColor;
753
- }
754
- },
755
- textBackgroundColor: {
756
- enumerable: true,
757
- get: function() {
758
- return this._textBackgroundColor;
759
- },
760
-
761
- set: function(textBackgroundColor) {
762
- this._textBackgroundColor = textBackgroundColor;
763
- }
764
- },
765
- textPosition: {
766
- enumerable: true,
767
- get: function() {
768
- return this._textPosition;
769
- },
770
-
771
- set: function(textPosition) {
772
- this._textPosition = textPosition;
773
- }
774
- },
775
- textAutoScroll: {
776
- enumerable: true,
777
- get: function() {
778
- return this._textAutoScroll;
779
- },
780
-
781
- set: function(textAutoScroll) {
782
- this._textAutoScroll = textAutoScroll;
783
- }
784
- },
785
- borderWidth: {
786
- enumerable: true,
787
- get: function() {
788
- return this._borderWidth;
789
- },
790
-
791
- set: function(borderWidth) {
792
- this._borderWidth = borderWidth;
793
- }
794
- },
795
- borderRadius: {
796
- enumerable: true,
797
- get: function() {
798
- return this._borderRadius;
799
- },
800
-
801
- set: function(borderRadius) {
802
- this._borderRadius = borderRadius;
803
- }
804
- },
805
- wrapped: {
806
- enumerable: true,
807
- get: function() {
808
- return this._wrapped;
809
- },
810
-
811
- set: function(wrapped) {
812
- this._wrapped = wrapped;
813
- }
814
- },
815
- position: {
816
- enumerable: true,
817
- get: function() {
818
- return this._position;
819
- },
820
-
821
- set: function(position) {
822
- this._position = position;
823
- }
824
- },
825
- segments: {
826
- enumerable: true,
827
- get: function() {
828
- return this._segments;
829
- }
830
- },
831
- draggable: {
832
- enumerable: true,
833
- get: function() {
834
- return this._draggable;
835
- }
836
- },
837
- orderable: {
838
- enumerable: true,
839
- get: function() {
840
- return this._orderable;
841
- }
842
- },
843
- resizable: {
844
- enumerable: true,
845
- get: function() {
846
- return this._resizable;
847
- }
848
- },
849
- cuttable: {
850
- enumerable: true,
851
- get: function() {
852
- return this._cuttable;
853
- }
854
- },
855
- deletable: {
856
- enumerable: true,
857
- get: function() {
858
- return this._deletable;
859
- }
860
- },
861
- wrapping: {
862
- enumerable: true,
863
- get: function() {
864
- return this._wrapping;
865
- },
866
-
867
- set: function(wrapping) {
868
- this._wrapping = wrapping;
869
- }
870
- },
871
- previewHeight: {
872
- enumerable: true,
873
- get: function() {
874
- return this._previewHeight;
875
- },
876
-
877
- set: function(previewHeight) {
878
- this._previewHeight = previewHeight;
879
- }
880
- },
881
- binaryHeight: {
882
- enumerable: true,
883
- get: function() {
884
- return this._binaryHeight;
885
- },
886
-
887
- set: function(binaryHeight) {
888
- this._binaryHeight = binaryHeight;
889
- }
890
- },
891
- indicators: {
892
- enumerable: true,
893
- get: function() {
894
- return this._indicators;
895
- }
896
- },
897
- markers: {
898
- enumerable: true,
899
- get: function() {
900
- return this._markers;
901
- }
902
- },
903
- buttons: {
904
- enumerable: true,
905
- get: function() {
906
- return this._buttons;
907
- }
908
- },
909
- markerColor: {
910
- enumerable: true,
911
- get: function() {
912
- return this._markerColor;
913
- }
914
- },
915
- markerWidth: {
916
- enumerable: true,
917
- get: function() {
918
- return this._markerWidth;
919
- }
920
- },
921
- volume: {
922
- enumerable: true,
923
- get: function() {
924
- return this._volume;
925
- },
926
-
927
- set: function(volume) {
928
- this._volume = volume;
929
- }
930
- },
931
- volumeRange: {
932
- enumerable: true,
933
- get: function() {
934
- return this._volumeRange;
935
- }
936
- },
937
- loading: {
938
- enumerable: true,
939
- get: function() {
940
- return this._loading;
941
- }
942
- },
943
- minSize: {
944
- enumerable: true,
945
- get: function() {
946
- return this._minSize;
947
- }
948
- },
949
- selected: {
950
- enumerable: true,
951
- get: function() {
952
- return this._selected;
953
- },
954
-
955
- set: function(selected) {
956
- this._selected = selected;
957
- }
958
- }
959
- });
960
-
961
- Source.prototype.updateTimes = function(newStartTime, newEndTime) {
962
- if (newStartTime !== null) {
963
- if (this._duration && newEndTime === null) {
964
- newStartTime = Utils.roundTime(Math.max(this._endTime - this._duration, newStartTime));
965
- }
966
- else {
967
- newStartTime = Utils.roundTime(newStartTime);
968
- }
969
- }
970
-
971
- if (newEndTime !== null) {
972
- if (this._duration && newStartTime === null) {
973
- newEndTime = Utils.roundTime(Math.min(this._startTime + this._duration, newEndTime));
974
- }
975
- else {
976
- newEndTime = Utils.roundTime(newEndTime);
977
- }
978
- }
979
-
980
- if ((newStartTime === null && newEndTime !== null)
981
- || (newStartTime !== null && newEndTime === null)) {
982
- this._updateMediaRange(this._startTime, newStartTime, this._endTime, newEndTime);
983
- }
984
-
985
- if (newStartTime !== null) {
986
- this._startTime = newStartTime;
987
- }
988
- if (newEndTime !== null) {
989
- this._endTime = newEndTime;
990
- }
991
- };
992
-
993
- Source.prototype._updateMediaRange = function(oldStartTime, newStartTime, oldEndTime,
994
- newEndTime) {
995
- var startDiff = 0;
996
- var endDiff = 0;
997
- var upperLimit;
998
-
999
- if (this._duration) {
1000
- upperLimit = this._duration;
1001
- }
1002
- else {
1003
- upperLimit = Number.POSITIVE_INFINITY;
1004
- }
1005
-
1006
- if (newStartTime !== null && oldStartTime !== null) {
1007
- startDiff = newStartTime - oldStartTime;
1008
- }
1009
- if (newEndTime !== null && oldEndTime !== null) {
1010
- endDiff = newEndTime - oldEndTime;
1011
- }
1012
-
1013
- var newMediaStartTime = this._mediaStartTime;
1014
- var newMediaEndTime = this._mediaEndTime;
1015
-
1016
- if (startDiff) {
1017
- if (startDiff < 0) {
1018
- // Try reducing mediaStartTime
1019
- if (newMediaStartTime > 0) {
1020
- var minStartTime = newMediaStartTime + startDiff;
1021
-
1022
- newMediaStartTime = Math.max(0, minStartTime);
1023
- if (minStartTime < 0) {
1024
- // Try increasing mediaEndTime
1025
- newMediaEndTime = Math.min(upperLimit, newMediaEndTime - minStartTime);
1026
- }
1027
- }
1028
- else {
1029
- // Try increasing mediaEndTime
1030
- newMediaEndTime = Math.min(upperLimit, newMediaEndTime - startDiff);
1031
- }
1032
- }
1033
- else {
1034
- // Try increasing mediaStartTime
1035
- if (newMediaStartTime < upperLimit) {
1036
- newMediaStartTime = Math.min(upperLimit, newMediaStartTime + startDiff);
1037
- }
1038
- }
1039
- }
1040
-
1041
- if (endDiff) {
1042
- if (endDiff > 0) {
1043
- // Try increasing mediaEndTime
1044
- if (newMediaEndTime < upperLimit) {
1045
- var maxEndTime = newMediaEndTime + endDiff;
1046
-
1047
- newMediaEndTime = Math.min(upperLimit, maxEndTime);
1048
- if (maxEndTime > upperLimit) {
1049
- // Try reducing mediaStartTime
1050
- newMediaStartTime = Math.max(0, newMediaStartTime - (maxEndTime - upperLimit));
1051
- }
1052
- }
1053
- else {
1054
- // Try reducing mediaStartTime
1055
- newMediaStartTime = Math.max(0, newMediaStartTime - endDiff);
1056
- }
1057
- }
1058
- else {
1059
- if (newEndTime - oldStartTime < upperLimit) {
1060
- if (oldEndTime - oldStartTime > upperLimit) {
1061
- endDiff += (oldEndTime - oldStartTime) - upperLimit;
1062
- }
1063
-
1064
- // Try reducing mediaEndTime
1065
- if (newMediaEndTime > 0) {
1066
- newMediaEndTime = Math.max(0, newMediaEndTime + endDiff);
1067
- }
1068
- }
1069
- }
1070
- }
1071
-
1072
- this._mediaStartTime = Utils.roundTime(newMediaStartTime);
1073
- this._mediaEndTime = Utils.roundTime(newMediaEndTime);
1074
- };
1075
-
1076
- Source.prototype.update = function(options) {
1077
- var opts = {
1078
- title: this.title,
1079
- titleAlignments: this.titleAlignments,
1080
- url: this.url,
1081
- previewUrl: this.previewUrl,
1082
- binaryUrl: this.binaryUrl,
1083
- kind: this.kind,
1084
- subkind: this.subkind,
1085
- duration: this.duration,
1086
- startTime: this.startTime,
1087
- endTime: this.endTime,
1088
- mediaStartTime: this.mediaStartTime,
1089
- mediaEndTime: this.mediaEndTime,
1090
- color: this.color,
1091
- backgroundColor: this.backgroundColor,
1092
- borderColor: this.borderColor,
1093
- selectedColor: this.selectedColor,
1094
- warningColor: this.warningColor,
1095
- warningWidth: this.warningWidth,
1096
- volumeSliderColor: this.volumeSliderColor,
1097
- volumeSliderWidth: this.volumeSliderWidth,
1098
- volumeSliderDraggingWidth: this.volumeSliderDraggingWidth,
1099
- textFont: this.textFont,
1100
- textFontSize: this.textFontSize,
1101
- textColor: this.textColor,
1102
- textBackgroundColor: this.textBackgroundColor,
1103
- textPosition: this.textPosition,
1104
- textAutoScroll: this.textAutoScroll,
1105
- borderWidth: this.borderWidth,
1106
- borderRadius: this.borderRadius,
1107
- wrapped: this.wrapped,
1108
- position: this.position,
1109
- draggable: this.draggable,
1110
- orderable: this.orderable,
1111
- resizable: this.resizable,
1112
- cuttable: this.cuttable,
1113
- deletable: this.deletable,
1114
- wrapping: this.wrapping,
1115
- previewHeight: this.previewHeight,
1116
- binaryHeight: this.binaryHeight,
1117
- indicators: this.indicators,
1118
- markers: this.markers,
1119
- buttons: this.buttons,
1120
- markerColor: this.markerColor,
1121
- markerWidth: this.markerWidth,
1122
- volume: this.volume,
1123
- volumeRange: this.volumeRange,
1124
- loading: this.loading
1125
- };
1126
-
1127
- Utils.extend(opts, options);
1128
-
1129
- validateSource(this._peaks, opts, 'update()');
1130
-
1131
- this._title = opts.title;
1132
- this._titleAlignments = opts.titleAlignments;
1133
- this._url = opts.url;
1134
- this._previewUrl = opts.previewUrl;
1135
- this._binaryUrl = opts.binaryUrl;
1136
- this._kind = opts.kind;
1137
- this._subkind = opts.subkind;
1138
- this._duration = opts.duration;
1139
- this._startTime = opts.startTime;
1140
- this._endTime = opts.endTime;
1141
- this._mediaStartTime = opts.mediaStartTime;
1142
- this._mediaEndTime = opts.mediaEndTime;
1143
- this._color = opts.color;
1144
- this._backgroundColor = opts.backgroundColor;
1145
- this._borderColor = opts.borderColor;
1146
- this._selectedColor = opts.selectedColor || Utils.shadeColor(opts.backgroundColor, 30);
1147
- this._warningColor = opts.warningColor;
1148
- this._warningWidth = opts.warningWidth;
1149
- this._volumeSliderColor = opts.volumeSliderColor;
1150
- this._volumeSliderWidth = opts.volumeSliderWidth;
1151
- this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
1152
- this._textFont = opts.textFont;
1153
- this._textFontSize = opts.textFontSize;
1154
- this._textColor = opts.textColor;
1155
- this._textBackgroundColor = opts.textBackgroundColor;
1156
- this._textPosition = opts.textPosition;
1157
- this._textAutoScroll = opts.textAutoScroll;
1158
- this._borderWidth = opts.borderWidth;
1159
- this._borderRadius = opts.borderRadius;
1160
- this._wrapped = opts.wrapped;
1161
- this._position = opts.position;
1162
- this._draggable = opts.draggable;
1163
- this._orderable = opts.orderable;
1164
- this._resizable = opts.resizable;
1165
- this._cuttable = opts.cuttable;
1166
- this._deletable = opts.deletable;
1167
- this._wrapping = opts.wrapping;
1168
- this._previewHeight = opts.previewHeight;
1169
- this._binaryHeight = opts.binaryHeight;
1170
- this._indicators = opts.indicators;
1171
- this._markers = opts.markers;
1172
- this._buttons = opts.buttons;
1173
- this._markerColor = opts.markerColor;
1174
- this._markerWidth = opts.markerWidth;
1175
- this._volume = opts.volume;
1176
- this._volumeRange = opts.volumeRange;
1177
- this._loading = opts.loading;
1178
-
1179
- if (options && typeof options === 'object') {
1180
- for (var key in options) {
1181
- if (Object.prototype.hasOwnProperty.call(options, key) && key.startsWith('custom_')) {
1182
- this[key] = options[key];
1183
- }
1184
- }
1185
- }
1186
-
1187
- this._peaks.emit('source.update', this);
1188
- };
1189
-
1190
- /**
1191
- * Returns <code>true</code> if the source overlaps a given time region.
1192
- *
1193
- * @param {Number} startTime The start of the time region, in seconds.
1194
- * @param {Number} endTime The end of the time region, in seconds.
1195
- * @returns {Boolean}
1196
- *
1197
- * @see http://wiki.c2.com/?TestIfDateRangesOverlap
1198
- */
1199
- Source.prototype.isVisible = function(startTime, endTime) {
1200
- return this._startTime < endTime && startTime < this._endTime;
1201
- };
1202
-
1203
- /**
1204
- * Update the indicators of this source.
1205
- *
1206
- * @param {Array<String>} newIndicators The new indicators.
1207
- */
1208
-
1209
- Source.prototype.setIndicators = function(newIndicators) {
1210
- this._indicators = newIndicators;
1211
- this._peaks.emit('source.setIndicators', this);
1212
- };
1213
-
1214
- /**
1215
- * Returns <code>true</code> if a warning should be shown
1216
- */
1217
-
1218
- Source.prototype.shouldShowWarning = function() {
1219
- return this._warningColor && this._duration > Utils.roundTime(this._endTime - this._startTime);
1220
- };
1221
-
1222
- Source.prototype.getVisibleTitle = function() {
1223
- if (this._titleAlignments.length === 0) {
1224
- return this._title;
1225
- }
1226
-
1227
- return this._titleAlignments.reduce(function(visibleTitle, alignment) {
1228
- if (this._mediaStartTime < alignment.end && alignment.start < this._mediaEndTime) {
1229
- visibleTitle.push(alignment.text);
1230
- }
1231
- return visibleTitle;
1232
- }.bind(this), []).join(' ');
1233
- };
1234
-
1235
- /**
1236
- * Returns a serializable object containing only the properties defined with Object.defineProperties.
1237
- * This includes all enumerable properties that can be safely serialized.
1238
- *
1239
- * @returns {Object} A plain object containing the serializable properties of the source.
1240
- */
1241
- Source.prototype.toSerializable = function() {
1242
- var serializable = {};
1243
-
1244
- // Get all custom properties
1245
- for (var key in this) {
1246
- if (Object.prototype.hasOwnProperty.call(this, key) && key.startsWith('custom_')) {
1247
- serializable[key] = this[key];
1248
- }
1249
- }
1250
-
1251
- // Add all the enumerable properties from the prototype
1252
- var proto = Object.getPrototypeOf(this);
1253
- var descriptors = Object.getOwnPropertyDescriptors(proto);
1254
-
1255
- for (var prop in descriptors) {
1256
- if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
1257
- var descriptor = descriptors[prop];
1258
-
1259
- if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
1260
- serializable[prop] = this[prop];
1261
- }
1262
- }
1263
- }
1264
-
1265
- return serializable;
1266
- };
1267
-
1268
- return Source;
1269
- });
1
+ /**
2
+ * @file
3
+ *
4
+ * Defines the {@link source} class.
5
+ *
6
+ * @module source
7
+ */
8
+
9
+ define([
10
+ '../utils'
11
+ ], function(Utils) {
12
+ 'use strict';
13
+
14
+ function validateSource(peaks, options, context) {
15
+ if (!Utils.isValidTime(options.startTime)) {
16
+ throw new TypeError('peaks.sources.' + context + ': startTime should be a valid number');
17
+ }
18
+
19
+ if (!Utils.isValidTime(options.endTime)) {
20
+ throw new TypeError('peaks.sources.' + context + ': endTime should be a valid number');
21
+ }
22
+
23
+ if (!Utils.isValidTime(options.duration) || options.duration <= 0) {
24
+ options.duration = 0;
25
+ }
26
+ else if (options.duration < peaks.options.minSourceSize) {
27
+ options.duration = peaks.options.minSourceSize;
28
+ }
29
+
30
+ options.duration = Utils.roundTime(options.duration);
31
+
32
+ if (options.startTime < 0) {
33
+ throw new RangeError('peaks.sources.' + context + ': startTime should be positive');
34
+ }
35
+
36
+ if (options.endTime < 0) {
37
+ throw new RangeError('peaks.sources.' + context + ': endTime should be positive');
38
+ }
39
+
40
+ if (options.endTime <= options.startTime) {
41
+ throw new RangeError(
42
+ 'peaks.sources.' + context + ': endTime should be greater than startTime'
43
+ );
44
+ }
45
+
46
+ if (options.endTime - options.startTime < peaks.options.minSourceSize) {
47
+ options.endTime = options.startTime + peaks.options.minSourceSize;
48
+ }
49
+
50
+ if (!Utils.isValidTime(options.mediaStartTime) || options.mediaStartTime < 0) {
51
+ options.mediaStartTime = 0;
52
+ }
53
+
54
+ if (!Utils.isValidTime(options.mediaEndTime)
55
+ || (options.mediaEndTime < options.mediaStartTime)
56
+ || (options.mediaEndTime - options.mediaStartTime !== options.endTime - options.startTime)) {
57
+ options.mediaEndTime = options.mediaStartTime + (options.endTime - options.startTime);
58
+ }
59
+
60
+ if (options.duration && options.mediaEndTime > options.duration) {
61
+ var timeWidth = options.mediaEndTime - options.mediaStartTime;
62
+
63
+ options.mediaEndTime = options.duration;
64
+ if (options.duration > timeWidth) {
65
+ options.mediaStartTime = options.mediaEndTime - timeWidth;
66
+ options.endTime = options.startTime + timeWidth;
67
+ }
68
+ else {
69
+ options.mediaStartTime = 0;
70
+ options.endTime = options.startTime + options.duration;
71
+ }
72
+ }
73
+
74
+ options.startTime = Utils.roundTime(options.startTime);
75
+ options.endTime = Utils.roundTime(options.endTime);
76
+ options.mediaStartTime = Utils.roundTime(options.mediaStartTime);
77
+ options.mediaEndTime = Utils.roundTime(options.mediaEndTime);
78
+
79
+ if (Utils.isNullOrUndefined(options.title)) {
80
+ options.title = '';
81
+ }
82
+ else if (!Utils.isString(options.title)) {
83
+ throw new TypeError('peaks.sources.' + context + ': title must be a string');
84
+ }
85
+
86
+ if (Utils.isNullOrUndefined(options.titleAlignments)) {
87
+ options.titleAlignments = [];
88
+ }
89
+ else if (!Array.isArray(options.titleAlignments)) {
90
+ throw new TypeError('peaks.sources.' + context + ': titleAlignments must be an array');
91
+ }
92
+
93
+ if (Utils.isNullOrUndefined(options.url)) {
94
+ options.url = '';
95
+ }
96
+ else if (!Utils.isString(options.url)) {
97
+ throw new TypeError('peaks.sources.' + context + ': url must be a string');
98
+ }
99
+
100
+ if (Utils.isNullOrUndefined(options.previewUrl)) {
101
+ options.previewUrl = '';
102
+ }
103
+ else if (!Utils.isString(options.previewUrl)) {
104
+ throw new TypeError('peaks.sources.' + context + ': previewUrl must be a string');
105
+ }
106
+
107
+ if (Utils.isNullOrUndefined(options.binaryUrl)) {
108
+ options.binaryUrl = '';
109
+ }
110
+ else if (!Utils.isString(options.binaryUrl)) {
111
+ throw new TypeError('peaks.sources.' + context + ': binaryUrl must be a string');
112
+ }
113
+
114
+ if (!Utils.isValidColor(options.color)) {
115
+ options.color = peaks.options.zoomWaveformColor;
116
+ }
117
+
118
+ if (!Utils.isValidColor(options.backgroundColor)) {
119
+ throw new TypeError(
120
+ 'peaks.sources.' + context + ': backgroundColor should be a valid CSS color'
121
+ );
122
+ }
123
+
124
+ if (!Utils.isValidColor(options.borderColor)) {
125
+ options.borderColor = options.color;
126
+ }
127
+
128
+ if (Utils.isNullOrUndefined(options.selectedColor)) {
129
+ options.selectedColor = null;
130
+ }
131
+ else if (!Utils.isValidColor(options.selectedColor)) {
132
+ throw new TypeError(
133
+ 'peaks.sources.' + context + ': selectedColor should be a valid CSS color'
134
+ );
135
+ }
136
+
137
+ if (Utils.isNullOrUndefined(options.warningColor)) {
138
+ options.warningColor = null;
139
+ }
140
+ else if (!Utils.isValidColor(options.warningColor)) {
141
+ throw new TypeError(
142
+ 'peaks.sources.' + context + ': warningColor should be a valid CSS color'
143
+ );
144
+ }
145
+
146
+ if (Utils.isNullOrUndefined(options.warningWidth)) {
147
+ options.warningWidth = 10;
148
+ }
149
+ else if (!Utils.isNumber(options.warningWidth)) {
150
+ throw new TypeError('peaks.sources.' + context + ': warningWidth should be a number');
151
+ }
152
+
153
+ if (Utils.isNullOrUndefined(options.volumeSliderColor)) {
154
+ options.volumeSliderColor = '#000000';
155
+ }
156
+ else if (!Utils.isValidColor(options.volumeSliderColor)) {
157
+ throw new TypeError(
158
+ 'peaks.sources.' + context + ': volumeSliderColor should be a valid CSS color'
159
+ );
160
+ }
161
+
162
+ if (Utils.isNullOrUndefined(options.volumeSliderWidth)) {
163
+ options.volumeSliderWidth = 2;
164
+ }
165
+ else if (!Utils.isNumber(options.volumeSliderWidth)) {
166
+ throw new TypeError('peaks.sources.' + context + ': volumeSliderWidth should be a number');
167
+ }
168
+
169
+ if (Utils.isNullOrUndefined(options.volumeSliderDraggingWidth)) {
170
+ options.volumeSliderDraggingWidth = options.volumeSliderWidth;
171
+ }
172
+ else if (!Utils.isNumber(options.volumeSliderDraggingWidth)) {
173
+ throw new TypeError(
174
+ 'peaks.sources.' + context + ': volumeSliderDraggingWidth should be a number'
175
+ );
176
+ }
177
+
178
+ if (Utils.isNullOrUndefined(options.textFont)) {
179
+ options.textFont = 'Arial';
180
+ }
181
+
182
+ if (Utils.isNullOrUndefined(options.textFontSize)) {
183
+ options.textFontSize = 12;
184
+ }
185
+
186
+ if (Utils.isNullOrUndefined(options.textColor)) {
187
+ options.textColor = '#000000';
188
+ }
189
+ else if (!Utils.isValidColor(options.textColor)) {
190
+ throw new TypeError('peaks.sources.' + context + ': textColor should be a valid CSS color');
191
+ }
192
+
193
+ if (!Utils.isNullOrUndefined(options.textBackgroundColor)
194
+ && !Utils.isValidColor(options.textBackgroundColor)) {
195
+ throw new TypeError(
196
+ 'peaks.sources.' + context + ': textBackgroundColor should be a valid CSS color'
197
+ );
198
+ }
199
+
200
+ if (Utils.isNullOrUndefined(options.textPosition)) {
201
+ options.textPosition = 'bottom';
202
+ }
203
+ else if (!Utils.isString(options.textPosition)) {
204
+ throw new TypeError('peaks.sources.' + context + ': textPosition must be a string');
205
+ }
206
+
207
+ if (Utils.isNullOrUndefined(options.textAutoScroll)) {
208
+ options.textAutoScroll = false;
209
+ }
210
+
211
+ if (Utils.isNullOrUndefined(options.borderWidth)) {
212
+ options.borderWidth = 0;
213
+ }
214
+
215
+ if (Utils.isNullOrUndefined(options.wrapped)) {
216
+ options.wrapped = false;
217
+ }
218
+ else if (!Utils.isBoolean(options.wrapped)) {
219
+ throw new TypeError('peaks.sources.' + context + ': wrapped must be a boolean');
220
+ }
221
+
222
+ if (Utils.isNullOrUndefined(options.draggable)) {
223
+ options.draggable = true;
224
+ }
225
+ else if (!Utils.isBoolean(options.draggable)) {
226
+ throw new TypeError('peaks.sources.' + context + ': draggable must be a boolean');
227
+ }
228
+
229
+ if (Utils.isNullOrUndefined(options.orderable)) {
230
+ options.orderable = true;
231
+ }
232
+ else if (!Utils.isBoolean(options.orderable)) {
233
+ throw new TypeError('peaks.sources.' + context + ': orderable must be a boolean');
234
+ }
235
+
236
+ if (Utils.isNullOrUndefined(options.resizable)) {
237
+ options.resizable = true;
238
+ }
239
+ else if (!Utils.isBoolean(options.resizable)) {
240
+ throw new TypeError('peaks.sources.' + context + ': resizable must be a boolean');
241
+ }
242
+
243
+ if (Utils.isNullOrUndefined(options.cuttable)) {
244
+ options.cuttable = true;
245
+ }
246
+ else if (!Utils.isBoolean(options.cuttable)) {
247
+ throw new TypeError('peaks.sources.' + context + ': cuttable must be a boolean');
248
+ }
249
+
250
+ if (Utils.isNullOrUndefined(options.deletable)) {
251
+ options.deletable = true;
252
+ }
253
+ else if (!Utils.isBoolean(options.deletable)) {
254
+ throw new TypeError('peaks.sources.' + context + ': deletable must be a boolean');
255
+ }
256
+
257
+ if (Utils.isNullOrUndefined(options.wrapping)) {
258
+ options.wrapping = 'both';
259
+ }
260
+ else if (!Utils.isString(options.wrapping)) {
261
+ throw new TypeError('peaks.sources.' + context + ': wrapping must be a string');
262
+ }
263
+
264
+ if (Utils.isNullOrUndefined(options.previewHeight)) {
265
+ options.previewHeight = 0;
266
+ }
267
+ else if (!Utils.isNumber(options.previewHeight)) {
268
+ throw new TypeError('peaks.sources.' + context + ': previewHeight must be a number');
269
+ }
270
+
271
+ if (Utils.isNullOrUndefined(options.binaryHeight)) {
272
+ options.binaryHeight = 0;
273
+ }
274
+ else if (!Utils.isNumber(options.binaryHeight)) {
275
+ throw new TypeError('peaks.sources.' + context + ': binaryHeight must be a number');
276
+ }
277
+
278
+ if (options.previewUrl && !options.previewHeight) {
279
+ if (options.binaryHeight) {
280
+ options.previewHeight = Math.max(peaks.options.lineHeight - options.binaryHeight, 0);
281
+ }
282
+ else {
283
+ options.previewHeight = peaks.options.lineHeight / 2;
284
+ }
285
+ }
286
+
287
+ if (options.binaryUrl && !options.binaryHeight) {
288
+ options.binaryHeight = Math.max(peaks.options.lineHeight - options.previewHeight, 0);
289
+ }
290
+
291
+ if (options.wrapping === 'reduced') {
292
+ options.wrapped = true;
293
+ }
294
+ else if (options.wrapping === 'complete') {
295
+ options.wrapped = false;
296
+ }
297
+
298
+ if (Utils.isNullOrUndefined(options.indicators)) {
299
+ options.indicators = [];
300
+ }
301
+
302
+ if (Utils.isNullOrUndefined(options.markers)) {
303
+ options.markers = [];
304
+ }
305
+
306
+ if (Utils.isNullOrUndefined(options.buttons)) {
307
+ options.buttons = [];
308
+ }
309
+ else if (!Array.isArray(options.buttons)) {
310
+ throw new TypeError('peaks.sources.' + context + ': buttons must be an array');
311
+ }
312
+
313
+ if (Utils.isNullOrUndefined(options.markerColor)
314
+ || !Utils.isValidColor(options.markerColor)) {
315
+ options.markerColor = options.color;
316
+ }
317
+
318
+ if (Utils.isNullOrUndefined(options.markerWidth)) {
319
+ options.markerWidth = 2;
320
+ }
321
+
322
+ if (!Utils.isNullOrUndefined(options.volumeRange)) {
323
+ if (!Array.isArray(options.volumeRange)
324
+ || options.volumeRange.length !== 2
325
+ || !options.volumeRange.every(Utils.isNumber)) {
326
+ throw new TypeError('peaks.sources.' + context + ': volumeRange must be an array of two numbers');
327
+ }
328
+ else if (options.volumeRange[0] > options.volumeRange[1]) {
329
+ throw new RangeError('peaks.sources.' + context + ': volumeRange[0] should be less than volumeRange[1]');
330
+ }
331
+ }
332
+
333
+ if (!Utils.isNullOrUndefined(options.volume)) {
334
+ if (!Utils.isNumber(options.volume)) {
335
+ throw new TypeError('peaks.sources.' + context + ': volume must be a number');
336
+ }
337
+ else {
338
+ options.volume = Utils.clamp(options.volume, options.volumeRange[0], options.volumeRange[1]);
339
+ }
340
+ }
341
+
342
+ if (Utils.isNullOrUndefined(options.loading)) {
343
+ options.loading = false;
344
+ }
345
+ else if (!Utils.isBoolean(options.loading)) {
346
+ throw new TypeError('peaks.sources.' + context + ': loading must be a boolean');
347
+ }
348
+ }
349
+
350
+ /**
351
+ * A source is an external media resource, represented on the timeline.
352
+ *
353
+ * @class
354
+ * @alias Source
355
+ *
356
+ * @param {Peaks} peaks A reference to the Peaks instance.
357
+ * @param {String} id A unique identifier for the source.
358
+ * @param {String} lineId The identifier of the line this source belongs to.
359
+ * @param {String} originId The original identifier of the source before any cuts.
360
+ * @param {String} elementId The HTML element identifier associated with this source.
361
+ * @param {String} title Name of the source.
362
+ * @param {Array<Object>} titleAlignments Array of objects with structure:
363
+ * [{text: String, start: Number, end: Number}, ...]
364
+ * @param {String} url Reference to the media element this source is representing.
365
+ * @param {String} previewUrl URL for preview media content.
366
+ * @param {String} binaryUrl URL for binary data associated with the source.
367
+ * @param {String} kind Type/category of the source.
368
+ * @param {String} subkind Sub-category of the source.
369
+ * @param {Number} duration Total duration of the source media, in seconds.
370
+ * @param {Number} startTime Source start time on the timeline, in seconds.
371
+ * @param {Number} endTime Source end time on the timeline, in seconds.
372
+ * @param {Number} mediaStartTime Start time within the source media, in seconds.
373
+ * @param {Number} mediaEndTime End time within the source media, in seconds.
374
+ * @param {String} color Primary color of the source representation.
375
+ * @param {String} backgroundColor Background color of the source.
376
+ * @param {String} borderColor Border color of the source.
377
+ * @param {String} selectedColor Color when the source is selected.
378
+ * @param {String} warningColor Color used for warning states.
379
+ * @param {String} volumeSliderColor Color of the volume slider.
380
+ * @param {Number} volumeSliderWidth Width of the volume slider.
381
+ * @param {Number} volumeSliderDraggingWidth Width of the volume slider when dragging.
382
+ * @param {String} textFont Font family for text display.
383
+ * @param {Number} textFontSize Font size for text display.
384
+ * @param {String} textColor Color of the text.
385
+ * @param {String} textBackgroundColor Background color of the text.
386
+ * @param {String} textPosition Position of text relative to the source.
387
+ * @param {Boolean} textAutoScroll If <code>true</code> text will auto-scroll.
388
+ * @param {Number} borderWidth Width of the source border.
389
+ * @param {Number} borderRadius Radius for rounded corners.
390
+ * @param {Boolean} wrapped If <code>true</code> the source representation will be smaller.
391
+ * @param {Boolean} draggable If <code>true</code> the source can be dragged.
392
+ * @param {Boolean} orderable If <code>true</code> the source can be reordered.
393
+ * @param {Boolean} resizable If <code>true</code> the source can be resized.
394
+ * @param {Boolean} cuttable If <code>true</code> the source can be cut.
395
+ * @param {Boolean} deletable If <code>true</code> the source can be deleted.
396
+ * @param {String} wrapping Wrapping mode for the source display.
397
+ * @param {Number} previewHeight Height of the preview area.
398
+ * @param {Number} binaryHeight Height of the binary data visualization.
399
+ * @param {Array} indicators Array containing indicator data for the source.
400
+ * @param {Array} markers Array containing marker data for the source.
401
+ * @param {Array} buttons Array containing button data for the source.
402
+ * @param {String} markerColor Color of the markers.
403
+ * @param {Number} markerWidth Width of the markers.
404
+ * @param {Number} volume Current volume level of the source.
405
+ * @param {Array<Number>} volumeRange Array containing min and max volume values.
406
+ * @param {Boolean} loading If <code>true</code> the source is currently loading.
407
+ */
408
+
409
+ function Source(peaks, id, lineId, originId, elementId, title, titleAlignments, url, previewUrl, binaryUrl, kind,
410
+ subkind, duration, startTime, endTime, mediaStartTime, mediaEndTime, color, backgroundColor,
411
+ borderColor, selectedColor, warningColor, warningWidth, volumeSliderColor, volumeSliderWidth,
412
+ volumeSliderDraggingWidth, textFont, textFontSize, textColor, textBackgroundColor, textPosition,
413
+ textAutoScroll, borderWidth, borderRadius, wrapped, draggable, orderable, resizable,
414
+ cuttable, deletable, wrapping, previewHeight, binaryHeight, indicators, markers, buttons, markerColor,
415
+ markerWidth, volume, volumeRange, loading, ...customParams) {
416
+ var opts = {
417
+ title: title,
418
+ titleAlignments: titleAlignments,
419
+ url: url,
420
+ previewUrl: previewUrl,
421
+ binaryUrl: binaryUrl,
422
+ kind: kind,
423
+ subkind: subkind,
424
+ duration: duration,
425
+ startTime: startTime,
426
+ endTime: endTime,
427
+ mediaStartTime: mediaStartTime,
428
+ mediaEndTime: mediaEndTime,
429
+ color: color,
430
+ backgroundColor: backgroundColor,
431
+ borderColor: borderColor,
432
+ selectedColor: selectedColor,
433
+ warningColor: warningColor,
434
+ warningWidth: warningWidth,
435
+ textFont: textFont,
436
+ textFontSize: textFontSize,
437
+ textColor: textColor,
438
+ textBackgroundColor: textBackgroundColor,
439
+ volumeSliderColor: volumeSliderColor,
440
+ volumeSliderWidth: volumeSliderWidth,
441
+ volumeSliderDraggingWidth: volumeSliderDraggingWidth,
442
+ textPosition: textPosition,
443
+ textAutoScroll: textAutoScroll,
444
+ borderWidth: borderWidth,
445
+ borderRadius: borderRadius,
446
+ wrapped: wrapped,
447
+ draggable: draggable,
448
+ orderable: orderable,
449
+ resizable: resizable,
450
+ cuttable: cuttable,
451
+ deletable: deletable,
452
+ wrapping: wrapping,
453
+ previewHeight: previewHeight,
454
+ binaryHeight: binaryHeight,
455
+ indicators: indicators,
456
+ markers: markers,
457
+ buttons: buttons,
458
+ markerColor: markerColor,
459
+ markerWidth: markerWidth,
460
+ volume: volume,
461
+ volumeRange: volumeRange,
462
+ loading: loading
463
+ };
464
+
465
+ validateSource(peaks, opts, 'add()');
466
+
467
+ this._peaks = peaks;
468
+ this._id = id;
469
+ this._lineId = lineId;
470
+ this._originId = originId || id;
471
+ this._elementId = elementId;
472
+ this._title = opts.title;
473
+ this._titleAlignments = opts.titleAlignments;
474
+ this._url = opts.url;
475
+ this._previewUrl = opts.previewUrl;
476
+ this._binaryUrl = opts.binaryUrl;
477
+ this._kind = opts.kind;
478
+ this._subkind = opts.subkind;
479
+ this._duration = opts.duration;
480
+ this._startTime = opts.startTime;
481
+ this._endTime = opts.endTime;
482
+ this._mediaStartTime = opts.mediaStartTime;
483
+ this._mediaEndTime = opts.mediaEndTime;
484
+ this._color = opts.color;
485
+ this._backgroundColor = opts.backgroundColor;
486
+ this._borderColor = opts.borderColor;
487
+ this._selectedColor = opts.selectedColor || Utils.shadeColor(opts.backgroundColor, 30);
488
+ this._warningColor = opts.warningColor;
489
+ this._warningWidth = opts.warningWidth;
490
+ this._volumeSliderColor = opts.volumeSliderColor;
491
+ this._volumeSliderWidth = opts.volumeSliderWidth;
492
+ this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
493
+ this._textFont = opts.textFont;
494
+ this._textFontSize = opts.textFontSize;
495
+ this._textColor = opts.textColor;
496
+ this._textBackgroundColor = opts.textBackgroundColor;
497
+ this._textPosition = opts.textPosition;
498
+ this._textAutoScroll = opts.textAutoScroll;
499
+ this._borderWidth = opts.borderWidth;
500
+ this._borderRadius = opts.borderRadius;
501
+ this._wrapped = opts.wrapped;
502
+ this._draggable = opts.draggable;
503
+ this._orderable = opts.orderable;
504
+ this._resizable = opts.resizable;
505
+ this._cuttable = opts.cuttable;
506
+ this._deletable = opts.deletable;
507
+ this._wrapping = opts.wrapping;
508
+ this._previewHeight = opts.previewHeight;
509
+ this._binaryHeight = opts.binaryHeight;
510
+ this._indicators = opts.indicators;
511
+ this._markers = opts.markers;
512
+ this._buttons = opts.buttons;
513
+ this._markerColor = opts.markerColor;
514
+ this._markerWidth = opts.markerWidth;
515
+ this._volume = opts.volume;
516
+ this._volumeRange = opts.volumeRange;
517
+ this._loading = opts.loading;
518
+ this._minSize = peaks.options.minSourceSize;
519
+ this._selected = false;
520
+
521
+ for (var i = 0; i < customParams.length; i += 2) {
522
+ var key = customParams[i];
523
+ var value = customParams[i + 1];
524
+
525
+ if (key && key.startsWith('custom_')) {
526
+ this[key] = value;
527
+ }
528
+ }
529
+ }
530
+
531
+ Object.defineProperties(Source.prototype, {
532
+ id: {
533
+ enumerable: true,
534
+ get: function() {
535
+ return this._id;
536
+ }
537
+ },
538
+ lineId: {
539
+ enumerable: true,
540
+ get: function() {
541
+ return this._lineId;
542
+ },
543
+
544
+ set: function(lineId) {
545
+ this._lineId = lineId;
546
+ }
547
+ },
548
+ originId: {
549
+ enumerable: true,
550
+ get: function() {
551
+ return this._originId;
552
+ }
553
+ },
554
+ elementId: {
555
+ enumerable: true,
556
+ get: function() {
557
+ return this._elementId;
558
+ }
559
+ },
560
+ title: {
561
+ enumerable: true,
562
+ get: function() {
563
+ return this._title;
564
+ },
565
+
566
+ set: function(title) {
567
+ this._title = title;
568
+ }
569
+ },
570
+ titleAlignments: {
571
+ enumerable: true,
572
+ get: function() {
573
+ return this._titleAlignments;
574
+ }
575
+ },
576
+ url: {
577
+ enumerable: true,
578
+ get: function() {
579
+ return this._url;
580
+ }
581
+ },
582
+ previewUrl: {
583
+ enumerable: true,
584
+ get: function() {
585
+ return this._previewUrl;
586
+ }
587
+ },
588
+ binaryUrl: {
589
+ enumerable: true,
590
+ get: function() {
591
+ return this._binaryUrl;
592
+ }
593
+ },
594
+ kind: {
595
+ enumerable: true,
596
+ get: function() {
597
+ return this._kind;
598
+ },
599
+
600
+ set: function(kind) {
601
+ this._kind = kind;
602
+ }
603
+ },
604
+ subkind: {
605
+ enumerable: true,
606
+ get: function() {
607
+ return this._subkind;
608
+ },
609
+
610
+ set: function(subkind) {
611
+ this._subkind = subkind;
612
+ }
613
+ },
614
+ duration: {
615
+ enumerable: true,
616
+ get: function() {
617
+ return this._duration;
618
+ }
619
+ },
620
+ startTime: {
621
+ enumerable: true,
622
+ get: function() {
623
+ return this._startTime;
624
+ }
625
+ },
626
+ endTime: {
627
+ enumerable: true,
628
+ get: function() {
629
+ return this._endTime;
630
+ }
631
+ },
632
+ mediaStartTime: {
633
+ enumerable: true,
634
+ get: function() {
635
+ return this._mediaStartTime;
636
+ },
637
+
638
+ set: function(mediaStartTime) {
639
+ this._mediaStartTime = mediaStartTime;
640
+ }
641
+ },
642
+ mediaEndTime: {
643
+ enumerable: true,
644
+ get: function() {
645
+ return this._mediaEndTime;
646
+ },
647
+
648
+ set: function(mediaEndTime) {
649
+ this._mediaEndTime = mediaEndTime;
650
+ }
651
+ },
652
+ color: {
653
+ enumerable: true,
654
+ get: function() {
655
+ return this._color;
656
+ },
657
+
658
+ set: function(color) {
659
+ this._color = color;
660
+ }
661
+ },
662
+ backgroundColor: {
663
+ enumerable: true,
664
+ get: function() {
665
+ return this._backgroundColor;
666
+ },
667
+
668
+ set: function(backgroundColor) {
669
+ this._backgroundColor = backgroundColor;
670
+ }
671
+ },
672
+ borderColor: {
673
+ enumerable: true,
674
+ get: function() {
675
+ return this._borderColor;
676
+ },
677
+
678
+ set: function(borderColor) {
679
+ this._borderColor = borderColor;
680
+ }
681
+ },
682
+ selectedColor: {
683
+ enumerable: true,
684
+ get: function() {
685
+ return this._selectedColor;
686
+ },
687
+
688
+ set: function(selectedColor) {
689
+ this._selectedColor = selectedColor;
690
+ }
691
+ },
692
+ warningColor: {
693
+ enumerable: true,
694
+ get: function() {
695
+ return this._warningColor;
696
+ },
697
+
698
+ set: function(warningColor) {
699
+ this._warningColor = warningColor;
700
+ }
701
+ },
702
+ warningWidth: {
703
+ enumerable: true,
704
+ get: function() {
705
+ return this._warningWidth;
706
+ },
707
+
708
+ set: function(warningWidth) {
709
+ this._warningWidth = warningWidth;
710
+ }
711
+ },
712
+ volumeSliderColor: {
713
+ enumerable: true,
714
+ get: function() {
715
+ return this._volumeSliderColor;
716
+ }
717
+ },
718
+ volumeSliderWidth: {
719
+ enumerable: true,
720
+ get: function() {
721
+ return this._volumeSliderWidth;
722
+ }
723
+ },
724
+ volumeSliderDraggingWidth: {
725
+ enumerable: true,
726
+ get: function() {
727
+ return this._volumeSliderDraggingWidth;
728
+ }
729
+ },
730
+ textFont: {
731
+ enumerable: true,
732
+ get: function() {
733
+ return this._textFont;
734
+ },
735
+
736
+ set: function(textFont) {
737
+ this._textFont = textFont;
738
+ }
739
+ },
740
+ textFontSize: {
741
+ enumerable: true,
742
+ get: function() {
743
+ return this._textFontSize;
744
+ },
745
+
746
+ set: function(textFontSize) {
747
+ this._textFontSize = textFontSize;
748
+ }
749
+ },
750
+ textColor: {
751
+ enumerable: true,
752
+ get: function() {
753
+ return this._textColor;
754
+ },
755
+
756
+ set: function(textColor) {
757
+ this._textColor = textColor;
758
+ }
759
+ },
760
+ textBackgroundColor: {
761
+ enumerable: true,
762
+ get: function() {
763
+ return this._textBackgroundColor;
764
+ },
765
+
766
+ set: function(textBackgroundColor) {
767
+ this._textBackgroundColor = textBackgroundColor;
768
+ }
769
+ },
770
+ textPosition: {
771
+ enumerable: true,
772
+ get: function() {
773
+ return this._textPosition;
774
+ },
775
+
776
+ set: function(textPosition) {
777
+ this._textPosition = textPosition;
778
+ }
779
+ },
780
+ textAutoScroll: {
781
+ enumerable: true,
782
+ get: function() {
783
+ return this._textAutoScroll;
784
+ },
785
+
786
+ set: function(textAutoScroll) {
787
+ this._textAutoScroll = textAutoScroll;
788
+ }
789
+ },
790
+ borderWidth: {
791
+ enumerable: true,
792
+ get: function() {
793
+ return this._borderWidth;
794
+ },
795
+
796
+ set: function(borderWidth) {
797
+ this._borderWidth = borderWidth;
798
+ }
799
+ },
800
+ borderRadius: {
801
+ enumerable: true,
802
+ get: function() {
803
+ return this._borderRadius;
804
+ },
805
+
806
+ set: function(borderRadius) {
807
+ this._borderRadius = borderRadius;
808
+ }
809
+ },
810
+ wrapped: {
811
+ enumerable: true,
812
+ get: function() {
813
+ return this._wrapped;
814
+ },
815
+
816
+ set: function(wrapped) {
817
+ this._wrapped = wrapped;
818
+ }
819
+ },
820
+ segments: {
821
+ enumerable: true,
822
+ get: function() {
823
+ return this._segments;
824
+ }
825
+ },
826
+ draggable: {
827
+ enumerable: true,
828
+ get: function() {
829
+ return this._draggable;
830
+ }
831
+ },
832
+ orderable: {
833
+ enumerable: true,
834
+ get: function() {
835
+ return this._orderable;
836
+ }
837
+ },
838
+ resizable: {
839
+ enumerable: true,
840
+ get: function() {
841
+ return this._resizable;
842
+ }
843
+ },
844
+ cuttable: {
845
+ enumerable: true,
846
+ get: function() {
847
+ return this._cuttable;
848
+ }
849
+ },
850
+ deletable: {
851
+ enumerable: true,
852
+ get: function() {
853
+ return this._deletable;
854
+ }
855
+ },
856
+ wrapping: {
857
+ enumerable: true,
858
+ get: function() {
859
+ return this._wrapping;
860
+ },
861
+
862
+ set: function(wrapping) {
863
+ this._wrapping = wrapping;
864
+ }
865
+ },
866
+ previewHeight: {
867
+ enumerable: true,
868
+ get: function() {
869
+ return this._previewHeight;
870
+ },
871
+
872
+ set: function(previewHeight) {
873
+ this._previewHeight = previewHeight;
874
+ }
875
+ },
876
+ binaryHeight: {
877
+ enumerable: true,
878
+ get: function() {
879
+ return this._binaryHeight;
880
+ },
881
+
882
+ set: function(binaryHeight) {
883
+ this._binaryHeight = binaryHeight;
884
+ }
885
+ },
886
+ indicators: {
887
+ enumerable: true,
888
+ get: function() {
889
+ return this._indicators;
890
+ }
891
+ },
892
+ markers: {
893
+ enumerable: true,
894
+ get: function() {
895
+ return this._markers;
896
+ }
897
+ },
898
+ buttons: {
899
+ enumerable: true,
900
+ get: function() {
901
+ return this._buttons;
902
+ }
903
+ },
904
+ markerColor: {
905
+ enumerable: true,
906
+ get: function() {
907
+ return this._markerColor;
908
+ }
909
+ },
910
+ markerWidth: {
911
+ enumerable: true,
912
+ get: function() {
913
+ return this._markerWidth;
914
+ }
915
+ },
916
+ volume: {
917
+ enumerable: true,
918
+ get: function() {
919
+ return this._volume;
920
+ },
921
+
922
+ set: function(volume) {
923
+ this._volume = volume;
924
+ }
925
+ },
926
+ volumeRange: {
927
+ enumerable: true,
928
+ get: function() {
929
+ return this._volumeRange;
930
+ }
931
+ },
932
+ loading: {
933
+ enumerable: true,
934
+ get: function() {
935
+ return this._loading;
936
+ }
937
+ },
938
+ minSize: {
939
+ enumerable: true,
940
+ get: function() {
941
+ return this._minSize;
942
+ }
943
+ },
944
+ selected: {
945
+ enumerable: true,
946
+ get: function() {
947
+ return this._selected;
948
+ },
949
+
950
+ set: function(selected) {
951
+ this._selected = selected;
952
+ }
953
+ }
954
+ });
955
+
956
+ Source.prototype.updateTimes = function(newStartTime, newEndTime) {
957
+ if (!Utils.isNullOrUndefined(newStartTime)) {
958
+ if (this._duration && Utils.isNullOrUndefined(newEndTime)) {
959
+ newStartTime = Utils.roundTime(Math.max(this._endTime - this._duration, newStartTime));
960
+ }
961
+ else {
962
+ newStartTime = Utils.roundTime(newStartTime);
963
+ }
964
+ }
965
+
966
+ if (!Utils.isNullOrUndefined(newEndTime)) {
967
+ if (this._duration && Utils.isNullOrUndefined(newStartTime)) {
968
+ newEndTime = Utils.roundTime(Math.min(this._startTime + this._duration, newEndTime));
969
+ }
970
+ else {
971
+ newEndTime = Utils.roundTime(newEndTime);
972
+ }
973
+ }
974
+
975
+ if ((Utils.isNullOrUndefined(newStartTime) && !Utils.isNullOrUndefined(newEndTime))
976
+ || (!Utils.isNullOrUndefined(newStartTime) && Utils.isNullOrUndefined(newEndTime))) {
977
+ this._updateMediaRange(this._startTime, newStartTime, this._endTime, newEndTime);
978
+ }
979
+
980
+ if (!Utils.isNullOrUndefined(newStartTime)) {
981
+ this._startTime = newStartTime;
982
+ }
983
+ if (!Utils.isNullOrUndefined(newEndTime)) {
984
+ this._endTime = newEndTime;
985
+ }
986
+ };
987
+
988
+ Source.prototype._updateMediaRange = function(oldStartTime, newStartTime, oldEndTime,
989
+ newEndTime) {
990
+ var startDiff = 0;
991
+ var endDiff = 0;
992
+ var upperLimit;
993
+
994
+ if (this._duration) {
995
+ upperLimit = this._duration;
996
+ }
997
+ else {
998
+ upperLimit = Number.POSITIVE_INFINITY;
999
+ }
1000
+
1001
+ if (!Utils.isNullOrUndefined(newStartTime) && !Utils.isNullOrUndefined(oldStartTime)) {
1002
+ startDiff = newStartTime - oldStartTime;
1003
+ }
1004
+ if (!Utils.isNullOrUndefined(newEndTime) && !Utils.isNullOrUndefined(oldEndTime)) {
1005
+ endDiff = newEndTime - oldEndTime;
1006
+ }
1007
+
1008
+ var newMediaStartTime = this._mediaStartTime;
1009
+ var newMediaEndTime = this._mediaEndTime;
1010
+
1011
+ if (startDiff) {
1012
+ if (startDiff < 0) {
1013
+ // Try reducing mediaStartTime
1014
+ if (newMediaStartTime > 0) {
1015
+ var minStartTime = newMediaStartTime + startDiff;
1016
+
1017
+ newMediaStartTime = Math.max(0, minStartTime);
1018
+ if (minStartTime < 0) {
1019
+ // Try increasing mediaEndTime
1020
+ newMediaEndTime = Math.min(upperLimit, newMediaEndTime - minStartTime);
1021
+ }
1022
+ }
1023
+ else {
1024
+ // Try increasing mediaEndTime
1025
+ newMediaEndTime = Math.min(upperLimit, newMediaEndTime - startDiff);
1026
+ }
1027
+ }
1028
+ else {
1029
+ // Try increasing mediaStartTime
1030
+ if (newMediaStartTime < upperLimit) {
1031
+ newMediaStartTime = Math.min(upperLimit, newMediaStartTime + startDiff);
1032
+ }
1033
+ }
1034
+ }
1035
+
1036
+ if (endDiff) {
1037
+ if (endDiff > 0) {
1038
+ // Try increasing mediaEndTime
1039
+ if (newMediaEndTime < upperLimit) {
1040
+ var maxEndTime = newMediaEndTime + endDiff;
1041
+
1042
+ newMediaEndTime = Math.min(upperLimit, maxEndTime);
1043
+ if (maxEndTime > upperLimit) {
1044
+ // Try reducing mediaStartTime
1045
+ newMediaStartTime = Math.max(0, newMediaStartTime - (maxEndTime - upperLimit));
1046
+ }
1047
+ }
1048
+ else {
1049
+ // Try reducing mediaStartTime
1050
+ newMediaStartTime = Math.max(0, newMediaStartTime - endDiff);
1051
+ }
1052
+ }
1053
+ else {
1054
+ if (newEndTime - oldStartTime < upperLimit) {
1055
+ if (oldEndTime - oldStartTime > upperLimit) {
1056
+ endDiff += (oldEndTime - oldStartTime) - upperLimit;
1057
+ }
1058
+
1059
+ // Try reducing mediaEndTime
1060
+ if (newMediaEndTime > 0) {
1061
+ newMediaEndTime = Math.max(0, newMediaEndTime + endDiff);
1062
+ }
1063
+ }
1064
+ }
1065
+ }
1066
+
1067
+ this._mediaStartTime = Utils.roundTime(newMediaStartTime);
1068
+ this._mediaEndTime = Utils.roundTime(newMediaEndTime);
1069
+ };
1070
+
1071
+ Source.prototype.update = function(options) {
1072
+ var opts = {
1073
+ title: this.title,
1074
+ titleAlignments: this.titleAlignments,
1075
+ url: this.url,
1076
+ previewUrl: this.previewUrl,
1077
+ binaryUrl: this.binaryUrl,
1078
+ kind: this.kind,
1079
+ subkind: this.subkind,
1080
+ duration: this.duration,
1081
+ startTime: this.startTime,
1082
+ endTime: this.endTime,
1083
+ mediaStartTime: this.mediaStartTime,
1084
+ mediaEndTime: this.mediaEndTime,
1085
+ color: this.color,
1086
+ backgroundColor: this.backgroundColor,
1087
+ borderColor: this.borderColor,
1088
+ selectedColor: this.selectedColor,
1089
+ warningColor: this.warningColor,
1090
+ warningWidth: this.warningWidth,
1091
+ volumeSliderColor: this.volumeSliderColor,
1092
+ volumeSliderWidth: this.volumeSliderWidth,
1093
+ volumeSliderDraggingWidth: this.volumeSliderDraggingWidth,
1094
+ textFont: this.textFont,
1095
+ textFontSize: this.textFontSize,
1096
+ textColor: this.textColor,
1097
+ textBackgroundColor: this.textBackgroundColor,
1098
+ textPosition: this.textPosition,
1099
+ textAutoScroll: this.textAutoScroll,
1100
+ borderWidth: this.borderWidth,
1101
+ borderRadius: this.borderRadius,
1102
+ wrapped: this.wrapped,
1103
+ draggable: this.draggable,
1104
+ orderable: this.orderable,
1105
+ resizable: this.resizable,
1106
+ cuttable: this.cuttable,
1107
+ deletable: this.deletable,
1108
+ wrapping: this.wrapping,
1109
+ previewHeight: this.previewHeight,
1110
+ binaryHeight: this.binaryHeight,
1111
+ indicators: this.indicators,
1112
+ markers: this.markers,
1113
+ buttons: this.buttons,
1114
+ markerColor: this.markerColor,
1115
+ markerWidth: this.markerWidth,
1116
+ volume: this.volume,
1117
+ volumeRange: this.volumeRange,
1118
+ loading: this.loading
1119
+ };
1120
+
1121
+ Utils.extend(opts, options);
1122
+
1123
+ validateSource(this._peaks, opts, 'update()');
1124
+
1125
+ this._title = opts.title;
1126
+ this._titleAlignments = opts.titleAlignments;
1127
+ this._url = opts.url;
1128
+ this._previewUrl = opts.previewUrl;
1129
+ this._binaryUrl = opts.binaryUrl;
1130
+ this._kind = opts.kind;
1131
+ this._subkind = opts.subkind;
1132
+ this._duration = opts.duration;
1133
+ this._startTime = opts.startTime;
1134
+ this._endTime = opts.endTime;
1135
+ this._mediaStartTime = opts.mediaStartTime;
1136
+ this._mediaEndTime = opts.mediaEndTime;
1137
+ this._color = opts.color;
1138
+ this._backgroundColor = opts.backgroundColor;
1139
+ this._borderColor = opts.borderColor;
1140
+ this._selectedColor = opts.selectedColor || Utils.shadeColor(opts.backgroundColor, 30);
1141
+ this._warningColor = opts.warningColor;
1142
+ this._warningWidth = opts.warningWidth;
1143
+ this._volumeSliderColor = opts.volumeSliderColor;
1144
+ this._volumeSliderWidth = opts.volumeSliderWidth;
1145
+ this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
1146
+ this._textFont = opts.textFont;
1147
+ this._textFontSize = opts.textFontSize;
1148
+ this._textColor = opts.textColor;
1149
+ this._textBackgroundColor = opts.textBackgroundColor;
1150
+ this._textPosition = opts.textPosition;
1151
+ this._textAutoScroll = opts.textAutoScroll;
1152
+ this._borderWidth = opts.borderWidth;
1153
+ this._borderRadius = opts.borderRadius;
1154
+ this._wrapped = opts.wrapped;
1155
+ this._draggable = opts.draggable;
1156
+ this._orderable = opts.orderable;
1157
+ this._resizable = opts.resizable;
1158
+ this._cuttable = opts.cuttable;
1159
+ this._deletable = opts.deletable;
1160
+ this._wrapping = opts.wrapping;
1161
+ this._previewHeight = opts.previewHeight;
1162
+ this._binaryHeight = opts.binaryHeight;
1163
+ this._indicators = opts.indicators;
1164
+ this._markers = opts.markers;
1165
+ this._buttons = opts.buttons;
1166
+ this._markerColor = opts.markerColor;
1167
+ this._markerWidth = opts.markerWidth;
1168
+ this._volume = opts.volume;
1169
+ this._volumeRange = opts.volumeRange;
1170
+ this._loading = opts.loading;
1171
+
1172
+ if (options && typeof options === 'object') {
1173
+ for (var key in options) {
1174
+ if (Object.prototype.hasOwnProperty.call(options, key) && key.startsWith('custom_')) {
1175
+ this[key] = options[key];
1176
+ }
1177
+ }
1178
+ }
1179
+
1180
+ this._peaks.emit('model.source.update', this);
1181
+ };
1182
+
1183
+ /**
1184
+ * Returns <code>true</code> if the source overlaps a given time region.
1185
+ *
1186
+ * @param {Number} startTime The start of the time region, in seconds.
1187
+ * @param {Number} endTime The end of the time region, in seconds.
1188
+ * @returns {Boolean}
1189
+ *
1190
+ * @see http://wiki.c2.com/?TestIfDateRangesOverlap
1191
+ */
1192
+ Source.prototype.isVisible = function(startTime, endTime) {
1193
+ return this._startTime < endTime && startTime < this._endTime;
1194
+ };
1195
+
1196
+ /**
1197
+ * Update the indicators of this source.
1198
+ *
1199
+ * @param {Array<String>} newIndicators The new indicators.
1200
+ */
1201
+
1202
+ Source.prototype.setIndicators = function(newIndicators) {
1203
+ this._indicators = newIndicators;
1204
+ this._peaks.emit('model.source.setIndicators', this);
1205
+ };
1206
+
1207
+ /**
1208
+ * Returns <code>true</code> if a warning should be shown
1209
+ */
1210
+
1211
+ Source.prototype.shouldShowWarning = function() {
1212
+ return this._warningColor && this._duration > Utils.roundTime(this._endTime - this._startTime);
1213
+ };
1214
+
1215
+ Source.prototype.getVisibleTitle = function() {
1216
+ if (this._titleAlignments.length === 0) {
1217
+ return this._title;
1218
+ }
1219
+
1220
+ return this._titleAlignments.reduce(function(visibleTitle, alignment) {
1221
+ if (this._mediaStartTime < alignment.end && alignment.start < this._mediaEndTime) {
1222
+ visibleTitle.push(alignment.text);
1223
+ }
1224
+ return visibleTitle;
1225
+ }.bind(this), []).join(' ');
1226
+ };
1227
+
1228
+ /**
1229
+ * Returns a serializable object containing only the properties defined with Object.defineProperties.
1230
+ * This includes all enumerable properties that can be safely serialized.
1231
+ *
1232
+ * @returns {Object} A plain object containing the serializable properties of the source.
1233
+ */
1234
+ Source.prototype.toSerializable = function() {
1235
+ var serializable = {};
1236
+
1237
+ // Get all custom properties
1238
+ for (var key in this) {
1239
+ if (Object.prototype.hasOwnProperty.call(this, key) && key.startsWith('custom_')) {
1240
+ serializable[key] = this[key];
1241
+ }
1242
+ }
1243
+
1244
+ // Add all the enumerable properties from the prototype
1245
+ var proto = Object.getPrototypeOf(this);
1246
+ var descriptors = Object.getOwnPropertyDescriptors(proto);
1247
+
1248
+ for (var prop in descriptors) {
1249
+ if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
1250
+ var descriptor = descriptors[prop];
1251
+
1252
+ if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
1253
+ serializable[prop] = this[prop];
1254
+ }
1255
+ }
1256
+ }
1257
+
1258
+ return serializable;
1259
+ };
1260
+
1261
+ return Source;
1262
+ });