@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.js CHANGED
@@ -3,23 +3,23 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
- var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
7
6
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
7
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
8
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
8
9
  var _typeof = require('@babel/runtime/helpers/typeof');
9
10
  var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
10
11
  var _createClass = require('@babel/runtime/helpers/createClass');
11
- var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
12
12
  var parseFileSize = require('filesize');
13
13
 
14
14
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
15
 
16
16
  var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
17
- var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
18
17
  var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
18
+ var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
19
+ var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
19
20
  var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
20
21
  var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);
21
22
  var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);
22
- var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
23
23
  var parseFileSize__default = /*#__PURE__*/_interopDefaultLegacy(parseFileSize);
24
24
 
25
25
  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; }
@@ -259,171 +259,212 @@ var roles = /*#__PURE__*/Object.freeze({
259
259
  VXA_READ: VXA_READ
260
260
  });
261
261
 
262
- var _excluded$4 = ["groupName"],
262
+ var _excluded$8 = ["value"],
263
263
  _excluded2$2 = ["start", "end"];
264
264
 
265
265
  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; }
266
266
 
267
267
  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__default["default"](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; }
268
268
 
269
- var parseValueList$1 = function parseValueList(value) {
270
- if (value === undefined) return [];
271
- if (value === null) return [{
272
- value: ''
273
- }];
269
+ var COMBINED_PROPERTY_KEYS = ['uuid', 'user', 'timestamp', 'change', 'conflict', 'mode', 'name', 'id', 'referenced', 'data', 'inheritance'];
270
+ var GROUP_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['cycle']);
271
+ var FIELD_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['value', 'reference', 'type', 'track']);
272
+ var FIELD_VALUE_PROPERTY_KEYS = [].concat(COMBINED_PROPERTY_KEYS, ['value', 'lang']);
273
+
274
+ var isObject$1 = function isObject(o) {
275
+ return Object.prototype.toString.call(o) === '[object Object]';
276
+ };
277
+
278
+ var isDate = function isDate(o) {
279
+ return Object.prototype.toString.call(o) === '[object Date]';
280
+ };
281
+
282
+ var isField = function isField(value) {
283
+ var FIELD_TYPES = ['string', 'boolean', 'number'];
284
+
285
+ var isFieldType = function isFieldType(v) {
286
+ return FIELD_TYPES.includes(_typeof__default["default"](v));
287
+ };
288
+
289
+ var isFieldObject = function isFieldObject(v) {
290
+ return isObject$1(v) && (v.value === null || isObject$1(v.value) || isFieldType(v.value));
291
+ };
292
+
293
+ if (value === null) {
294
+ return true;
295
+ }
274
296
 
275
297
  if (Array.isArray(value)) {
276
- return value.map(function (valueOrObject) {
277
- if (_typeof__default["default"](valueOrObject) === 'object') {
278
- return _objectSpread$7({
279
- value: valueOrObject.value || ''
280
- }, valueOrObject);
281
- }
298
+ return value.some(isField);
299
+ }
282
300
 
283
- return {
284
- value: valueOrObject
285
- };
286
- });
301
+ return isFieldType(value) || isFieldObject(value) || isDate(value);
302
+ };
303
+
304
+ var isGroup = function isGroup(value) {
305
+ var isGroupObject = function isGroupObject(v) {
306
+ return isObject$1(v) && v.value === undefined && Object.entries(value);
307
+ };
308
+
309
+ if (Array.isArray(value)) {
310
+ return value.every(isGroup);
287
311
  }
288
312
 
289
- if (value.value) return [value];
290
- return [{
291
- value: value
292
- }];
313
+ return isGroupObject(value);
293
314
  };
294
315
 
