@vidispine/vdt-js 22.3.0-pre.3 → 22.3.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.
package/dist/index.es.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
- import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
3
2
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
3
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
+ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
4
5
  import _typeof from '@babel/runtime/helpers/typeof';
5
6
  import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
6
7
  import _createClass from '@babel/runtime/helpers/createClass';
7
- import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
8
8
  import parseFileSize from 'filesize';
9
9
 
10
10
  function ownKeys$8(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -244,171 +244,212 @@ var roles = /*#__PURE__*/Object.freeze({
244
244
  VXA_READ: VXA_READ
245
245
  });
246
246
 
247
- var _excluded$4 = ["groupName"],
247
+ var _excluded$8 = ["value"],
248
248
  _excluded2$2 = ["start", "end"];
249
249
 
250
250
  function ownKeys$7(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
251
251
 
252
252
  function _objectSpread$7(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$7(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$7(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
253
253
 
254
- var parseValueList$1 = function parseValueList(value) {
255
- if (value === undefined) return [];
256
- if (value === null) return [{
257
- value: ''
258
- }];
254
+ var COMBINED_PROPERTY_KEYS = ['uuid', 'user', 'timestamp', 'change', 'conflict', 'mode', 'name', 'id', 'referenced', 'data', 'inheritance'];
255
+ var GROUP_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['cycle']);
256
+ var FIELD_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['value', 'reference', 'type', 'track']);
257
+ var FIELD_VALUE_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['value', 'lang']);
258
+
259
+ var isObject$1 = function isObject(o) {
260
+ return Object.prototype.toString.call(o) === '[object Object]';
261
+ };
262
+
263
+ var isDate = function isDate(o) {
264
+ return Object.prototype.toString.call(o) === '[object Date]';
265
+ };
266
+
267
+ var isField = function isField(value) {
268
+ var FIELD_TYPES = ['string', 'boolean', 'number'];
269
+
270
+ var isFieldType = function isFieldType(v) {
271
+ return FIELD_TYPES.includes(_typeof(v));
272
+ };
273
+
274
+ var isFieldObject = function isFieldObject(v) {
275
+ return isObject$1(v) && (v.value === null || isObject$1(v.value) || isFieldType(v.value));
276
+ };
277
+
278
+ if (value === null) {
279
+ return true;
280
+ }
259
281
 
260
282
  if (Array.isArray(value)) {
261
- return value.map(function (valueOrObject) {
262
- if (_typeof(valueOrObject) === 'object') {
263
- return _objectSpread$7({
264
- value: valueOrObject.value || ''
265
- }, valueOrObject);
266
- }
283
+ return value.some(isField);
284
+ }
267
285
 
268
- return {
269
- value: valueOrObject
270
- };
271
- });
286
+ return isFieldType(value) || isFieldObject(value) || isDate(value);
287
+ };
288
+
289
+ var isGroup = function isGroup(value) {
290
+ var isGroupObject = function isGroupObject(v) {
291
+ return isObject$1(v) && v.value === undefined && Object.entries(value);
292
+ };
293
+
294
+ if (Array.isArray(value)) {
295
+ return value.every(isGroup);
272
296
  }
273
297
 
274
- if (value.value) return [value];
275
- return [{
276
- value: value
277
- }];
298
+ return isGroupObject(value);
278
299
  };
279
300
 
280
- var parseValue = function parseValue() {
281
- var fieldValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
301
+ var tryPluralize = function tryPluralize(str, arr) {
302
+ return str + (arr.length > 1 ? 's' : '');
303
+ };
282
304
 
283
- if (fieldValue && (fieldValue.value || fieldValue.name)) {
284
- var valueList = fieldValue.value,
285
- uuid = fieldValue.uuid;
286
- var value = parseValueList$1(valueList);
287
- return {
288
- value: value,
289
- uuid: uuid
290
- };
305
+ var ensureKeysAreValid = function ensureKeysAreValid(keysToCheck, keysToMatch) {
306
+ var unsupportedKeys = keysToCheck.filter(function (k) {
307
+ return !keysToMatch.includes(k);
308
+ });
309
+
310
+ if (unsupportedKeys.length) {
311
+ throw Error("Unsupported ".concat(tryPluralize('key', unsupportedKeys), " (").concat(unsupportedKeys.join(', '), ")"));
291
312
  }
313
+ };
292
314
 
315
+ var parseValue = function parseValue(value) {
316
+ if (Array.isArray(value)) {
317
+ throw Error('Invalid value object, cannot be array');
318
+ }
319
+
320
+ if ([undefined, null].includes(value)) return {};
321
+ if (isDate(value)) return {
322
+ value: value.toISOString()
323
+ };
293
324
  return {
294
- value: parseValueList$1(fieldValue)
325
+ value: value
295
326
  };
296
327
  };
297
328
 
298
- var parseField$1 = function parseField() {
299
- var field = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
300
- var name = field.name,
301
- value = field.value;
302
- var parsedValue = parseValue(value);
303
- return _objectSpread$7({
304
- name: name
305
- }, parsedValue);
329
+ var parseValueObject = function parseValueObject(valueObject) {
330
+ ensureKeysAreValid(Object.keys(valueObject), FIELD_VALUE_PROPERTY_KEYS);
331
+
332
+ if (Object.keys(valueObject).length === 0) {
333
+ throw Error('Invalid value object, cannot be empty object');
334
+ }
335
+
336
+ var parsedValue = parseValue(valueObject === null || valueObject === void 0 ? void 0 : valueObject.value);
337
+ return _objectSpread$7(_objectSpread$7({}, valueObject), parsedValue !== undefined ? parsedValue : {});
306
338
  };
307
339
 
308
- var shouldBeField = function shouldBeField(_ref) {
309
- var name = _ref.name,
310
- value = _ref.value;
311
- return ['string', 'boolean', 'number'].includes(_typeof(value)) || name !== 'group' && Array.isArray(value) || value === null;
340
+ var parseFieldValue = function parseFieldValue(value) {
341
+ if ([undefined, null].includes(value)) return undefined;
342
+ if (Array.isArray(value)) return value.map(parseFieldValue);
343
+ if (isObject$1(value)) return parseValueObject(value);
344
+ return parseValue(value);
312
345
  };
313
346
 
314
- var parseGroup$1 = function parseGroup() {
315
- var thisGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
316
- var groupName = thisGroup.name,
317
- _thisGroup$value = thisGroup.value,
318
- groupsOrFields = _thisGroup$value === void 0 ? {} : _thisGroup$value; // eslint-disable-next-line no-use-before-define
347
+ var parseFieldObject = function parseFieldObject(fieldObject) {
348
+ ensureKeysAreValid(Object.keys(fieldObject), FIELD_PROPERTY_KEYS);
349
+ var parsedFieldValue = parseFieldValue(fieldObject === null || fieldObject === void 0 ? void 0 : fieldObject.value);
319
350
 
320
- var _parseGroupsOrFields = parseGroupsOrFields(groupsOrFields),
321
- field = _parseGroupsOrFields.field,
322
- group = _parseGroupsOrFields.group;
351
+ if (parsedFieldValue === undefined) {
352
+ fieldObject.value;
353
+ var fieldObjectWithoutValue = _objectWithoutProperties(fieldObject, _excluded$8);
354
+
355
+ return fieldObjectWithoutValue;
356
+ }
357
+
358
+ return _objectSpread$7(_objectSpread$7({}, fieldObject), {}, {
359
+ value: _toConsumableArray(Array.isArray(parsedFieldValue) ? parsedFieldValue : [parsedFieldValue])
360
+ });
361
+ };
362
+
363
+ var parseField$1 = function parseField(field) {
364
+ if (isObject$1(field)) {
365
+ return parseFieldObject(field);
366
+ }
367
+
368
+ var parsedFieldValue = parseFieldValue(field);
369
+
370
+ if (parsedFieldValue === undefined) {
371
+ return undefined;
372
+ }
323
373
 
324
374
  return {
325
- name: groupName,
326
- group: group,
327
- field: field
375
+ value: _toConsumableArray(Array.isArray(parsedFieldValue) ? parsedFieldValue : [parsedFieldValue])
328
376
  };
329
377
  };
330
378
 
331
- var parseGroupsOrFields = function parseGroupsOrFields(groupsOrFields) {
379
+ var parseGroupsAndFields = function parseGroupsAndFields(groupOrField) {
332
380
  var group = [];
333
381
  var field = [];
334
- Object.entries(groupsOrFields).forEach(function (_ref2) {
335
- var _ref3 = _slicedToArray(_ref2, 2),
336
- name = _ref3[0],
337
- value = _ref3[1];
338
-
339
- if (shouldBeField({
340
- name: name,
341
- value: value
342
- })) {
343
- field.push(parseField$1({
344
- name: name,
345
- value: value
346
- }));
347
- } else if (Array.isArray(value)) {
348
- value.forEach(function (_ref4) {
349
- var groupName = _ref4.groupName,
350
- groupValue = _objectWithoutProperties(_ref4, _excluded$4);
351
-
352
- group.push(parseGroup$1({
353
- name: groupName,
354
- value: groupValue
355
- }));
382
+ var groupAttributes = {};
383
+ Object.entries(groupOrField || {}).forEach(function (_ref) {
384
+ var _ref2 = _slicedToArray(_ref, 2),
385
+ name = _ref2[0],
386
+ value = _ref2[1];
387
+
388
+ if (GROUP_PROPERTY_KEYS.includes(name)) {
389
+ groupAttributes = _objectSpread$7(_objectSpread$7({}, groupAttributes), {}, _defineProperty({}, name, value));
390
+ } else if (isField(value)) {
391
+ try {
392
+ field.push(_objectSpread$7({
393
+ name: name
394
+ }, parseField$1(value)));
395
+ } catch (error) {
396
+ throw Error(error.message + (name ? " for field \"".concat(name, "\"") : ''));
397
+ }
398
+ } else if (isGroup(value)) {
399
+ (Array.isArray(value) ? value : [value]).forEach(function (v) {
400
+ group.push(_objectSpread$7({
401
+ name: name
402
+ }, parseGroupsAndFields(v)));
356
403
  });
357
404
  } else {
358
- group.push(parseGroup$1({
359
- name: name,
360
- value: value
361
- }));
405
+ throw Error("Unhandled value for \"".concat(name, "\""));
362
406
  }
363
407
  });
364
- return {
365
- group: group,
408
+ return _objectSpread$7(_objectSpread$7(_objectSpread$7({}, groupAttributes), group.length > 0 ? {
409
+ group: group
410
+ } : {}), field.length > 0 ? {
366
411
  field: field
367
- };
412
+ } : {});
368
413
  };
369
414
 
370
415
  var parseTimespan$1 = function parseTimespan() {
371
416
  var timespan = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
372
417
 
373
- var _ref5 = timespan || {},
374
- _ref5$start = _ref5.start,
375
- start = _ref5$start === void 0 ? '-INF' : _ref5$start,
376
- _ref5$end = _ref5.end,
377
- end = _ref5$end === void 0 ? '+INF' : _ref5$end,
378
- groupsOrFields = _objectWithoutProperties(_ref5, _excluded2$2);
418
+ var _ref3 = timespan || {},
419
+ _ref3$start = _ref3.start,
420
+ start = _ref3$start === void 0 ? '-INF' : _ref3$start,
421
+ _ref3$end = _ref3.end,
422
+ end = _ref3$end === void 0 ? '+INF' : _ref3$end,
423
+ groupsAndFields = _objectWithoutProperties(_ref3, _excluded2$2);
379
424
 
380
- var _parseGroupsOrFields2 = parseGroupsOrFields(groupsOrFields),
381
- group = _parseGroupsOrFields2.group,
382
- field = _parseGroupsOrFields2.field;
425
+ var _parseGroupsAndFields = parseGroupsAndFields(groupsAndFields),
426
+ group = _parseGroupsAndFields.group,
427
+ field = _parseGroupsAndFields.field;
383
428
 
384
- return {
385
- start: start,
386
- end: end,
387
- field: field,
429
+ return _objectSpread$7(_objectSpread$7(_objectSpread$7({}, group ? {
388
430
  group: group
389
- };
431
+ } : {}), field ? {
432
+ field: field
433
+ } : {}), {}, {
434
+ start: start,
435
+ end: end
436
+ });
390
437
  };
391
438
  /**
392
- * Create a MetadataType object from a metadata object
393
- * @param {Object} metadata={} - object with metadata to create MetadataType object of
394
- * @returns {Object} MetadataType
439
+ * Create a VidiCore MetadataType from a simplified object structure
440
+ *
441
+ * @param {object} metadata - object to create MetadataType from
442
+ * @returns {object} a MetadataType object
395
443
  */
396
444
 
397
445
 
398
446
  var createMetadataType = function createMetadataType() {
399
447
  var metadata = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
400
- var metadataType = {};
401
-
402
- if (Array.isArray(metadata)) {
403
- metadataType.timespan = metadata.map(function (thisTimeSpan) {
404
- return parseTimespan$1(thisTimeSpan);
405
- });
406
- } else {
407
- var genericTimespan = parseTimespan$1(metadata);
408
- metadataType.timespan = [genericTimespan];
409
- }
410
-
411
- return metadataType;
448
+ return {
449
+ timespan: (Array.isArray(metadata) ? metadata : [metadata]).map(function (t) {
450
+ return parseTimespan$1(t);
451
+ })
452
+ };
412
453
  };
413
454
 
414
455
  var sortTimespanList = function sortTimespanList(timespan1, timespan2) {
@@ -434,7 +475,7 @@ var sortTimespanList = function sortTimespanList(timespan1, timespan2) {
434
475
  return 0;
435
476
  };
436
477
 
437
- var _excluded$3 = ["value"],
478
+ var _excluded$7 = ["value"],
438
479
  _excluded2$1 = ["field", "group"],
439
480
  _excluded3 = ["field", "group"];
440
481
 
@@ -479,7 +520,7 @@ var parseField = function parseField() {
479
520
 
480
521
  var _field$value = field.value,
481
522
  value = _field$value === void 0 ? [] : _field$value,
482
- attributes = _objectWithoutProperties(field, _excluded$3);
523
+ attributes = _objectWithoutProperties(field, _excluded$7);
483
524
 
484
525
  var parsedValueList = parseValueList(value, options);
485
526
  if (includeAttributes || includeFieldAttributes) return _objectSpread$6(_objectSpread$6({}, attributes), {}, {
@@ -628,21 +669,21 @@ var parseGroupList = function parseGroupList() {
628
669
  /**
629
670
  * Parses timespan according to specified options.
630
671
  * The attributes can be targeted for each sub-type.
631
- * @param {Object} timespan={} - The timespan response from the API.
632
- * @param {Object} options={} - Options which change how the metadataType is parsed.
633
- * @param {string} options.joinValue=undefined - String to join the values, eg ','.
634
- * @param {boolean} options.includeAttributes=false - Include attributes on all objects.
635
- * @param {boolean} options.includeTimespanAttributes=false - Include attributes on timespans.
636
- * @param {boolean} options.includeGroupAttributes=false - Include attributes on groups.
637
- * @param {boolean} options.includeFieldAttributes=false - Include attributes on fields.
638
- * @param {boolean} options.includeValueAttributes=false - Include attributes on values.
639
- * @param {boolean} options.flat=false - Flatten to key/value (Note: keys may be overwritten).
640
- * @param {boolean} options.flatTimespan=false - Flatten timespan.
641
- * @param {boolean} options.flatGroup=false - Flatten group.
642
- * @param {boolean} options.groupAsList=false - Return groups as list.
643
- * @param {boolean} options.fieldAsList=false - Return fields as list.
644
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
645
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
672
+ * @param {Object} [timespan={}] - A timespan from VidiCore.
673
+ * @param {Object} [options={}] - Options which change how the metadataType is parsed.
674
+ * @param {string} [options.joinValue=undefined] - String to join the values, eg ','.
675
+ * @param {boolean} [options.includeAttributes=false] - Include attributes on all objects.
676
+ * @param {boolean} [options.includeTimespanAttributes=false] - Include attributes on timespans.
677
+ * @param {boolean} [options.includeGroupAttributes=false] - Include attributes on groups.
678
+ * @param {boolean} [options.includeFieldAttributes=false] - Include attributes on fields.
679
+ * @param {boolean} [options.includeValueAttributes=false] - Include attributes on values.
680
+ * @param {boolean} [options.flat=false] - Flatten to key/value (Note: keys may be overwritten).
681
+ * @param {boolean} [options.flatTimespan=false] - Flatten timespan.
682
+ * @param {boolean} [options.flatGroup=false] - Flatten group.
683
+ * @param {boolean} [options.groupAsList=false] - Return groups as list.
684
+ * @param {boolean} [options.fieldAsList=false] - Return fields as list.
685
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
686
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
646
687
  * @returns {Object} Metadata object parsed according to options.
647
688
  */
648
689
 
@@ -707,7 +748,8 @@ function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) {
707
748
  /**
708
749
  * Parses timespanList according to specified options.
709
750
  * The attributes can be targeted for each sub-type.
710
- * @param {Object[]} timespanList - The timespanList response from the API.
751
+ *
752
+ * @param {Object[]} timespanList - A timespanList from VidiCore.
711
753
  * @param {Object} options - Options which change how the metadataType is parsed.
712
754
  * @param {string} options.joinValue - String to join the values, eg ','.
713
755
  * @param {boolean} options.includeAttributes - Include attributes on all objects.
@@ -723,8 +765,8 @@ function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) {
723
765
  * @param {boolean} options.timespanAsList - Return timespans as list.
724
766
  * @param {boolean} options.groupAsList - Return groups as list.
725
767
  * @param {boolean} options.fieldAsList - Return fields as list.
726
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
727
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
768
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
769
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
728
770
  * @returns {Object} Metadata object parsed according to options.
729
771
  */
730
772
 
@@ -767,11 +809,11 @@ var parseTimespanList = function parseTimespanList() {
767
809
  return output;
768
810
  };
769
811
 
770
- var _excluded$2 = ["timespan"];
812
+ var _excluded$6 = ["timespan"];
771
813
  /**
772
814
  * Parses MetadataType according to specified options.
773
815
  * The attributes can be targeted for each sub-type.
774
- * @param {Object} metadataType - The MetadataType response from the API.
816
+ * @param {Object} metadataType - A MetadataType from VidiCore.
775
817
  * @param {Object} options - Options which change how the metadataType is parsed.
776
818
  * @param {string} options.joinValue - String to join the values, eg ','.
777
819
  * @param {boolean} options.includeAttributes - Include attributes on all objects.
@@ -787,8 +829,8 @@ var _excluded$2 = ["timespan"];
787
829
  * @param {boolean} options.timespanAsList - Return timespans as list.
788
830
  * @param {boolean} options.groupAsList - Return groups as list.
789
831
  * @param {boolean} options.fieldAsList - Return fields as list.
790
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
791
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
832
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
833
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
792
834
  * @returns {Object} Metadata object parsed according to options.
793
835
  */
794
836
 
@@ -804,7 +846,7 @@ var parseMetadataType = function parseMetadataType() {
804
846
  var _ref2 = metadataType || {},
805
847
  _ref2$timespan = _ref2.timespan,
806
848
  timespanList = _ref2$timespan === void 0 ? [] : _ref2$timespan,
807
- attributes = _objectWithoutProperties(_ref2, _excluded$2);
849
+ attributes = _objectWithoutProperties(_ref2, _excluded$6);
808
850
 
809
851
  if (sortTimespan) timespanList.sort(sortTimespanList);
810
852
  var timespan = parseTimespanList(timespanList, options);
@@ -829,12 +871,12 @@ function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if
829
871
  function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$4(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
830
872
 
831
873
  /**
832
- * Parses highlight timespan responses from the api into key/value object.
874
+ * Parses highlight timespan in VidiCore into key/value object.
833
875
  * The attributes can be targeted for each sub-type.
834
- * @param {Object[]} highlightTimespan - A timespan object from the api response.
876
+ * @param {Object[]} highlightTimespan - A VidiCore timespan object.
835
877
  * @param {Object} options - Options which change how the timespans are parsed.
836
- * @param {boolean} options.arrayOnSingle=true - Return an array if there is a single value.
837
- * @param {boolean} options.timespanAsList=false - Return timespans as list.
878
+ * @param {boolean} [options.arrayOnSingle=true] - Return an array if there is a single value.
879
+ * @param {boolean} [options.timespanAsList=false] - Return timespans as list.
838
880
  * @param {string} options.joinValue - String to join the values, eg ','.
839
881
  */
840
882
  var parseHighlightTimespan = function parseHighlightTimespan() {
@@ -844,13 +886,13 @@ var parseHighlightTimespan = function parseHighlightTimespan() {
844
886
  start = _ref.start,
845
887
  end = _ref.end;
846
888
 
847
- var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
848
- var _opts$arrayOnSingle = opts.arrayOnSingle,
849
- arrayOnSingle = _opts$arrayOnSingle === void 0 ? true : _opts$arrayOnSingle,
850
- _opts$joinValue = opts.joinValue,
851
- joinValue = _opts$joinValue === void 0 ? undefined : _opts$joinValue,
852
- _opts$timespanAsList = opts.timespanAsList,
853
- timespanAsList = _opts$timespanAsList === void 0 ? undefined : _opts$timespanAsList;
889
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
890
+ var _options$arrayOnSingl = options.arrayOnSingle,
891
+ arrayOnSingle = _options$arrayOnSingl === void 0 ? true : _options$arrayOnSingl,
892
+ _options$joinValue = options.joinValue,
893
+ joinValue = _options$joinValue === void 0 ? undefined : _options$joinValue,
894
+ _options$timespanAsLi = options.timespanAsList,
895
+ timespanAsList = _options$timespanAsLi === void 0 ? undefined : _options$timespanAsLi;
854
896
  var initialValue = timespanAsList ? {
855
897
  start: start,
856
898
  end: end
@@ -877,38 +919,38 @@ function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if
877
919
 
878
920
  function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$3(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
879
921
  /**
880
- * Parses highlight timespans responses from the api into key/value object.
922
+ * Parses highlight timespans from VidiCore into key/value object.
881
923
  * The attributes can be targeted for each sub-type.
882
- * @param {Object} highlightTimespanList - A list of timespans from the api response.
924
+ * @param {Object} highlightTimespanList - A list of timespans from VidiCore.
883
925
  * @param {Object} options - Options which change how the timespans are parsed.
884
- * @param {boolean} options.arrayOnSingle=true - Return an array if there is a single value.
926
+ * @param {boolean} [options.arrayOnSingle=true] - Return an array if there is a single value.
885
927
  * @param {string} options.joinValue - String to join the values, eg ','.
886
- * @param {boolean} options.timespanAsList=false - Return timespans as list.
887
- * @param {boolean} options.flat=false - Flatten to field-name/field-value (Note: field-values may be overwritten).
888
- * @param {boolean} options.flatTimespan=false - Flatten timespan to object with start/end as key.
889
- * @param {string} options.joinTimespan=_ - Character to join the start/end timecodes.
928
+ * @param {boolean} [options.timespanAsList=false] - Return timespans as list.
929
+ * @param {boolean} [options.flat=false] - Flatten to field-name/field-value (Note: field-values may be overwritten).
930
+ * @param {boolean} [options.flatTimespan=false] - Flatten timespan to object with start/end as key.
931
+ * @param {string} [options.joinTimespan=_] - Character to join the start/end timecodes.
890
932
  */
891
933
 
892
934
  var parseHighlightTimespanList = function parseHighlightTimespanList() {
893
935
  var highlightTimespanList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
894
- var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
895
- var flat = opts.flat,
896
- timespanAsList = opts.timespanAsList,
897
- _opts$joinTimespan = opts.joinTimespan,
898
- joinTimespan = _opts$joinTimespan === void 0 ? '_' : _opts$joinTimespan,
899
- flatTimespan = opts.flatTimespan;
936
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
937
+ var flat = options.flat,
938
+ timespanAsList = options.timespanAsList,
939
+ _options$joinTimespan = options.joinTimespan,
940
+ joinTimespan = _options$joinTimespan === void 0 ? '_' : _options$joinTimespan,
941
+ flatTimespan = options.flatTimespan;
900
942
  if (timespanAsList === true) return highlightTimespanList.map(function (timespan) {
901
- return parseHighlightTimespan(timespan, opts);
943
+ return parseHighlightTimespan(timespan, options);
902
944
  });
903
945
  if (flat === true || flatTimespan === true) return highlightTimespanList.reduce(function (a, timespan) {
904
- return _objectSpread$3(_objectSpread$3({}, a), parseHighlightTimespan(timespan, opts));
946
+ return _objectSpread$3(_objectSpread$3({}, a), parseHighlightTimespan(timespan, options));
905
947
  }, {});
906
948
  return highlightTimespanList.reduce(function (a, timespan) {
907
- return _objectSpread$3(_objectSpread$3({}, a), {}, _defineProperty({}, [timespan.start, timespan.end].join(joinTimespan), parseHighlightTimespan(timespan, opts)));
949
+ return _objectSpread$3(_objectSpread$3({}, a), {}, _defineProperty({}, [timespan.start, timespan.end].join(joinTimespan), parseHighlightTimespan(timespan, options)));
908
950
  }, {});
909
951
  };
910
952
 
911
- var CONSTANT_TIMEBASES = {
953
+ var MAP_CONSTANT_TO_DEN_NUM = {
912
954
  PAL: {
913
955
  denominator: 25,
914
956
  numerator: 1
@@ -928,59 +970,61 @@ var CONSTANT_TIMEBASES = {
928
970
  59.94: {
929
971
  denominator: 60000,
930
972
  numerator: 1001
931
- }
932
- };
933
- var FRAME_SEPARATORS = {
934
- ':': {
935
- dropFrame: false,
936
- field: 2
937
- },
938
- ';': {
939
- dropFrame: true,
940
- field: 2
941
973
  },
942
- '.': {
943
- dropFrame: false,
944
- field: 1
974
+ 23.976: {
975
+ denominator: 48000,
976
+ numerator: 2002
945
977
  },
946
- ',': {
947
- dropFrame: true,
948
- field: 1
978
+ 23.98: {
979
+ denominator: 48000,
980
+ numerator: 2002
949
981
  }
950
982
  };
983
+ var TIME_BASE_CONSTANTS = Object.keys(MAP_CONSTANT_TO_DEN_NUM);
984
+
985
+ /**
986
+ * TimeBase class representing the TimeBaseType in VidiCore
987
+ *
988
+ * For more info, see the [Time bases section in VidiCore API Docs](https://apidoc.vidispine.com/latest/time.html#time-bases)
989
+ */
951
990
 
952
991
  var TimeBase = /*#__PURE__*/function () {
953
- function TimeBase() {
954
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
992
+ /**
993
+ * Constructor for TimeBase
994
+ *
995
+ * @param {object} [timeCodeType={}] A time base type object
996
+ * @param {number} [timeCodeType.numerator=1] The numerator for the TimeBase
997
+ * @param {number} [timeCodeType.denominator=1] The denominator for the TimeBase
998
+ */
999
+ function TimeBase(timeCodeType) {
1000
+ _classCallCheck(this, TimeBase);
1001
+
1002
+ var _ref = timeCodeType || {},
955
1003
  _ref$numerator = _ref.numerator,
956
1004
  numerator = _ref$numerator === void 0 ? 1 : _ref$numerator,
957
1005
  _ref$denominator = _ref.denominator,
958
1006
  denominator = _ref$denominator === void 0 ? 1 : _ref$denominator;
959
1007
 
960
- _classCallCheck(this, TimeBase);
961
-
962
1008
  this.numerator = Number(numerator);
963
1009
  this.denominator = Number(denominator);
964
1010
  }
1011
+ /**
1012
+ * Get TimeBase in a constant representation (e.g. "PAL") if possible, otherwise undefined
1013
+ * @returns {string} Constant representation of the TimeBase
1014
+ */
1015
+
965
1016
 
966
1017
  _createClass(TimeBase, [{
967
- key: "toJSON",
968
- value: function toJSON() {
969
- return {
970
- denominator: this.denominator,
971
- numerator: this.numerator
972
- };
973
- }
974
- }, {
975
1018
  key: "toConstant",
976
1019
  value: function toConstant() {
977
1020
  var _this = this;
978
1021
 
979
- var constant;
980
- Object.entries(CONSTANT_TIMEBASES).find(function (thisTimeBase) {
981
- var _thisTimeBase = _slicedToArray(thisTimeBase, 2),
982
- thisTimeBaseText = _thisTimeBase[0],
983
- thisTimeBaseType = _thisTimeBase[1];
1022
+ var constant; // If multiple equal den/num, it selects first in MAP_CONSTANT_TO_DEN_NUM
1023
+
1024
+ Object.entries(MAP_CONSTANT_TO_DEN_NUM).find(function (timeBaseConstant) {
1025
+ var _timeBaseConstant = _slicedToArray(timeBaseConstant, 2),
1026
+ thisTimeBaseText = _timeBaseConstant[0],
1027
+ thisTimeBaseType = _timeBaseConstant[1];
984
1028
 
985
1029
  var numerator = thisTimeBaseType.numerator,
986
1030
  denominator = thisTimeBaseType.denominator;
@@ -994,18 +1038,36 @@ var TimeBase = /*#__PURE__*/function () {
994
1038
  });
995
1039
  return constant;
996
1040
  }
1041
+ /**
1042
+ * Get TimeBase as a VidiCore TimeBaseType string
1043
+ *
1044
+ * Default format: denominator(:numerator if > 1)
1045
+ * `constant` has precedence over `fraction` if both are true (e.g. NTSC > 30000:1001)
1046
+ *
1047
+ * @param {object} [options={}] For how to display it as text
1048
+ * @param {boolean} [options.constant=false] Show time base as constant (e.g. PAL)
1049
+ * @param {boolean} [options.fraction=false] Show time base as fraction (25:1) even when numerator is 1
1050
+ * @returns {string} Text representation of the TimeBase
1051
+ */
1052
+
997
1053
  }, {
998
1054
  key: "toText",
999
1055
  value: function toText() {
1000
- var useConstant = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1056
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1057
+
1058
+ var _ref2 = options || {},
1059
+ _ref2$constant = _ref2.constant,
1060
+ constant = _ref2$constant === void 0 ? false : _ref2$constant,
1061
+ _ref2$fraction = _ref2.fraction,
1062
+ fraction = _ref2$fraction === void 0 ? false : _ref2$fraction;
1001
1063
 
1002
- if (useConstant) {
1064
+ if (constant) {
1003
1065
  var _timeBaseText = this.toConstant();
1004
1066
 
1005
1067
  if (_timeBaseText) return _timeBaseText;
1006
1068
  }
1007
1069
 
1008
- if (this.numerator > 1) {
1070
+ if (fraction || this.numerator > 1) {
1009
1071
  var _timeBaseText2 = [this.denominator, this.numerator].join(':');
1010
1072
 
1011
1073
  return _timeBaseText2;
@@ -1014,13 +1076,40 @@ var TimeBase = /*#__PURE__*/function () {
1014
1076
  var timeBaseText = String(this.denominator);
1015
1077
  return timeBaseText;
1016
1078
  }
1079
+ /**
1080
+ * Output TimeBase as frame rate (by default max 16 decimal places)
1081
+ *
1082
+ *
1083
+ * For `options.fixed`:
1084
+ * - `true` gives two decimal places
1085
+ * - `false` gives max amount of decimal places
1086
+ * - `number` gives that amount of decimal places
1087
+ *
1088
+ * Default format: rate with two decimals if needed (i.e. decimals are > 0)
1089
+ * Option precedence (when all true): `constant` > `rounded` > `fixed`
1090
+ *
1091
+ * @param {object} [options={}] For how to display it as rate
1092
+ * @param {boolean|number} [options.fixed=true] Amount of decimal places (true gives 2 decimal places)
1093
+ * @param {boolean} [options.constant=false] Use constant representation (if applicable)
1094
+ * @param {boolean} [options.rounded=false] Rounded to nearest integer
1095
+ *
1096
+ * @returns {number} Rate of the TimeBase
1097
+ */
1098
+
1017
1099
  }, {
1018
1100
  key: "toRate",
1019
1101
  value: function toRate() {
1020
- var useConstant = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1021
- var round = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1102
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1022
1103
 
1023
- if (useConstant) {
1104
+ var _ref3 = options || {},
1105
+ _ref3$constant = _ref3.constant,
1106
+ constant = _ref3$constant === void 0 ? false : _ref3$constant,
1107
+ _ref3$rounded = _ref3.rounded,
1108
+ rounded = _ref3$rounded === void 0 ? false : _ref3$rounded,
1109
+ _ref3$fixed = _ref3.fixed,
1110
+ fixed = _ref3$fixed === void 0 ? true : _ref3$fixed;
1111
+
1112
+ if (constant) {
1024
1113
  var _rate = this.toConstant();
1025
1114
 
1026
1115
  if (_rate) return _rate;
@@ -1032,56 +1121,110 @@ var TimeBase = /*#__PURE__*/function () {
1032
1121
  return rate;
1033
1122
  }
1034
1123
 
1035
- return round ? rate.toFixed(2) : rate;
1124
+ if (rounded) {
1125
+ return Math.round(rate);
1126
+ }
1127
+
1128
+ if (fixed === true || typeof fixed === 'number') {
1129
+ return Number(rate.toFixed(fixed === true ? 2 : fixed));
1130
+ }
1131
+
1132
+ return rate;
1133
+ }
1134
+ /**
1135
+ * Get TimeBase in a object representation
1136
+ *
1137
+ * @returns {object} TimeBase as `{denominator, numerator}` object
1138
+ */
1139
+
1140
+ }, {
1141
+ key: "toObject",
1142
+ value: function toObject() {
1143
+ return {
1144
+ denominator: this.denominator,
1145
+ numerator: this.numerator
1146
+ };
1147
+ }
1148
+ /**
1149
+ * @deprecated Use {@link TimeBase#toObject|toObject} instead
1150
+ *
1151
+ * @returns {object} TimeBase as `{denominator, numerator}` object
1152
+ */
1153
+
1154
+ }, {
1155
+ key: "toJson",
1156
+ value: function toJson() {
1157
+ // eslint-disable-next-line no-console
1158
+ console.warn('Deprecated - use toObject instead');
1159
+ return this.toObject();
1036
1160
  }
1037
1161
  }]);
1038
1162
 
1039
1163
  return TimeBase;
1040
1164
  }();
1041
1165
 
1042
- var formatTimeBaseType = function formatTimeBaseType(timeBase) {
1043
- return new TimeBase(timeBase);
1044
- };
1166
+ /**
1167
+ * Format a string representation of a time base to a TimeBase Instance
1168
+ *
1169
+ * @param {string} timeBaseText The string to format to a TimeBase instance
1170
+ * @returns {TimeBase} A TimeBase Instance
1171
+ */
1045
1172
 
1046
1173
  var formatTimeBaseText = function formatTimeBaseText(timeBaseText) {
1047
1174
  if (timeBaseText === undefined) {
1048
- return formatTimeBaseType();
1175
+ return new TimeBase();
1049
1176
  }
1050
1177
 
1051
1178
  if (typeof timeBaseText === 'number') {
1052
- return formatTimeBaseType({
1179
+ return new TimeBase({
1053
1180
  denominator: timeBaseText
1054
1181
  });
1055
1182
  }
1056
1183
 
1057
- if (timeBaseText.includes(':')) {
1184
+ if (typeof timeBaseText === 'string' && timeBaseText.includes(':')) {
1058
1185
  var _timeBaseText$split = timeBaseText.split(':'),
1059
1186
  _timeBaseText$split2 = _slicedToArray(_timeBaseText$split, 2),
1060
- _denominator = _timeBaseText$split2[0],
1187
+ denominator = _timeBaseText$split2[0],
1061
1188
  numerator = _timeBaseText$split2[1];
1062
1189
 
1063
- return formatTimeBaseType({
1064
- denominator: _denominator,
1190
+ return new TimeBase({
1191
+ denominator: denominator,
1065
1192
  numerator: numerator
1066
1193
  });
1067
1194
  }
1068
1195
 
1069
- if (Object.keys(CONSTANT_TIMEBASES).includes(timeBaseText)) {
1070
- return formatTimeBaseType(CONSTANT_TIMEBASES[timeBaseText]);
1196
+ if (TIME_BASE_CONSTANTS.includes(timeBaseText)) {
1197
+ return new TimeBase(MAP_CONSTANT_TO_DEN_NUM[timeBaseText]);
1071
1198
  }
1072
1199
 
1073
- var denominator = Number(timeBaseText);
1074
-
1075
- if (Number.isNaN(denominator)) {
1076
- throw new Error("timeBaseText must be a number or ".concat(Object.keys(CONSTANT_TIMEBASES).join(','), " - is ").concat(timeBaseText));
1200
+ if (!['string', 'number'].includes(_typeof(timeBaseText)) || Number.isNaN(Number(timeBaseText))) {
1201
+ throw new Error("timeBaseText must be a number or ".concat(TIME_BASE_CONSTANTS.join(','), " - is ").concat(JSON.stringify(timeBaseText)));
1077
1202
  }
1078
1203
 
1079
- return formatTimeBaseType({
1080
- denominator: denominator
1204
+ return new TimeBase({
1205
+ denominator: Number(timeBaseText)
1081
1206
  });
1082
1207
  };
1083
1208
 
1084
- var formatTimeBase = function formatTimeBase(timeBase) {
1209
+ /**
1210
+ * Create a TimeBase instance of an object
1211
+ *
1212
+ * @param {object} timeBase A TimeBase object ({ numerator, denominator })
1213
+ * @returns {TimeBase} A TimeBase instance
1214
+ */
1215
+
1216
+ var formatTimeBaseType = function formatTimeBaseType(timeBase) {
1217
+ return new TimeBase(timeBase);
1218
+ };
1219
+
1220
+ /**
1221
+ * Create a TimeBase Instance from a string or object representation of a time base
1222
+ *
1223
+ * @param {string|object} timeBase Expressed as "denominator:numerator" or { numerator, denominator }
1224
+ * @returns {TimeBase} A TimeBase instance
1225
+ */
1226
+
1227
+ var createTimeBase = function createTimeBase(timeBase) {
1085
1228
  if (_typeof(timeBase) === 'object') {
1086
1229
  return formatTimeBaseType(timeBase);
1087
1230
  }
@@ -1089,47 +1232,86 @@ var formatTimeBase = function formatTimeBase(timeBase) {
1089
1232
  return formatTimeBaseText(timeBase);
1090
1233
  };
1091
1234
 
1092
- var getDropFrames$1 = function getDropFrames(roundedFrameRate) {
1093
- return roundedFrameRate === 60 ? 4 : 2;
1235
+ /**
1236
+ * @private
1237
+ *
1238
+ * Drops 4 frames (0-3) for 59.97 and 2 frames (0-1) for 29.97/NTSC
1239
+ *
1240
+ * @param {TimeBase} timeBase to check
1241
+ * @returns {number} amount of frame drops for specified timeBase
1242
+ */
1243
+ var getAmountOfFrameDrops = function getAmountOfFrameDrops(timeBase) {
1244
+ var timeBaseConstant = timeBase.toRate({
1245
+ constant: true
1246
+ });
1247
+ return timeBaseConstant === '59.94' && 4 || ['NTSC', '29.97'].includes(timeBaseConstant) && 2 || 0;
1094
1248
  };
1095
1249
 
1096
- var getRoundedFrameRate$1 = function getRoundedFrameRate(timeBase) {
1097
- return Math.round(timeBase.denominator / timeBase.numerator);
1250
+ /**
1251
+ * @private
1252
+ *
1253
+ * Check if TimeBase drops frames
1254
+ *
1255
+ * @param {object} timeBase TimeBase Instance to check
1256
+ * @returns {boolean} true if time base drops frames, false otherwise
1257
+ */
1258
+
1259
+ var isDropFrameTimeBase = function isDropFrameTimeBase(timeBase) {
1260
+ return getAmountOfFrameDrops(timeBase) > 0;
1098
1261
  };
1099
1262
 
1100
- function countDroppedFrames(frames, roundedFrameRate) {
1101
- var dropFrames = getDropFrames$1(roundedFrameRate);
1102
- var oneMinuteUndroppedFrames = 60 * roundedFrameRate;
1103
- var oneMinuteDroppedFrames = 60 * roundedFrameRate - dropFrames;
1104
- var tenMinuteFrames = 10 * (oneMinuteUndroppedFrames - dropFrames) + dropFrames;
1105
- var tenMinuteChunks = Math.floor(frames / tenMinuteFrames);
1106
- var minuteRemainder = Math.max(0, frames % tenMinuteFrames - oneMinuteUndroppedFrames);
1107
- var oneMinuteChunks = Math.floor(minuteRemainder / oneMinuteDroppedFrames);
1108
- var frameRemainder = minuteRemainder % oneMinuteDroppedFrames;
1109
- var frameChunks = frameRemainder > 0 ? dropFrames : 0;
1110
- return tenMinuteChunks * 9 * dropFrames + oneMinuteChunks * dropFrames + frameChunks;
1111
- }
1263
+ var _excluded$5 = ["hours"];
1112
1264
 
1113
- var isDropFrameTimeBase = function isDropFrameTimeBase(_ref) {
1114
- var numerator = _ref.numerator,
1115
- denominator = _ref.denominator;
1116
- return numerator === 1001 && (denominator === 60000 || denominator === 30000);
1265
+ var getDroppedFramesFromSamples = function getDroppedFramesFromSamples(_ref) {
1266
+ var samples = _ref.samples,
1267
+ timeBase = _ref.timeBase;
1268
+ var amountOfFrameDrops = getAmountOfFrameDrops(timeBase);
1269
+ if (amountOfFrameDrops === 0) return 0;
1270
+ var roundedFrameRate = timeBase.toRate({
1271
+ rounded: true
1272
+ });
1273
+ var oneMinuteNotDroppedFrames = 60 * roundedFrameRate;
1274
+ var amountOfFramesToDropPerMinute = 60 * roundedFrameRate - amountOfFrameDrops;
1275
+ var tenMinuteFrames = 10 * (oneMinuteNotDroppedFrames - amountOfFrameDrops) + amountOfFrameDrops;
1276
+ var amountOfTenMinuteChunks = Math.floor((samples + 1) / tenMinuteFrames);
1277
+ var minuteRemainder = Math.max(0, (samples + 1) % tenMinuteFrames - oneMinuteNotDroppedFrames);
1278
+ var amountOfOneMinuteReminderChunks = Math.floor(minuteRemainder / amountOfFramesToDropPerMinute);
1279
+ var frameRemainder = minuteRemainder % amountOfFramesToDropPerMinute;
1280
+ var amountOfFrameRemainderChunks = frameRemainder > 0 ? amountOfFrameDrops : 0;
1281
+ return amountOfTenMinuteChunks * 9 * amountOfFrameDrops + amountOfOneMinuteReminderChunks * amountOfFrameDrops + amountOfFrameRemainderChunks;
1117
1282
  };
1283
+ /**
1284
+ * TimeCode class representing the TimeCodeType in VidiCore
1285
+ *
1286
+ * For more info, see the [Time Codes section of VidiCore API Docs](https://apidoc.vidispine.com/latest/time.html#time-codes)
1287
+ */
1288
+
1118
1289
 
1119
1290
  var TimeCode = /*#__PURE__*/function () {
1291
+ /**
1292
+ * Constructor for TimeCode
1293
+ *
1294
+ * @param {object} [timeCodeType={}] Object to create TimeCode of
1295
+ * @param {number} [timeCodeType.samples=0] Amount of samples for the time code
1296
+ * @param {object|string|number} [timeCodeType.timeBase={numerator: 1, denominator: 1}] The time base it should have
1297
+ * @param {object} [options={}] Options for the timeCode
1298
+ * @param {boolean} options.dropFrame If time code should be dropFrame or not (by default checks timeBase)
1299
+ * @param {string} options.frameSeparator Separator to use for frame smpte output (default ":" for non-drop-frame and ";" for dropFrame)
1300
+ */
1120
1301
  function TimeCode() {
1121
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1122
- _ref2$samples = _ref2.samples,
1123
- samples = _ref2$samples === void 0 ? 0 : _ref2$samples,
1124
- timeBase = _ref2.timeBase;
1302
+ var _options$dropFrame, _options$frameSeparat;
1125
1303
 
1126
- var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
1127
- dropFrame = _ref3.dropFrame,
1128
- _ref3$field = _ref3.field,
1129
- field = _ref3$field === void 0 ? 2 : _ref3$field;
1304
+ var timeCodeType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1305
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1130
1306
 
1131
1307
  _classCallCheck(this, TimeCode);
1132
1308
 
1309
+ var _ref2 = timeCodeType || {},
1310
+ _ref2$samples = _ref2.samples,
1311
+ samples = _ref2$samples === void 0 ? 0 : _ref2$samples,
1312
+ _ref2$timeBase = _ref2.timeBase,
1313
+ timeBase = _ref2$timeBase === void 0 ? new TimeBase() : _ref2$timeBase;
1314
+
1133
1315
  if (typeof samples === 'number') {
1134
1316
  this.samples = samples;
1135
1317
  } else if (typeof samples === 'string') {
@@ -1144,21 +1326,39 @@ var TimeCode = /*#__PURE__*/function () {
1144
1326
  throw new Error("samples is not number/string/-Inf/+Inf is: ".concat(samples));
1145
1327
  }
1146
1328
 
1147
- this.timeBase = new TimeBase(timeBase);
1148
- this.dropFrame = dropFrame === undefined ? isDropFrameTimeBase(this.timeBase) : dropFrame;
1149
- this.field = field;
1329
+ this.timeBase = createTimeBase(timeBase);
1330
+ this.dropFrame = (_options$dropFrame = options === null || options === void 0 ? void 0 : options.dropFrame) !== null && _options$dropFrame !== void 0 ? _options$dropFrame : isDropFrameTimeBase(this.timeBase);
1331
+ this.frameSeparator = (_options$frameSeparat = options === null || options === void 0 ? void 0 : options.frameSeparator) !== null && _options$frameSeparat !== void 0 ? _options$frameSeparat : this.dropFrame ? ';' : ':';
1150
1332
  }
1333
+ /**
1334
+ * Return this TimeCode added with the supplied timeCodeType
1335
+ * If time bases differ, it will retain the time base of this TimeCode instance
1336
+ * If supplied time code has a more granular time base - it will round down exceeding samples (hasn't reached that sample yet)
1337
+ *
1338
+ * Note: This might make you "lose" frames depending on granularity of time bases, e.g.
1339
+ * "51@50".add("25@25") => "101@50"
1340
+ * while "25@25".add("51@50") => "50@25" (not "101@50")
1341
+ *
1342
+ * @param {TimeCode} timeCodeType A TimeCode instance you want to add with
1343
+ * @returns A new TimeCode instance with the addition applied
1344
+ */
1345
+
1151
1346
 
1152
1347
  _createClass(TimeCode, [{
1153
1348
  key: "add",
1154
- value: function add(val) {
1155
- var _val$timeBase = val.timeBase,
1156
- numerator = _val$timeBase.numerator,
1157
- denominator = _val$timeBase.denominator;
1158
- var conformedTimeCode = val;
1349
+ value: function add(timeCodeType) {
1350
+ if (!(timeCodeType !== null && timeCodeType !== void 0 && timeCodeType.timeBase) || (timeCodeType === null || timeCodeType === void 0 ? void 0 : timeCodeType.samples) === undefined) {
1351
+ throw Error('Invalid timeCodeType, cannot be added');
1352
+ }
1353
+
1354
+ var _timeCodeType$timeBas = timeCodeType.timeBase;
1355
+ _timeCodeType$timeBas = _timeCodeType$timeBas === void 0 ? {} : _timeCodeType$timeBas;
1356
+ var numerator = _timeCodeType$timeBas.numerator,
1357
+ denominator = _timeCodeType$timeBas.denominator;
1358
+ var conformedTimeCode = timeCodeType;
1159
1359
 
1160
1360
  if (numerator !== this.timeBase.numerator || denominator !== this.timeBase.denominator) {
1161
- conformedTimeCode = val.conformTimeBase(this.timeBase);
1361
+ conformedTimeCode = timeCodeType.conformTimeBase(this.timeBase);
1162
1362
  }
1163
1363
 
1164
1364
  var _conformedTimeCode = conformedTimeCode,
@@ -1168,16 +1368,34 @@ var TimeCode = /*#__PURE__*/function () {
1168
1368
  timeBase: this.timeBase
1169
1369
  });
1170
1370
  }
1371
+ /**
1372
+ * Return this TimeCode subtracted with the supplied timeCodeType
1373
+ * If time bases differ, it will retain the time base of the instance time code
1374
+ * If supplied time code has a more granular time base - it will round down exceeding samples (hasn't reached that sample yet)
1375
+ *
1376
+ * Note: This might make you "lose" frames depending on granularity of time bases, e.g.
1377
+ * "101@50".subtract("25@25") => "51@50"
1378
+ * while "50@25".subtract("51@50") => "25@25" (not "49@50")
1379
+ *
1380
+ * @param {TimeCode} timeCodeType A TimeCode instance you want to subtract with
1381
+ * @returns A new TimeCode instance with the subtraction applied
1382
+ */
1383
+
1171
1384
  }, {
1172
1385
  key: "subtract",
1173
- value: function subtract(val) {
1174
- var _val$timeBase2 = val.timeBase,
1175
- numerator = _val$timeBase2.numerator,
1176
- denominator = _val$timeBase2.denominator;
1177
- var conformedTimeCode = val;
1386
+ value: function subtract(timeCodeType) {
1387
+ if (!(timeCodeType !== null && timeCodeType !== void 0 && timeCodeType.timeBase) || (timeCodeType === null || timeCodeType === void 0 ? void 0 : timeCodeType.samples) === undefined) {
1388
+ throw Error('Invalid timeCodeType, cannot be subtracted');
1389
+ }
1390
+
1391
+ var _timeCodeType$timeBas2 = timeCodeType.timeBase;
1392
+ _timeCodeType$timeBas2 = _timeCodeType$timeBas2 === void 0 ? {} : _timeCodeType$timeBas2;
1393
+ var numerator = _timeCodeType$timeBas2.numerator,
1394
+ denominator = _timeCodeType$timeBas2.denominator;
1395
+ var conformedTimeCode = timeCodeType;
1178
1396
 
1179
1397
  if (numerator !== this.timeBase.numerator || denominator !== this.timeBase.denominator) {
1180
- conformedTimeCode = val.conformTimeBase(this.timeBase);
1398
+ conformedTimeCode = timeCodeType.conformTimeBase(this.timeBase);
1181
1399
  }
1182
1400
 
1183
1401
  var _conformedTimeCode2 = conformedTimeCode,
@@ -1187,361 +1405,765 @@ var TimeCode = /*#__PURE__*/function () {
1187
1405
  timeBase: this.timeBase
1188
1406
  });
1189
1407
  }
1408
+ /**
1409
+ * Creates a new TimeCode instance with specified timeBase and samples adjusted to that.
1410
+ *
1411
+ * If it conforms to a less granular time base - it will floor samples (hasn't reached that sample yet)
1412
+ * - e.g. "51@50".conformTo("PAL") => "25@PAL" (not "26@PAL")
1413
+ *
1414
+ * @param {string|object} conformTo The TimeBase it should conform the TimeCode to
1415
+ * @returns A new TimeCode instance with the conformTo timeBase applied
1416
+ */
1417
+
1190
1418
  }, {
1191
1419
  key: "conformTimeBase",
1192
1420
  value: function conformTimeBase(conformTo) {
1193
- var timeBase = conformTo;
1421
+ var conformToTimeBase = conformTo;
1194
1422
 
1195
- if (conformTo instanceof TimeCode === false) {
1196
- timeBase = new TimeBase(conformTo);
1423
+ if (!(conformTo instanceof TimeBase)) {
1424
+ conformToTimeBase = createTimeBase(conformTo);
1197
1425
  }
1198
1426
 
1199
- var samples = Math.round(this.samples / (this.timeBase.toRate(false, false) / timeBase.toRate(false, false)));
1427
+ var samples = Math.floor(this.samples / (this.timeBase.toRate({
1428
+ fixed: false
1429
+ }) / conformToTimeBase.toRate({
1430
+ fixed: false
1431
+ })));
1200
1432
  var timeCode = {
1201
1433
  samples: samples,
1202
- timeBase: timeBase
1434
+ timeBase: conformToTimeBase
1203
1435
  };
1204
1436
  return new TimeCode(timeCode);
1205
1437
  }
1206
- }, {
1207
- key: "toJSON",
1208
- value: function toJSON() {
1209
- return {
1210
- samples: this.samples,
1211
- timeBase: this.timeBase
1212
- };
1213
- }
1438
+ /**
1439
+ * Get TimeCode as a text representation
1440
+ *
1441
+ * Default format: samples@denominator(:numerator if > 1)
1442
+ * `constant` has precedence over `fraction` if both are true
1443
+ *
1444
+ * @param {object} [options={}] TimeBase toText options
1445
+ * @param {boolean} [options.includeTimeBaseForSeconds=false] include time base even if seconds
1446
+ * @param {boolean} [options.constant=false] show as constant (e.g. @PAL)
1447
+ * @param {boolean} [options.fraction=false] show as fraction (@25:1)
1448
+ * @returns Text representation of TimeCode
1449
+ */
1450
+
1214
1451
  }, {
1215
1452
  key: "toText",
1216
1453
  value: function toText() {
1217
- var timeCodeText = String(this.samples);
1218
- var timeBaseText = this.timeBase.toText();
1454
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1455
+ var timeCodeText = "".concat(this.samples);
1456
+ var timeBaseText = this.timeBase.toText(options);
1219
1457
 
1220
- if (timeBaseText !== '1') {
1458
+ if (options !== null && options !== void 0 && options.includeTimeBaseForSeconds || !['1', '1:1'].includes(timeBaseText)) {
1221
1459
  timeCodeText = [this.samples, timeBaseText].join('@');
1222
1460
  }
1223
1461
 
1224
1462
  return timeCodeText;
1225
1463
  }
1464
+ /**
1465
+ * Get TimeCode in a units object representation
1466
+ *
1467
+ * @returns {object} in the format { hours, minutes, seconds, frames }
1468
+ */
1469
+
1226
1470
  }, {
1227
- key: "toSeconds",
1228
- value: function toSeconds() {
1229
- var _this$timeBase = this.timeBase,
1230
- numerator = _this$timeBase.numerator,
1231
- denominator = _this$timeBase.denominator;
1232
- return this.samples * (numerator / denominator);
1471
+ key: "toUnits",
1472
+ value: function toUnits() {
1473
+ var totalSamples = this.samples + (this.dropFrame ? getDroppedFramesFromSamples(this) : 0);
1474
+ var roundedFrameRate = this.timeBase.toRate({
1475
+ rounded: true
1476
+ }); // Calculated without drop-frame but with 2 decimal places
1477
+
1478
+ if (['23.976', '23.98'].includes(this.timeBase.toConstant())) {
1479
+ roundedFrameRate = this.timeBase.toRate({
1480
+ fixed: true
1481
+ });
1482
+ }
1483
+
1484
+ var hours = Math.floor(totalSamples / (3600 * roundedFrameRate));
1485
+ var minutes = Math.floor(totalSamples / (60 * roundedFrameRate)) % 60;
1486
+ var seconds = Math.floor(totalSamples / roundedFrameRate) % 60;
1487
+ var frames = Math.floor(totalSamples % roundedFrameRate);
1488
+ return {
1489
+ hours: hours,
1490
+ minutes: minutes,
1491
+ seconds: seconds,
1492
+ frames: frames
1493
+ };
1233
1494
  }
1495
+ /**
1496
+ * Get TimeCode in a time object representation
1497
+ * "milliseconds" is rounded down, if you want another representation use "partialSeconds"
1498
+ *
1499
+ * @returns {object} in the format { hours, minutes, seconds, milliseconds, partialSeconds }
1500
+ */
1501
+
1234
1502
  }, {
1235
1503
  key: "toTime",
1236
1504
  value: function toTime() {
1237
- var roundedFrameRate = getRoundedFrameRate$1(this.timeBase);
1238
- var totalSamples = this.samples + (this.dropFrame ? countDroppedFrames(this.samples + 1, roundedFrameRate) : 0);
1239
- var hours = Math.floor(totalSamples / (3600 * roundedFrameRate));
1240
- var minutes = Math.floor(totalSamples / (60 * roundedFrameRate)) % 60;
1241
- var seconds = Math.floor(totalSamples / roundedFrameRate) % 60;
1242
- var frames = totalSamples % roundedFrameRate;
1243
- var partialSeconds = frames / roundedFrameRate;
1505
+ var totalSamples = this.samples + getDroppedFramesFromSamples(this);
1506
+
1507
+ var _this$toUnits = this.toUnits(),
1508
+ hours = _this$toUnits.hours,
1509
+ minutes = _this$toUnits.minutes,
1510
+ seconds = _this$toUnits.seconds;
1511
+
1512
+ var roundedFrameRate = this.timeBase.toRate({
1513
+ rounded: true
1514
+ });
1515
+ var framesPrecise = totalSamples % roundedFrameRate;
1516
+ var milliseconds = Math.floor(1000 * framesPrecise / roundedFrameRate);
1517
+ var partialSeconds = framesPrecise / roundedFrameRate;
1244
1518
  return {
1245
1519
  hours: hours,
1246
1520
  minutes: minutes,
1247
1521
  seconds: seconds,
1248
- frames: frames,
1522
+ milliseconds: milliseconds,
1249
1523
  partialSeconds: partialSeconds
1250
1524
  };
1251
1525
  }
1526
+ /**
1527
+ * Get TimeCode in a seconds representation
1528
+ *
1529
+ * @returns {number} the seconds
1530
+ */
1531
+
1532
+ }, {
1533
+ key: "toSeconds",
1534
+ value: function toSeconds() {
1535
+ var _this$timeBase = this.timeBase,
1536
+ numerator = _this$timeBase.numerator,
1537
+ denominator = _this$timeBase.denominator;
1538
+ return Math.round(1000 * +(this.samples * numerator / denominator)) / 1000;
1539
+ }
1540
+ /**
1541
+ * Get TimeCode in a duration representation
1542
+ * The time unit char keys for the format string are:
1543
+ * - "h" for hour
1544
+ * - "m" for minute
1545
+ * - "s" for seconds
1546
+ * - "S" for milliseconds
1547
+ * Any other char will be kept in the duration output string.
1548
+ *
1549
+ * Add consecutive chars for zero padding.
1550
+ *
1551
+ * By default it:
1552
+ * - uses colon delimiter (e.g. for format "hhmmss")
1553
+ * - shows "m:ss" or "h:mm:ss" if format is undefined
1554
+ *
1555
+ * @param {object} [options={}]
1556
+ * @param {string} options.format specify format of duration string, e.g. hh:mm:ss.S for 01:23:04.5
1557
+ * @returns {string} Duration representation of the TimeCode
1558
+ */
1559
+
1252
1560
  }, {
1253
1561
  key: "toDuration",
1254
1562
  value: function toDuration() {
1255
- var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1256
- format = _ref4.format;
1563
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1564
+ var format = options.format;
1257
1565
 
1258
1566
  var _this$toTime = this.toTime(),
1259
1567
  hours = _this$toTime.hours,
1260
- minutes = _this$toTime.minutes,
1261
- seconds = _this$toTime.seconds;
1568
+ rest = _objectWithoutProperties(_this$toTime, _excluded$5);
1262
1569
 
1263
- if (typeof format === 'string') {
1264
- if (format.toLowerCase() === 'hhmmss') {
1265
- return [hours.toFixed().padStart(2, '0'), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1266
- }
1570
+ var minutes = rest.minutes,
1571
+ seconds = rest.seconds,
1572
+ milliseconds = rest.milliseconds;
1573
+
1574
+ if (!!format && typeof format !== 'string') {
1575
+ throw Error('format has to be a string');
1267
1576
  }
1268
1577
 
1269
- if (hours) {
1270
- return [hours.toFixed(), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1578
+ var isBefore = function isBefore(unit, units) {
1579
+ return !format.includes(unit) || !units.some(function (u) {
1580
+ return format.includes(u) && format.lastIndexOf(unit) > format.indexOf(u);
1581
+ });
1582
+ };
1583
+
1584
+ if (!!format && !(isBefore('h', ['m', 's', 'S']) && isBefore('m', ['s', 'S']) && isBefore('s', ['S']))) {
1585
+ throw Error('format order is unsupported (has to be h, m, s then S)');
1271
1586
  }
1272
1587
 
1273
- if (minutes >= 10) {
1274
- return [minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1588
+ if (!format) {
1589
+ return "".concat(hours > 0 ? "".concat(hours, ":").concat("".concat(minutes).padStart(2, '0')) : minutes, ":").concat("".concat(seconds).padStart(2, '0'));
1275
1590
  }
1276
1591
 
1277
- return [minutes.toFixed(), seconds.toFixed().padStart(2, '0')].join(':');
1592
+ var countConsecutiveChars = function countConsecutiveChars(i, arr) {
1593
+ var j = i;
1594
+
1595
+ while (arr[j] === arr[j + 1]) {
1596
+ j += 1;
1597
+ }
1598
+
1599
+ return j - i + 1;
1600
+ };
1601
+
1602
+ var timeUnitKeys = ['h', 'm', 's', 'S'];
1603
+ var output = [];
1604
+
1605
+ _toConsumableArray(format).forEach(function (c, i, arr) {
1606
+ switch (c) {
1607
+ case 'h':
1608
+ {
1609
+ if (arr[i - 1] === 'h') {
1610
+ break;
1611
+ }
1612
+
1613
+ var amount = countConsecutiveChars(i, arr);
1614
+ output.push("".concat(hours).padStart(amount, '0'));
1615
+
1616
+ if (timeUnitKeys.includes(arr[i + amount])) {
1617
+ output.push(':');
1618
+ }
1619
+
1620
+ break;
1621
+ }
1622
+
1623
+ case 'm':
1624
+ {
1625
+ if (arr[i - 1] === 'm') {
1626
+ break;
1627
+ }
1628
+
1629
+ var _amount = countConsecutiveChars(i, arr);
1630
+
1631
+ if (!format.includes('h')) {
1632
+ minutes *= hours * 60;
1633
+ }
1634
+
1635
+ output.push("".concat(minutes).padStart(_amount, '0'));
1636
+
1637
+ if (timeUnitKeys.includes(arr[i + _amount])) {
1638
+ output.push(':');
1639
+ }
1640
+
1641
+ break;
1642
+ }
1643
+
1644
+ case 's':
1645
+ {
1646
+ if (arr[i - 1] === 's') {
1647
+ break;
1648
+ }
1649
+
1650
+ var _amount2 = countConsecutiveChars(i, arr);
1651
+
1652
+ if (!format.includes('m')) {
1653
+ seconds *= minutes * 60;
1654
+ }
1655
+
1656
+ output.push("".concat(seconds).padStart(_amount2, '0'));
1657
+
1658
+ if (timeUnitKeys.includes(arr[i + _amount2])) {
1659
+ output.push('.');
1660
+ }
1661
+
1662
+ break;
1663
+ }
1664
+
1665
+ case 'S':
1666
+ {
1667
+ if (arr[i - 1] === 'S') {
1668
+ break;
1669
+ }
1670
+
1671
+ var _amount3 = countConsecutiveChars(i, arr);
1672
+
1673
+ if (!format.includes('s')) {
1674
+ milliseconds *= seconds * 1000;
1675
+ }
1676
+
1677
+ output.push("".concat(Math.round(milliseconds / Math.pow(10, 3 - _amount3))).padStart(_amount3, '0'));
1678
+ break;
1679
+ }
1680
+
1681
+ default:
1682
+ output.push(c);
1683
+ }
1684
+ });
1685
+
1686
+ return output.join('');
1278
1687
  }
1688
+ /**
1689
+ * Get TimeCode in a smpte representation
1690
+ *
1691
+ * @returns {string} Smpte representation of the TimeCode
1692
+ */
1693
+
1279
1694
  }, {
1280
1695
  key: "toSmpte",
1281
1696
  value: function toSmpte() {
1282
- var _this = this;
1283
-
1284
1697
  if (this.samples === -Infinity) return '00:00:00:00';
1285
1698
 
1286
- var _this$toTime2 = this.toTime(),
1287
- hours = _this$toTime2.hours,
1288
- minutes = _this$toTime2.minutes,
1289
- seconds = _this$toTime2.seconds,
1290
- frames = _this$toTime2.frames;
1699
+ var _this$toUnits2 = this.toUnits(),
1700
+ hours = _this$toUnits2.hours,
1701
+ minutes = _this$toUnits2.minutes,
1702
+ seconds = _this$toUnits2.seconds,
1703
+ frames = _this$toUnits2.frames;
1291
1704
 
1292
1705
  var hhmmss = [hours.toFixed().padStart(2, '0'), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1706
+ return [hhmmss, "".concat(frames).padStart(2, '0')].join(this.frameSeparator);
1707
+ }
1708
+ /**
1709
+ * Get TimeCode as a VidiCore TimeCodeType object
1710
+ *
1711
+ * @returns {object} TimeCode as `{ samples, timeBase }`
1712
+ */
1293
1713
 
1294
- var _Object$entries$find = Object.entries(FRAME_SEPARATORS).find(function (thisSeparator) {
1295
- var _thisSeparator = _slicedToArray(thisSeparator, 2),
1296
- _thisSeparator$ = _thisSeparator[1],
1297
- dropFrame = _thisSeparator$.dropFrame,
1298
- field = _thisSeparator$.field;
1299
-
1300
- return dropFrame === _this.dropFrame && field === _this.field;
1301
- }),
1302
- _Object$entries$find2 = _slicedToArray(_Object$entries$find, 1),
1303
- _Object$entries$find3 = _Object$entries$find2[0],
1304
- frameSeparator = _Object$entries$find3 === void 0 ? ':' : _Object$entries$find3;
1305
-
1306
- return [hhmmss, frames.toFixed().padStart(2, '0')].join(frameSeparator);
1714
+ }, {
1715
+ key: "toObject",
1716
+ value: function toObject() {
1717
+ return {
1718
+ samples: this.samples,
1719
+ timeBase: this.timeBase.toObject()
1720
+ };
1307
1721
  }
1722
+ /**
1723
+ * @deprecated Use {@link TimeCode#toObject|toObject} instead
1724
+ *
1725
+ * @returns {object} TimeCode as `{ samples, timeBase }`
1726
+ */
1727
+
1308
1728
  }, {
1309
- key: "toFraction",
1310
- value: function toFraction() {
1311
- return "".concat(this.samples, "@").concat(this.timeBase.denominator, ":").concat(this.timeBase.numerator);
1729
+ key: "toJson",
1730
+ value: function toJson() {
1731
+ // eslint-disable-next-line no-console
1732
+ console.warn('Deprecated - use toObject instead');
1733
+ return this.toObject();
1312
1734
  }
1313
1735
  }]);
1314
1736
 
1315
1737
  return TimeCode;
1316
1738
  }();
1317
1739
 
1318
- var formatTimeCodeType = function formatTimeCodeType(timeCode, options) {
1319
- return new TimeCode(timeCode, options);
1320
- };
1321
-
1322
- var formatTimeCodeText = function formatTimeCodeText(timeCodeText, options) {
1323
- if (timeCodeText === undefined) {
1324
- var _timeCode = {
1325
- samples: 0
1326
- };
1327
- return formatTimeCodeType(_timeCode, options);
1328
- }
1740
+ /* eslint-disable no-self-assign */
1329
1741
 
1330
- if (typeof timeCodeText === 'number') {
1331
- var _timeCode2 = {
1332
- samples: timeCodeText
1333
- };
1334
- return formatTimeCodeType(_timeCode2, options);
1742
+ /**
1743
+ * @private
1744
+ *
1745
+ * Using Euclid's algorithm
1746
+ *
1747
+ * @param {number} num1 a number
1748
+ * @param {number} num2 another number
1749
+ * @returns {number} the greatest common divisor as a number
1750
+ */
1751
+ var getGreatestCommonDivisor = function getGreatestCommonDivisor(num1, num2) {
1752
+ var a = Math.abs(num1);
1753
+ var b = Math.abs(num2);
1754
+
1755
+ while (a && b && a !== b) {
1756
+ if (a > b) {
1757
+ var _ref = [a - b, b];
1758
+ a = _ref[0];
1759
+ b = _ref[1];
1760
+ } else {
1761
+ var _ref2 = [a, b - a];
1762
+ a = _ref2[0];
1763
+ b = _ref2[1];
1764
+ }
1335
1765
  }
1336
1766
 
1337
- if (timeCodeText.includes('@')) {
1338
- var _timeCodeText$split = timeCodeText.split('@'),
1339
- _timeCodeText$split2 = _slicedToArray(_timeCodeText$split, 2),
1340
- samplesString = _timeCodeText$split2[0],
1341
- timeBaseText = _timeCodeText$split2[1];
1342
-
1343
- var _samples = Number(samplesString);
1344
-
1345
- var timeBase = formatTimeBaseText(timeBaseText);
1346
- var _timeCode3 = {
1347
- samples: _samples,
1348
- timeBase: timeBase
1349
- };
1350
- return formatTimeCodeType(_timeCode3, options);
1351
- }
1767
+ return a || b;
1768
+ };
1352
1769
 
1353
- if (timeCodeText === '-INF') {
1354
- var _samples2 = -Infinity;
1770
+ var _excluded$4 = ["timeBase", "useGCD"];
1771
+ /**
1772
+ * Format seconds to TimeCode object
1773
+ * Input time base is always 1:1 since it expects seconds as input
1774
+ *
1775
+ * Note: Max 15 digits accuracy (double precision float64), e.g.
1776
+ * - 10^6 seconds can have 10^9 decimals (nanosecond) precision
1777
+ * - 10^9 seconds can have 10^6 decimals (microsecond) precision
1778
+ * - 10^12 seconds can have 10^3 decimals (millisecond) precision
1779
+ *
1780
+ * @param {string|number} seconds With or without decimals ("." and "," are both interpreted as decimal)
1781
+ * @param {object} [options={}] Options for how to format the seconds to a TimeCode
1782
+ * @param {object|string} options.timeBase What TimeBase the resulting TimeCode should have (if unset and useGCD=false, denominator will be 10^<amount-of-decimals>)
1783
+ * @param {boolean} [options.useGCD=false] Samples and denominator are divided with GCD (ignored if timeBase is set) (e.g. 1.04 => 104@100 => 26@25)
1784
+ * @returns {TimeCode} A TimeCode instance
1785
+ */
1355
1786
 
1356
- var _timeCode4 = {
1357
- samples: _samples2
1358
- };
1359
- return formatTimeCodeType(_timeCode4, options);
1360
- }
1787
+ var formatTimeCodeSeconds = function formatTimeCodeSeconds(seconds) {
1788
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1361
1789
 
1362
- if (timeCodeText === '+INF') {
1363
- var _samples3 = Infinity;
1364
- var _timeCode5 = {
1365
- samples: _samples3
1366
- };
1367
- return formatTimeCodeType(_timeCode5, options);
1368
- }
1790
+ var timeBase = options.timeBase,
1791
+ _options$useGCD = options.useGCD,
1792
+ useGCD = _options$useGCD === void 0 ? false : _options$useGCD,
1793
+ timeCodeOptions = _objectWithoutProperties(options, _excluded$4);
1369
1794
 
1370
- var samples = Number(timeCodeText);
1795
+ var secondsWithDot = "".concat(seconds).replace(/,/g, '.');
1796
+ var amountOfDigits = secondsWithDot.replace('.', '').length;
1371
1797
 
1372
- if (Number.isNaN(samples)) {
1373
- throw new Error("timeBaseText must be a number or sample@timeBase - is ".concat(timeCodeText));
1798
+ if (amountOfDigits > 16) {
1799
+ throw new Error("Amount of second digits cannot be more than 16, is ".concat(amountOfDigits));
1374
1800
  }
1375
1801
 
1376
- var timeCode = {
1377
- samples: samples
1378
- };
1379
- return formatTimeCodeType(timeCode, options);
1380
- };
1381
-
1382
- var formatSeconds = function formatSeconds(seconds, timeBase, options) {
1383
- if (Number.isNaN(Number(seconds))) {
1802
+ if (Number.isNaN(+secondsWithDot)) {
1384
1803
  throw new Error("seconds must be digits, is ".concat(seconds));
1385
1804
  }
1386
1805
 
1387
- var _ref = timeBase || {},
1388
- _ref$denominator = _ref.denominator,
1389
- denominator = _ref$denominator === void 0 ? 1 : _ref$denominator,
1390
- _ref$numerator = _ref.numerator,
1391
- numerator = _ref$numerator === void 0 ? 1 : _ref$numerator;
1806
+ var denominator = 1;
1807
+ var samples;
1392
1808
 
1393
- var samples = seconds * (denominator / numerator);
1394
- var timeCode = {
1395
- samples: samples,
1396
- timeBase: timeBase || {}
1397
- };
1398
- return new TimeCode(timeCode, options);
1399
- };
1400
-
1401
- var formatSecondsPrecise = function formatSecondsPrecise(seconds, timeBase, options) {
1402
- if (Number.isNaN(Number(seconds))) {
1403
- throw new Error("seconds must be digits, is ".concat(seconds));
1404
- }
1405
-
1406
- var _ref = timeBase || {},
1407
- _ref$numerator = _ref.numerator,
1408
- numerator = _ref$numerator === void 0 ? 1 : _ref$numerator;
1809
+ if (Number.isInteger(+secondsWithDot)) {
1810
+ samples = +secondsWithDot * denominator;
1811
+ } else {
1812
+ var _ms$length;
1409
1813
 
1410
- var _ref2 = timeBase || {},
1411
- _ref2$denominator = _ref2.denominator,
1412
- denominator = _ref2$denominator === void 0 ? 1 : _ref2$denominator;
1814
+ var _secondsWithDot$split = secondsWithDot.split('.'),
1815
+ _secondsWithDot$split2 = _slicedToArray(_secondsWithDot$split, 2),
1816
+ ms = _secondsWithDot$split2[1];
1413
1817
 
1414
- if (!Number.isInteger(seconds)) {
1415
- var decimalPlaces = String(seconds).split('.')[1].length;
1818
+ var decimalPlaces = Math.min((_ms$length = ms === null || ms === void 0 ? void 0 : ms.length) !== null && _ms$length !== void 0 ? _ms$length : 0, 16);
1416
1819
  denominator *= Math.pow(10, decimalPlaces);
1820
+ samples = Math.round(secondsWithDot * denominator);
1821
+ }
1822
+
1823
+ if (!timeBase && useGCD) {
1824
+ var gcd = getGreatestCommonDivisor(denominator, samples);
1825
+ samples /= gcd;
1826
+ denominator /= gcd;
1417
1827
  }
1418
1828
 
1419
- var samples = (seconds * (denominator / numerator)).toFixed();
1420
- var timeCode = {
1829
+ var timeCode = new TimeCode({
1421
1830
  samples: samples,
1422
1831
  timeBase: {
1423
1832
  denominator: denominator,
1424
- numerator: numerator
1833
+ numerator: 1
1425
1834
  }
1426
- };
1427
- return new TimeCode(timeCode, options);
1835
+ }, timeCodeOptions);
1836
+ return timeBase ? timeCode.conformTimeBase(createTimeBase(timeBase === true ? 1 : timeBase)) : timeCode;
1428
1837
  };
1429
1838
 
1839
+ var _excluded$3 = ["exceedingMode", "timeBase"];
1840
+
1430
1841
  function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
1431
1842
 
1432
1843
  function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$2(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
1433
-
1434
- var getDropFrames = function getDropFrames(roundedFrameRate) {
1435
- return roundedFrameRate === 60 ? 4 : 2;
1844
+ var MAP_SEPARATOR_TO_OPTIONS = {
1845
+ ':': {
1846
+ dropFrame: false,
1847
+ frameSeparator: ':'
1848
+ },
1849
+ '.': {
1850
+ dropFrame: false,
1851
+ frameSeparator: '.'
1852
+ },
1853
+ ';': {
1854
+ dropFrame: true,
1855
+ frameSeparator: ';'
1856
+ },
1857
+ ',': {
1858
+ dropFrame: true,
1859
+ frameSeparator: ','
1860
+ }
1436
1861
  };
1862
+ var getDroppedFramesFromSmpte = function getDroppedFramesFromSmpte(_ref, samples, timeBase) {
1863
+ var _ref2 = _slicedToArray(_ref, 4),
1864
+ hh = _ref2[0],
1865
+ mm = _ref2[1],
1866
+ ss = _ref2[2],
1867
+ ff = _ref2[3];
1868
+
1869
+ var roundedFrameRate = timeBase.toRate({
1870
+ rounded: true
1871
+ });
1872
+ var dropFrames = getAmountOfFrameDrops(timeBase);
1437
1873
 
1438
- var getRoundedFrameRate = function getRoundedFrameRate(timeBase) {
1439
- return Math.round(timeBase.denominator / timeBase.numerator);
1874
+ if (samples === 0 || dropFrames === 0) {
1875
+ return 0;
1876
+ }
1877
+
1878
+ var shouldDropMinute = mm % 10 !== 0;
1879
+ var shouldDropSecond = shouldDropMinute && ss === 0;
1880
+ var hourFrames = hh * (3600 * roundedFrameRate - 54 * dropFrames);
1881
+ var minuteFrames = mm * 60 * roundedFrameRate - (mm - Math.ceil(mm / 10)) * dropFrames;
1882
+ var secondFrames = ss * roundedFrameRate - (shouldDropMinute && ss > 1 ? dropFrames : 0);
1883
+
1884
+ if (shouldDropSecond && ff < dropFrames) {
1885
+ throw new Error("Frame does not exist for ".concat(timeBase.toRate({
1886
+ constant: true
1887
+ }), " drop-frame"));
1888
+ }
1889
+
1890
+ var frameFrames = shouldDropSecond ? ff - dropFrames : ff;
1891
+ var samplesWithoutDroppedFrames = hourFrames + minuteFrames + secondFrames + frameFrames;
1892
+ return samples - samplesWithoutDroppedFrames;
1440
1893
  };
1441
1894
 
1442
- var splitSmpte = function splitSmpte(smpteText) {
1443
- var hasDropFrameSeparator = smpteText.match(/[^0-9:\-_]/);
1444
- var hhmmssff;
1445
- var frameOptions = {};
1895
+ var splitSmpte = function splitSmpte(smpte) {
1896
+ var _ref3 = (smpte === null || smpte === void 0 ? void 0 : smpte.match(/[^0-9:\-_]/)) || [],
1897
+ _ref4 = _slicedToArray(_ref3, 1),
1898
+ nonColonFrameSeparator = _ref4[0];
1446
1899
 
1447
- if (hasDropFrameSeparator) {
1448
- var _hasDropFrameSeparato = _slicedToArray(hasDropFrameSeparator, 1),
1449
- frameSeparator = _hasDropFrameSeparato[0];
1900
+ var smpteValues = [];
1901
+ var options = {
1902
+ frameSeparator: ':',
1903
+ dropFrame: false
1904
+ };
1450
1905
 
1451
- var _smpteText$split = smpteText.split(frameSeparator),
1452
- _smpteText$split2 = _slicedToArray(_smpteText$split, 2),
1453
- hhmmss = _smpteText$split2[0],
1454
- splitFrames = _smpteText$split2[1];
1906
+ if (nonColonFrameSeparator) {
1907
+ var _smpte$split = smpte.split(nonColonFrameSeparator),
1908
+ _smpte$split2 = _slicedToArray(_smpte$split, 2),
1909
+ hhmmss = _smpte$split2[0],
1910
+ ff = _smpte$split2[1];
1455
1911
 
1456
- hhmmssff = [].concat(_toConsumableArray(hhmmss.split(':')), [splitFrames]);
1457
- frameOptions = FRAME_SEPARATORS[frameSeparator] || {};
1912
+ smpteValues = [].concat(_toConsumableArray(hhmmss.split(':')), [ff]);
1913
+ options = MAP_SEPARATOR_TO_OPTIONS[nonColonFrameSeparator] || {};
1458
1914
  } else {
1459
- hhmmssff = smpteText.split(':');
1915
+ smpteValues = smpte.split(':');
1460
1916
  }
1461
1917
 
1462
- hhmmssff = hhmmssff.map(Number);
1918
+ smpteValues = smpteValues.map(Number);
1463
1919
 
1464
- if (hhmmssff.length > 4 || hhmmssff.some(function (n) {
1920
+ if (smpteValues.length !== 4) {
1921
+ throw new Error('Invalid format, must be "##:##:##:##');
1922
+ }
1923
+
1924
+ if (smpteValues.some(function (n) {
1465
1925
  return Number.isNaN(n);
1466
1926
  })) {
1467
- throw new Error('Invalid SMPTE timecode');
1927
+ throw new Error('Invalid format, values must be numbers');
1468
1928
  }
1469
1929
 
1470
- return [hhmmssff, frameOptions];
1930
+ return [smpteValues, options];
1471
1931
  };
1472
1932
 
1473
- var countSamples = function countSamples(hh, mm, ss, ff, _ref) {
1474
- var dropFrame = _ref.dropFrame,
1475
- roundedFrameRate = _ref.roundedFrameRate;
1933
+ var getSamplesFromSmpte = function getSamplesFromSmpte(smpteValues, timeBase, dropFrame) {
1934
+ var _smpteValues = _slicedToArray(smpteValues, 4),
1935
+ hh = _smpteValues[0],
1936
+ mm = _smpteValues[1],
1937
+ ss = _smpteValues[2],
1938
+ ff = _smpteValues[3];
1939
+
1940
+ var roundedFrameRate = timeBase.toRate({
1941
+ rounded: true
1942
+ });
1943
+ var samples = hh * 3600 * roundedFrameRate + mm * 60 * roundedFrameRate + ss * roundedFrameRate + ff;
1944
+ return samples - (dropFrame ? getDroppedFramesFromSmpte(smpteValues, samples, timeBase) : 0);
1945
+ }; // Better naming than "useValueExcess" and "useValueTruncate" must exist
1946
+
1947
+
1948
+ var EXCEEDING_OPTIONS = ['error', 'add', 'ignore'];
1949
+ /**
1950
+ * Format smpte text to a TimeCode Instance
1951
+ *
1952
+ * exceedingMode:
1953
+ * - "overflow" exceeding values will be kept (e.g. PAL and 00:00:00:25 => 00:00:01:00)
1954
+ * - "truncate" exceeding values will be truncated (e.g. PAL and 00:00:00:25 => 00:00:00:24)
1955
+ * - "error" exceeding values will throw error (e.g. PAL and 00:00:00:25 => Error)
1956
+ *
1957
+ * @param {string} smpte String representation of smpte
1958
+ * @param {object} [options={}] What options to use for creating the time code from smpte (all not specified below are passed to the TimeCode constructor)
1959
+ * @param {object|string|number} options.timeBase TimeBase of smpte (and consequently TimeBase of output TimeCode)
1960
+ * @param {string} [options.exceedingMode=error] How to handle exceeding values (`overflow|truncate|error`)
1961
+ * @param {boolean} options.dropFrame If it should parse and create time code using dropFrame
1962
+ * @param {string} options.frameSeparator What frame separator the TimeCode should store (defaults to what the smpte has)
1963
+ * @returns {TimeCode} A TimeCode instance
1964
+ */
1965
+
1966
+ var formatTimeCodeSmpte = function formatTimeCodeSmpte(smpte) {
1967
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1968
+
1969
+ var _options$exceedingMod = options.exceedingMode,
1970
+ exceedingMode = _options$exceedingMod === void 0 ? 'error' : _options$exceedingMod,
1971
+ timeBase = options.timeBase,
1972
+ timeCodeOptions = _objectWithoutProperties(options, _excluded$3);
1476
1973
 
1477
- if (!dropFrame) {
1478
- return hh * 3600 * roundedFrameRate + mm * 60 * roundedFrameRate + ss * roundedFrameRate + ff;
1974
+ if ([null, undefined].includes(smpte)) {
1975
+ throw new Error("smpte cannot be undefined or null");
1479
1976
  }
1480
1977
 
1481
- if (![30, 60].includes(roundedFrameRate)) {
1482
- throw new Error('Cannot use dropframe with non NTSC timebase');
1978
+ if (typeof smpte !== 'string') {
1979
+ throw new Error("smpte must be a string, is ".concat(JSON.stringify(smpte)));
1483
1980
  }
1484
1981
 
1485
- var dropFrames = getDropFrames(roundedFrameRate);
1486
- var shouldDropMinute = mm % 10 !== 0;
1487
- var shouldDropSecond = shouldDropMinute && ss === 0;
1488
- var hourFrames = hh * (3600 * roundedFrameRate - 54 * dropFrames);
1489
- var minuteFrames = mm * 60 * roundedFrameRate - (mm - Math.ceil(mm / 10)) * dropFrames;
1490
- var secondFrames = ss * roundedFrameRate - (shouldDropMinute && ss > 1 ? dropFrames : 0);
1982
+ var _splitSmpte = splitSmpte(smpte),
1983
+ _splitSmpte2 = _slicedToArray(_splitSmpte, 2),
1984
+ smpteValues = _splitSmpte2[0],
1985
+ timeCodeOptionsFromSmpte = _splitSmpte2[1];
1491
1986
 
1492
- if (shouldDropSecond && ff < dropFrames) {
1493
- throw new Error('Invalid ff');
1987
+ var timeBaseInstance = createTimeBase(timeBase);
1988
+
1989
+ var mergedOptions = _objectSpread$2(_objectSpread$2({}, timeCodeOptionsFromSmpte), {}, {
1990
+ dropFrame: isDropFrameTimeBase(timeBaseInstance)
1991
+ }, timeCodeOptions);
1992
+
1993
+ var roundedFrameRate = timeBaseInstance.toRate({
1994
+ rounded: true
1995
+ });
1996
+ var maxFrame = Math.max(0, roundedFrameRate - 1);
1997
+
1998
+ if (smpteValues.some(function (v) {
1999
+ return v < 0;
2000
+ })) {
2001
+ throw new Error('Negative values are not supported');
1494
2002
  }
1495
2003
 
1496
- var frameFrames = shouldDropSecond ? ff - dropFrames : ff;
1497
- return hourFrames + minuteFrames + secondFrames + frameFrames;
2004
+ var samples;
2005
+
2006
+ switch (exceedingMode) {
2007
+ case 'error':
2008
+ {
2009
+ var _smpteValues2 = _slicedToArray(smpteValues, 4),
2010
+ hours = _smpteValues2[0],
2011
+ minutes = _smpteValues2[1],
2012
+ seconds = _smpteValues2[2],
2013
+ frames = _smpteValues2[3];
2014
+
2015
+ if (hours >= 100) {
2016
+ throw Error('Minutes has to be less than 60');
2017
+ }
2018
+
2019
+ if (minutes >= 60) {
2020
+ throw Error('Minutes has to be less than 60');
2021
+ }
2022
+
2023
+ if (seconds >= 60) {
2024
+ throw Error('Seconds has to be less than 60');
2025
+ }
2026
+
2027
+ if (frames > maxFrame) {
2028
+ throw Error("Frames has to be less or equal to ".concat(maxFrame));
2029
+ }
2030
+
2031
+ samples = getSamplesFromSmpte(smpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2032
+ break;
2033
+ }
2034
+
2035
+ case 'ignore':
2036
+ {
2037
+ var _smpteValues3 = _slicedToArray(smpteValues, 4),
2038
+ _hours = _smpteValues3[0],
2039
+ _minutes = _smpteValues3[1],
2040
+ _seconds = _smpteValues3[2],
2041
+ _frames = _smpteValues3[3];
2042
+
2043
+ var truncatedSmpteValues = [Math.min(100, _hours), Math.min(59, _minutes), Math.min(59, _seconds), Math.min(maxFrame, _frames)];
2044
+ samples = getSamplesFromSmpte(truncatedSmpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2045
+ break;
2046
+ }
2047
+
2048
+ case 'add':
2049
+ {
2050
+ samples = getSamplesFromSmpte(smpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2051
+ break;
2052
+ }
2053
+
2054
+ default:
2055
+ {
2056
+ throw new Error("Invalid exceedingMode, options are ".concat(JSON.stringify(EXCEEDING_OPTIONS)));
2057
+ }
2058
+ }
2059
+
2060
+ return new TimeCode({
2061
+ samples: samples,
2062
+ timeBase: timeBaseInstance
2063
+ }, mergedOptions);
1498
2064
  };
1499
2065
 
1500
- var formatSmpte = function formatSmpte(smpteText, timeBaseText) {
1501
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2066
+ var _excluded$2 = ["timeBase"];
2067
+ /**
2068
+ * Format text to a TimeCode instance
2069
+ *
2070
+ * @param {string} timeCodeText A time code text (e.g. "25@PAL")
2071
+ * @param {object} [options={}] Options for how to format
2072
+ * @param {object|string} options.timeBase The time base the returned TimeCode should have
2073
+ * @returns {TimeCode} A TimeCode instance
2074
+ */
1502
2075
 
1503
- if (smpteText === undefined) {
1504
- var _timeBase = formatTimeBase(timeBaseText);
2076
+ var formatTimeCodeText = function formatTimeCodeText(timeCodeText, options) {
2077
+ var _timeCodeObject;
2078
+
2079
+ var _ref = options || {},
2080
+ timeBase = _ref.timeBase,
2081
+ timeCodeOptions = _objectWithoutProperties(_ref, _excluded$2);
2082
+
2083
+ var timeCodeObject;
2084
+
2085
+ if (timeCodeText === undefined) {
2086
+ timeCodeObject = {
2087
+ samples: 0
2088
+ };
2089
+ } else if (typeof timeCodeText === 'number') {
2090
+ timeCodeObject = {
2091
+ samples: timeCodeText
2092
+ };
2093
+ } else if (timeCodeText.includes('@')) {
2094
+ var _timeCodeText$split = timeCodeText.split('@'),
2095
+ _timeCodeText$split2 = _slicedToArray(_timeCodeText$split, 2),
2096
+ samplesString = _timeCodeText$split2[0],
2097
+ timeBaseText = _timeCodeText$split2[1];
1505
2098
 
1506
- var _timeCode = {
1507
- samples: 0,
1508
- timeBase: _timeBase
2099
+ var samples = Number(samplesString);
2100
+ timeCodeObject = {
2101
+ samples: samples,
2102
+ timeBase: formatTimeBaseText(timeBaseText)
2103
+ };
2104
+ } else if (timeCodeText === '-INF') {
2105
+ timeCodeObject = {
2106
+ samples: -Infinity
2107
+ };
2108
+ } else if (timeCodeText === '+INF') {
2109
+ timeCodeObject = {
2110
+ samples: Infinity
2111
+ };
2112
+ } else {
2113
+ timeCodeObject = {
2114
+ samples: Number(timeCodeText)
1509
2115
  };
1510
- return formatTimeCodeType(_timeCode);
1511
2116
  }
1512
2117
 
1513
- if (typeof smpteText !== 'string') {
1514
- throw new Error("smpteText must be a string, is ".concat(smpteText));
2118
+ if (Number.isNaN((_timeCodeObject = timeCodeObject) === null || _timeCodeObject === void 0 ? void 0 : _timeCodeObject.samples) || timeCodeObject.timeBase && !(timeCodeObject.timeBase instanceof TimeBase)) {
2119
+ throw new Error("timeCodeText must be a number or sample@timeBase - is ".concat(timeCodeText));
1515
2120
  }
1516
2121
 
1517
- var _splitSmpte = splitSmpte(smpteText),
1518
- _splitSmpte2 = _slicedToArray(_splitSmpte, 2),
1519
- _splitSmpte2$ = _slicedToArray(_splitSmpte2[0], 4),
1520
- hh = _splitSmpte2$[0],
1521
- mm = _splitSmpte2$[1],
1522
- ss = _splitSmpte2$[2],
1523
- _splitSmpte2$$ = _splitSmpte2$[3],
1524
- ff = _splitSmpte2$$ === void 0 ? 0 : _splitSmpte2$$,
1525
- frameOptions = _splitSmpte2[1];
1526
-
1527
- var _frameOptions$dropFra = frameOptions.dropFrame,
1528
- dropFrame = _frameOptions$dropFra === void 0 ? false : _frameOptions$dropFra;
1529
- var timeBase = formatTimeBase(timeBaseText);
1530
- var roundedFrameRate = getRoundedFrameRate(timeBase);
1531
-
1532
- if (mm >= 60 || mm < 0 || ss >= 60 || ss < 0 || ff >= roundedFrameRate || ff < 0) {
1533
- throw new Error('Invalid mm, ss or ff');
1534
- }
1535
-
1536
- var samples = countSamples(hh, mm, ss, ff, {
1537
- dropFrame: dropFrame,
1538
- roundedFrameRate: roundedFrameRate
1539
- });
1540
- var timeCode = {
1541
- samples: samples,
1542
- timeBase: timeBase
1543
- };
1544
- return formatTimeCodeType(timeCode, _objectSpread$2(_objectSpread$2({}, frameOptions), options));
2122
+ var timeCode = new TimeCode(timeCodeObject, timeCodeOptions);
2123
+ return timeBase ? timeCode.conformTimeBase(createTimeBase(timeBase)) : timeCode;
2124
+ };
2125
+
2126
+ /**
2127
+ * Format an object to a TimeCode instance
2128
+ *
2129
+ * @param {object} timeCode To create TimeCode instance of
2130
+ * @param {object} options For the TimeCode constructor
2131
+ * @returns {TimeCode} A TimeCode instance
2132
+ */
2133
+
2134
+ var formatTimeCodeType = function formatTimeCodeType(timeCode, options) {
2135
+ return new TimeCode(timeCode, options);
2136
+ };
2137
+
2138
+ var isObject = function isObject(o) {
2139
+ return Object.prototype.toString.call(o) === '[object Object]';
2140
+ };
2141
+
2142
+ var isString = function isString(s) {
2143
+ return typeof s === 'string';
2144
+ };
2145
+
2146
+ var hasSmpteFormat = function hasSmpteFormat(s) {
2147
+ return isString(s) && !!s.match(/^(\d\d+):(\d\d+):(\d\d+)(:|;|\.|,)(\d\d+)$/);
2148
+ };
2149
+
2150
+ var isNumber = function isNumber(s) {
2151
+ return !Number.isNaN(Number(s));
2152
+ };
2153
+ /**
2154
+ * Create a TimeCode instance from smpte, seconds/samples, timeCode object or string
2155
+ *
2156
+ * @param {object|string|number} timeCode Smpte, seconds/samples, timeCode object or string
2157
+ * @param {object} [options={}] For the format functions
2158
+ * @returns {TimeCode} A TimeCode instance
2159
+ */
2160
+
2161
+
2162
+ var createTimeCode = function createTimeCode(timeCode, options) {
2163
+ if (isObject(timeCode)) return formatTimeCodeType(timeCode, options);
2164
+ if (hasSmpteFormat(timeCode)) return formatTimeCodeSmpte(timeCode, options);
2165
+ if (isNumber(timeCode)) return formatTimeCodeSeconds(timeCode, options);
2166
+ return formatTimeCodeText(timeCode, options);
1545
2167
  };
1546
2168
 
1547
2169
  function timeToCueTime(_ref) {
@@ -1561,10 +2183,10 @@ function timeToCueTime(_ref) {
1561
2183
  }
1562
2184
  /**
1563
2185
  * Convert subtitle groups to WebVtt subtitle format
1564
- * @param {Object} input={}
2186
+ * @param {Object} [input={}]
1565
2187
  * @param {Object} input.metadataType - MetadataType response from API.
1566
- * @param {string} input.subtitleGroup=stl_subtitle - Name of group containing subtitle field/text.
1567
- * @param {string} input.subtitleField=stl_text - Name of field (text) to use for the subtitles.
2188
+ * @param {string} [input.subtitleGroup=stl_subtitle] - Name of group containing subtitle field/text.
2189
+ * @param {string} [input.subtitleField=stl_text] - Name of field (text) to use for the subtitles.
1568
2190
  * @returns {string} WebVtt subtitles
1569
2191
  */
1570
2192
 
@@ -1607,6 +2229,9 @@ var metadataTypeToWebVtt = function metadataTypeToWebVtt(_ref2) {
1607
2229
  return "WEBVTT\n\n\n".concat(vttCues.join('\n'));
1608
2230
  };
1609
2231
 
2232
+ var SYSTEM_FIELDGROUPS = ['stl_subtitle', 'stl_tti', 'stl_gsi', 'mrk_marker', 'pho_validation', 'pho_resource', 'pho_error', 'facedetect_rect', 'facedetect_face', 'originalTrackFilename', 'stl_gsiHeader'];
2233
+ var SYSTEM_FIELDS = ['title', 'user', 'shapeTag', 'representativeThumbnail', 'representativeThumbnailNoAuth', 'representativeItems', 'itemId', 'collectionId', 'mediaType', 'mimeType', 'created', 'startTimeCode', 'startSeconds', 'fieldValidationError', 'schemaValidationError', 'originalFilename', 'originalUri', 'originalAudioCodec', 'originalVideoCodec', 'originalHeight', 'originalWidth', 'originalFormat', 'durationSeconds', 'durationTimeCode', 'solr-index', '__user', '__collection', '__collection_size', '__ancestor_collection', '__ancestor_collection_size', '__shape', '__shape_size', '__shape_last_added', '__placeholder_shape_size', '__version', '__version_count', '__storage', '__storage_size', '__shapetag_{tag}_hash_{hash}', '__storage_{tag}', '__storage_{tag}_size', '__storagegroup', '__storagegroup_size', '__sequence', '__sequence_size', '__metadata_last_modified', '__external_id', '__deletion_lock_id', '__deletion_lock_expiry', '__child_collection', '__child_collection_size', '__parent_collection', '__parent_collection_size', '__items_size', 'stl_text', 'stl_justification', 'stl_xrelative', 'stl_yrelative', 'stl_vertical', 'stl_verticalbase', 'stl_horizontalbase', 'stl_sizerelative', 'stl_color', 'stl_outline', 'stl_outlinecolor', 'stl_outlinesize', 'stl_font', 'stl_service', 'stl_tti', 'stl_gsi', 'cct', 'tcd', 'tcf', 'oet', 'cd', 'mnc', 'cpn', 'dfc', 'tcp', 'tcs', 'tet', 'tnb', 'tnd', 'en', 'co', 'tng', 'rd', 'mnr', 'dsc', 'opt', 'lc', 'tpt', 'tn', 'slr', 'tns', 'rn', 'pub', 'dsn', 'ecd', 'mrk_zerolength', 'mrk_text', 'mrk_color', 'pho_resource_name', 'pho_error_level', 'pho_error_code', 'pho_error_description', 'facedetect_rect_width', 'facedetect_rect_height', 'facedetect_rect_y', 'facedetect_rect_x', 'facedetect_pid', 'facedetect_rect', 'trackId', 'eidr_actor', 'eidr_alternateId', 'eidr_countryOfOrigin', 'eidr_director', 'eidr_id', 'eidr_referentType', 'eidr_releaseDate', 'eidr_resourceName', 'eidr_status', 'eidr_sync', 'ttml_div', 'ttml_root', 'vxa_collection_id', 'vxaId', 'vxaLocalPath', 'tco', 'cs', 'ebn', 'tf', 'cf', 'sgn', 'tci', 'jc', 'vp', 'sn'];
2234
+
1610
2235
  var createFacetType = function createFacetType() {
1611
2236
  var fieldList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1612
2237
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -1756,12 +2381,13 @@ var parseContainerComponent = function parseContainerComponent(containerComponen
1756
2381
  }
1757
2382
 
1758
2383
  if (durationTimeCode !== undefined && durationTimeCode.samples !== 0) {
1759
- parsedContainerComponent.durationTimeCode = formatTimeCodeType(durationTimeCode);
1760
- parsedContainerComponent.duration = parsedContainerComponent.durationTimeCode.toDuration();
2384
+ var timeCode = formatTimeCodeType(durationTimeCode);
2385
+ parsedContainerComponent.durationTimeCode = timeCode.toObject();
2386
+ parsedContainerComponent.duration = timeCode.toDuration();
1761
2387
  }
1762
2388
 
1763
2389
  if (startTimestamp) {
1764
- parsedContainerComponent.startTimestamp = formatTimeCodeType(startTimestamp);
2390
+ parsedContainerComponent.startTimestamp = formatTimeCodeType(startTimestamp).toObject();
1765
2391
  }
1766
2392
 
1767
2393
  if (startTimecode !== undefined && timeCodeTimeBase) {
@@ -1833,8 +2459,10 @@ var parseVideoComponent = function parseVideoComponent(videoComponent) {
1833
2459
  samples: samples,
1834
2460
  timeBase: timeBase
1835
2461
  });
1836
- frameRate = timeCode.timeBase.toRate(true);
1837
- smpte = timeCode.toSmpte(true);
2462
+ frameRate = timeCode.timeBase.toRate({
2463
+ constant: true
2464
+ });
2465
+ smpte = timeCode.toSmpte();
1838
2466
  }
1839
2467
 
1840
2468
  var height = resolution.height,
@@ -2066,6 +2694,7 @@ var IMAGE = 'IMAGE';
2066
2694
  var AUDIO = 'AUDIO';
2067
2695
  var VIDEO = 'VIDEO';
2068
2696
  var DOCUMENT = 'DOCUMENT';
2697
+ var BINARY = 'BINARY';
2069
2698
  var getShapeMediaType = function getShapeMediaType() {
2070
2699
  var shapeType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2071
2700
  var mimeType = shapeType.mimeType,
@@ -2088,6 +2717,7 @@ var getShapeMediaType = function getShapeMediaType() {
2088
2717
  if (mimeType.endsWith('/msword')) return DOCUMENT;
2089
2718
  if (mimeType.endsWith('/json')) return DOCUMENT;
2090
2719
  if (mimeType.endsWith('/xml')) return DOCUMENT;
2720
+ if (mimeType.endsWith('/octet-stream')) return BINARY;
2091
2721
  return undefined;
2092
2722
  };
2093
2723
 
@@ -2213,7 +2843,9 @@ var parseMediaConvertPreset = function parseMediaConvertPreset(transcodePresetTy
2213
2843
  numerator: numerator
2214
2844
  });
2215
2845
  output.timeBase = timeBase;
2216
- output.frameRate = timeBase.toRate(true);
2846
+ output.frameRate = timeBase.toRate({
2847
+ constant: true
2848
+ });
2217
2849
  }
2218
2850
  }
2219
2851
 
@@ -2258,7 +2890,9 @@ var parseTranscodePreset = function parseTranscodePreset(transcodePresetType) {
2258
2890
  if (video.framerate) {
2259
2891
  var timeBase = formatTimeBaseType(video.framerate);
2260
2892
  output.timeBase = timeBase;
2261
- output.frameRate = timeBase.toRate(true);
2893
+ output.frameRate = timeBase.toRate({
2894
+ constant: true
2895
+ });
2262
2896
  }
2263
2897
 
2264
2898
  if (video.scaling) {
@@ -2305,5 +2939,5 @@ var getDocumentType = function getDocumentType() {
2305
2939
  return undefined;
2306
2940
  };
2307
2941
 
2308
- export { TimeBase, TimeCode, createFacetType, createMetadataType, filterShapeSource, findNearestThumbnail, formatSeconds, formatSecondsPrecise, formatSmpte, formatTimeBase, formatTimeBaseText, formatTimeBaseType, formatTimeCodeText, formatTimeCodeType, getDocumentType, getShapeMediaType, metadataTypeToWebVtt, parseAspectRatio, parseAudioComponent, parseBaseMediaInfoType, parseBinaryComponent, parseContainerComponent, parseFacetType, parseFileType, parseHighlightTimespan, parseHighlightTimespanList, parseKeyValuePairType, parseMediaConvertPreset, parseMetadataType, parseNowDate, parseShapeType, parseSimpleMetadataType, parseTimespan, parseTimespanList, parseTranscodePreset, parseVideoComponent, roles };
2942
+ export { SYSTEM_FIELDGROUPS, SYSTEM_FIELDS, TimeBase, TimeCode, createFacetType, createMetadataType, createTimeBase, createTimeCode, filterShapeSource, findNearestThumbnail, formatTimeBaseText, formatTimeBaseType, formatTimeCodeSeconds, formatTimeCodeSmpte, formatTimeCodeText, formatTimeCodeType, getDocumentType, getShapeMediaType, metadataTypeToWebVtt, parseAspectRatio, parseAudioComponent, parseBaseMediaInfoType, parseBinaryComponent, parseContainerComponent, parseFacetType, parseFileType, parseHighlightTimespan, parseHighlightTimespanList, parseKeyValuePairType, parseMediaConvertPreset, parseMetadataType, parseNowDate, parseShapeType, parseSimpleMetadataType, parseTimespan, parseTimespanList, parseTranscodePreset, parseVideoComponent, roles };
2309
2943
  //# sourceMappingURL=index.es.js.map