@vidispine/vdt-js 22.3.0-pre.5 → 22.3.0

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