295
- var parseValue = function parseValue() {
296
- var fieldValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
316
+ var tryPluralize = function tryPluralize(str, arr) {
317
+ return str + (arr.length > 1 ? 's' : '');
318
+ };
297
319
 
298
- if (fieldValue && (fieldValue.value || fieldValue.name)) {
299
- var valueList = fieldValue.value,
300
- uuid = fieldValue.uuid;
301
- var value = parseValueList$1(valueList);
302
- return {
303
- value: value,
304
- uuid: uuid
305
- };
320
+ var ensureKeysAreValid = function ensureKeysAreValid(keysToCheck, keysToMatch) {
321
+ var unsupportedKeys = keysToCheck.filter(function (k) {
322
+ return !keysToMatch.includes(k);
323
+ });
324
+
325
+ if (unsupportedKeys.length) {
326
+ throw Error("Unsupported ".concat(tryPluralize('key', unsupportedKeys), " (").concat(unsupportedKeys.join(', '), ")"));
327
+ }
328
+ };
329
+
330
+ var parseValue = function parseValue(value) {
331
+ if (Array.isArray(value)) {
332
+ throw Error('Invalid value object, cannot be array');
306
333
  }
307
334
 
335
+ if ([undefined, null].includes(value)) return {};
336
+ if (isDate(value)) return {
337
+ value: value.toISOString()
338
+ };
308
339
  return {
309
- value: parseValueList$1(fieldValue)
340
+ value: value
310
341
  };
311
342
  };
312
343
 
313
- var parseField$1 = function parseField() {
314
- var field = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
315
- var name = field.name,
316
- value = field.value;
317
- var parsedValue = parseValue(value);
318
- return _objectSpread$7({
319
- name: name
320
- }, parsedValue);
344
+ var parseValueObject = function parseValueObject(valueObject) {
345
+ ensureKeysAreValid(Object.keys(valueObject), FIELD_VALUE_PROPERTY_KEYS);
346
+
347
+ if (Object.keys(valueObject).length === 0) {
348
+ throw Error('Invalid value object, cannot be empty object');
349
+ }
350
+
351
+ var parsedValue = parseValue(valueObject === null || valueObject === void 0 ? void 0 : valueObject.value);
352
+ return _objectSpread$7(_objectSpread$7({}, valueObject), parsedValue !== undefined ? parsedValue : {});
321
353
  };
322
354
 
323
- var shouldBeField = function shouldBeField(_ref) {
324
- var name = _ref.name,
325
- value = _ref.value;
326
- return ['string', 'boolean', 'number'].includes(_typeof__default["default"](value)) || name !== 'group' && Array.isArray(value) || value === null;
355
+ var parseFieldValue = function parseFieldValue(value) {
356
+ if ([undefined, null].includes(value)) return undefined;
357
+ if (Array.isArray(value)) return value.map(parseFieldValue);
358
+ if (isObject$1(value)) return parseValueObject(value);
359
+ return parseValue(value);
327
360
  };
328
361
 
329
- var parseGroup$1 = function parseGroup() {
330
- var thisGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
331
- var groupName = thisGroup.name,
332
- _thisGroup$value = thisGroup.value,
333
- groupsOrFields = _thisGroup$value === void 0 ? {} : _thisGroup$value; // eslint-disable-next-line no-use-before-define
362
+ var parseFieldObject = function parseFieldObject(fieldObject) {
363
+ ensureKeysAreValid(Object.keys(fieldObject), FIELD_PROPERTY_KEYS);
364
+ var parsedFieldValue = parseFieldValue(fieldObject === null || fieldObject === void 0 ? void 0 : fieldObject.value);
365
+
366
+ if (parsedFieldValue === undefined) {
367
+ fieldObject.value;
368
+ var fieldObjectWithoutValue = _objectWithoutProperties__default["default"](fieldObject, _excluded$8);
369
+
370
+ return fieldObjectWithoutValue;
371
+ }
372
+
373
+ return _objectSpread$7(_objectSpread$7({}, fieldObject), {}, {
374
+ value: _toConsumableArray__default["default"](Array.isArray(parsedFieldValue) ? parsedFieldValue : [parsedFieldValue])
375
+ });
376
+ };
377
+
378
+ var parseField$1 = function parseField(field) {
379
+ if (isObject$1(field)) {
380
+ return parseFieldObject(field);
381
+ }
334
382
 
335
- var _parseGroupsOrFields = parseGroupsOrFields(groupsOrFields),
336
- field = _parseGroupsOrFields.field,
337
- group = _parseGroupsOrFields.group;
383
+ var parsedFieldValue = parseFieldValue(field);
384
+
385
+ if (parsedFieldValue === undefined) {
386
+ return undefined;
387
+ }
338
388
 
339
389
  return {
340
- name: groupName,
341
- group: group,
342
- field: field
390
+ value: _toConsumableArray__default["default"](Array.isArray(parsedFieldValue) ? parsedFieldValue : [parsedFieldValue])
343
391
  };
344
392
  };
345
393
 
346
- var parseGroupsOrFields = function parseGroupsOrFields(groupsOrFields) {
394
+ var parseGroupsAndFields = function parseGroupsAndFields(groupOrField) {
347
395
  var group = [];
348
396
  var field = [];
349
- Object.entries(groupsOrFields).forEach(function (_ref2) {
350
- var _ref3 = _slicedToArray__default["default"](_ref2, 2),
351
- name = _ref3[0],
352
- value = _ref3[1];
353
-
354
- if (shouldBeField({
355
- name: name,
356
- value: value
357
- })) {
358
- field.push(parseField$1({
359
- name: name,
360
- value: value
361
- }));
362
- } else if (Array.isArray(value)) {
363
- value.forEach(function (_ref4) {
364
- var groupName = _ref4.groupName,
365
- groupValue = _objectWithoutProperties__default["default"](_ref4, _excluded$4);
366
-
367
- group.push(parseGroup$1({
368
- name: groupName,
369
- value: groupValue
370
- }));
397
+ var groupAttributes = {};
398
+ Object.entries(groupOrField || {}).forEach(function (_ref) {
399
+ var _ref2 = _slicedToArray__default["default"](_ref, 2),
400
+ name = _ref2[0],
401
+ value = _ref2[1];
402
+
403
+ if (GROUP_PROPERTY_KEYS.includes(name)) {
404
+ groupAttributes = _objectSpread$7(_objectSpread$7({}, groupAttributes), {}, _defineProperty__default["default"]({}, name, value));
405
+ } else if (isField(value)) {
406
+ try {
407
+ field.push(_objectSpread$7({
408
+ name: name
409
+ }, parseField$1(value)));
410
+ } catch (error) {
411
+ throw Error(error.message + (name ? " for field \"".concat(name, "\"") : ''));
412
+ }
413
+ } else if (isGroup(value)) {
414
+ (Array.isArray(value) ? value : [value]).forEach(function (v) {
415
+ group.push(_objectSpread$7({
416
+ name: name
417
+ }, parseGroupsAndFields(v)));
371
418
  });
372
419
  } else {
373
- group.push(parseGroup$1({
374
- name: name,
375
- value: value
376
- }));
420
+ throw Error("Unhandled value for \"".concat(name, "\""));
377
421
  }
378
422
  });
379
- return {
380
- group: group,
423
+ return _objectSpread$7(_objectSpread$7(_objectSpread$7({}, groupAttributes), group.length > 0 ? {
424
+ group: group
425
+ } : {}), field.length > 0 ? {
381
426
  field: field
382
- };
427
+ } : {});
383
428
  };
384
429
 
385
430
  var parseTimespan$1 = function parseTimespan() {
386
431
  var timespan = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
387
432
 
388
- var _ref5 = timespan || {},
389
- _ref5$start = _ref5.start,
390
- start = _ref5$start === void 0 ? '-INF' : _ref5$start,
391
- _ref5$end = _ref5.end,
392
- end = _ref5$end === void 0 ? '+INF' : _ref5$end,
393
- groupsOrFields = _objectWithoutProperties__default["default"](_ref5, _excluded2$2);
433
+ var _ref3 = timespan || {},
434
+ _ref3$start = _ref3.start,
435
+ start = _ref3$start === void 0 ? '-INF' : _ref3$start,
436
+ _ref3$end = _ref3.end,
437
+ end = _ref3$end === void 0 ? '+INF' : _ref3$end,
438
+ groupsAndFields = _objectWithoutProperties__default["default"](_ref3, _excluded2$2);
394
439
 
395
- var _parseGroupsOrFields2 = parseGroupsOrFields(groupsOrFields),
396
- group = _parseGroupsOrFields2.group,
397
- field = _parseGroupsOrFields2.field;
440
+ var _parseGroupsAndFields = parseGroupsAndFields(groupsAndFields),
441
+ group = _parseGroupsAndFields.group,
442
+ field = _parseGroupsAndFields.field;
398
443
 
399
- return {
400
- start: start,
401
- end: end,
402
- field: field,
444
+ return _objectSpread$7(_objectSpread$7(_objectSpread$7({}, group ? {
403
445
  group: group
404
- };
446
+ } : {}), field ? {
447
+ field: field
448
+ } : {}), {}, {
449
+ start: start,
450
+ end: end
451
+ });
405
452
  };
406
453
  /**
407
- * Create a MetadataType object from a metadata object
408
- * @param {Object} metadata={} - object with metadata to create MetadataType object of
409
- * @returns {Object} MetadataType
454
+ * Create a VidiCore MetadataType from a simplified object structure
455
+ *
456
+ * @param {object} metadata - object to create MetadataType from
457
+ * @returns {object} a MetadataType object
410
458
  */
411
459
 
412
460
 
413
461
  var createMetadataType = function createMetadataType() {
414
462
  var metadata = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
415
- var metadataType = {};
416
-
417
- if (Array.isArray(metadata)) {
418
- metadataType.timespan = metadata.map(function (thisTimeSpan) {
419
- return parseTimespan$1(thisTimeSpan);
420
- });
421
- } else {
422
- var genericTimespan = parseTimespan$1(metadata);
423
- metadataType.timespan = [genericTimespan];
424
- }
425
-
426
- return metadataType;
463
+ return {
464
+ timespan: (Array.isArray(metadata) ? metadata : [metadata]).map(function (t) {
465
+ return parseTimespan$1(t);
466
+ })
467
+ };
427
468
  };
428
469
 
429
470
  var sortTimespanList = function sortTimespanList(timespan1, timespan2) {
@@ -449,7 +490,7 @@ var sortTimespanList = function sortTimespanList(timespan1, timespan2) {
449
490
  return 0;
450
491
  };
451
492
 
452
- var _excluded$3 = ["value"],
493
+ var _excluded$7 = ["value"],
453
494
  _excluded2$1 = ["field", "group"],
454
495
  _excluded3 = ["field", "group"];
455
496
 
@@ -494,7 +535,7 @@ var parseField = function parseField() {
494
535
 
495
536
  var _field$value = field.value,
496
537
  value = _field$value === void 0 ? [] : _field$value,
497
- attributes = _objectWithoutProperties__default["default"](field, _excluded$3);
538
+ attributes = _objectWithoutProperties__default["default"](field, _excluded$7);
498
539
 
499
540
  var parsedValueList = parseValueList(value, options);
500
541
  if (includeAttributes || includeFieldAttributes) return _objectSpread$6(_objectSpread$6({}, attributes), {}, {
@@ -643,21 +684,21 @@ var parseGroupList = function parseGroupList() {
643
684
  /**
644
685
  * Parses timespan according to specified options.
645
686
  * The attributes can be targeted for each sub-type.
646
- * @param {Object} timespan={} - The timespan response from the API.
647
- * @param {Object} options={} - Options which change how the metadataType is parsed.
648
- * @param {string} options.joinValue=undefined - String to join the values, eg ','.
649
- * @param {boolean} options.includeAttributes=false - Include attributes on all objects.
650
- * @param {boolean} options.includeTimespanAttributes=false - Include attributes on timespans.
651
- * @param {boolean} options.includeGroupAttributes=false - Include attributes on groups.
652
- * @param {boolean} options.includeFieldAttributes=false - Include attributes on fields.
653
- * @param {boolean} options.includeValueAttributes=false - Include attributes on values.
654
- * @param {boolean} options.flat=false - Flatten to key/value (Note: keys may be overwritten).
655
- * @param {boolean} options.flatTimespan=false - Flatten timespan.
656
- * @param {boolean} options.flatGroup=false - Flatten group.
657
- * @param {boolean} options.groupAsList=false - Return groups as list.
658
- * @param {boolean} options.fieldAsList=false - Return fields as list.
659
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
660
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
687
+ * @param {Object} [timespan={}] - A timespan from VidiCore.
688
+ * @param {Object} [options={}] - Options which change how the metadataType is parsed.
689
+ * @param {string} [options.joinValue=undefined] - String to join the values, eg ','.
690
+ * @param {boolean} [options.includeAttributes=false] - Include attributes on all objects.
691
+ * @param {boolean} [options.includeTimespanAttributes=false] - Include attributes on timespans.
692
+ * @param {boolean} [options.includeGroupAttributes=false] - Include attributes on groups.
693
+ * @param {boolean} [options.includeFieldAttributes=false] - Include attributes on fields.
694
+ * @param {boolean} [options.includeValueAttributes=false] - Include attributes on values.
695
+ * @param {boolean} [options.flat=false] - Flatten to key/value (Note: keys may be overwritten).
696
+ * @param {boolean} [options.flatTimespan=false] - Flatten timespan.
697
+ * @param {boolean} [options.flatGroup=false] - Flatten group.
698
+ * @param {boolean} [options.groupAsList=false] - Return groups as list.
699
+ * @param {boolean} [options.fieldAsList=false] - Return fields as list.
700
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
701
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
661
702
  * @returns {Object} Metadata object parsed according to options.
662
703
  */
663
704
 
@@ -722,7 +763,8 @@ function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) {
722
763
  /**
723
764
  * Parses timespanList according to specified options.
724
765
  * The attributes can be targeted for each sub-type.
725
- * @param {Object[]} timespanList - The timespanList response from the API.
766
+ *
767
+ * @param {Object[]} timespanList - A timespanList from VidiCore.
726
768
  * @param {Object} options - Options which change how the metadataType is parsed.
727
769
  * @param {string} options.joinValue - String to join the values, eg ','.
728
770
  * @param {boolean} options.includeAttributes - Include attributes on all objects.
@@ -738,8 +780,8 @@ function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) {
738
780
  * @param {boolean} options.timespanAsList - Return timespans as list.
739
781
  * @param {boolean} options.groupAsList - Return groups as list.
740
782
  * @param {boolean} options.fieldAsList - Return fields as list.
741
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
742
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
783
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
784
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
743
785
  * @returns {Object} Metadata object parsed according to options.
744
786
  */
745
787
 
@@ -782,11 +824,11 @@ var parseTimespanList = function parseTimespanList() {
782
824
  return output;
783
825
  };
784
826
 
785
- var _excluded$2 = ["timespan"];
827
+ var _excluded$6 = ["timespan"];
786
828
  /**
787
829
  * Parses MetadataType according to specified options.
788
830
  * The attributes can be targeted for each sub-type.
789
- * @param {Object} metadataType - The MetadataType response from the API.
831
+ * @param {Object} metadataType - A MetadataType from VidiCore.
790
832
  * @param {Object} options - Options which change how the metadataType is parsed.
791
833
  * @param {string} options.joinValue - String to join the values, eg ','.
792
834
  * @param {boolean} options.includeAttributes - Include attributes on all objects.
@@ -802,8 +844,8 @@ var _excluded$2 = ["timespan"];
802
844
  * @param {boolean} options.timespanAsList - Return timespans as list.
803
845
  * @param {boolean} options.groupAsList - Return groups as list.
804
846
  * @param {boolean} options.fieldAsList - Return fields as list.
805
- * @param {boolean} options.arrayOnSingle=true - Return fields as array even if single field.
806
- * @param {boolean} options.arrayOnSingleValue=true - Return fields as array even if single field value.
847
+ * @param {boolean} [options.arrayOnSingle=true] - Return fields as array even if single field.
848
+ * @param {boolean} [options.arrayOnSingleValue=true] - Return fields as array even if single field value.
807
849
  * @returns {Object} Metadata object parsed according to options.
808
850
  */
809
851
 
@@ -819,7 +861,7 @@ var parseMetadataType = function parseMetadataType() {
819
861
  var _ref2 = metadataType || {},
820
862
  _ref2$timespan = _ref2.timespan,
821
863
  timespanList = _ref2$timespan === void 0 ? [] : _ref2$timespan,
822
- attributes = _objectWithoutProperties__default["default"](_ref2, _excluded$2);
864
+ attributes = _objectWithoutProperties__default["default"](_ref2, _excluded$6);
823
865
 
824
866
  if (sortTimespan) timespanList.sort(sortTimespanList);
825
867
  var timespan = parseTimespanList(timespanList, options);
@@ -844,12 +886,12 @@ function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if
844
886
  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__default["default"](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; }
845
887
 
846
888
  /**
847
- * Parses highlight timespan responses from the api into key/value object.
889
+ * Parses highlight timespan in VidiCore into key/value object.
848
890
  * The attributes can be targeted for each sub-type.
849
- * @param {Object[]} highlightTimespan - A timespan object from the api response.
891
+ * @param {Object[]} highlightTimespan - A VidiCore timespan object.
850
892
  * @param {Object} options - Options which change how the timespans are parsed.
851
- * @param {boolean} options.arrayOnSingle=true - Return an array if there is a single value.
852
- * @param {boolean} options.timespanAsList=false - Return timespans as list.
893
+ * @param {boolean} [options.arrayOnSingle=true] - Return an array if there is a single value.
894
+ * @param {boolean} [options.timespanAsList=false] - Return timespans as list.
853
895
  * @param {string} options.joinValue - String to join the values, eg ','.
854
896
  */
855
897
  var parseHighlightTimespan = function parseHighlightTimespan() {
@@ -859,13 +901,13 @@ var parseHighlightTimespan = function parseHighlightTimespan() {
859
901
  start = _ref.start,
860
902
  end = _ref.end;
861
903
 
862
- var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
863
- var _opts$arrayOnSingle = opts.arrayOnSingle,
864
- arrayOnSingle = _opts$arrayOnSingle === void 0 ? true : _opts$arrayOnSingle,
865
- _opts$joinValue = opts.joinValue,
866
- joinValue = _opts$joinValue === void 0 ? undefined : _opts$joinValue,
867
- _opts$timespanAsList = opts.timespanAsList,
868
- timespanAsList = _opts$timespanAsList === void 0 ? undefined : _opts$timespanAsList;
904
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
905
+ var _options$arrayOnSingl = options.arrayOnSingle,
906
+ arrayOnSingle = _options$arrayOnSingl === void 0 ? true : _options$arrayOnSingl,
907
+ _options$joinValue = options.joinValue,
908
+ joinValue = _options$joinValue === void 0 ? undefined : _options$joinValue,
909
+ _options$timespanAsLi = options.timespanAsList,
910
+ timespanAsList = _options$timespanAsLi === void 0 ? undefined : _options$timespanAsLi;
869
911
  var initialValue = timespanAsList ? {
870
912
  start: start,
871
913
  end: end
@@ -892,38 +934,38 @@ function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if
892
934
 
893
935
  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__default["default"](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; }
894
936
  /**
895
- * Parses highlight timespans responses from the api into key/value object.
937
+ * Parses highlight timespans from VidiCore into key/value object.
896
938
  * The attributes can be targeted for each sub-type.
897
- * @param {Object} highlightTimespanList - A list of timespans from the api response.
939
+ * @param {Object} highlightTimespanList - A list of timespans from VidiCore.
898
940
  * @param {Object} options - Options which change how the timespans are parsed.
899
- * @param {boolean} options.arrayOnSingle=true - Return an array if there is a single value.
941
+ * @param {boolean} [options.arrayOnSingle=true] - Return an array if there is a single value.
900
942
  * @param {string} options.joinValue - String to join the values, eg ','.
901
- * @param {boolean} options.timespanAsList=false - Return timespans as list.
902
- * @param {boolean} options.flat=false - Flatten to field-name/field-value (Note: field-values may be overwritten).
903
- * @param {boolean} options.flatTimespan=false - Flatten timespan to object with start/end as key.
904
- * @param {string} options.joinTimespan=_ - Character to join the start/end timecodes.
943
+ * @param {boolean} [options.timespanAsList=false] - Return timespans as list.
944
+ * @param {boolean} [options.flat=false] - Flatten to field-name/field-value (Note: field-values may be overwritten).
945
+ * @param {boolean} [options.flatTimespan=false] - Flatten timespan to object with start/end as key.
946
+ * @param {string} [options.joinTimespan=_] - Character to join the start/end timecodes.
905
947
  */
906
948
 
907
949
  var parseHighlightTimespanList = function parseHighlightTimespanList() {
908
950
  var highlightTimespanList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
909
- var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
910
- var flat = opts.flat,
911
- timespanAsList = opts.timespanAsList,
912
- _opts$joinTimespan = opts.joinTimespan,
913
- joinTimespan = _opts$joinTimespan === void 0 ? '_' : _opts$joinTimespan,
914
- flatTimespan = opts.flatTimespan;
951
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
952
+ var flat = options.flat,
953
+ timespanAsList = options.timespanAsList,
954
+ _options$joinTimespan = options.joinTimespan,
955
+ joinTimespan = _options$joinTimespan === void 0 ? '_' : _options$joinTimespan,
956
+ flatTimespan = options.flatTimespan;
915
957
  if (timespanAsList === true) return highlightTimespanList.map(function (timespan) {
916
- return parseHighlightTimespan(timespan, opts);
958
+ return parseHighlightTimespan(timespan, options);
917
959
  });
918
960
  if (flat === true || flatTimespan === true) return highlightTimespanList.reduce(function (a, timespan) {
919
- return _objectSpread$3(_objectSpread$3({}, a), parseHighlightTimespan(timespan, opts));
961
+ return _objectSpread$3(_objectSpread$3({}, a), parseHighlightTimespan(timespan, options));
920
962
  }, {});
921
963
  return highlightTimespanList.reduce(function (a, timespan) {
922
- return _objectSpread$3(_objectSpread$3({}, a), {}, _defineProperty__default["default"]({}, [timespan.start, timespan.end].join(joinTimespan), parseHighlightTimespan(timespan, opts)));
964
+ return _objectSpread$3(_objectSpread$3({}, a), {}, _defineProperty__default["default"]({}, [timespan.start, timespan.end].join(joinTimespan), parseHighlightTimespan(timespan, options)));
923
965
  }, {});
924
966
  };
925
967
 
926
- var CONSTANT_TIMEBASES = {
968
+ var MAP_CONSTANT_TO_DEN_NUM = {
927
969
  PAL: {
928
970
  denominator: 25,
929
971
  numerator: 1
@@ -943,59 +985,61 @@ var CONSTANT_TIMEBASES = {
943
985
  59.94: {
944
986
  denominator: 60000,
945
987
  numerator: 1001
946
- }
947
- };
948
- var FRAME_SEPARATORS = {
949
- ':': {
950
- dropFrame: false,
951
- field: 2
952
988
  },
953
- ';': {
954
- dropFrame: true,
955
- field: 2
989
+ 23.976: {
990
+ denominator: 48000,
991
+ numerator: 2002
956
992
  },
957
- '.': {
958
- dropFrame: false,
959
- field: 1
960
- },
961
- ',': {
962
- dropFrame: true,
963
- field: 1
993
+ 23.98: {
994
+ denominator: 48000,
995
+ numerator: 2002
964
996
  }
965
997
  };
998
+ var TIME_BASE_CONSTANTS = Object.keys(MAP_CONSTANT_TO_DEN_NUM);
999
+
1000
+ /**
1001
+ * TimeBase class representing the TimeBaseType in VidiCore
1002
+ *
1003
+ * For more info, see the [Time bases section in VidiCore API Docs](https://apidoc.vidispine.com/latest/time.html#time-bases)
1004
+ */
966
1005
 
967
1006
  var TimeBase = /*#__PURE__*/function () {
968
- function TimeBase() {
969
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1007
+ /**
1008
+ * Constructor for TimeBase
1009
+ *
1010
+ * @param {object} [timeCodeType={}] A time base type object
1011
+ * @param {number} [timeCodeType.numerator=1] The numerator for the TimeBase
1012
+ * @param {number} [timeCodeType.denominator=1] The denominator for the TimeBase
1013
+ */
1014
+ function TimeBase(timeCodeType) {
1015
+ _classCallCheck__default["default"](this, TimeBase);
1016
+
1017
+ var _ref = timeCodeType || {},
970
1018
  _ref$numerator = _ref.numerator,
971
1019
  numerator = _ref$numerator === void 0 ? 1 : _ref$numerator,
972
1020
  _ref$denominator = _ref.denominator,
973
1021
  denominator = _ref$denominator === void 0 ? 1 : _ref$denominator;
974
1022
 
975
- _classCallCheck__default["default"](this, TimeBase);
976
-
977
1023
  this.numerator = Number(numerator);
978
1024
  this.denominator = Number(denominator);
979
1025
  }
1026
+ /**
1027
+ * Get TimeBase in a constant representation (e.g. "PAL") if possible, otherwise undefined
1028
+ * @returns {string} Constant representation of the TimeBase
1029
+ */
1030
+
980
1031
 
981
1032
  _createClass__default["default"](TimeBase, [{
982
- key: "toJSON",
983
- value: function toJSON() {
984
- return {
985
- denominator: this.denominator,
986
- numerator: this.numerator
987
- };
988
- }
989
- }, {
990
1033
  key: "toConstant",
991
1034
  value: function toConstant() {
992
1035
  var _this = this;
993
1036
 
994
- var constant;
995
- Object.entries(CONSTANT_TIMEBASES).find(function (thisTimeBase) {
996
- var _thisTimeBase = _slicedToArray__default["default"](thisTimeBase, 2),
997
- thisTimeBaseText = _thisTimeBase[0],
998
- thisTimeBaseType = _thisTimeBase[1];
1037
+ var constant; // If multiple equal den/num, it selects first in MAP_CONSTANT_TO_DEN_NUM
1038
+
1039
+ Object.entries(MAP_CONSTANT_TO_DEN_NUM).find(function (timeBaseConstant) {
1040
+ var _timeBaseConstant = _slicedToArray__default["default"](timeBaseConstant, 2),
1041
+ thisTimeBaseText = _timeBaseConstant[0],
1042
+ thisTimeBaseType = _timeBaseConstant[1];
999
1043
 
1000
1044
  var numerator = thisTimeBaseType.numerator,
1001
1045
  denominator = thisTimeBaseType.denominator;
@@ -1009,18 +1053,36 @@ var TimeBase = /*#__PURE__*/function () {
1009
1053
  });
1010
1054
  return constant;
1011
1055
  }
1056
+ /**
1057
+ * Get TimeBase as a VidiCore TimeBaseType string
1058
+ *
1059
+ * Default format: denominator(:numerator if > 1)
1060
+ * `constant` has precedence over `fraction` if both are true (e.g. NTSC > 30000:1001)
1061
+ *
1062
+ * @param {object} [options={}] For how to display it as text
1063
+ * @param {boolean} [options.constant=false] Show time base as constant (e.g. PAL)
1064
+ * @param {boolean} [options.fraction=false] Show time base as fraction (25:1) even when numerator is 1
1065
+ * @returns {string} Text representation of the TimeBase
1066
+ */
1067
+
1012
1068
  }, {
1013
1069
  key: "toText",
1014
1070
  value: function toText() {
1015
- var useConstant = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1071
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1072
+
1073
+ var _ref2 = options || {},
1074
+ _ref2$constant = _ref2.constant,
1075
+ constant = _ref2$constant === void 0 ? false : _ref2$constant,
1076
+ _ref2$fraction = _ref2.fraction,
1077
+ fraction = _ref2$fraction === void 0 ? false : _ref2$fraction;
1016
1078
 
1017
- if (useConstant) {
1079
+ if (constant) {
1018
1080
  var _timeBaseText = this.toConstant();
1019
1081
 
1020
1082
  if (_timeBaseText) return _timeBaseText;
1021
1083
  }
1022
1084
 
1023
- if (this.numerator > 1) {
1085
+ if (fraction || this.numerator > 1) {
1024
1086
  var _timeBaseText2 = [this.denominator, this.numerator].join(':');
1025
1087
 
1026
1088
  return _timeBaseText2;
@@ -1029,13 +1091,40 @@ var TimeBase = /*#__PURE__*/function () {
1029
1091
  var timeBaseText = String(this.denominator);
1030
1092
  return timeBaseText;
1031
1093
  }
1094
+ /**
1095
+ * Output TimeBase as frame rate (by default max 16 decimal places)
1096
+ *
1097
+ *
1098
+ * For `options.fixed`:
1099
+ * - `true` gives two decimal places
1100
+ * - `false` gives max amount of decimal places
1101
+ * - `number` gives that amount of decimal places
1102
+ *
1103
+ * Default format: rate with two decimals if needed (i.e. decimals are > 0)
1104
+ * Option precedence (when all true): `constant` > `rounded` > `fixed`
1105
+ *
1106
+ * @param {object} [options={}] For how to display it as rate
1107
+ * @param {boolean|number} [options.fixed=true] Amount of decimal places (true gives 2 decimal places)
1108
+ * @param {boolean} [options.constant=false] Use constant representation (if applicable)
1109
+ * @param {boolean} [options.rounded=false] Rounded to nearest integer
1110
+ *
1111
+ * @returns {number} Rate of the TimeBase
1112
+ */
1113
+
1032
1114
  }, {
1033
1115
  key: "toRate",
1034
1116
  value: function toRate() {
1035
- var useConstant = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1036
- var round = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1117
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1037
1118
 
1038
- if (useConstant) {
1119
+ var _ref3 = options || {},
1120
+ _ref3$constant = _ref3.constant,
1121
+ constant = _ref3$constant === void 0 ? false : _ref3$constant,
1122
+ _ref3$rounded = _ref3.rounded,
1123
+ rounded = _ref3$rounded === void 0 ? false : _ref3$rounded,
1124
+ _ref3$fixed = _ref3.fixed,
1125
+ fixed = _ref3$fixed === void 0 ? true : _ref3$fixed;
1126
+
1127
+ if (constant) {
1039
1128
  var _rate = this.toConstant();
1040
1129
 
1041
1130
  if (_rate) return _rate;
@@ -1047,56 +1136,110 @@ var TimeBase = /*#__PURE__*/function () {
1047
1136
  return rate;
1048
1137
  }
1049
1138
 
1050
- return round ? rate.toFixed(2) : rate;
1139
+ if (rounded) {
1140
+ return Math.round(rate);
1141
+ }
1142
+
1143
+ if (fixed === true || typeof fixed === 'number') {
1144
+ return Number(rate.toFixed(fixed === true ? 2 : fixed));
1145
+ }
1146
+
1147
+ return rate;
1148
+ }
1149
+ /**
1150
+ * Get TimeBase in a object representation
1151
+ *
1152
+ * @returns {object} TimeBase as `{denominator, numerator}` object
1153
+ */
1154
+
1155
+ }, {
1156
+ key: "toObject",
1157
+ value: function toObject() {
1158
+ return {
1159
+ denominator: this.denominator,
1160
+ numerator: this.numerator
1161
+ };
1162
+ }
1163
+ /**
1164
+ * @deprecated Use {@link TimeBase#toObject|toObject} instead
1165
+ *
1166
+ * @returns {object} TimeBase as `{denominator, numerator}` object
1167
+ */
1168
+
1169
+ }, {
1170
+ key: "toJson",
1171
+ value: function toJson() {
1172
+ // eslint-disable-next-line no-console
1173
+ console.warn('Deprecated - use toObject instead');
1174
+ return this.toObject();
1051
1175
  }
1052
1176
  }]);
1053
1177
 
1054
1178
  return TimeBase;
1055
1179
  }();
1056
1180
 
1057
- var formatTimeBaseType = function formatTimeBaseType(timeBase) {
1058
- return new TimeBase(timeBase);
1059
- };
1181
+ /**
1182
+ * Format a string representation of a time base to a TimeBase Instance
1183
+ *
1184
+ * @param {string} timeBaseText The string to format to a TimeBase instance
1185
+ * @returns {TimeBase} A TimeBase Instance
1186
+ */
1060
1187
 
1061
1188
  var formatTimeBaseText = function formatTimeBaseText(timeBaseText) {
1062
1189
  if (timeBaseText === undefined) {
1063
- return formatTimeBaseType();
1190
+ return new TimeBase();
1064
1191
  }
1065
1192
 
1066
1193
  if (typeof timeBaseText === 'number') {
1067
- return formatTimeBaseType({
1194
+ return new TimeBase({
1068
1195
  denominator: timeBaseText
1069
1196
  });
1070
1197
  }
1071
1198
 
1072
- if (timeBaseText.includes(':')) {
1199
+ if (typeof timeBaseText === 'string' && timeBaseText.includes(':')) {
1073
1200
  var _timeBaseText$split = timeBaseText.split(':'),
1074
1201
  _timeBaseText$split2 = _slicedToArray__default["default"](_timeBaseText$split, 2),
1075
- _denominator = _timeBaseText$split2[0],
1202
+ denominator = _timeBaseText$split2[0],
1076
1203
  numerator = _timeBaseText$split2[1];
1077
1204
 
1078
- return formatTimeBaseType({
1079
- denominator: _denominator,
1205
+ return new TimeBase({
1206
+ denominator: denominator,
1080
1207
  numerator: numerator
1081
1208
  });
1082
1209
  }
1083
1210
 
1084
- if (Object.keys(CONSTANT_TIMEBASES).includes(timeBaseText)) {
1085
- return formatTimeBaseType(CONSTANT_TIMEBASES[timeBaseText]);
1211
+ if (TIME_BASE_CONSTANTS.includes(timeBaseText)) {
1212
+ return new TimeBase(MAP_CONSTANT_TO_DEN_NUM[timeBaseText]);
1086
1213
  }
1087
1214
 
1088
- var denominator = Number(timeBaseText);
1089
-
1090
- if (Number.isNaN(denominator)) {
1091
- throw new Error("timeBaseText must be a number or ".concat(Object.keys(CONSTANT_TIMEBASES).join(','), " - is ").concat(timeBaseText));
1215
+ if (!['string', 'number'].includes(_typeof__default["default"](timeBaseText)) || Number.isNaN(Number(timeBaseText))) {
1216
+ throw new Error("timeBaseText must be a number or ".concat(TIME_BASE_CONSTANTS.join(','), " - is ").concat(JSON.stringify(timeBaseText)));
1092
1217
  }
1093
1218
 
1094
- return formatTimeBaseType({
1095
- denominator: denominator
1219
+ return new TimeBase({
1220
+ denominator: Number(timeBaseText)
1096
1221
  });
1097
1222
  };
1098
1223
 
1099
- var formatTimeBase = function formatTimeBase(timeBase) {
1224
+ /**
1225
+ * Create a TimeBase instance of an object
1226
+ *
1227
+ * @param {object} timeBase A TimeBase object ({ numerator, denominator })
1228
+ * @returns {TimeBase} A TimeBase instance
1229
+ */
1230
+
1231
+ var formatTimeBaseType = function formatTimeBaseType(timeBase) {
1232
+ return new TimeBase(timeBase);
1233
+ };
1234
+
1235
+ /**
1236
+ * Create a TimeBase Instance from a string or object representation of a time base
1237
+ *
1238
+ * @param {string|object} timeBase Expressed as "denominator:numerator" or { numerator, denominator }
1239
+ * @returns {TimeBase} A TimeBase instance
1240
+ */
1241
+
1242
+ var createTimeBase = function createTimeBase(timeBase) {
1100
1243
  if (_typeof__default["default"](timeBase) === 'object') {
1101
1244
  return formatTimeBaseType(timeBase);
1102
1245
  }
@@ -1104,47 +1247,86 @@ var formatTimeBase = function formatTimeBase(timeBase) {
1104
1247
  return formatTimeBaseText(timeBase);
1105
1248
  };
1106
1249
 
1107
- var getDropFrames$1 = function getDropFrames(roundedFrameRate) {
1108
- return roundedFrameRate === 60 ? 4 : 2;
1250
+ /**
1251
+ * @private
1252
+ *
1253
+ * Drops 4 frames (0-3) for 59.97 and 2 frames (0-1) for 29.97/NTSC
1254
+ *
1255
+ * @param {TimeBase} timeBase to check
1256
+ * @returns {number} amount of frame drops for specified timeBase
1257
+ */
1258
+ var getAmountOfFrameDrops = function getAmountOfFrameDrops(timeBase) {
1259
+ var timeBaseConstant = timeBase.toRate({
1260
+ constant: true
1261
+ });
1262
+ return timeBaseConstant === '59.94' && 4 || ['NTSC', '29.97'].includes(timeBaseConstant) && 2 || 0;
1109
1263
  };
1110
1264
 
1111
- var getRoundedFrameRate$1 = function getRoundedFrameRate(timeBase) {
1112
- return Math.round(timeBase.denominator / timeBase.numerator);
1265
+ /**
1266
+ * @private
1267
+ *
1268
+ * Check if TimeBase drops frames
1269
+ *
1270
+ * @param {object} timeBase TimeBase Instance to check
1271
+ * @returns {boolean} true if time base drops frames, false otherwise
1272
+ */
1273
+
1274
+ var isDropFrameTimeBase = function isDropFrameTimeBase(timeBase) {
1275
+ return getAmountOfFrameDrops(timeBase) > 0;
1113
1276
  };
1114
1277
 
1115
- function countDroppedFrames(frames, roundedFrameRate) {
1116
- var dropFrames = getDropFrames$1(roundedFrameRate);
1117
- var oneMinuteUndroppedFrames = 60 * roundedFrameRate;
1118
- var oneMinuteDroppedFrames = 60 * roundedFrameRate - dropFrames;
1119
- var tenMinuteFrames = 10 * (oneMinuteUndroppedFrames - dropFrames) + dropFrames;
1120
- var tenMinuteChunks = Math.floor(frames / tenMinuteFrames);
1121
- var minuteRemainder = Math.max(0, frames % tenMinuteFrames - oneMinuteUndroppedFrames);
1122
- var oneMinuteChunks = Math.floor(minuteRemainder / oneMinuteDroppedFrames);
1123
- var frameRemainder = minuteRemainder % oneMinuteDroppedFrames;
1124
- var frameChunks = frameRemainder > 0 ? dropFrames : 0;
1125
- return tenMinuteChunks * 9 * dropFrames + oneMinuteChunks * dropFrames + frameChunks;
1126
- }
1278
+ var _excluded$5 = ["hours"];
1127
1279
 
1128
- var isDropFrameTimeBase = function isDropFrameTimeBase(_ref) {
1129
- var numerator = _ref.numerator,
1130
- denominator = _ref.denominator;
1131
- return numerator === 1001 && (denominator === 60000 || denominator === 30000);
1280
+ var getDroppedFramesFromSamples = function getDroppedFramesFromSamples(_ref) {
1281
+ var samples = _ref.samples,
1282
+ timeBase = _ref.timeBase;
1283
+ var amountOfFrameDrops = getAmountOfFrameDrops(timeBase);
1284
+ if (amountOfFrameDrops === 0) return 0;
1285
+ var roundedFrameRate = timeBase.toRate({
1286
+ rounded: true
1287
+ });
1288
+ var oneMinuteNotDroppedFrames = 60 * roundedFrameRate;
1289
+ var amountOfFramesToDropPerMinute = 60 * roundedFrameRate - amountOfFrameDrops;
1290
+ var tenMinuteFrames = 10 * (oneMinuteNotDroppedFrames - amountOfFrameDrops) + amountOfFrameDrops;
1291
+ var amountOfTenMinuteChunks = Math.floor((samples + 1) / tenMinuteFrames);
1292
+ var minuteRemainder = Math.max(0, (samples + 1) % tenMinuteFrames - oneMinuteNotDroppedFrames);
1293
+ var amountOfOneMinuteReminderChunks = Math.floor(minuteRemainder / amountOfFramesToDropPerMinute);
1294
+ var frameRemainder = minuteRemainder % amountOfFramesToDropPerMinute;
1295
+ var amountOfFrameRemainderChunks = frameRemainder > 0 ? amountOfFrameDrops : 0;
1296
+ return amountOfTenMinuteChunks * 9 * amountOfFrameDrops + amountOfOneMinuteReminderChunks * amountOfFrameDrops + amountOfFrameRemainderChunks;
1132
1297
  };
1298
+ /**
1299
+ * TimeCode class representing the TimeCodeType in VidiCore
1300
+ *
1301
+ * For more info, see the [Time Codes section of VidiCore API Docs](https://apidoc.vidispine.com/latest/time.html#time-codes)
1302
+ */
1303
+
1133
1304
 
1134
1305
  var TimeCode = /*#__PURE__*/function () {
1306
+ /**
1307
+ * Constructor for TimeCode
1308
+ *
1309
+ * @param {object} [timeCodeType={}] Object to create TimeCode of
1310
+ * @param {number} [timeCodeType.samples=0] Amount of samples for the time code
1311
+ * @param {object|string|number} [timeCodeType.timeBase={numerator: 1, denominator: 1}] The time base it should have
1312
+ * @param {object} [options={}] Options for the timeCode
1313
+ * @param {boolean} options.dropFrame If time code should be dropFrame or not (by default checks timeBase)
1314
+ * @param {string} options.frameSeparator Separator to use for frame smpte output (default ":" for non-drop-frame and ";" for dropFrame)
1315
+ */
1135
1316
  function TimeCode() {
1136
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1137
- _ref2$samples = _ref2.samples,
1138
- samples = _ref2$samples === void 0 ? 0 : _ref2$samples,
1139
- timeBase = _ref2.timeBase;
1317
+ var _options$dropFrame, _options$frameSeparat;
1140
1318
 
1141
- var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
1142
- dropFrame = _ref3.dropFrame,
1143
- _ref3$field = _ref3.field,
1144
- field = _ref3$field === void 0 ? 2 : _ref3$field;
1319
+ var timeCodeType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1320
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1145
1321
 
1146
1322
  _classCallCheck__default["default"](this, TimeCode);
1147
1323
 
1324
+ var _ref2 = timeCodeType || {},
1325
+ _ref2$samples = _ref2.samples,
1326
+ samples = _ref2$samples === void 0 ? 0 : _ref2$samples,
1327
+ _ref2$timeBase = _ref2.timeBase,
1328
+ timeBase = _ref2$timeBase === void 0 ? new TimeBase() : _ref2$timeBase;
1329
+
1148
1330
  if (typeof samples === 'number') {
1149
1331
  this.samples = samples;
1150
1332
  } else if (typeof samples === 'string') {
@@ -1159,21 +1341,39 @@ var TimeCode = /*#__PURE__*/function () {
1159
1341
  throw new Error("samples is not number/string/-Inf/+Inf is: ".concat(samples));
1160
1342
  }
1161
1343
 
1162
- this.timeBase = new TimeBase(timeBase);
1163
- this.dropFrame = dropFrame === undefined ? isDropFrameTimeBase(this.timeBase) : dropFrame;
1164
- this.field = field;
1344
+ this.timeBase = createTimeBase(timeBase);
1345
+ this.dropFrame = (_options$dropFrame = options === null || options === void 0 ? void 0 : options.dropFrame) !== null && _options$dropFrame !== void 0 ? _options$dropFrame : isDropFrameTimeBase(this.timeBase);
1346
+ this.frameSeparator = (_options$frameSeparat = options === null || options === void 0 ? void 0 : options.frameSeparator) !== null && _options$frameSeparat !== void 0 ? _options$frameSeparat : this.dropFrame ? ';' : ':';
1165
1347
  }
1348
+ /**
1349
+ * Return this TimeCode added with the supplied timeCodeType
1350
+ * If time bases differ, it will retain the time base of this TimeCode instance
1351
+ * If supplied time code has a more granular time base - it will round down exceeding samples (hasn't reached that sample yet)
1352
+ *
1353
+ * Note: This might make you "lose" frames depending on granularity of time bases, e.g.
1354
+ * "51@50".add("25@25") => "101@50"
1355
+ * while "25@25".add("51@50") => "50@25" (not "101@50")
1356
+ *
1357
+ * @param {TimeCode} timeCodeType A TimeCode instance you want to add with
1358
+ * @returns A new TimeCode instance with the addition applied
1359
+ */
1360
+
1166
1361
 
1167
1362
  _createClass__default["default"](TimeCode, [{
1168
1363
  key: "add",
1169
- value: function add(val) {
1170
- var _val$timeBase = val.timeBase,
1171
- numerator = _val$timeBase.numerator,
1172
- denominator = _val$timeBase.denominator;
1173
- var conformedTimeCode = val;
1364
+ value: function add(timeCodeType) {
1365
+ if (!(timeCodeType !== null && timeCodeType !== void 0 && timeCodeType.timeBase) || (timeCodeType === null || timeCodeType === void 0 ? void 0 : timeCodeType.samples) === undefined) {
1366
+ throw Error('Invalid timeCodeType, cannot be added');
1367
+ }
1368
+
1369
+ var _timeCodeType$timeBas = timeCodeType.timeBase;
1370
+ _timeCodeType$timeBas = _timeCodeType$timeBas === void 0 ? {} : _timeCodeType$timeBas;
1371
+ var numerator = _timeCodeType$timeBas.numerator,
1372
+ denominator = _timeCodeType$timeBas.denominator;
1373
+ var conformedTimeCode = timeCodeType;
1174
1374
 
1175
1375
  if (numerator !== this.timeBase.numerator || denominator !== this.timeBase.denominator) {
1176
- conformedTimeCode = val.conformTimeBase(this.timeBase);
1376
+ conformedTimeCode = timeCodeType.conformTimeBase(this.timeBase);
1177
1377
  }
1178
1378
 
1179
1379
  var _conformedTimeCode = conformedTimeCode,
@@ -1183,16 +1383,34 @@ var TimeCode = /*#__PURE__*/function () {
1183
1383
  timeBase: this.timeBase
1184
1384
  });
1185
1385
  }
1386
+ /**
1387
+ * Return this TimeCode subtracted with the supplied timeCodeType
1388
+ * If time bases differ, it will retain the time base of the instance time code
1389
+ * If supplied time code has a more granular time base - it will round down exceeding samples (hasn't reached that sample yet)
1390
+ *
1391
+ * Note: This might make you "lose" frames depending on granularity of time bases, e.g.
1392
+ * "101@50".subtract("25@25") => "51@50"
1393
+ * while "50@25".subtract("51@50") => "25@25" (not "49@50")
1394
+ *
1395
+ * @param {TimeCode} timeCodeType A TimeCode instance you want to subtract with
1396
+ * @returns A new TimeCode instance with the subtraction applied
1397
+ */
1398
+
1186
1399
  }, {
1187
1400
  key: "subtract",
1188
- value: function subtract(val) {
1189
- var _val$timeBase2 = val.timeBase,
1190
- numerator = _val$timeBase2.numerator,
1191
- denominator = _val$timeBase2.denominator;
1192
- var conformedTimeCode = val;
1401
+ value: function subtract(timeCodeType) {
1402
+ if (!(timeCodeType !== null && timeCodeType !== void 0 && timeCodeType.timeBase) || (timeCodeType === null || timeCodeType === void 0 ? void 0 : timeCodeType.samples) === undefined) {
1403
+ throw Error('Invalid timeCodeType, cannot be subtracted');
1404
+ }
1405
+
1406
+ var _timeCodeType$timeBas2 = timeCodeType.timeBase;
1407
+ _timeCodeType$timeBas2 = _timeCodeType$timeBas2 === void 0 ? {} : _timeCodeType$timeBas2;
1408
+ var numerator = _timeCodeType$timeBas2.numerator,
1409
+ denominator = _timeCodeType$timeBas2.denominator;
1410
+ var conformedTimeCode = timeCodeType;
1193
1411
 
1194
1412
  if (numerator !== this.timeBase.numerator || denominator !== this.timeBase.denominator) {
1195
- conformedTimeCode = val.conformTimeBase(this.timeBase);
1413
+ conformedTimeCode = timeCodeType.conformTimeBase(this.timeBase);
1196
1414
  }
1197
1415
 
1198
1416
  var _conformedTimeCode2 = conformedTimeCode,
@@ -1202,361 +1420,765 @@ var TimeCode = /*#__PURE__*/function () {
1202
1420
  timeBase: this.timeBase
1203
1421
  });
1204
1422
  }
1423
+ /**
1424
+ * Creates a new TimeCode instance with specified timeBase and samples adjusted to that.
1425
+ *
1426
+ * If it conforms to a less granular time base - it will floor samples (hasn't reached that sample yet)
1427
+ * - e.g. "51@50".conformTo("PAL") => "25@PAL" (not "26@PAL")
1428
+ *
1429
+ * @param {string|object} conformTo The TimeBase it should conform the TimeCode to
1430
+ * @returns A new TimeCode instance with the conformTo timeBase applied
1431
+ */
1432
+
1205
1433
  }, {
1206
1434
  key: "conformTimeBase",
1207
1435
  value: function conformTimeBase(conformTo) {
1208
- var timeBase = conformTo;
1436
+ var conformToTimeBase = conformTo;
1209
1437
 
1210
- if (conformTo instanceof TimeCode === false) {
1211
- timeBase = new TimeBase(conformTo);
1438
+ if (!(conformTo instanceof TimeBase)) {
1439
+ conformToTimeBase = createTimeBase(conformTo);
1212
1440
  }
1213
1441
 
1214
- var samples = Math.round(this.samples / (this.timeBase.toRate(false, false) / timeBase.toRate(false, false)));
1442
+ var samples = Math.floor(this.samples / (this.timeBase.toRate({
1443
+ fixed: false
1444
+ }) / conformToTimeBase.toRate({
1445
+ fixed: false
1446
+ })));
1215
1447
  var timeCode = {
1216
1448
  samples: samples,
1217
- timeBase: timeBase
1449
+ timeBase: conformToTimeBase
1218
1450
  };
1219
1451
  return new TimeCode(timeCode);
1220
1452
  }
1221
- }, {
1222
- key: "toJSON",
1223
- value: function toJSON() {
1224
- return {
1225
- samples: this.samples,
1226
- timeBase: this.timeBase
1227
- };
1228
- }
1453
+ /**
1454
+ * Get TimeCode as a text representation
1455
+ *
1456
+ * Default format: samples@denominator(:numerator if > 1)
1457
+ * `constant` has precedence over `fraction` if both are true
1458
+ *
1459
+ * @param {object} [options={}] TimeBase toText options
1460
+ * @param {boolean} [options.includeTimeBaseForSeconds=false] include time base even if seconds
1461
+ * @param {boolean} [options.constant=false] show as constant (e.g. @PAL)
1462
+ * @param {boolean} [options.fraction=false] show as fraction (@25:1)
1463
+ * @returns Text representation of TimeCode
1464
+ */
1465
+
1229
1466
  }, {
1230
1467
  key: "toText",
1231
1468
  value: function toText() {
1232
- var timeCodeText = String(this.samples);
1233
- var timeBaseText = this.timeBase.toText();
1469
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1470
+ var timeCodeText = "".concat(this.samples);
1471
+ var timeBaseText = this.timeBase.toText(options);
1234
1472
 
1235
- if (timeBaseText !== '1') {
1473
+ if (options !== null && options !== void 0 && options.includeTimeBaseForSeconds || !['1', '1:1'].includes(timeBaseText)) {
1236
1474
  timeCodeText = [this.samples, timeBaseText].join('@');
1237
1475
  }
1238
1476
 
1239
1477
  return timeCodeText;
1240
1478
  }
1479
+ /**
1480
+ * Get TimeCode in a units object representation
1481
+ *
1482
+ * @returns {object} in the format { hours, minutes, seconds, frames }
1483
+ */
1484
+
1241
1485
  }, {
1242
- key: "toSeconds",
1243
- value: function toSeconds() {
1244
- var _this$timeBase = this.timeBase,
1245
- numerator = _this$timeBase.numerator,
1246
- denominator = _this$timeBase.denominator;
1247
- return this.samples * (numerator / denominator);
1486
+ key: "toUnits",
1487
+ value: function toUnits() {
1488
+ var totalSamples = this.samples + (this.dropFrame ? getDroppedFramesFromSamples(this) : 0);
1489
+ var roundedFrameRate = this.timeBase.toRate({
1490
+ rounded: true
1491
+ }); // Calculated without drop-frame but with 2 decimal places
1492
+
1493
+ if (['23.976', '23.98'].includes(this.timeBase.toConstant())) {
1494
+ roundedFrameRate = this.timeBase.toRate({
1495
+ fixed: true
1496
+ });
1497
+ }
1498
+
1499
+ var hours = Math.floor(totalSamples / (3600 * roundedFrameRate));
1500
+ var minutes = Math.floor(totalSamples / (60 * roundedFrameRate)) % 60;
1501
+ var seconds = Math.floor(totalSamples / roundedFrameRate) % 60;
1502
+ var frames = Math.floor(totalSamples % roundedFrameRate);
1503
+ return {
1504
+ hours: hours,
1505
+ minutes: minutes,
1506
+ seconds: seconds,
1507
+ frames: frames
1508
+ };
1248
1509
  }
1510
+ /**
1511
+ * Get TimeCode in a time object representation
1512
+ * "milliseconds" is rounded down, if you want another representation use "partialSeconds"
1513
+ *
1514
+ * @returns {object} in the format { hours, minutes, seconds, milliseconds, partialSeconds }
1515
+ */
1516
+
1249
1517
  }, {
1250
1518
  key: "toTime",
1251
1519
  value: function toTime() {
1252
- var roundedFrameRate = getRoundedFrameRate$1(this.timeBase);
1253
- var totalSamples = this.samples + (this.dropFrame ? countDroppedFrames(this.samples + 1, roundedFrameRate) : 0);
1254
- var hours = Math.floor(totalSamples / (3600 * roundedFrameRate));
1255
- var minutes = Math.floor(totalSamples / (60 * roundedFrameRate)) % 60;
1256
- var seconds = Math.floor(totalSamples / roundedFrameRate) % 60;
1257
- var frames = totalSamples % roundedFrameRate;
1258
- var partialSeconds = frames / roundedFrameRate;
1520
+ var totalSamples = this.samples + getDroppedFramesFromSamples(this);
1521
+
1522
+ var _this$toUnits = this.toUnits(),
1523
+ hours = _this$toUnits.hours,
1524
+ minutes = _this$toUnits.minutes,
1525
+ seconds = _this$toUnits.seconds;
1526
+
1527
+ var roundedFrameRate = this.timeBase.toRate({
1528
+ rounded: true
1529
+ });
1530
+ var framesPrecise = totalSamples % roundedFrameRate;
1531
+ var milliseconds = Math.floor(1000 * framesPrecise / roundedFrameRate);
1532
+ var partialSeconds = framesPrecise / roundedFrameRate;
1259
1533
  return {
1260
1534
  hours: hours,
1261
1535
  minutes: minutes,
1262
1536
  seconds: seconds,
1263
- frames: frames,
1537
+ milliseconds: milliseconds,
1264
1538
  partialSeconds: partialSeconds
1265
1539
  };
1266
1540
  }
1541
+ /**
1542
+ * Get TimeCode in a seconds representation
1543
+ *
1544
+ * @returns {number} the seconds
1545
+ */
1546
+
1547
+ }, {
1548
+ key: "toSeconds",
1549
+ value: function toSeconds() {
1550
+ var _this$timeBase = this.timeBase,
1551
+ numerator = _this$timeBase.numerator,
1552
+ denominator = _this$timeBase.denominator;
1553
+ return Math.round(1000 * +(this.samples * numerator / denominator)) / 1000;
1554
+ }
1555
+ /**
1556
+ * Get TimeCode in a duration representation
1557
+ * The time unit char keys for the format string are:
1558
+ * - "h" for hour
1559
+ * - "m" for minute
1560
+ * - "s" for seconds
1561
+ * - "S" for milliseconds
1562
+ * Any other char will be kept in the duration output string.
1563
+ *
1564
+ * Add consecutive chars for zero padding.
1565
+ *
1566
+ * By default it:
1567
+ * - uses colon delimiter (e.g. for format "hhmmss")
1568
+ * - shows "m:ss" or "h:mm:ss" if format is undefined
1569
+ *
1570
+ * @param {object} [options={}]
1571
+ * @param {string} options.format specify format of duration string, e.g. hh:mm:ss.S for 01:23:04.5
1572
+ * @returns {string} Duration representation of the TimeCode
1573
+ */
1574
+
1267
1575
  }, {
1268
1576
  key: "toDuration",
1269
1577
  value: function toDuration() {
1270
- var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1271
- format = _ref4.format;
1578
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1579
+ var format = options.format;
1272
1580
 
1273
1581
  var _this$toTime = this.toTime(),
1274
1582
  hours = _this$toTime.hours,
1275
- minutes = _this$toTime.minutes,
1276
- seconds = _this$toTime.seconds;
1583
+ rest = _objectWithoutProperties__default["default"](_this$toTime, _excluded$5);
1277
1584
 
1278
- if (typeof format === 'string') {
1279
- if (format.toLowerCase() === 'hhmmss') {
1280
- return [hours.toFixed().padStart(2, '0'), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1281
- }
1585
+ var minutes = rest.minutes,
1586
+ seconds = rest.seconds,
1587
+ milliseconds = rest.milliseconds;
1588
+
1589
+ if (!!format && typeof format !== 'string') {
1590
+ throw Error('format has to be a string');
1282
1591
  }
1283
1592
 
1284
- if (hours) {
1285
- return [hours.toFixed(), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1593
+ var isBefore = function isBefore(unit, units) {
1594
+ return !format.includes(unit) || !units.some(function (u) {
1595
+ return format.includes(u) && format.lastIndexOf(unit) > format.indexOf(u);
1596
+ });
1597
+ };
1598
+
1599
+ if (!!format && !(isBefore('h', ['m', 's', 'S']) && isBefore('m', ['s', 'S']) && isBefore('s', ['S']))) {
1600
+ throw Error('format order is unsupported (has to be h, m, s then S)');
1286
1601
  }
1287
1602
 
1288
- if (minutes >= 10) {
1289
- return [minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1603
+ if (!format) {
1604
+ return "".concat(hours > 0 ? "".concat(hours, ":").concat("".concat(minutes).padStart(2, '0')) : minutes, ":").concat("".concat(seconds).padStart(2, '0'));
1290
1605
  }
1291
1606
 
1292
- return [minutes.toFixed(), seconds.toFixed().padStart(2, '0')].join(':');
1607
+ var countConsecutiveChars = function countConsecutiveChars(i, arr) {
1608
+ var j = i;
1609
+
1610
+ while (arr[j] === arr[j + 1]) {
1611
+ j += 1;
1612
+ }
1613
+
1614
+ return j - i + 1;
1615
+ };
1616
+
1617
+ var timeUnitKeys = ['h', 'm', 's', 'S'];
1618
+ var output = [];
1619
+
1620
+ _toConsumableArray__default["default"](format).forEach(function (c, i, arr) {
1621
+ switch (c) {
1622
+ case 'h':
1623
+ {
1624
+ if (arr[i - 1] === 'h') {
1625
+ break;
1626
+ }
1627
+
1628
+ var amount = countConsecutiveChars(i, arr);
1629
+ output.push("".concat(hours).padStart(amount, '0'));
1630
+
1631
+ if (timeUnitKeys.includes(arr[i + amount])) {
1632
+ output.push(':');
1633
+ }
1634
+
1635
+ break;
1636
+ }
1637
+
1638
+ case 'm':
1639
+ {
1640
+ if (arr[i - 1] === 'm') {
1641
+ break;
1642
+ }
1643
+
1644
+ var _amount = countConsecutiveChars(i, arr);
1645
+
1646
+ if (!format.includes('h')) {
1647
+ minutes *= hours * 60;
1648
+ }
1649
+
1650
+ output.push("".concat(minutes).padStart(_amount, '0'));
1651
+
1652
+ if (timeUnitKeys.includes(arr[i + _amount])) {
1653
+ output.push(':');
1654
+ }
1655
+
1656
+ break;
1657
+ }
1658
+
1659
+ case 's':
1660
+ {
1661
+ if (arr[i - 1] === 's') {
1662
+ break;
1663
+ }
1664
+
1665
+ var _amount2 = countConsecutiveChars(i, arr);
1666
+
1667
+ if (!format.includes('m')) {
1668
+ seconds *= minutes * 60;
1669
+ }
1670
+
1671
+ output.push("".concat(seconds).padStart(_amount2, '0'));
1672
+
1673
+ if (timeUnitKeys.includes(arr[i + _amount2])) {
1674
+ output.push('.');
1675
+ }
1676
+
1677
+ break;
1678
+ }
1679
+
1680
+ case 'S':
1681
+ {
1682
+ if (arr[i - 1] === 'S') {
1683
+ break;
1684
+ }
1685
+
1686
+ var _amount3 = countConsecutiveChars(i, arr);
1687
+
1688
+ if (!format.includes('s')) {
1689
+ milliseconds *= seconds * 1000;
1690
+ }
1691
+
1692
+ output.push("".concat(Math.round(milliseconds / Math.pow(10, 3 - _amount3))).padStart(_amount3, '0'));
1693
+ break;
1694
+ }
1695
+
1696
+ default:
1697
+ output.push(c);
1698
+ }
1699
+ });
1700
+
1701
+ return output.join('');
1293
1702
  }
1703
+ /**
1704
+ * Get TimeCode in a smpte representation
1705
+ *
1706
+ * @returns {string} Smpte representation of the TimeCode
1707
+ */
1708
+
1294
1709
  }, {
1295
1710
  key: "toSmpte",
1296
1711
  value: function toSmpte() {
1297
- var _this = this;
1298
-
1299
1712
  if (this.samples === -Infinity) return '00:00:00:00';
1300
1713
 
1301
- var _this$toTime2 = this.toTime(),
1302
- hours = _this$toTime2.hours,
1303
- minutes = _this$toTime2.minutes,
1304
- seconds = _this$toTime2.seconds,
1305
- frames = _this$toTime2.frames;
1714
+ var _this$toUnits2 = this.toUnits(),
1715
+ hours = _this$toUnits2.hours,
1716
+ minutes = _this$toUnits2.minutes,
1717
+ seconds = _this$toUnits2.seconds,
1718
+ frames = _this$toUnits2.frames;
1306
1719
 
1307
1720
  var hhmmss = [hours.toFixed().padStart(2, '0'), minutes.toFixed().padStart(2, '0'), seconds.toFixed().padStart(2, '0')].join(':');
1721
+ return [hhmmss, "".concat(frames).padStart(2, '0')].join(this.frameSeparator);
1722
+ }
1723
+ /**
1724
+ * Get TimeCode as a VidiCore TimeCodeType object
1725
+ *
1726
+ * @returns {object} TimeCode as `{ samples, timeBase }`
1727
+ */
1308
1728
 
1309
- var _Object$entries$find = Object.entries(FRAME_SEPARATORS).find(function (thisSeparator) {
1310
- var _thisSeparator = _slicedToArray__default["default"](thisSeparator, 2),
1311
- _thisSeparator$ = _thisSeparator[1],
1312
- dropFrame = _thisSeparator$.dropFrame,
1313
- field = _thisSeparator$.field;
1314
-
1315
- return dropFrame === _this.dropFrame && field === _this.field;
1316
- }),
1317
- _Object$entries$find2 = _slicedToArray__default["default"](_Object$entries$find, 1),
1318
- _Object$entries$find3 = _Object$entries$find2[0],
1319
- frameSeparator = _Object$entries$find3 === void 0 ? ':' : _Object$entries$find3;
1320
-
1321
- return [hhmmss, frames.toFixed().padStart(2, '0')].join(frameSeparator);
1729
+ }, {
1730
+ key: "toObject",
1731
+ value: function toObject() {
1732
+ return {
1733
+ samples: this.samples,
1734
+ timeBase: this.timeBase.toObject()
1735
+ };
1322
1736
  }
1737
+ /**
1738
+ * @deprecated Use {@link TimeCode#toObject|toObject} instead
1739
+ *
1740
+ * @returns {object} TimeCode as `{ samples, timeBase }`
1741
+ */
1742
+
1323
1743
  }, {
1324
- key: "toFraction",
1325
- value: function toFraction() {
1326
- return "".concat(this.samples, "@").concat(this.timeBase.denominator, ":").concat(this.timeBase.numerator);
1744
+ key: "toJson",
1745
+ value: function toJson() {
1746
+ // eslint-disable-next-line no-console
1747
+ console.warn('Deprecated - use toObject instead');
1748
+ return this.toObject();
1327
1749
  }
1328
1750
  }]);
1329
1751
 
1330
1752
  return TimeCode;
1331
1753
  }();
1332
1754
 
1333
- var formatTimeCodeType = function formatTimeCodeType(timeCode, options) {
1334
- return new TimeCode(timeCode, options);
1335
- };
1336
-
1337
- var formatTimeCodeText = function formatTimeCodeText(timeCodeText, options) {
1338
- if (timeCodeText === undefined) {
1339
- var _timeCode = {
1340
- samples: 0
1341
- };
1342
- return formatTimeCodeType(_timeCode, options);
1343
- }
1755
+ /* eslint-disable no-self-assign */
1344
1756
 
1345
- if (typeof timeCodeText === 'number') {
1346
- var _timeCode2 = {
1347
- samples: timeCodeText
1348
- };
1349
- return formatTimeCodeType(_timeCode2, options);
1757
+ /**
1758
+ * @private
1759
+ *
1760
+ * Using Euclid's algorithm
1761
+ *
1762
+ * @param {number} num1 a number
1763
+ * @param {number} num2 another number
1764
+ * @returns {number} the greatest common divisor as a number
1765
+ */
1766
+ var getGreatestCommonDivisor = function getGreatestCommonDivisor(num1, num2) {
1767
+ var a = Math.abs(num1);
1768
+ var b = Math.abs(num2);
1769
+
1770
+ while (a && b && a !== b) {
1771
+ if (a > b) {
1772
+ var _ref = [a - b, b];
1773
+ a = _ref[0];
1774
+ b = _ref[1];
1775
+ } else {
1776
+ var _ref2 = [a, b - a];
1777
+ a = _ref2[0];
1778
+ b = _ref2[1];
1779
+ }
1350
1780
  }
1351
1781
 
1352
- if (timeCodeText.includes('@')) {
1353
- var _timeCodeText$split = timeCodeText.split('@'),
1354
- _timeCodeText$split2 = _slicedToArray__default["default"](_timeCodeText$split, 2),
1355
- samplesString = _timeCodeText$split2[0],
1356
- timeBaseText = _timeCodeText$split2[1];
1357
-
1358
- var _samples = Number(samplesString);
1359
-
1360
- var timeBase = formatTimeBaseText(timeBaseText);
1361
- var _timeCode3 = {
1362
- samples: _samples,
1363
- timeBase: timeBase
1364
- };
1365
- return formatTimeCodeType(_timeCode3, options);
1366
- }
1782
+ return a || b;
1783
+ };
1367
1784
 
1368
- if (timeCodeText === '-INF') {
1369
- var _samples2 = -Infinity;
1785
+ var _excluded$4 = ["timeBase", "useGCD"];
1786
+ /**
1787
+ * Format seconds to TimeCode object
1788
+ * Input time base is always 1:1 since it expects seconds as input
1789
+ *
1790
+ * Note: Max 15 digits accuracy (double precision float64), e.g.
1791
+ * - 10^6 seconds can have 10^9 decimals (nanosecond) precision
1792
+ * - 10^9 seconds can have 10^6 decimals (microsecond) precision
1793
+ * - 10^12 seconds can have 10^3 decimals (millisecond) precision
1794
+ *
1795
+ * @param {string|number} seconds With or without decimals ("." and "," are both interpreted as decimal)
1796
+ * @param {object} [options={}] Options for how to format the seconds to a TimeCode
1797
+ * @param {object|string} options.timeBase What TimeBase the resulting TimeCode should have (if unset and useGCD=false, denominator will be 10^<amount-of-decimals>)
1798
+ * @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)
1799
+ * @returns {TimeCode} A TimeCode instance
1800
+ */
1370
1801
 
1371
- var _timeCode4 = {
1372
- samples: _samples2
1373
- };
1374
- return formatTimeCodeType(_timeCode4, options);
1375
- }
1802
+ var formatTimeCodeSeconds = function formatTimeCodeSeconds(seconds) {
1803
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1376
1804
 
1377
- if (timeCodeText === '+INF') {
1378
- var _samples3 = Infinity;
1379
- var _timeCode5 = {
1380
- samples: _samples3
1381
- };
1382
- return formatTimeCodeType(_timeCode5, options);
1383
- }
1805
+ var timeBase = options.timeBase,
1806
+ _options$useGCD = options.useGCD,
1807
+ useGCD = _options$useGCD === void 0 ? false : _options$useGCD,
1808
+ timeCodeOptions = _objectWithoutProperties__default["default"](options, _excluded$4);
1384
1809
 
1385
- var samples = Number(timeCodeText);
1810
+ var secondsWithDot = "".concat(seconds).replace(/,/g, '.');
1811
+ var amountOfDigits = secondsWithDot.replace('.', '').length;
1386
1812
 
1387
- if (Number.isNaN(samples)) {
1388
- throw new Error("timeBaseText must be a number or sample@timeBase - is ".concat(timeCodeText));
1813
+ if (amountOfDigits > 16) {
1814
+ throw new Error("Amount of second digits cannot be more than 16, is ".concat(amountOfDigits));
1389
1815
  }
1390
1816
 
1391
- var timeCode = {
1392
- samples: samples
1393
- };
1394
- return formatTimeCodeType(timeCode, options);
1395
- };
1396
-
1397
- var formatSeconds = function formatSeconds(seconds, timeBase, options) {
1398
- if (Number.isNaN(Number(seconds))) {
1817
+ if (Number.isNaN(+secondsWithDot)) {
1399
1818
  throw new Error("seconds must be digits, is ".concat(seconds));
1400
1819
  }
1401
1820
 
1402
- var _ref = timeBase || {},
1403
- _ref$denominator = _ref.denominator,
1404
- denominator = _ref$denominator === void 0 ? 1 : _ref$denominator,
1405
- _ref$numerator = _ref.numerator,
1406
- numerator = _ref$numerator === void 0 ? 1 : _ref$numerator;
1821
+ var denominator = 1;
1822
+ var samples;
1407
1823
 
1408
- var samples = seconds * (denominator / numerator);
1409
- var timeCode = {
1410
- samples: samples,
1411
- timeBase: timeBase || {}
1412
- };
1413
- return new TimeCode(timeCode, options);
1414
- };
1415
-
1416
- var formatSecondsPrecise = function formatSecondsPrecise(seconds, timeBase, options) {
1417
- if (Number.isNaN(Number(seconds))) {
1418
- throw new Error("seconds must be digits, is ".concat(seconds));
1419
- }
1420
-
1421
- var _ref = timeBase || {},
1422
- _ref$numerator = _ref.numerator,
1423
- numerator = _ref$numerator === void 0 ? 1 : _ref$numerator;
1824
+ if (Number.isInteger(+secondsWithDot)) {
1825
+ samples = +secondsWithDot * denominator;
1826
+ } else {
1827
+ var _ms$length;
1424
1828
 
1425
- var _ref2 = timeBase || {},
1426
- _ref2$denominator = _ref2.denominator,
1427
- denominator = _ref2$denominator === void 0 ? 1 : _ref2$denominator;
1829
+ var _secondsWithDot$split = secondsWithDot.split('.'),
1830
+ _secondsWithDot$split2 = _slicedToArray__default["default"](_secondsWithDot$split, 2),
1831
+ ms = _secondsWithDot$split2[1];
1428
1832
 
1429
- if (!Number.isInteger(seconds)) {
1430
- var decimalPlaces = String(seconds).split('.')[1].length;
1833
+ var decimalPlaces = Math.min((_ms$length = ms === null || ms === void 0 ? void 0 : ms.length) !== null && _ms$length !== void 0 ? _ms$length : 0, 16);
1431
1834
  denominator *= Math.pow(10, decimalPlaces);
1835
+ samples = Math.round(secondsWithDot * denominator);
1432
1836
  }
1433
1837
 
1434
- var samples = (seconds * (denominator / numerator)).toFixed();
1435
- var timeCode = {
1838
+ if (!timeBase && useGCD) {
1839
+ var gcd = getGreatestCommonDivisor(denominator, samples);
1840
+ samples /= gcd;
1841
+ denominator /= gcd;
1842
+ }
1843
+
1844
+ var timeCode = new TimeCode({
1436
1845
  samples: samples,
1437
1846
  timeBase: {
1438
1847
  denominator: denominator,
1439
- numerator: numerator
1848
+ numerator: 1
1440
1849
  }
1441
- };
1442
- return new TimeCode(timeCode, options);
1850
+ }, timeCodeOptions);
1851
+ return timeBase ? timeCode.conformTimeBase(createTimeBase(timeBase === true ? 1 : timeBase)) : timeCode;
1443
1852
  };
1444
1853
 
1854
+ var _excluded$3 = ["exceedingMode", "timeBase"];
1855
+
1445
1856
  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; }
1446
1857
 
1447
1858
  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__default["default"](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; }
1448
-
1449
- var getDropFrames = function getDropFrames(roundedFrameRate) {
1450
- return roundedFrameRate === 60 ? 4 : 2;
1859
+ var MAP_SEPARATOR_TO_OPTIONS = {
1860
+ ':': {
1861
+ dropFrame: false,
1862
+ frameSeparator: ':'
1863
+ },
1864
+ '.': {
1865
+ dropFrame: false,
1866
+ frameSeparator: '.'
1867
+ },
1868
+ ';': {
1869
+ dropFrame: true,
1870
+ frameSeparator: ';'
1871
+ },
1872
+ ',': {
1873
+ dropFrame: true,
1874
+ frameSeparator: ','
1875
+ }
1451
1876
  };
1877
+ var getDroppedFramesFromSmpte = function getDroppedFramesFromSmpte(_ref, samples, timeBase) {
1878
+ var _ref2 = _slicedToArray__default["default"](_ref, 4),
1879
+ hh = _ref2[0],
1880
+ mm = _ref2[1],
1881
+ ss = _ref2[2],
1882
+ ff = _ref2[3];
1883
+
1884
+ var roundedFrameRate = timeBase.toRate({
1885
+ rounded: true
1886
+ });
1887
+ var dropFrames = getAmountOfFrameDrops(timeBase);
1452
1888
 
1453
- var getRoundedFrameRate = function getRoundedFrameRate(timeBase) {
1454
- return Math.round(timeBase.denominator / timeBase.numerator);
1889
+ if (samples === 0 || dropFrames === 0) {
1890
+ return 0;
1891
+ }
1892
+
1893
+ var shouldDropMinute = mm % 10 !== 0;
1894
+ var shouldDropSecond = shouldDropMinute && ss === 0;
1895
+ var hourFrames = hh * (3600 * roundedFrameRate - 54 * dropFrames);
1896
+ var minuteFrames = mm * 60 * roundedFrameRate - (mm - Math.ceil(mm / 10)) * dropFrames;
1897
+ var secondFrames = ss * roundedFrameRate - (shouldDropMinute && ss > 1 ? dropFrames : 0);
1898
+
1899
+ if (shouldDropSecond && ff < dropFrames) {
1900
+ throw new Error("Frame does not exist for ".concat(timeBase.toRate({
1901
+ constant: true
1902
+ }), " drop-frame"));
1903
+ }
1904
+
1905
+ var frameFrames = shouldDropSecond ? ff - dropFrames : ff;
1906
+ var samplesWithoutDroppedFrames = hourFrames + minuteFrames + secondFrames + frameFrames;
1907
+ return samples - samplesWithoutDroppedFrames;
1455
1908
  };
1456
1909
 
1457
- var splitSmpte = function splitSmpte(smpteText) {
1458
- var hasDropFrameSeparator = smpteText.match(/[^0-9:\-_]/);
1459
- var hhmmssff;
1460
- var frameOptions = {};
1910
+ var splitSmpte = function splitSmpte(smpte) {
1911
+ var _ref3 = (smpte === null || smpte === void 0 ? void 0 : smpte.match(/[^0-9:\-_]/)) || [],
1912
+ _ref4 = _slicedToArray__default["default"](_ref3, 1),
1913
+ nonColonFrameSeparator = _ref4[0];
1461
1914
 
1462
- if (hasDropFrameSeparator) {
1463
- var _hasDropFrameSeparato = _slicedToArray__default["default"](hasDropFrameSeparator, 1),
1464
- frameSeparator = _hasDropFrameSeparato[0];
1915
+ var smpteValues = [];
1916
+ var options = {
1917
+ frameSeparator: ':',
1918
+ dropFrame: false
1919
+ };
1465
1920
 
1466
- var _smpteText$split = smpteText.split(frameSeparator),
1467
- _smpteText$split2 = _slicedToArray__default["default"](_smpteText$split, 2),
1468
- hhmmss = _smpteText$split2[0],
1469
- splitFrames = _smpteText$split2[1];
1921
+ if (nonColonFrameSeparator) {
1922
+ var _smpte$split = smpte.split(nonColonFrameSeparator),
1923
+ _smpte$split2 = _slicedToArray__default["default"](_smpte$split, 2),
1924
+ hhmmss = _smpte$split2[0],
1925
+ ff = _smpte$split2[1];
1470
1926
 
1471
- hhmmssff = [].concat(_toConsumableArray__default["default"](hhmmss.split(':')), [splitFrames]);
1472
- frameOptions = FRAME_SEPARATORS[frameSeparator] || {};
1927
+ smpteValues = [].concat(_toConsumableArray__default["default"](hhmmss.split(':')), [ff]);
1928
+ options = MAP_SEPARATOR_TO_OPTIONS[nonColonFrameSeparator] || {};
1473
1929
  } else {
1474
- hhmmssff = smpteText.split(':');
1930
+ smpteValues = smpte.split(':');
1475
1931
  }
1476
1932
 
1477
- hhmmssff = hhmmssff.map(Number);
1933
+ smpteValues = smpteValues.map(Number);
1478
1934
 
1479
- if (hhmmssff.length > 4 || hhmmssff.some(function (n) {
1935
+ if (smpteValues.length !== 4) {
1936
+ throw new Error('Invalid format, must be "##:##:##:##');
1937
+ }
1938
+
1939
+ if (smpteValues.some(function (n) {
1480
1940
  return Number.isNaN(n);
1481
1941
  })) {
1482
- throw new Error('Invalid SMPTE timecode');
1942
+ throw new Error('Invalid format, values must be numbers');
1483
1943
  }
1484
1944
 
1485
- return [hhmmssff, frameOptions];
1945
+ return [smpteValues, options];
1486
1946
  };
1487
1947
 
1488
- var countSamples = function countSamples(hh, mm, ss, ff, _ref) {
1489
- var dropFrame = _ref.dropFrame,
1490
- roundedFrameRate = _ref.roundedFrameRate;
1948
+ var getSamplesFromSmpte = function getSamplesFromSmpte(smpteValues, timeBase, dropFrame) {
1949
+ var _smpteValues = _slicedToArray__default["default"](smpteValues, 4),
1950
+ hh = _smpteValues[0],
1951
+ mm = _smpteValues[1],
1952
+ ss = _smpteValues[2],
1953
+ ff = _smpteValues[3];
1954
+
1955
+ var roundedFrameRate = timeBase.toRate({
1956
+ rounded: true
1957
+ });
1958
+ var samples = hh * 3600 * roundedFrameRate + mm * 60 * roundedFrameRate + ss * roundedFrameRate + ff;
1959
+ return samples - (dropFrame ? getDroppedFramesFromSmpte(smpteValues, samples, timeBase) : 0);
1960
+ }; // Better naming than "useValueExcess" and "useValueTruncate" must exist
1961
+
1962
+
1963
+ var EXCEEDING_OPTIONS = ['error', 'add', 'ignore'];
1964
+ /**
1965
+ * Format smpte text to a TimeCode Instance
1966
+ *
1967
+ * exceedingMode:
1968
+ * - "overflow" exceeding values will be kept (e.g. PAL and 00:00:00:25 => 00:00:01:00)
1969
+ * - "truncate" exceeding values will be truncated (e.g. PAL and 00:00:00:25 => 00:00:00:24)
1970
+ * - "error" exceeding values will throw error (e.g. PAL and 00:00:00:25 => Error)
1971
+ *
1972
+ * @param {string} smpte String representation of smpte
1973
+ * @param {object} [options={}] What options to use for creating the time code from smpte (all not specified below are passed to the TimeCode constructor)
1974
+ * @param {object|string|number} options.timeBase TimeBase of smpte (and consequently TimeBase of output TimeCode)
1975
+ * @param {string} [options.exceedingMode=error] How to handle exceeding values (`overflow|truncate|error`)
1976
+ * @param {boolean} options.dropFrame If it should parse and create time code using dropFrame
1977
+ * @param {string} options.frameSeparator What frame separator the TimeCode should store (defaults to what the smpte has)
1978
+ * @returns {TimeCode} A TimeCode instance
1979
+ */
1980
+
1981
+ var formatTimeCodeSmpte = function formatTimeCodeSmpte(smpte) {
1982
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1491
1983
 
1492
- if (!dropFrame) {
1493
- return hh * 3600 * roundedFrameRate + mm * 60 * roundedFrameRate + ss * roundedFrameRate + ff;
1984
+ var _options$exceedingMod = options.exceedingMode,
1985
+ exceedingMode = _options$exceedingMod === void 0 ? 'error' : _options$exceedingMod,
1986
+ timeBase = options.timeBase,
1987
+ timeCodeOptions = _objectWithoutProperties__default["default"](options, _excluded$3);
1988
+
1989
+ if ([null, undefined].includes(smpte)) {
1990
+ throw new Error("smpte cannot be undefined or null");
1494
1991
  }
1495
1992
 
1496
- if (![30, 60].includes(roundedFrameRate)) {
1497
- throw new Error('Cannot use dropframe with non NTSC timebase');
1993
+ if (typeof smpte !== 'string') {
1994
+ throw new Error("smpte must be a string, is ".concat(JSON.stringify(smpte)));
1498
1995
  }
1499
1996
 
1500
- var dropFrames = getDropFrames(roundedFrameRate);
1501
- var shouldDropMinute = mm % 10 !== 0;
1502
- var shouldDropSecond = shouldDropMinute && ss === 0;
1503
- var hourFrames = hh * (3600 * roundedFrameRate - 54 * dropFrames);
1504
- var minuteFrames = mm * 60 * roundedFrameRate - (mm - Math.ceil(mm / 10)) * dropFrames;
1505
- var secondFrames = ss * roundedFrameRate - (shouldDropMinute && ss > 1 ? dropFrames : 0);
1997
+ var _splitSmpte = splitSmpte(smpte),
1998
+ _splitSmpte2 = _slicedToArray__default["default"](_splitSmpte, 2),
1999
+ smpteValues = _splitSmpte2[0],
2000
+ timeCodeOptionsFromSmpte = _splitSmpte2[1];
1506
2001
 
1507
- if (shouldDropSecond && ff < dropFrames) {
1508
- throw new Error('Invalid ff');
2002
+ var timeBaseInstance = createTimeBase(timeBase);
2003
+
2004
+ var mergedOptions = _objectSpread$2(_objectSpread$2({}, timeCodeOptionsFromSmpte), {}, {
2005
+ dropFrame: isDropFrameTimeBase(timeBaseInstance)
2006
+ }, timeCodeOptions);
2007
+
2008
+ var roundedFrameRate = timeBaseInstance.toRate({
2009
+ rounded: true
2010
+ });
2011
+ var maxFrame = Math.max(0, roundedFrameRate - 1);
2012
+
2013
+ if (smpteValues.some(function (v) {
2014
+ return v < 0;
2015
+ })) {
2016
+ throw new Error('Negative values are not supported');
1509
2017
  }
1510
2018
 
1511
- var frameFrames = shouldDropSecond ? ff - dropFrames : ff;
1512
- return hourFrames + minuteFrames + secondFrames + frameFrames;
2019
+ var samples;
2020
+
2021
+ switch (exceedingMode) {
2022
+ case 'error':
2023
+ {
2024
+ var _smpteValues2 = _slicedToArray__default["default"](smpteValues, 4),
2025
+ hours = _smpteValues2[0],
2026
+ minutes = _smpteValues2[1],
2027
+ seconds = _smpteValues2[2],
2028
+ frames = _smpteValues2[3];
2029
+
2030
+ if (hours >= 100) {
2031
+ throw Error('Minutes has to be less than 60');
2032
+ }
2033
+
2034
+ if (minutes >= 60) {
2035
+ throw Error('Minutes has to be less than 60');
2036
+ }
2037
+
2038
+ if (seconds >= 60) {
2039
+ throw Error('Seconds has to be less than 60');
2040
+ }
2041
+
2042
+ if (frames > maxFrame) {
2043
+ throw Error("Frames has to be less or equal to ".concat(maxFrame));
2044
+ }
2045
+
2046
+ samples = getSamplesFromSmpte(smpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2047
+ break;
2048
+ }
2049
+
2050
+ case 'ignore':
2051
+ {
2052
+ var _smpteValues3 = _slicedToArray__default["default"](smpteValues, 4),
2053
+ _hours = _smpteValues3[0],
2054
+ _minutes = _smpteValues3[1],
2055
+ _seconds = _smpteValues3[2],
2056
+ _frames = _smpteValues3[3];
2057
+
2058
+ var truncatedSmpteValues = [Math.min(100, _hours), Math.min(59, _minutes), Math.min(59, _seconds), Math.min(maxFrame, _frames)];
2059
+ samples = getSamplesFromSmpte(truncatedSmpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2060
+ break;
2061
+ }
2062
+
2063
+ case 'add':
2064
+ {
2065
+ samples = getSamplesFromSmpte(smpteValues, timeBaseInstance, mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.dropFrame);
2066
+ break;
2067
+ }
2068
+
2069
+ default:
2070
+ {
2071
+ throw new Error("Invalid exceedingMode, options are ".concat(JSON.stringify(EXCEEDING_OPTIONS)));
2072
+ }
2073
+ }
2074
+
2075
+ return new TimeCode({
2076
+ samples: samples,
2077
+ timeBase: timeBaseInstance
2078
+ }, mergedOptions);
1513
2079
  };
1514
2080
 
1515
- var formatSmpte = function formatSmpte(smpteText, timeBaseText) {
1516
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2081
+ var _excluded$2 = ["timeBase"];
2082
+ /**
2083
+ * Format text to a TimeCode instance
2084
+ *
2085
+ * @param {string} timeCodeText A time code text (e.g. "25@PAL")
2086
+ * @param {object} [options={}] Options for how to format
2087
+ * @param {object|string} options.timeBase The time base the returned TimeCode should have
2088
+ * @returns {TimeCode} A TimeCode instance
2089
+ */
2090
+
2091
+ var formatTimeCodeText = function formatTimeCodeText(timeCodeText, options) {
2092
+ var _timeCodeObject;
1517
2093
 
1518
- if (smpteText === undefined) {
1519
- var _timeBase = formatTimeBase(timeBaseText);
2094
+ var _ref = options || {},
2095
+ timeBase = _ref.timeBase,
2096
+ timeCodeOptions = _objectWithoutProperties__default["default"](_ref, _excluded$2);
2097
+
2098
+ var timeCodeObject;
2099
+
2100
+ if (timeCodeText === undefined) {
2101
+ timeCodeObject = {
2102
+ samples: 0
2103
+ };
2104
+ } else if (typeof timeCodeText === 'number') {
2105
+ timeCodeObject = {
2106
+ samples: timeCodeText
2107
+ };
2108
+ } else if (timeCodeText.includes('@')) {
2109
+ var _timeCodeText$split = timeCodeText.split('@'),
2110
+ _timeCodeText$split2 = _slicedToArray__default["default"](_timeCodeText$split, 2),
2111
+ samplesString = _timeCodeText$split2[0],
2112
+ timeBaseText = _timeCodeText$split2[1];
1520
2113
 
1521
- var _timeCode = {
1522
- samples: 0,
1523
- timeBase: _timeBase
2114
+ var samples = Number(samplesString);
2115
+ timeCodeObject = {
2116
+ samples: samples,
2117
+ timeBase: formatTimeBaseText(timeBaseText)
2118
+ };
2119
+ } else if (timeCodeText === '-INF') {
2120
+ timeCodeObject = {
2121
+ samples: -Infinity
2122
+ };
2123
+ } else if (timeCodeText === '+INF') {
2124
+ timeCodeObject = {
2125
+ samples: Infinity
2126
+ };
2127
+ } else {
2128
+ timeCodeObject = {
2129
+ samples: Number(timeCodeText)
1524
2130
  };
1525
- return formatTimeCodeType(_timeCode);
1526
2131
  }
1527
2132
 
1528
- if (typeof smpteText !== 'string') {
1529
- throw new Error("smpteText must be a string, is ".concat(smpteText));
2133
+ if (Number.isNaN((_timeCodeObject = timeCodeObject) === null || _timeCodeObject === void 0 ? void 0 : _timeCodeObject.samples) || timeCodeObject.timeBase && !(timeCodeObject.timeBase instanceof TimeBase)) {
2134
+ throw new Error("timeCodeText must be a number or sample@timeBase - is ".concat(timeCodeText));
1530
2135
  }
1531
2136
 
1532
- var _splitSmpte = splitSmpte(smpteText),
1533
- _splitSmpte2 = _slicedToArray__default["default"](_splitSmpte, 2),
1534
- _splitSmpte2$ = _slicedToArray__default["default"](_splitSmpte2[0], 4),
1535
- hh = _splitSmpte2$[0],
1536
- mm = _splitSmpte2$[1],
1537
- ss = _splitSmpte2$[2],
1538
- _splitSmpte2$$ = _splitSmpte2$[3],
1539
- ff = _splitSmpte2$$ === void 0 ? 0 : _splitSmpte2$$,
1540
- frameOptions = _splitSmpte2[1];
1541
-
1542
- var _frameOptions$dropFra = frameOptions.dropFrame,
1543
- dropFrame = _frameOptions$dropFra === void 0 ? false : _frameOptions$dropFra;
1544
- var timeBase = formatTimeBase(timeBaseText);
1545
- var roundedFrameRate = getRoundedFrameRate(timeBase);
1546
-
1547
- if (mm >= 60 || mm < 0 || ss >= 60 || ss < 0 || ff >= roundedFrameRate || ff < 0) {
1548
- throw new Error('Invalid mm, ss or ff');
1549
- }
1550
-
1551
- var samples = countSamples(hh, mm, ss, ff, {
1552
- dropFrame: dropFrame,
1553
- roundedFrameRate: roundedFrameRate
1554
- });
1555
- var timeCode = {
1556
- samples: samples,
1557
- timeBase: timeBase
1558
- };
1559
- return formatTimeCodeType(timeCode, _objectSpread$2(_objectSpread$2({}, frameOptions), options));
2137
+ var timeCode = new TimeCode(timeCodeObject, timeCodeOptions);
2138
+ return timeBase ? timeCode.conformTimeBase(createTimeBase(timeBase)) : timeCode;
2139
+ };
2140
+
2141
+ /**
2142
+ * Format an object to a TimeCode instance
2143
+ *
2144
+ * @param {object} timeCode To create TimeCode instance of
2145
+ * @param {object} options For the TimeCode constructor
2146
+ * @returns {TimeCode} A TimeCode instance
2147
+ */
2148
+
2149
+ var formatTimeCodeType = function formatTimeCodeType(timeCode, options) {
2150
+ return new TimeCode(timeCode, options);
2151
+ };
2152
+
2153
+ var isObject = function isObject(o) {
2154
+ return Object.prototype.toString.call(o) === '[object Object]';
2155
+ };
2156
+
2157
+ var isString = function isString(s) {
2158
+ return typeof s === 'string';
2159
+ };
2160
+
2161
+ var hasSmpteFormat = function hasSmpteFormat(s) {
2162
+ return isString(s) && !!s.match(/^(\d\d+):(\d\d+):(\d\d+)(:|;|\.|,)(\d\d+)$/);
2163
+ };
2164
+
2165
+ var isNumber = function isNumber(s) {
2166
+ return !Number.isNaN(Number(s));
2167
+ };
2168
+ /**
2169
+ * Create a TimeCode instance from smpte, seconds/samples, timeCode object or string
2170
+ *
2171
+ * @param {object|string|number} timeCode Smpte, seconds/samples, timeCode object or string
2172
+ * @param {object} [options={}] For the format functions
2173
+ * @returns {TimeCode} A TimeCode instance
2174
+ */
2175
+
2176
+
2177
+ var createTimeCode = function createTimeCode(timeCode, options) {
2178
+ if (isObject(timeCode)) return formatTimeCodeType(timeCode, options);
2179
+ if (hasSmpteFormat(timeCode)) return formatTimeCodeSmpte(timeCode, options);
2180
+ if (isNumber(timeCode)) return formatTimeCodeSeconds(timeCode, options);
2181
+ return formatTimeCodeText(timeCode, options);
1560
2182
  };
1561
2183
 
1562
2184
  function timeToCueTime(_ref) {
@@ -1576,10 +2198,10 @@ function timeToCueTime(_ref) {
1576
2198
  }
1577
2199
  /**
1578
2200
  * Convert subtitle groups to WebVtt subtitle format
1579
- * @param {Object} input={}
2201
+ * @param {Object} [input={}]
1580
2202
  * @param {Object} input.metadataType - MetadataType response from API.
1581
- * @param {string} input.subtitleGroup=stl_subtitle - Name of group containing subtitle field/text.
1582
- * @param {string} input.subtitleField=stl_text - Name of field (text) to use for the subtitles.
2203
+ * @param {string} [input.subtitleGroup=stl_subtitle] - Name of group containing subtitle field/text.
2204
+ * @param {string} [input.subtitleField=stl_text] - Name of field (text) to use for the subtitles.
1583
2205
  * @returns {string} WebVtt subtitles
1584
2206
  */
1585
2207
 
@@ -1622,6 +2244,9 @@ var metadataTypeToWebVtt = function metadataTypeToWebVtt(_ref2) {
1622
2244
  return "WEBVTT\n\n\n".concat(vttCues.join('\n'));
1623
2245
  };
1624
2246
 
2247
+ var SYSTEM_FIELDGROUPS = ['stl_subtitle', 'stl_tti', 'stl_gsi', 'mrk_marker', 'pho_validation', 'pho_resource', 'pho_error', 'facedetect_rect', 'facedetect_face', 'originalTrackFilename', 'stl_gsiHeader'];
2248
+ 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'];
2249
+
1625
2250
  var createFacetType = function createFacetType() {
1626
2251
  var fieldList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1627
2252
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -1771,12 +2396,13 @@ var parseContainerComponent = function parseContainerComponent(containerComponen
1771
2396
  }
1772
2397
 
1773
2398
  if (durationTimeCode !== undefined && durationTimeCode.samples !== 0) {
1774
- parsedContainerComponent.durationTimeCode = formatTimeCodeType(durationTimeCode);
1775
- parsedContainerComponent.duration = parsedContainerComponent.durationTimeCode.toDuration();
2399
+ var timeCode = formatTimeCodeType(durationTimeCode);
2400
+ parsedContainerComponent.durationTimeCode = timeCode.toObject();
2401
+ parsedContainerComponent.duration = timeCode.toDuration();
1776
2402
  }
1777
2403
 
1778
2404
  if (startTimestamp) {
1779
- parsedContainerComponent.startTimestamp = formatTimeCodeType(startTimestamp);
2405
+ parsedContainerComponent.startTimestamp = formatTimeCodeType(startTimestamp).toObject();
1780
2406
  }
1781
2407
 
1782
2408
  if (startTimecode !== undefined && timeCodeTimeBase) {
@@ -1848,8 +2474,10 @@ var parseVideoComponent = function parseVideoComponent(videoComponent) {
1848
2474
  samples: samples,
1849
2475
  timeBase: timeBase
1850
2476
  });
1851
- frameRate = timeCode.timeBase.toRate(true);
1852
- smpte = timeCode.toSmpte(true);
2477
+ frameRate = timeCode.timeBase.toRate({
2478
+ constant: true
2479
+ });
2480
+ smpte = timeCode.toSmpte();
1853
2481
  }
1854
2482
 
1855
2483
  var height = resolution.height,
@@ -2081,6 +2709,7 @@ var IMAGE = 'IMAGE';
2081
2709
  var AUDIO = 'AUDIO';
2082
2710
  var VIDEO = 'VIDEO';
2083
2711
  var DOCUMENT = 'DOCUMENT';
2712
+ var BINARY = 'BINARY';
2084
2713
  var getShapeMediaType = function getShapeMediaType() {
2085
2714
  var shapeType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2086
2715
  var mimeType = shapeType.mimeType,
@@ -2103,6 +2732,7 @@ var getShapeMediaType = function getShapeMediaType() {
2103
2732
  if (mimeType.endsWith('/msword')) return DOCUMENT;
2104
2733
  if (mimeType.endsWith('/json')) return DOCUMENT;
2105
2734
  if (mimeType.endsWith('/xml')) return DOCUMENT;
2735
+ if (mimeType.endsWith('/octet-stream')) return BINARY;
2106
2736
  return undefined;
2107
2737
  };
2108
2738
 
@@ -2228,7 +2858,9 @@ var parseMediaConvertPreset = function parseMediaConvertPreset(transcodePresetTy
2228
2858
  numerator: numerator
2229
2859
  });
2230
2860
  output.timeBase = timeBase;
2231
- output.frameRate = timeBase.toRate(true);
2861
+ output.frameRate = timeBase.toRate({
2862
+ constant: true
2863
+ });
2232
2864
  }
2233
2865
  }
2234
2866
 
@@ -2273,7 +2905,9 @@ var parseTranscodePreset = function parseTranscodePreset(transcodePresetType) {
2273
2905
  if (video.framerate) {
2274
2906
  var timeBase = formatTimeBaseType(video.framerate);
2275
2907
  output.timeBase = timeBase;
2276
- output.frameRate = timeBase.toRate(true);
2908
+ output.frameRate = timeBase.toRate({
2909
+ constant: true
2910
+ });
2277
2911
  }
2278
2912
 
2279
2913
  if (video.scaling) {
@@ -2320,18 +2954,20 @@ var getDocumentType = function getDocumentType() {
2320
2954
  return undefined;
2321
2955
  };
2322
2956
 
2957
+ exports.SYSTEM_FIELDGROUPS = SYSTEM_FIELDGROUPS;
2958
+ exports.SYSTEM_FIELDS = SYSTEM_FIELDS;
2323
2959
  exports.TimeBase = TimeBase;
2324
2960
  exports.TimeCode = TimeCode;
2325
2961
  exports.createFacetType = createFacetType;
2326
2962
  exports.createMetadataType = createMetadataType;
2963
+ exports.createTimeBase = createTimeBase;
2964
+ exports.createTimeCode = createTimeCode;
2327
2965
  exports.filterShapeSource = filterShapeSource;
2328
2966
  exports.findNearestThumbnail = findNearestThumbnail;
2329
- exports.formatSeconds = formatSeconds;
2330
- exports.formatSecondsPrecise = formatSecondsPrecise;
2331
- exports.formatSmpte = formatSmpte;
2332
- exports.formatTimeBase = formatTimeBase;
2333
2967
  exports.formatTimeBaseText = formatTimeBaseText;
2334
2968
  exports.formatTimeBaseType = formatTimeBaseType;
2969
+ exports.formatTimeCodeSeconds = formatTimeCodeSeconds;
2970
+ exports.formatTimeCodeSmpte = formatTimeCodeSmpte;
2335
2971
  exports.formatTimeCodeText = formatTimeCodeText;
2336
2972
  exports.formatTimeCodeType = formatTimeCodeType;
2337
2973
  exports.getDocumentType = getDocumentType;