@teselagen/sequence-utils 0.3.36 → 0.3.38-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/DNAComplementMap.d.ts +1 -1
  2. package/addGapsToSeqReads.d.ts +16 -3
  3. package/adjustAnnotationsToInsert.d.ts +2 -1
  4. package/adjustBpsToReplaceOrInsert.d.ts +2 -1
  5. package/aliasedEnzymesByName.d.ts +37 -1
  6. package/aminoAcidToDegenerateDnaMap.d.ts +1 -31
  7. package/aminoAcidToDegenerateRnaMap.d.ts +1 -1
  8. package/annotateSingleSeq.d.ts +5 -4
  9. package/annotationTypes.d.ts +2 -2
  10. package/autoAnnotate.d.ts +17 -8
  11. package/bioData.d.ts +10 -58
  12. package/calculateEndStability.d.ts +1 -1
  13. package/calculateNebTa.d.ts +6 -1
  14. package/calculateNebTm.d.ts +6 -4
  15. package/calculatePercentGC.d.ts +1 -1
  16. package/calculateSantaLuciaTm.d.ts +28 -114
  17. package/calculateTm.d.ts +13 -1
  18. package/computeDigestFragments.d.ts +30 -24
  19. package/condensePairwiseAlignmentDifferences.d.ts +1 -1
  20. package/convertAACaretPositionOrRangeToDna.d.ts +2 -1
  21. package/convertDnaCaretPositionOrRangeToAA.d.ts +2 -1
  22. package/cutSequenceByRestrictionEnzyme.d.ts +2 -1
  23. package/defaultEnzymesByName.d.ts +2 -1
  24. package/degenerateDnaToAminoAcidMap.d.ts +1 -1
  25. package/degenerateRnaToAminoAcidMap.d.ts +1 -1
  26. package/deleteSequenceDataAtRange.d.ts +2 -1
  27. package/diffUtils.d.ts +9 -7
  28. package/doesEnzymeChopOutsideOfRecognitionSite.d.ts +2 -1
  29. package/featureTypesAndColors.d.ts +19 -6
  30. package/filterSequenceString.d.ts +14 -10
  31. package/findApproxMatches.d.ts +7 -1
  32. package/findNearestRangeOfSequenceOverlapToPosition.d.ts +2 -1
  33. package/findOrfsInPlasmid.d.ts +2 -11
  34. package/findSequenceMatches.d.ts +11 -1
  35. package/generateAnnotations.d.ts +2 -1
  36. package/generateSequenceData.d.ts +8 -13
  37. package/getAllInsertionsInSeqReads.d.ts +11 -1
  38. package/getAminoAcidDataForEachBaseOfDna.d.ts +6 -5
  39. package/getAminoAcidFromSequenceTriplet.d.ts +1 -1
  40. package/getAminoAcidStringFromSequenceString.d.ts +3 -1
  41. package/getCodonRangeForAASliver.d.ts +3 -4
  42. package/getComplementAminoAcidStringFromSequenceString.d.ts +1 -1
  43. package/getComplementSequenceAndAnnotations.d.ts +5 -1
  44. package/getComplementSequenceString.d.ts +1 -1
  45. package/getCutsiteType.d.ts +2 -1
  46. package/getCutsitesFromSequence.d.ts +2 -1
  47. package/getDegenerateDnaStringFromAAString.d.ts +1 -1
  48. package/getDegenerateRnaStringFromAAString.d.ts +1 -1
  49. package/getDigestFragmentsForCutsites.d.ts +4 -1
  50. package/getDigestFragmentsForRestrictionEnzymes.d.ts +8 -1
  51. package/getInsertBetweenVals.d.ts +2 -1
  52. package/getLeftAndRightOfSequenceInRangeGivenPosition.d.ts +2 -1
  53. package/getOrfsFromSequence.d.ts +17 -11
  54. package/getOverlapBetweenTwoSequences.d.ts +2 -1
  55. package/getPossiblePartsFromSequenceAndEnzymes.d.ts +18 -1
  56. package/getReverseAminoAcidStringFromSequenceString.d.ts +1 -1
  57. package/getReverseComplementAminoAcidStringFromSequenceString.d.ts +1 -1
  58. package/getReverseComplementAnnotation.d.ts +11 -1
  59. package/getReverseComplementSequenceAndAnnotations.d.ts +5 -1
  60. package/getReverseComplementSequenceString.d.ts +1 -1
  61. package/getReverseSequenceString.d.ts +1 -1
  62. package/getSequenceDataBetweenRange.d.ts +9 -1
  63. package/getVirtualDigest.d.ts +11 -10
  64. package/guessIfSequenceIsDnaAndNotProtein.d.ts +5 -1
  65. package/index.cjs +733 -484
  66. package/index.d.ts +8 -5
  67. package/index.js +733 -484
  68. package/index.umd.cjs +733 -484
  69. package/insertGapsIntoRefSeq.d.ts +2 -1
  70. package/insertSequenceDataAtPositionOrRange.d.ts +10 -1
  71. package/isEnzymeType2S.d.ts +2 -1
  72. package/mapAnnotationsToRows.d.ts +9 -1
  73. package/package.json +9 -6
  74. package/prepareCircularViewData.d.ts +2 -1
  75. package/prepareRowData.d.ts +7 -3
  76. package/proteinAlphabet.d.ts +1 -1
  77. package/rotateBpsToPosition.d.ts +1 -1
  78. package/rotateSequenceDataToPosition.d.ts +3 -1
  79. package/shiftAnnotationsByLen.d.ts +4 -3
  80. package/src/DNAComplementMap.ts +32 -0
  81. package/src/addGapsToSeqReads.ts +436 -0
  82. package/src/adjustAnnotationsToInsert.ts +20 -0
  83. package/src/adjustBpsToReplaceOrInsert.ts +73 -0
  84. package/src/aliasedEnzymesByName.ts +7366 -0
  85. package/src/aminoAcidToDegenerateDnaMap.ts +32 -0
  86. package/src/aminoAcidToDegenerateRnaMap.ts +32 -0
  87. package/src/annotateSingleSeq.ts +37 -0
  88. package/src/annotationTypes.ts +23 -0
  89. package/src/autoAnnotate.test.js +0 -1
  90. package/src/autoAnnotate.ts +290 -0
  91. package/src/bioData.ts +65 -0
  92. package/src/calculateEndStability.ts +91 -0
  93. package/src/calculateNebTa.ts +46 -0
  94. package/src/calculateNebTm.ts +132 -0
  95. package/src/calculatePercentGC.ts +3 -0
  96. package/src/calculateSantaLuciaTm.ts +184 -0
  97. package/src/calculateTm.ts +242 -0
  98. package/src/computeDigestFragments.ts +238 -0
  99. package/src/condensePairwiseAlignmentDifferences.ts +85 -0
  100. package/src/convertAACaretPositionOrRangeToDna.ts +28 -0
  101. package/src/convertDnaCaretPositionOrRangeToAA.ts +28 -0
  102. package/src/cutSequenceByRestrictionEnzyme.ts +345 -0
  103. package/src/defaultEnzymesByName.ts +280 -0
  104. package/src/degenerateDnaToAminoAcidMap.ts +5 -0
  105. package/src/degenerateRnaToAminoAcidMap.ts +5 -0
  106. package/src/deleteSequenceDataAtRange.ts +13 -0
  107. package/src/diffUtils.ts +80 -0
  108. package/src/doesEnzymeChopOutsideOfRecognitionSite.ts +16 -0
  109. package/src/featureTypesAndColors.js +1 -1
  110. package/src/featureTypesAndColors.ts +167 -0
  111. package/src/filterSequenceString.ts +153 -0
  112. package/src/findApproxMatches.ts +58 -0
  113. package/src/findNearestRangeOfSequenceOverlapToPosition.ts +43 -0
  114. package/src/findOrfsInPlasmid.js +6 -1
  115. package/src/findOrfsInPlasmid.ts +31 -0
  116. package/src/findSequenceMatches.ts +154 -0
  117. package/src/generateAnnotations.ts +39 -0
  118. package/src/generateSequenceData.ts +212 -0
  119. package/src/getAllInsertionsInSeqReads.ts +100 -0
  120. package/src/getAminoAcidDataForEachBaseOfDna.ts +305 -0
  121. package/src/getAminoAcidFromSequenceTriplet.ts +27 -0
  122. package/src/getAminoAcidStringFromSequenceString.ts +36 -0
  123. package/src/getCodonRangeForAASliver.ts +73 -0
  124. package/src/getComplementAminoAcidStringFromSequenceString.ts +10 -0
  125. package/src/getComplementSequenceAndAnnotations.ts +25 -0
  126. package/src/getComplementSequenceString.ts +23 -0
  127. package/src/getCutsiteType.ts +18 -0
  128. package/src/getCutsitesFromSequence.ts +22 -0
  129. package/src/getDegenerateDnaStringFromAAString.ts +15 -0
  130. package/src/getDegenerateRnaStringFromAAString.ts +15 -0
  131. package/src/getDigestFragmentsForCutsites.ts +126 -0
  132. package/src/getDigestFragmentsForRestrictionEnzymes.ts +50 -0
  133. package/src/getInsertBetweenVals.ts +31 -0
  134. package/src/getLeftAndRightOfSequenceInRangeGivenPosition.ts +40 -0
  135. package/src/getMassOfAaString.ts +29 -0
  136. package/src/getOrfsFromSequence.ts +132 -0
  137. package/src/getOverlapBetweenTwoSequences.ts +30 -0
  138. package/src/getPossiblePartsFromSequenceAndEnzymes.ts +149 -0
  139. package/src/getReverseAminoAcidStringFromSequenceString.ts +22 -0
  140. package/src/getReverseComplementAminoAcidStringFromSequenceString.ts +10 -0
  141. package/src/getReverseComplementAnnotation.ts +33 -0
  142. package/src/getReverseComplementSequenceAndAnnotations.ts +46 -0
  143. package/src/getReverseComplementSequenceString.ts +18 -0
  144. package/src/getReverseSequenceString.ts +12 -0
  145. package/src/getSequenceDataBetweenRange.ts +154 -0
  146. package/src/getVirtualDigest.ts +139 -0
  147. package/src/guessIfSequenceIsDnaAndNotProtein.ts +39 -0
  148. package/src/index.test.ts +43 -0
  149. package/src/index.ts +111 -0
  150. package/src/insertGapsIntoRefSeq.ts +43 -0
  151. package/src/insertSequenceDataAtPosition.ts +2 -0
  152. package/src/insertSequenceDataAtPositionOrRange.ts +328 -0
  153. package/src/isEnzymeType2S.ts +5 -0
  154. package/src/mapAnnotationsToRows.ts +256 -0
  155. package/src/prepareCircularViewData.ts +24 -0
  156. package/src/prepareRowData.ts +61 -0
  157. package/src/prepareRowData_output1.json +1 -0
  158. package/src/proteinAlphabet.ts +271 -0
  159. package/src/rotateBpsToPosition.ts +12 -0
  160. package/src/rotateSequenceDataToPosition.ts +54 -0
  161. package/src/shiftAnnotationsByLen.ts +24 -0
  162. package/src/threeLetterSequenceStringToAminoAcidMap.ts +198 -0
  163. package/src/tidyUpAnnotation.ts +205 -0
  164. package/src/tidyUpSequenceData.ts +213 -0
  165. package/src/types.ts +109 -0
  166. package/threeLetterSequenceStringToAminoAcidMap.d.ts +11 -921
  167. package/tidyUpAnnotation.d.ts +13 -11
  168. package/tidyUpSequenceData.d.ts +15 -1
  169. package/types.d.ts +105 -0
package/index.cjs CHANGED
@@ -2588,9 +2588,10 @@ function getOverlapOfNonCircularRanges(rangeA, rangeB) {
2588
2588
  }
2589
2589
  }
2590
2590
  }
2591
+ return null;
2591
2592
  }
2592
2593
  __name(getOverlapOfNonCircularRanges, "getOverlapOfNonCircularRanges");
2593
- function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength, joinIfPossible) {
2594
+ function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength, joinIfPossible = false) {
2594
2595
  const normalizedRangeA = splitRangeIntoTwoPartsIfItIsCircular(
2595
2596
  rangeA,
2596
2597
  maxRangeLength
@@ -2611,6 +2612,22 @@ function getOverlapsOfPotentiallyCircularRanges(rangeA, rangeB, maxRangeLength,
2611
2612
  }
2612
2613
  });
2613
2614
  });
2615
+ if (joinIfPossible && normalizedRangeA.length === 2 && normalizedRangeB.length === 2 && maxRangeLength) {
2616
+ const joinedOverlap = {};
2617
+ overlaps = flatMap(overlaps, (o) => {
2618
+ if (o.start === 0) {
2619
+ joinedOverlap.end = o.end;
2620
+ return [];
2621
+ } else if (o.end === maxRangeLength - 1) {
2622
+ joinedOverlap.start = o.start;
2623
+ return [];
2624
+ }
2625
+ return [o];
2626
+ });
2627
+ if (Object.keys(joinedOverlap).length > 0) {
2628
+ overlaps.push(joinedOverlap);
2629
+ }
2630
+ }
2614
2631
  return overlaps;
2615
2632
  }
2616
2633
  __name(getOverlapsOfPotentiallyCircularRanges, "getOverlapsOfPotentiallyCircularRanges");
@@ -2682,10 +2699,7 @@ function trimRangeByAnotherRange(rangeToBeTrimmed, trimmingRange, sequenceLength
2682
2699
  if (!overlaps.length) {
2683
2700
  return rangeToBeTrimmed;
2684
2701
  }
2685
- const splitRangesToBeTrimmed = splitRangeIntoTwoPartsIfItIsCircular(
2686
- rangeToBeTrimmed,
2687
- sequenceLength
2688
- );
2702
+ const splitRangesToBeTrimmed = splitRangeIntoTwoPartsIfItIsCircular(rangeToBeTrimmed, sequenceLength);
2689
2703
  splitRangesToBeTrimmed.forEach(function(nonCircularRangeToBeTrimmed, index) {
2690
2704
  overlaps.forEach(function(overlap) {
2691
2705
  if (nonCircularRangeToBeTrimmed) {
@@ -2728,6 +2742,7 @@ function trimRangeByAnotherRange(rangeToBeTrimmed, trimmingRange, sequenceLength
2728
2742
  end: outputTrimmedRange.end
2729
2743
  });
2730
2744
  }
2745
+ return void 0;
2731
2746
  }
2732
2747
  __name(trimRangeByAnotherRange, "trimRangeByAnotherRange");
2733
2748
  function adjustRangeToDeletionOfAnotherRange(rangeToBeAdjusted, anotherRange, maxLength) {
@@ -2874,28 +2889,36 @@ function collapseOverlapsGeneratedFromRangeComparisonIfPossible(overlaps, sequen
2874
2889
  }
2875
2890
  }
2876
2891
  }
2892
+ return overlaps;
2877
2893
  }
2878
2894
  __name(collapseOverlapsGeneratedFromRangeComparisonIfPossible, "collapseOverlapsGeneratedFromRangeComparisonIfPossible");
2879
2895
  function provideInclusiveOptions(funToWrap) {
2880
- return function() {
2881
- const args = Array.prototype.slice.call(arguments);
2896
+ return function(...args) {
2882
2897
  const options = args[args.length - 1];
2883
2898
  if (options && (options.inclusive1BasedEnd || options.inclusive1BasedStart)) {
2884
2899
  args.forEach(function(arg, index) {
2885
- if (arg && arg.start > -1 && options.inclusive1BasedStart) {
2886
- args[index] = assign(arg, { start: arg.start - 1 });
2900
+ const potentialRange = arg;
2901
+ if (potentialRange && typeof potentialRange.start === "number" && potentialRange.start > -1 && options.inclusive1BasedStart) {
2902
+ args[index] = assign(potentialRange, {
2903
+ start: potentialRange.start - 1
2904
+ });
2887
2905
  }
2888
- if (arg && arg.end > -1 && options.inclusive1BasedEnd) {
2889
- args[index] = assign(arg, { end: arg.end - 1 });
2906
+ if (potentialRange && typeof potentialRange.end === "number" && potentialRange.end > -1 && options.inclusive1BasedEnd) {
2907
+ args[index] = assign(potentialRange, {
2908
+ end: potentialRange.end - 1
2909
+ });
2890
2910
  }
2891
2911
  });
2892
2912
  }
2893
2913
  let returnVal = funToWrap.apply(this, args);
2894
- if (returnVal && returnVal.start > -1 && options && options.inclusive1BasedStart) {
2895
- returnVal = assign(returnVal, { start: returnVal.start + 1 });
2914
+ const potentialReturn = returnVal;
2915
+ if (potentialReturn && typeof potentialReturn.start === "number" && potentialReturn.start > -1 && options && options.inclusive1BasedStart) {
2916
+ returnVal = assign(potentialReturn, {
2917
+ start: potentialReturn.start + 1
2918
+ });
2896
2919
  }
2897
- if (returnVal && returnVal.end > -1 && options && options.inclusive1BasedEnd) {
2898
- returnVal = assign(returnVal, { end: returnVal.end + 1 });
2920
+ if (potentialReturn && typeof potentialReturn.end === "number" && potentialReturn.end > -1 && options && options.inclusive1BasedEnd) {
2921
+ returnVal = assign(potentialReturn, { end: potentialReturn.end + 1 });
2899
2922
  }
2900
2923
  return returnVal;
2901
2924
  };
@@ -2941,7 +2964,7 @@ function isPositionWithinRange(position, range, sequenceLength, includeStartEdge
2941
2964
  return positionFits;
2942
2965
  }
2943
2966
  __name(isPositionWithinRange, "isPositionWithinRange");
2944
- function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPositions) {
2967
+ function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPositions = false) {
2945
2968
  let position = pPosition;
2946
2969
  if (position < 0) {
2947
2970
  position += sequenceLength;
@@ -3121,7 +3144,9 @@ function getSequenceWithinRange(range, sequence) {
3121
3144
  if (typeof subSequence === "string") {
3122
3145
  subSequence += sequence.slice(0, range.end + 1);
3123
3146
  } else {
3124
- subSequence = subSequence.concat(sequence.slice(0, range.end + 1));
3147
+ subSequence = subSequence.concat(
3148
+ sequence.slice(0, range.end + 1)
3149
+ );
3125
3150
  }
3126
3151
  return subSequence;
3127
3152
  } else {
@@ -3141,7 +3166,7 @@ function getShortestDistanceBetweenTwoPositions(position1, position2, sequenceLe
3141
3166
  }
3142
3167
  __name(getShortestDistanceBetweenTwoPositions, "getShortestDistanceBetweenTwoPositions");
3143
3168
  function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, assignYOffsetToRange) {
3144
- let yOffset = [];
3169
+ let yOffset = 0;
3145
3170
  const openYOffsetFound = YOffsetLevelsWithRanges.some(
3146
3171
  function(rangesAlreadyAddedToYOffset, index) {
3147
3172
  const rangeBlocked = rangesAlreadyAddedToYOffset.some(
@@ -3154,6 +3179,7 @@ function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, a
3154
3179
  );
3155
3180
  if (!rangeBlocked) {
3156
3181
  yOffset = index;
3182
+ if (assignYOffsetToRange) range.yOffset = index;
3157
3183
  rangesAlreadyAddedToYOffset.push(range);
3158
3184
  return true;
3159
3185
  }
@@ -3162,6 +3188,7 @@ function getYOffsetForPotentiallyCircularRange(range, YOffsetLevelsWithRanges, a
3162
3188
  );
3163
3189
  if (!openYOffsetFound) {
3164
3190
  yOffset = YOffsetLevelsWithRanges.length;
3191
+ if (assignYOffsetToRange) range.yOffset = YOffsetLevelsWithRanges.length;
3165
3192
  }
3166
3193
  return yOffset;
3167
3194
  }
@@ -3173,7 +3200,8 @@ function getYOffsetsForPotentiallyCircularRanges(ranges, assignYOffsetToRange) {
3173
3200
  ranges.forEach(function(range) {
3174
3201
  const yOffset = getYOffsetForPotentiallyCircularRange(
3175
3202
  range,
3176
- yOffsetLevels
3203
+ yOffsetLevels,
3204
+ assignYOffsetToRange
3177
3205
  );
3178
3206
  yOffsets.push(yOffset);
3179
3207
  if (yOffset > maxYOffset) {
@@ -3188,21 +3216,20 @@ function getYOffsetsForPotentiallyCircularRanges(ranges, assignYOffsetToRange) {
3188
3216
  __name(getYOffsetsForPotentiallyCircularRanges, "getYOffsetsForPotentiallyCircularRanges");
3189
3217
  const invertRange = provideInclusiveOptions(invertRange$1);
3190
3218
  function invertRange$1(rangeOrCaret, rangeMax) {
3191
- if (rangeOrCaret.start > -1) {
3219
+ if (typeof rangeOrCaret !== "number" && rangeOrCaret.start > -1) {
3192
3220
  const start = rangeOrCaret.end + 1;
3193
3221
  const end = rangeOrCaret.start - 1;
3194
3222
  return {
3195
3223
  start: normalizePositionByRangeLength(start, rangeMax, false),
3196
3224
  end: normalizePositionByRangeLength(end, rangeMax, false)
3197
3225
  };
3198
- } else {
3199
- if (rangeOrCaret > -1) {
3200
- return {
3201
- start: normalizePositionByRangeLength(rangeOrCaret, rangeMax, false),
3202
- end: normalizePositionByRangeLength(rangeOrCaret - 1, rangeMax, false)
3203
- };
3204
- }
3226
+ } else if (typeof rangeOrCaret === "number" && rangeOrCaret > -1) {
3227
+ return {
3228
+ start: normalizePositionByRangeLength(rangeOrCaret, rangeMax, false),
3229
+ end: normalizePositionByRangeLength(rangeOrCaret - 1, rangeMax, false)
3230
+ };
3205
3231
  }
3232
+ return void 0;
3206
3233
  }
3207
3234
  __name(invertRange$1, "invertRange$1");
3208
3235
  function isPositionCloserToRangeStartThanRangeEnd(position, range, maxLength) {
@@ -3256,9 +3283,10 @@ function zeroSubrangeByContainerRange(subRange, containerRange, sequenceLength)
3256
3283
  "subRange must be fully contained by containerRange! Otherwise this function does not make sense"
3257
3284
  );
3258
3285
  }
3259
- const newSubrange = {};
3260
- newSubrange.start = subRange.start - containerRange.start;
3261
- newSubrange.end = subRange.end - containerRange.start;
3286
+ const newSubrange = {
3287
+ start: subRange.start - containerRange.start,
3288
+ end: subRange.end - containerRange.start
3289
+ };
3262
3290
  if (newSubrange.start < 0) {
3263
3291
  newSubrange.start += sequenceLength;
3264
3292
  }
@@ -3269,10 +3297,10 @@ function zeroSubrangeByContainerRange(subRange, containerRange, sequenceLength)
3269
3297
  }
3270
3298
  __name(zeroSubrangeByContainerRange, "zeroSubrangeByContainerRange");
3271
3299
  function adjustRangeToRotation(rangeToBeAdjusted, rotateTo = 0, rangeLength) {
3272
- const mod = rangeLength ? modulo : identity;
3300
+ const mod = /* @__PURE__ */ __name((n) => rangeLength ? modulo(n, rangeLength) : n, "mod");
3273
3301
  const newRange = assign({}, rangeToBeAdjusted, {
3274
- start: mod(rangeToBeAdjusted.start - (rotateTo || 0), rangeLength),
3275
- end: mod(rangeToBeAdjusted.end - (rotateTo || 0), rangeLength)
3302
+ start: mod(rangeToBeAdjusted.start - (rotateTo || 0)),
3303
+ end: mod(rangeToBeAdjusted.end - (rotateTo || 0))
3276
3304
  });
3277
3305
  return newRange;
3278
3306
  }
@@ -3358,7 +3386,11 @@ function autoAnnotate({
3358
3386
  forEach(
3359
3387
  omitBy(seqsToAnnotateById, (s) => !s.sequence.length),
3360
3388
  ({ circular, sequence }, id) => {
3361
- function getMatches({ seqToMatchAgainst, isReverse, seqLen: seqLen2 }) {
3389
+ function getMatches({
3390
+ seqToMatchAgainst,
3391
+ isReverse,
3392
+ seqLen: seqLen2
3393
+ }) {
3362
3394
  let match;
3363
3395
  let lastMatch;
3364
3396
  try {
@@ -3378,13 +3410,13 @@ function autoAnnotate({
3378
3410
  };
3379
3411
  const range = {
3380
3412
  start: matchStart,
3381
- end: normalizePositionByRangeLength(matchEnd - 1, seqLen2)
3413
+ end: normalizePositionByRangeLength(matchEnd - 1, seqLen2, false)
3382
3414
  };
3383
3415
  if (!annotationsToAddBySeqId[id])
3384
3416
  annotationsToAddBySeqId[id] = [];
3385
3417
  annotationsToAddBySeqId[id].push(__spreadProps(__spreadValues({}, isReverse ? {
3386
- start: reversePositionInRange(range.end, seqLen2),
3387
- end: reversePositionInRange(range.start, seqLen2)
3418
+ start: reversePositionInRange(range.end, seqLen2, false),
3419
+ end: reversePositionInRange(range.start, seqLen2, false)
3388
3420
  } : range), {
3389
3421
  strand: isReverse ? -1 : 1,
3390
3422
  id: ann.id
@@ -3415,14 +3447,22 @@ function autoAnnotate({
3415
3447
  const origSeq = seqsToAnnotateById[id];
3416
3448
  const alreadyExistingAnnsByStartEnd = {};
3417
3449
  forEach(origSeq.annotations, (ann) => {
3418
- alreadyExistingAnnsByStartEnd[getStartEndStr(ann, { compareName })] = ann;
3450
+ alreadyExistingAnnsByStartEnd[getStartEndStr(
3451
+ __spreadProps(__spreadValues({}, ann), { strand: typeof ann.strand === "string" ? 1 : ann.strand }),
3452
+ { compareName }
3453
+ )] = ann;
3419
3454
  });
3420
3455
  const warningCounter = {};
3421
3456
  const toAdd = anns.filter((ann) => {
3422
- const alreadyExistingAnn = alreadyExistingAnnsByStartEnd[getStartEndStr(ann, { compareName })];
3457
+ const alreadyExistingAnn = alreadyExistingAnnsByStartEnd[getStartEndStr(
3458
+ __spreadProps(__spreadValues({}, ann), {
3459
+ strand: typeof ann.strand === "string" ? 1 : ann.strand
3460
+ }),
3461
+ { compareName }
3462
+ )];
3423
3463
  if (alreadyExistingAnn) return false;
3424
- if (warnIfMoreThan) {
3425
- warningCounter[ann.id] = (warningCounter[ann.id] || 0) + 1;
3464
+ if (warnIfMoreThan && ann.id !== void 0) {
3465
+ warningCounter[String(ann.id)] = (warningCounter[String(ann.id)] || 0) + 1;
3426
3466
  }
3427
3467
  return true;
3428
3468
  }).sort((a, b) => a.start - b.start);
@@ -3431,16 +3471,23 @@ function autoAnnotate({
3431
3471
  }
3432
3472
  warnIfMoreThan && forEach(warningCounter, (num, annId) => {
3433
3473
  if (num > warnIfMoreThan) {
3434
- toReturn.__more_than_warnings = toReturn.__more_than_warnings || {};
3435
- toReturn.__more_than_warnings[id] = toReturn.__more_than_warnings[id] || [];
3436
- toReturn.__more_than_warnings[id].push(annId);
3474
+ const warnings = toReturn["__more_than_warnings"] || {};
3475
+ warnings[id] = warnings[id] || [];
3476
+ warnings[id].push(annId);
3477
+ toReturn["__more_than_warnings"] = warnings;
3437
3478
  }
3438
3479
  });
3439
3480
  });
3440
3481
  return toReturn;
3441
3482
  }
3442
3483
  __name(autoAnnotate, "autoAnnotate");
3443
- function getStartEndStr({ start, end, name, strand, forward }, { compareName }) {
3484
+ function getStartEndStr({
3485
+ start,
3486
+ end,
3487
+ name,
3488
+ strand,
3489
+ forward
3490
+ }, { compareName }) {
3444
3491
  const isReverse = strand === -1 || forward === false;
3445
3492
  return `${start}-${end}-${isReverse ? "rev" : "for"}-${compareName ? name : ""}`;
3446
3493
  }
@@ -3454,13 +3501,12 @@ function convertApELikeRegexToRegex(regString = "") {
3454
3501
  let hitLeftCaret;
3455
3502
  let hitRightCaret;
3456
3503
  for (const bp of regString.replace("(", "").replace(")", "")) {
3457
- let maybeHandleRightCaret = function(justAdded) {
3504
+ let maybeHandleRightCaret = /* @__PURE__ */ __name(function(justAdded) {
3458
3505
  if (hitRightCaret) {
3459
3506
  rightOfCaretHolder += justAdded;
3460
3507
  afterRightCaretHolder = `${rightOfCaretHolder}${afterRightCaretHolder.length ? "|" : ""}${afterRightCaretHolder}`;
3461
3508
  }
3462
- };
3463
- __name(maybeHandleRightCaret, "maybeHandleRightCaret");
3509
+ }, "maybeHandleRightCaret");
3464
3510
  const ambigVal = ambiguous_dna_values[bp.toUpperCase()];
3465
3511
  if (ambigVal && ambigVal.length > 1) {
3466
3512
  let valToUse;
@@ -3563,7 +3609,7 @@ const genbankFeatureTypes = [
3563
3609
  { name: "regulatory", color: "#3F6C51" },
3564
3610
  { name: "SecStr", color: "#7B4B94" },
3565
3611
  { name: "Site", color: "#7D82B8" },
3566
- { name: "telomere", color: "DE9151" },
3612
+ { name: "telomere", color: "#DE9151" },
3567
3613
  { name: "tmRNA", color: "#B7E3CC" },
3568
3614
  { name: "unsure", color: "#C4FFB2" },
3569
3615
  { name: "V_segment", color: "#D6F7A3" },
@@ -3645,16 +3691,17 @@ const getMergedFeatureMap = /* @__PURE__ */ __name(() => {
3645
3691
  })),
3646
3692
  "name"
3647
3693
  );
3648
- let featureOverrides = typeof window !== "undefined" && get$1(window, "tg_featureTypeOverrides") || typeof global !== "undefined" && get$1(global, "tg_featureTypeOverrides");
3649
- featureOverrides = featureOverrides || [];
3650
- featureOverrides = featureOverrides.map((fo) => {
3694
+ const featureOverrides = typeof window !== "undefined" && get$1(window, "tg_featureTypeOverrides") || typeof global !== "undefined" && get$1(global, "tg_featureTypeOverrides") || [];
3695
+ const mappedOverrides = featureOverrides.map((fo) => {
3651
3696
  const originalGenbankFeat = keyedGBFeats[fo.name];
3652
3697
  return __spreadValues(__spreadValues(__spreadValues({}, originalGenbankFeat), fo), originalGenbankFeat ? { isOverridden: true } : { isCustomType: true });
3653
3698
  });
3654
- featureOverrides = keyBy(featureOverrides, "name");
3655
- return __spreadValues(__spreadValues({}, keyedGBFeats), featureOverrides);
3699
+ const keyedOverrides = keyBy(mappedOverrides, "name");
3700
+ return __spreadValues(__spreadValues({}, keyedGBFeats), keyedOverrides);
3656
3701
  }, "getMergedFeatureMap");
3657
- const getFeatureToColorMap = /* @__PURE__ */ __name(({ includeHidden } = {}) => {
3702
+ const getFeatureToColorMap = /* @__PURE__ */ __name(({
3703
+ includeHidden
3704
+ } = {}) => {
3658
3705
  const toRet = {};
3659
3706
  filter(
3660
3707
  getMergedFeatureMap(),
@@ -3664,7 +3711,9 @@ const getFeatureToColorMap = /* @__PURE__ */ __name(({ includeHidden } = {}) =>
3664
3711
  });
3665
3712
  return toRet;
3666
3713
  }, "getFeatureToColorMap");
3667
- const getFeatureTypes = /* @__PURE__ */ __name(({ includeHidden } = {}) => filter(getMergedFeatureMap(), (f) => includeHidden ? true : !f.isHidden).map(
3714
+ const getFeatureTypes = /* @__PURE__ */ __name(({
3715
+ includeHidden
3716
+ } = {}) => filter(getMergedFeatureMap(), (f) => includeHidden ? true : !f.isHidden).map(
3668
3717
  (f) => f.name
3669
3718
  ), "getFeatureTypes");
3670
3719
  function getDefaultExportFromCjs(x) {
@@ -3969,10 +4018,15 @@ __name(requireShortid, "requireShortid");
3969
4018
  var shortidExports = requireShortid();
3970
4019
  const shortid = /* @__PURE__ */ getDefaultExportFromCjs(shortidExports);
3971
4020
  function cutSequenceByRestrictionEnzyme(pSequence, circular, restrictionEnzyme) {
3972
- if (restrictionEnzyme.forwardRegex.length === 0 || restrictionEnzyme.reverseRegex.length === 0) {
3973
- const returnArray = [];
3974
- returnArray.error = "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long.";
3975
- return returnArray;
4021
+ if (!restrictionEnzyme.forwardRegex || // Add check for undefined
4022
+ !restrictionEnzyme.reverseRegex || // Add check for undefined
4023
+ restrictionEnzyme.forwardRegex.length === 0 || restrictionEnzyme.reverseRegex.length === 0) {
4024
+ console.warn(
4025
+ "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long."
4026
+ );
4027
+ const returnVal = [];
4028
+ returnVal.error = "Cannot cut sequence. Enzyme restriction site must be at least 1 bp long.";
4029
+ return returnVal;
3976
4030
  }
3977
4031
  const forwardRegExpPattern = new RegExp(restrictionEnzyme.forwardRegex, "ig");
3978
4032
  const sequence = pSequence;
@@ -3997,54 +4051,54 @@ function cutSequenceByRestrictionEnzyme(pSequence, circular, restrictionEnzyme)
3997
4051
  }
3998
4052
  return cutsitesForward.concat(cutsitesReverse);
3999
4053
  function reverseAllPositionsOfCutsite(cutsite, rangeLength) {
4054
+ cutsite = assign({}, cutsite);
4000
4055
  cutsite.start = reversePositionInRange(cutsite.start, rangeLength, false);
4001
4056
  cutsite.end = reversePositionInRange(cutsite.end, rangeLength, false);
4002
- cutsite.topSnipPosition = reversePositionInRange(
4003
- cutsite.topSnipPosition,
4004
- rangeLength,
4005
- true
4006
- );
4007
- cutsite.bottomSnipPosition = reversePositionInRange(
4008
- cutsite.bottomSnipPosition,
4009
- rangeLength,
4010
- true
4011
- );
4012
- if (cutsite.cutsTwice) {
4013
- cutsite.upstreamTopSnip = reversePositionInRange(
4014
- cutsite.upstreamTopSnip,
4057
+ cutsite.topSnipPosition = cutsite.topSnipPosition != null ? reversePositionInRange(cutsite.topSnipPosition, rangeLength, true) : null;
4058
+ cutsite.bottomSnipPosition = cutsite.bottomSnipPosition != null ? reversePositionInRange(cutsite.bottomSnipPosition, rangeLength, true) : null;
4059
+ if (cutsite.cutType === 1 && cutsite.cutsTwice) {
4060
+ if (cutsite.upstreamTopSnip != null && cutsite.upstreamBottomSnip != null) {
4061
+ cutsite.upstreamTopSnip = reversePositionInRange(
4062
+ cutsite.upstreamTopSnip,
4063
+ rangeLength,
4064
+ true
4065
+ );
4066
+ cutsite.upstreamBottomSnip = reversePositionInRange(
4067
+ cutsite.upstreamBottomSnip,
4068
+ rangeLength,
4069
+ true
4070
+ );
4071
+ }
4072
+ }
4073
+ if (cutsite.recognitionSiteRange) {
4074
+ cutsite.recognitionSiteRange = __spreadValues({}, cutsite.recognitionSiteRange);
4075
+ cutsite.recognitionSiteRange.start = reversePositionInRange(
4076
+ cutsite.recognitionSiteRange.start,
4015
4077
  rangeLength,
4016
- true
4078
+ false
4017
4079
  );
4018
- cutsite.upstreamBottomSnip = reversePositionInRange(
4019
- cutsite.upstreamBottomSnip,
4080
+ cutsite.recognitionSiteRange.end = reversePositionInRange(
4081
+ cutsite.recognitionSiteRange.end,
4020
4082
  rangeLength,
4021
- true
4083
+ false
4022
4084
  );
4023
4085
  }
4024
- cutsite.recognitionSiteRange.start = reversePositionInRange(
4025
- cutsite.recognitionSiteRange.start,
4026
- rangeLength,
4027
- false
4028
- );
4029
- cutsite.recognitionSiteRange.end = reversePositionInRange(
4030
- cutsite.recognitionSiteRange.end,
4031
- rangeLength,
4032
- false
4033
- );
4034
- return assign({}, cutsite, {
4086
+ return __spreadProps(__spreadValues({}, cutsite), {
4035
4087
  start: cutsite.end,
4036
4088
  end: cutsite.start,
4037
- overhangBps: getReverseComplementSequenceString(cutsite.overhangBps),
4089
+ overhangBps: getReverseComplementSequenceString(
4090
+ cutsite.overhangBps || ""
4091
+ ),
4038
4092
  topSnipPosition: cutsite.bottomSnipPosition,
4039
4093
  bottomSnipPosition: cutsite.topSnipPosition,
4040
4094
  upstreamTopSnip: cutsite.upstreamBottomSnip,
4041
4095
  upstreamBottomSnip: cutsite.upstreamTopSnip,
4042
4096
  upstreamTopBeforeBottom: !!cutsite.upstreamTopBeforeBottom,
4043
4097
  topSnipBeforeBottom: !!cutsite.topSnipBeforeBottom,
4044
- recognitionSiteRange: {
4098
+ recognitionSiteRange: cutsite.recognitionSiteRange ? {
4045
4099
  start: cutsite.recognitionSiteRange.end,
4046
4100
  end: cutsite.recognitionSiteRange.start
4047
- },
4101
+ } : void 0,
4048
4102
  forward: false
4049
4103
  });
4050
4104
  }
@@ -4056,7 +4110,7 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4056
4110
  let restrictionCutSite;
4057
4111
  const recognitionSiteLength = restrictionEnzyme.site.length;
4058
4112
  const originalSequence = sequence;
4059
- const originalSequenceLength = sequence.length;
4113
+ const originalSequenceLengthVal = sequence.length;
4060
4114
  if (circular) {
4061
4115
  sequence += sequence;
4062
4116
  }
@@ -4065,7 +4119,10 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4065
4119
  let startIndex = 0;
4066
4120
  let subSequence = sequence;
4067
4121
  while (matchIndex !== -1) {
4068
- const recognitionSiteRange = {};
4122
+ const recognitionSiteRange = {
4123
+ start: 0,
4124
+ end: 0
4125
+ };
4069
4126
  let start;
4070
4127
  let end;
4071
4128
  let upstreamTopSnip = null;
@@ -4080,37 +4137,39 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4080
4137
  recognitionSiteRange.end = matchIndex + recognitionSiteLength - 1 + startIndex;
4081
4138
  end = recognitionSiteRange.end;
4082
4139
  if (restrictionEnzyme.cutType === 1) {
4083
- upstreamTopSnip = recognitionSiteRange.end - restrictionEnzyme.usForward;
4084
- upstreamBottomSnip = recognitionSiteRange.end - restrictionEnzyme.usReverse;
4085
- if (upstreamTopSnip >= 0 && upstreamBottomSnip >= 0) {
4086
- fitsWithinSequence = true;
4087
- if (upstreamTopSnip < upstreamBottomSnip) {
4088
- if (start > upstreamTopSnip) {
4089
- start = upstreamTopSnip + 1;
4140
+ if (restrictionEnzyme.usForward != null && restrictionEnzyme.usReverse != null) {
4141
+ upstreamTopSnip = recognitionSiteRange.end - restrictionEnzyme.usForward;
4142
+ upstreamBottomSnip = recognitionSiteRange.end - restrictionEnzyme.usReverse;
4143
+ if (upstreamTopSnip >= 0 && upstreamBottomSnip >= 0) {
4144
+ fitsWithinSequence = true;
4145
+ if (upstreamTopSnip < upstreamBottomSnip) {
4146
+ if (start > upstreamTopSnip) {
4147
+ start = upstreamTopSnip + 1;
4148
+ }
4149
+ upstreamTopBeforeBottom = true;
4150
+ } else {
4151
+ if (start > upstreamBottomSnip) {
4152
+ start = upstreamBottomSnip + 1;
4153
+ }
4090
4154
  }
4091
- upstreamTopBeforeBottom = true;
4155
+ upstreamTopSnip = normalizePositionByRangeLength(
4156
+ upstreamTopSnip,
4157
+ originalSequenceLengthVal,
4158
+ true
4159
+ );
4160
+ upstreamBottomSnip = normalizePositionByRangeLength(
4161
+ upstreamBottomSnip,
4162
+ originalSequenceLengthVal,
4163
+ true
4164
+ );
4092
4165
  } else {
4093
- if (start > upstreamBottomSnip) {
4094
- start = upstreamBottomSnip + 1;
4095
- }
4166
+ upstreamTopSnip = null;
4167
+ upstreamBottomSnip = null;
4096
4168
  }
4097
- upstreamTopSnip = normalizePositionByRangeLength(
4098
- upstreamTopSnip,
4099
- originalSequenceLength,
4100
- true
4101
- );
4102
- upstreamBottomSnip = normalizePositionByRangeLength(
4103
- upstreamBottomSnip,
4104
- originalSequenceLength,
4105
- true
4106
- );
4107
- } else {
4108
- upstreamTopSnip = null;
4109
- upstreamBottomSnip = null;
4110
4169
  }
4111
4170
  }
4112
- topSnipPosition = recognitionSiteRange.start + restrictionEnzyme.topSnipOffset;
4113
- bottomSnipPosition = recognitionSiteRange.start + restrictionEnzyme.bottomSnipOffset;
4171
+ topSnipPosition = recognitionSiteRange.start + (restrictionEnzyme.topSnipOffset || 0);
4172
+ bottomSnipPosition = recognitionSiteRange.start + (restrictionEnzyme.bottomSnipOffset || 0);
4114
4173
  if (bottomSnipPosition <= currentSequenceLength && topSnipPosition <= currentSequenceLength) {
4115
4174
  fitsWithinSequence = true;
4116
4175
  if (topSnipPosition > bottomSnipPosition) {
@@ -4125,61 +4184,70 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4125
4184
  }
4126
4185
  topSnipPosition = normalizePositionByRangeLength(
4127
4186
  topSnipPosition,
4128
- originalSequenceLength,
4187
+ originalSequenceLengthVal,
4129
4188
  true
4130
4189
  );
4131
4190
  bottomSnipPosition = normalizePositionByRangeLength(
4132
4191
  bottomSnipPosition,
4133
- originalSequenceLength,
4192
+ originalSequenceLengthVal,
4134
4193
  true
4135
4194
  );
4136
4195
  } else {
4137
4196
  topSnipPosition = null;
4138
4197
  bottomSnipPosition = null;
4139
4198
  }
4140
- if (fitsWithinSequence && start >= 0 && end >= 0 && start < originalSequenceLength && end < currentSequenceLength) {
4199
+ if (fitsWithinSequence && start >= 0 && end >= 0 && start < originalSequenceLengthVal && end < currentSequenceLength) {
4141
4200
  start = normalizePositionByRangeLength(
4142
4201
  start,
4143
- originalSequenceLength,
4202
+ originalSequenceLengthVal,
4203
+ false
4204
+ );
4205
+ end = normalizePositionByRangeLength(
4206
+ end,
4207
+ originalSequenceLengthVal,
4144
4208
  false
4145
4209
  );
4146
- end = normalizePositionByRangeLength(end, originalSequenceLength, false);
4147
4210
  recognitionSiteRange.start = normalizePositionByRangeLength(
4148
4211
  recognitionSiteRange.start,
4149
- originalSequenceLength,
4212
+ originalSequenceLengthVal,
4150
4213
  false
4151
4214
  );
4152
4215
  recognitionSiteRange.end = normalizePositionByRangeLength(
4153
4216
  recognitionSiteRange.end,
4154
- originalSequenceLength,
4217
+ originalSequenceLengthVal,
4155
4218
  false
4156
4219
  );
4157
4220
  let cutRange = {
4158
4221
  start: -1,
4159
4222
  end: -1
4160
4223
  };
4161
- if (topSnipPosition !== bottomSnipPosition) {
4224
+ if (topSnipPosition !== null && bottomSnipPosition !== null && topSnipPosition !== bottomSnipPosition) {
4162
4225
  cutRange = topSnipBeforeBottom ? {
4163
4226
  start: topSnipPosition,
4164
4227
  end: normalizePositionByRangeLength(
4165
4228
  bottomSnipPosition - 1,
4166
- originalSequenceLength
4229
+ originalSequenceLengthVal
4167
4230
  )
4168
4231
  } : {
4169
4232
  start: bottomSnipPosition,
4170
4233
  end: normalizePositionByRangeLength(
4171
4234
  topSnipPosition - 1,
4172
- originalSequenceLength
4235
+ originalSequenceLengthVal
4173
4236
  )
4174
4237
  };
4175
4238
  }
4176
- const overhangBps = getSequenceWithinRange(cutRange, originalSequence);
4239
+ const overhangBps = getSequenceWithinRange(
4240
+ cutRange,
4241
+ originalSequence
4242
+ );
4177
4243
  restrictionCutSite = {
4178
4244
  id: shortid(),
4179
4245
  start,
4180
4246
  end,
4181
4247
  topSnipPosition,
4248
+ // Allow null
4182
4249
  bottomSnipPosition,
4250
+ // Allow null
4183
4251
  topSnipBeforeBottom,
4184
4252
  overhangBps,
4185
4253
  overhangSize: overhangBps.length,
@@ -4201,16 +4269,19 @@ function cutSequence(forwardRegExpPattern, restrictionEnzyme, sequence, circular
4201
4269
  return restrictionCutSites;
4202
4270
  }
4203
4271
  __name(cutSequence, "cutSequence");
4204
- function getCutsitesFromSequence(sequence, circular, restrictionEnzymes) {
4205
- const cutsitesByName = {};
4206
- for (let i = 0; i < restrictionEnzymes.length; i++) {
4207
- const re = restrictionEnzymes[i];
4208
- const cutsites = cutSequenceByRestrictionEnzyme(sequence, circular, re);
4209
- if (cutsites.length) {
4210
- cutsitesByName[re.name] = cutsites;
4272
+ function getCutsitesFromSequence(sequence, circular, contextEnzymes) {
4273
+ const cutsites = flatMap(contextEnzymes, (enzyme) => {
4274
+ return cutSequenceByRestrictionEnzyme(sequence, circular, enzyme);
4275
+ });
4276
+ const cutsitesByNameMap = {};
4277
+ cutsites.forEach((cutsite) => {
4278
+ const name = cutsite.name || "";
4279
+ if (!cutsitesByNameMap[name]) {
4280
+ cutsitesByNameMap[name] = [];
4211
4281
  }
4212
- }
4213
- return cutsitesByName;
4282
+ cutsitesByNameMap[name].push(cutsite);
4283
+ });
4284
+ return cutsitesByNameMap;
4214
4285
  }
4215
4286
  __name(getCutsitesFromSequence, "getCutsitesFromSequence");
4216
4287
  function computeDigestFragments({
@@ -4228,9 +4299,9 @@ function computeDigestFragments({
4228
4299
  const fragments = [];
4229
4300
  const overlappingEnzymes = [];
4230
4301
  const pairs = [];
4231
- const sortedCutsites = cutsites.sort((a, b) => {
4232
- return a.topSnipPosition - b.topSnipPosition;
4233
- });
4302
+ const sortedCutsites = cutsites.filter(
4303
+ (c) => c.topSnipPosition != null && c.bottomSnipPosition != null
4304
+ );
4234
4305
  if (!circular && cutsites.length) {
4235
4306
  sortedCutsites.push({
4236
4307
  id: "seqTerm_" + shortid(),
@@ -4239,6 +4310,8 @@ function computeDigestFragments({
4239
4310
  overhangBps: "",
4240
4311
  topSnipPosition: 0,
4241
4312
  bottomSnipPosition: 0,
4313
+ overhangSize: 0,
4314
+ // Added to satisfy CutSite
4242
4315
  upstreamTopSnip: 0,
4243
4316
  upstreamBottomSnip: 0,
4244
4317
  upstreamTopBeforeBottom: false,
@@ -4249,26 +4322,34 @@ function computeDigestFragments({
4249
4322
  },
4250
4323
  forward: true,
4251
4324
  name: "Sequence_Terminus",
4325
+ type: "START_OR_END_OF_SEQ",
4252
4326
  restrictionEnzyme: {
4253
- name: "Sequence_Terminus"
4327
+ name: "Sequence_Terminus",
4328
+ site: "",
4329
+ forwardRegex: "",
4330
+ reverseRegex: ""
4254
4331
  }
4255
4332
  });
4256
4333
  }
4334
+ sortedCutsites.sort((a, b) => {
4335
+ return a.topSnipPosition - b.topSnipPosition;
4336
+ });
4257
4337
  sortedCutsites.forEach((cutsite1, index) => {
4338
+ if (!computeDigestDisabled) {
4339
+ pairs.push([
4340
+ cutsite1,
4341
+ sortedCutsites[index + 1] ? sortedCutsites[index + 1] : sortedCutsites[0]
4342
+ ]);
4343
+ }
4258
4344
  if (computePartialDigest && !computePartialDigestDisabled) {
4259
4345
  sortedCutsites.forEach((cs, index2) => {
4260
- if (index2 === index + 1 || index2 === 0) {
4346
+ const isAdjacent = index2 === index + 1 || index === sortedCutsites.length - 1 && index2 === 0;
4347
+ if (isAdjacent) {
4261
4348
  return;
4262
4349
  }
4263
4350
  pairs.push([cutsite1, sortedCutsites[index2]]);
4264
4351
  });
4265
4352
  }
4266
- if (!computeDigestDisabled) {
4267
- pairs.push([
4268
- cutsite1,
4269
- sortedCutsites[index + 1] ? sortedCutsites[index + 1] : sortedCutsites[0]
4270
- ]);
4271
- }
4272
4353
  });
4273
4354
  pairs.forEach((r) => {
4274
4355
  let [cut1, cut2] = r;
@@ -4313,12 +4394,17 @@ function computeDigestFragments({
4313
4394
  cut2.name = "Linear_Sequence_End";
4314
4395
  cut2.restrictionEnzyme.name = "Linear_Sequence_End";
4315
4396
  }
4397
+ cut1 = __spreadProps(__spreadValues({}, cut1), {
4398
+ isOverhangIncludedInFragmentSize: cut1.name !== "Linear_Sequence_Start" && cut1.name !== "Sequence_Terminus" && (cut1.overhangSize || 0) > 0 && !!cut1.topSnipBeforeBottom
4399
+ });
4400
+ cut2 = __spreadProps(__spreadValues({}, cut2), {
4401
+ isOverhangIncludedInFragmentSize: cut2.name !== "Linear_Sequence_End" && cut2.name !== "Sequence_Terminus" && (cut2.overhangSize || 0) > 0 && !cut2.topSnipBeforeBottom
4402
+ });
4316
4403
  const id = start + "-" + end + "-" + size + "-";
4317
4404
  const name = `${cut1.restrictionEnzyme.name} -- ${cut2.restrictionEnzyme.name} ${size} bps`;
4318
- getRangeLength({ start, end }, sequenceLength);
4319
4405
  fragments.push({
4320
4406
  isFormedFromLinearEnd,
4321
- madeFromOneCutsite: cut1 === cut2,
4407
+ madeFromOneCutsite: cut1.id === cut2.id,
4322
4408
  start,
4323
4409
  end,
4324
4410
  size,
@@ -4359,12 +4445,14 @@ function getDigestFragsForSeqAndEnzymes({
4359
4445
  includeOverAndUnderHangs
4360
4446
  }) {
4361
4447
  const cutsitesByName = getCutsitesFromSequence(sequence, circular, enzymes);
4362
- return computeDigestFragments({
4448
+ const digest = computeDigestFragments({
4363
4449
  includeOverAndUnderHangs,
4364
4450
  cutsites: flatMap(cutsitesByName),
4365
4451
  sequenceLength: sequence.length,
4366
4452
  circular
4367
4453
  });
4454
+ digest.fragments.sort((a, b) => b.size - a.size);
4455
+ return digest;
4368
4456
  }
4369
4457
  __name(getDigestFragsForSeqAndEnzymes, "getDigestFragsForSeqAndEnzymes");
4370
4458
  function cloneRegExp(re) {
@@ -5933,7 +6021,8 @@ function expandAndResolve(threeLetterCodon) {
5933
6021
  let allPossibleThreeLetterCodons = [""];
5934
6022
  for (const set of picks) {
5935
6023
  const next = [];
5936
- for (const prefix of allPossibleThreeLetterCodons) for (const b of set) next.push(prefix + b);
6024
+ for (const prefix of allPossibleThreeLetterCodons)
6025
+ for (const b of set) next.push(prefix + b);
5937
6026
  allPossibleThreeLetterCodons = next;
5938
6027
  }
5939
6028
  let foundAminoAcid = null;
@@ -5979,10 +6068,13 @@ function getAminoAcidFromSequenceTriplet(sequenceString) {
5979
6068
  if (aa) {
5980
6069
  return aa;
5981
6070
  }
5982
- const letter = degenerateDnaToAminoAcidMap[
5983
- sequenceString.replace("x", "n")
5984
- //replace x's with n's as those are equivalent dna chars
5985
- ] || "x";
6071
+ const letter = (
6072
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6073
+ degenerateDnaToAminoAcidMap[
6074
+ sequenceString.replace("x", "n")
6075
+ //replace x's with n's as those are equivalent dna chars
6076
+ ] || "x"
6077
+ );
5986
6078
  return proteinAlphabet[letter.toUpperCase()];
5987
6079
  }
5988
6080
  __name(getAminoAcidFromSequenceTriplet, "getAminoAcidFromSequenceTriplet");
@@ -6379,25 +6471,25 @@ function coerceLocation({
6379
6471
  circular,
6380
6472
  name
6381
6473
  }) {
6382
- location.start = parseInt(location.start, 10);
6383
- location.end = parseInt(location.end, 10);
6474
+ location.start = parseInt(String(location.start), 10);
6475
+ location.end = parseInt(String(location.end), 10);
6384
6476
  if (convertAnnotationsFromAAIndices) {
6385
6477
  location.start = location.start * 3;
6386
6478
  location.end = location.end * 3 + 2;
6387
6479
  }
6388
- if (location.start < 0 || !(location.start <= size - 1) || location.start > size - 1) {
6480
+ if (size !== void 0 && (location.start < 0 || location.start > size - 1)) {
6389
6481
  messages.push(
6390
6482
  "Invalid annotation start: " + location.start + " detected for " + location.name + " and set to size: " + size
6391
6483
  );
6392
6484
  location.start = Math.max(0, size - (isProtein ? 3 : 1));
6393
6485
  }
6394
- if (location.end < 0 || !(location.end <= size - 1) || location.end > size - 1) {
6486
+ if (size !== void 0 && (location.end < 0 || location.end > size - 1)) {
6395
6487
  messages.push(
6396
6488
  "Invalid annotation end: " + location.end + " detected for " + location.name + " and set to seq size: " + size
6397
6489
  );
6398
6490
  location.end = Math.max(0, size - 1);
6399
6491
  }
6400
- if (location.start > location.end && circular === false) {
6492
+ if (size !== void 0 && location.start > location.end && circular === false) {
6401
6493
  messages.push(
6402
6494
  "Invalid circular annotation detected for " + name + ". end set to 1"
6403
6495
  );
@@ -6406,21 +6498,30 @@ function coerceLocation({
6406
6498
  }
6407
6499
  __name(coerceLocation, "coerceLocation");
6408
6500
  function getDegenerateDnaStringFromAAString(aaString) {
6409
- return aaString.split("").map((char) => aminoAcidToDegenerateDnaMap[char.toLowerCase()] || "nnn").join("");
6501
+ return aaString.split("").map(
6502
+ (char) => aminoAcidToDegenerateDnaMap[char.toLowerCase()] || "nnn"
6503
+ ).join("");
6410
6504
  }
6411
6505
  __name(getDegenerateDnaStringFromAAString, "getDegenerateDnaStringFromAAString");
6412
- function getAminoAcidStringFromSequenceString(sequenceString, { doNotExcludeAsterisk } = {}) {
6506
+ function getAminoAcidStringFromSequenceString(sequenceString, options = {}) {
6507
+ const { doNotExcludeAsterisk } = options;
6413
6508
  const aminoAcidsPerBase = getAminoAcidDataForEachBaseOfDna(
6414
6509
  sequenceString,
6415
- true
6510
+ true,
6511
+ null,
6512
+ false
6416
6513
  );
6417
6514
  const aaArray = [];
6418
6515
  let aaString = "";
6419
6516
  aminoAcidsPerBase.forEach((aa, index) => {
6517
+ var _a;
6420
6518
  if (!aa.fullCodon) {
6421
6519
  return;
6422
6520
  }
6423
- if (!doNotExcludeAsterisk && index >= aminoAcidsPerBase.length - 3 && aa.aminoAcid.value === "*") {
6521
+ if (!doNotExcludeAsterisk && index >= aminoAcidsPerBase.length - 3 && ((_a = aa.aminoAcid) == null ? void 0 : _a.value) === "*") {
6522
+ return;
6523
+ }
6524
+ if (aa.aminoAcidIndex === null || !aa.aminoAcid) {
6424
6525
  return;
6425
6526
  }
6426
6527
  aaArray[aa.aminoAcidIndex] = aa.aminoAcid.value;
@@ -6447,7 +6548,7 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6447
6548
  messages: []
6448
6549
  };
6449
6550
  if (!seqData) {
6450
- seqData = {};
6551
+ seqData = { sequence: "" };
6451
6552
  }
6452
6553
  if (!seqData.sequence) {
6453
6554
  seqData.sequence = "";
@@ -6510,25 +6611,27 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6510
6611
  const featureTypes = getFeatureTypes();
6511
6612
  annotationTypes.forEach((annotationType) => {
6512
6613
  if (!Array.isArray(seqData[annotationType])) {
6513
- if (typeof seqData[annotationType] === "object") {
6514
- seqData[annotationType] = Object.keys(seqData[annotationType]).map(
6515
- (key) => {
6516
- return seqData[annotationType][key];
6517
- }
6518
- );
6614
+ if (seqData[annotationType] && typeof seqData[annotationType] === "object") {
6615
+ seqData[annotationType] = Object.keys(
6616
+ seqData[annotationType]
6617
+ ).map((key) => {
6618
+ return seqData[annotationType][key];
6619
+ });
6519
6620
  } else {
6520
6621
  seqData[annotationType] = [];
6521
6622
  }
6522
6623
  }
6523
- seqData[annotationType] = seqData[annotationType].filter((annotation) => {
6524
- return tidyUpAnnotation(annotation, __spreadProps(__spreadValues({}, options), {
6525
- featureTypes,
6526
- sequenceData: seqData,
6527
- convertAnnotationsFromAAIndices,
6528
- mutative: true,
6529
- annotationType
6530
- }));
6531
- });
6624
+ seqData[annotationType] = seqData[annotationType].filter(
6625
+ (annotation) => {
6626
+ return tidyUpAnnotation(annotation, __spreadProps(__spreadValues({}, options), {
6627
+ featureTypes,
6628
+ sequenceData: seqData,
6629
+ convertAnnotationsFromAAIndices,
6630
+ mutative: true,
6631
+ annotationType
6632
+ }));
6633
+ }
6634
+ );
6532
6635
  });
6533
6636
  if (!noTranslationData) {
6534
6637
  seqData.translations = flatMap(seqData.translations, (translation) => {
@@ -6536,7 +6639,7 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6536
6639
  if (noCdsTranslations && translation.translationType === "CDS Feature") {
6537
6640
  return [];
6538
6641
  }
6539
- const codonStart = ((_b = (_a = translation == null ? void 0 : translation.notes) == null ? void 0 : _a.codon_start) == null ? void 0 : _b[0]) - 1 || 0;
6642
+ const codonStart = ((_b = (_a = translation == null ? void 0 : translation.notes) == null ? void 0 : _a["codon_start"]) == null ? void 0 : _b[0]) - 1 || 0;
6540
6643
  const expandedRange = expandOrContractRangeByLength(
6541
6644
  translation,
6542
6645
  -codonStart,
@@ -6546,8 +6649,9 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6546
6649
  if (!expandedRange.aminoAcids && !seqData.noSequence) {
6547
6650
  expandedRange.aminoAcids = getAminoAcidDataForEachBaseOfDna(
6548
6651
  seqData.sequence,
6549
- expandedRange.forward,
6550
- expandedRange
6652
+ expandedRange.forward || false,
6653
+ expandedRange,
6654
+ false
6551
6655
  );
6552
6656
  }
6553
6657
  return expandedRange;
@@ -6555,19 +6659,22 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6555
6659
  }
6556
6660
  if (annotationsAsObjects) {
6557
6661
  annotationTypes.forEach((name) => {
6558
- seqData[name] = seqData[name].reduce((acc, item) => {
6559
- let itemId;
6560
- if (item.id || item.id === 0) {
6561
- itemId = item.id;
6562
- } else {
6563
- itemId = shortid();
6564
- if (!doNotProvideIdsForAnnotations) {
6565
- item.id = itemId;
6662
+ seqData[name] = seqData[name].reduce(
6663
+ (acc, item) => {
6664
+ let itemId;
6665
+ if (item.id || item.id === 0) {
6666
+ itemId = item.id;
6667
+ } else {
6668
+ itemId = shortid();
6669
+ if (!doNotProvideIdsForAnnotations) {
6670
+ item.id = itemId;
6671
+ }
6566
6672
  }
6567
- }
6568
- acc[itemId] = item;
6569
- return acc;
6570
- }, {});
6673
+ acc[itemId] = item;
6674
+ return acc;
6675
+ },
6676
+ {}
6677
+ );
6571
6678
  });
6572
6679
  }
6573
6680
  if (logMessages && response.messages.length > 0) {
@@ -6577,17 +6684,17 @@ function tidyUpSequenceData(pSeqData, options = {}) {
6577
6684
  }
6578
6685
  __name(tidyUpSequenceData, "tidyUpSequenceData");
6579
6686
  const getDiffFromSeqs = /* @__PURE__ */ __name((oldData, newData, { ignoreKeys = [] } = {}) => {
6580
- oldData = tidyUpSequenceData(oldData, {
6687
+ const cleanedOldData = tidyUpSequenceData(oldData, {
6581
6688
  annotationsAsObjects: true,
6582
6689
  noTranslationData: true,
6583
6690
  doNotRemoveInvalidChars: true
6584
6691
  });
6585
- newData = tidyUpSequenceData(newData, {
6692
+ const cleanedNewData = tidyUpSequenceData(newData, {
6586
6693
  annotationsAsObjects: true,
6587
6694
  noTranslationData: true,
6588
6695
  doNotRemoveInvalidChars: true
6589
6696
  });
6590
- [oldData, newData].forEach((d) => {
6697
+ [cleanedOldData, cleanedNewData].forEach((d) => {
6591
6698
  [
6592
6699
  "cutsites",
6593
6700
  "orfs",
@@ -6610,27 +6717,26 @@ const getDiffFromSeqs = /* @__PURE__ */ __name((oldData, newData, { ignoreKeys =
6610
6717
  });
6611
6718
  }
6612
6719
  });
6613
- return diff(oldData, newData);
6720
+ return diff(cleanedOldData, cleanedNewData);
6614
6721
  }, "getDiffFromSeqs");
6615
- const patchSeqWithDiff = /* @__PURE__ */ __name((oldData, diff2, { ignoreKeys = [] } = {}) => {
6722
+ const patchSeqWithDiff = /* @__PURE__ */ __name((oldData, diffData, { ignoreKeys = [] } = {}) => {
6616
6723
  ignoreKeys.forEach((k) => {
6617
- delete diff2[k];
6724
+ delete diffData[k];
6618
6725
  });
6619
- return patch(
6620
- tidyUpSequenceData(cloneDeep(oldData), {
6621
- annotationsAsObjects: true,
6622
- doNotRemoveInvalidChars: true
6623
- }),
6624
- diff2
6625
- );
6726
+ const tidyOld = tidyUpSequenceData(cloneDeep(oldData), {
6727
+ annotationsAsObjects: true,
6728
+ doNotRemoveInvalidChars: true
6729
+ });
6730
+ return patch(tidyOld, diffData);
6626
6731
  }, "patchSeqWithDiff");
6627
- const reverseSeqDiff = /* @__PURE__ */ __name((diff2) => {
6628
- return reverse(diff2);
6732
+ const reverseSeqDiff = /* @__PURE__ */ __name((diffData) => {
6733
+ return reverse(diffData);
6629
6734
  }, "reverseSeqDiff");
6630
6735
  function getAllInsertionsInSeqReads(seqReads) {
6631
6736
  const allInsertionsInSeqReads = [];
6632
6737
  seqReads.forEach((seqRead) => {
6633
6738
  const splitSeqRead = seqRead.cigar.match(/([0-9]*[MDI])/g);
6739
+ if (!splitSeqRead) return;
6634
6740
  for (let componentI = 0; componentI < splitSeqRead.length; componentI++) {
6635
6741
  if (splitSeqRead[componentI].slice(-1) === "I") {
6636
6742
  let bpPosOfInsertion = seqRead.pos;
@@ -6674,14 +6780,19 @@ function getAllInsertionsInSeqReads(seqReads) {
6674
6780
  return sortedInsertions;
6675
6781
  }
6676
6782
  __name(getAllInsertionsInSeqReads, "getAllInsertionsInSeqReads");
6677
- function annotateSingleSeq({ fullSeq, searchSeq }) {
6783
+ function annotateSingleSeq({
6784
+ fullSeq,
6785
+ searchSeq
6786
+ }) {
6678
6787
  const fullSeqId = fullSeq.id || "fullSeqId";
6679
6788
  const searchSeqId = searchSeq.id || "searchSeqId";
6680
6789
  const results = autoAnnotate({
6681
6790
  seqsToAnnotateById: {
6682
- [fullSeqId]: __spreadProps(__spreadValues({}, fullSeq), {
6683
- id: fullSeqId
6684
- })
6791
+ [fullSeqId]: {
6792
+ sequence: fullSeq.sequence,
6793
+ circular: fullSeq.circular,
6794
+ annotations: fullSeq.features || []
6795
+ }
6685
6796
  },
6686
6797
  annotationsToCheckById: {
6687
6798
  [searchSeqId]: __spreadProps(__spreadValues({}, searchSeq), {
@@ -6731,7 +6842,9 @@ const aminoAcidToDegenerateRnaMap = {
6731
6842
  z: "sar"
6732
6843
  };
6733
6844
  function getDegenerateRnaStringFromAAString(aaString) {
6734
- return aaString.split("").map((char) => aminoAcidToDegenerateRnaMap[char.toLowerCase()] || "nnn").join("");
6845
+ return aaString.split("").map(
6846
+ (char) => aminoAcidToDegenerateRnaMap[char.toLowerCase()] || "nnn"
6847
+ ).join("");
6735
6848
  }
6736
6849
  __name(getDegenerateRnaStringFromAAString, "getDegenerateRnaStringFromAAString");
6737
6850
  function getVirtualDigest({
@@ -6746,7 +6859,7 @@ function getVirtualDigest({
6746
6859
  const overlappingEnzymes = [];
6747
6860
  const pairs = [];
6748
6861
  const sortedCutsites = cutsites.sort((a, b) => {
6749
- return a.topSnipPosition - b.topSnipPosition;
6862
+ return (a.topSnipPosition || 0) - (b.topSnipPosition || 0);
6750
6863
  });
6751
6864
  sortedCutsites.forEach((cutsite1, index) => {
6752
6865
  if (computePartialDigest && !computePartialDigestDisabled) {
@@ -6763,11 +6876,11 @@ function getVirtualDigest({
6763
6876
  });
6764
6877
  pairs.forEach(([cut1, cut2]) => {
6765
6878
  const start = normalizePositionByRangeLength(
6766
- cut1.topSnipPosition,
6879
+ cut1.topSnipPosition || 0,
6767
6880
  sequenceLength
6768
6881
  );
6769
6882
  const end = normalizePositionByRangeLength(
6770
- cut2.topSnipPosition - 1,
6883
+ (cut2.topSnipPosition || 0) - 1,
6771
6884
  sequenceLength
6772
6885
  );
6773
6886
  if (!isCircular && start > end) {
@@ -6781,6 +6894,7 @@ function getVirtualDigest({
6781
6894
  name: "End Of Seq"
6782
6895
  }
6783
6896
  }
6897
+ // Cast to CutSite as it's a mock
6784
6898
  };
6785
6899
  const frag2 = {
6786
6900
  start: 0,
@@ -6791,6 +6905,7 @@ function getVirtualDigest({
6791
6905
  name: "Start Of Seq"
6792
6906
  }
6793
6907
  },
6908
+ // Cast
6794
6909
  cut2
6795
6910
  };
6796
6911
  fragments.push(addSizeIdName(frag1, sequenceLength));
@@ -6893,27 +7008,18 @@ function findApproxMatches(searchSeq, targetSeq, maxMismatches, circular = false
6893
7008
  return matches;
6894
7009
  }
6895
7010
  __name(findApproxMatches, "findApproxMatches");
6896
- var spliceString$1;
6897
- var hasRequiredSpliceString;
6898
- function requireSpliceString() {
6899
- if (hasRequiredSpliceString) return spliceString$1;
6900
- hasRequiredSpliceString = 1;
6901
- spliceString$1 = /* @__PURE__ */ __name(function spliceSlice(str, index, count, add) {
6902
- return str.slice(0, index) + (add || "") + str.slice(index + count);
6903
- }, "spliceSlice");
6904
- return spliceString$1;
6905
- }
6906
- __name(requireSpliceString, "requireSpliceString");
6907
- var spliceStringExports = requireSpliceString();
6908
- const spliceString = /* @__PURE__ */ getDefaultExportFromCjs(spliceStringExports);
6909
7011
  function adjustBpsToReplaceOrInsert(bpString, insertString = "", caretPositionOrRange) {
6910
7012
  let stringToReturn = bpString;
6911
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7013
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange && caretPositionOrRange.start > -1) {
6912
7014
  if (getRangeLength(caretPositionOrRange, bpString.length) === bpString.length) {
6913
7015
  return insertString;
6914
7016
  }
6915
7017
  const ranges = splitRangeIntoTwoPartsIfItIsCircular(
6916
- invertRange(caretPositionOrRange, bpString.length)
7018
+ invertRange(
7019
+ caretPositionOrRange,
7020
+ bpString.length
7021
+ ),
7022
+ bpString.length
6917
7023
  );
6918
7024
  stringToReturn = "";
6919
7025
  ranges.forEach((range, index) => {
@@ -6939,6 +7045,16 @@ function adjustBpsToReplaceOrInsert(bpString, insertString = "", caretPositionOr
6939
7045
  return stringToReturn;
6940
7046
  }
6941
7047
  __name(adjustBpsToReplaceOrInsert, "adjustBpsToReplaceOrInsert");
7048
+ const spliceString = /* @__PURE__ */ __name((str, index, count, add) => {
7049
+ let i = index;
7050
+ if (i < 0) {
7051
+ i = str.length + i;
7052
+ if (i < 0) {
7053
+ i = 0;
7054
+ }
7055
+ }
7056
+ return str.slice(0, i) + (add || "") + str.slice(i + count);
7057
+ }, "spliceString");
6942
7058
  function calculatePercentGC(bps) {
6943
7059
  return (bps.match(/[cg]/gi) || []).length / bps.length * 100 || 0;
6944
7060
  }
@@ -6964,11 +7080,17 @@ const calcTmMethods = {
6964
7080
  * monovalentCationConc - THe monovalent salt concentration. Defaults to 50e-3M.
6965
7081
  * return - Temperature for the given sequence, in Celsius.
6966
7082
  */
6967
- calculateTemperature: /* @__PURE__ */ __name(function(_sequence, { type, A, R, primerConc, monovalentCationConc } = {}) {
7083
+ calculateTemperature: /* @__PURE__ */ __name(function(_sequence, {
7084
+ type,
7085
+ A,
7086
+ R,
7087
+ primerConc,
7088
+ monovalentCationConc
7089
+ } = {}) {
6968
7090
  const sequence = (_sequence || "").toLowerCase();
6969
7091
  if (typeof type === "undefined") {
6970
7092
  type = this.TABLE_BRESLAUER;
6971
- } else if (type != this.TABLE_BRESLAUER && type != this.TABLE_UNIFIED && type != this.TABLE_SUGIMOTO) {
7093
+ } else if (type !== this.TABLE_BRESLAUER && type !== this.TABLE_UNIFIED && type !== this.TABLE_SUGIMOTO) {
6972
7094
  throw new Error("Invalid table type!");
6973
7095
  }
6974
7096
  if (!A) {
@@ -6984,11 +7106,14 @@ const calcTmMethods = {
6984
7106
  monovalentCationConc = this.monovalentCationConc;
6985
7107
  }
6986
7108
  const sequenceLength = sequence.length;
6987
- if (sequenceLength == 0) {
7109
+ if (sequenceLength === 0) {
6988
7110
  return 0;
6989
7111
  }
6990
7112
  const deltaHTable = this.getDeltaHTable(type);
6991
7113
  const deltaSTable = this.getDeltaSTable(type);
7114
+ if (!deltaHTable || !deltaSTable) {
7115
+ return 0;
7116
+ }
6992
7117
  const neighbors = [];
6993
7118
  neighbors.push(this.calculateReps(sequence, "aa"));
6994
7119
  neighbors.push(this.calculateNumberOfOccurrences(sequence, "at"));
@@ -7022,7 +7147,7 @@ const calcTmMethods = {
7022
7147
  * @return {Number[]} deltaH table for given algorithm.
7023
7148
  */
7024
7149
  getDeltaHTable: /* @__PURE__ */ __name(function(type) {
7025
- if (type == this.TABLE_BRESLAUER) {
7150
+ if (type === this.TABLE_BRESLAUER) {
7026
7151
  return [
7027
7152
  9.1,
7028
7153
  8.6,
@@ -7041,7 +7166,7 @@ const calcTmMethods = {
7041
7166
  6.5,
7042
7167
  11.1
7043
7168
  ];
7044
- } else if (type == this.TABLE_SUGIMOTO) {
7169
+ } else if (type === this.TABLE_SUGIMOTO) {
7045
7170
  return [
7046
7171
  8,
7047
7172
  5.6,
@@ -7060,7 +7185,7 @@ const calcTmMethods = {
7060
7185
  9.4,
7061
7186
  11.9
7062
7187
  ];
7063
- } else if (type == this.TABLE_UNIFIED) {
7188
+ } else if (type === this.TABLE_UNIFIED) {
7064
7189
  return [
7065
7190
  7.9,
7066
7191
  7.2,
@@ -7083,39 +7208,6 @@ const calcTmMethods = {
7083
7208
  return null;
7084
7209
  }
7085
7210
  }, "getDeltaHTable"),
7086
- // "AA/TT": -7.9, 7.9
7087
- // "AT/TA": -7.2, 7.2
7088
- // "AC/TG": -8.4, 8.4
7089
- // "AG/TC": -7.8, 7.8
7090
- // "TT/AA": -7.9, 7.9
7091
- // "TA/AT": -7.2, 7.2
7092
- // "TG/AC": -8.5, 8.2
7093
- // "TC/AG": -8.2, 8.5
7094
- // "CC/GG": -8.0, 8.0
7095
- // "CA/GT": -8.5, 8.5
7096
- // "CT/GA": -7.8, 7.8
7097
- // "CG/GC": -10.6, 10.6
7098
- // "GG/CC": -8.0, 8.0
7099
- // "GA/CT": -8.2, 8.2,
7100
- // "GT/CA": -8.4, 8.4
7101
- // "GC/CG": -9.8, 9.8
7102
- // aa, at, ac, ag, tt, ta, tc, tg, cc, ca, ct, cg, gg, ga, gt, gc
7103
- // "AA/TT": -22.2,22.2,
7104
- // "AT/TA": -20.4,20.4,
7105
- // "AC/TG": -22.4,22.4,
7106
- // "AG/TC": -21.0,21.0,
7107
- // "TT/AA": -22.2,22.2,
7108
- // "TA/AT": -21.3,21.3,
7109
- // "TC/AG": -22.2,22.2,
7110
- // "TG/AC": -22.7,22.7,
7111
- // "CC/GG": -19.9,19.9,
7112
- // "CA/GT": -22.7,22.7,
7113
- // "CT/GA": -21.0,21.0,
7114
- // "CG/GC": -27.2,27.2,
7115
- // "GG/CC": -19.9,19.9,
7116
- // "GT/CA": -22.4,22.2,
7117
- // "GA/CT": -22.2,22.4,
7118
- // "GC/CG": -24.4,24.4
7119
7211
  /**
7120
7212
  * @private
7121
7213
  * Function to return deltaS table for given algorithm.
@@ -7123,7 +7215,7 @@ const calcTmMethods = {
7123
7215
  * @return {Number[]} deltaS table for given algorithm.
7124
7216
  */
7125
7217
  getDeltaSTable: /* @__PURE__ */ __name(function(type) {
7126
- if (type == this.TABLE_BRESLAUER) {
7218
+ if (type === this.TABLE_BRESLAUER) {
7127
7219
  return [
7128
7220
  24,
7129
7221
  23.9,
@@ -7142,7 +7234,7 @@ const calcTmMethods = {
7142
7234
  17.3,
7143
7235
  26.7
7144
7236
  ];
7145
- } else if (type == this.TABLE_SUGIMOTO) {
7237
+ } else if (type === this.TABLE_SUGIMOTO) {
7146
7238
  return [
7147
7239
  21.9,
7148
7240
  15.2,
@@ -7161,7 +7253,7 @@ const calcTmMethods = {
7161
7253
  25.5,
7162
7254
  29
7163
7255
  ];
7164
- } else if (type == this.TABLE_UNIFIED) {
7256
+ } else if (type === this.TABLE_UNIFIED) {
7165
7257
  return [
7166
7258
  22.2,
7167
7259
  20.4,
@@ -7195,14 +7287,14 @@ const calcTmMethods = {
7195
7287
  */
7196
7288
  calculateReps: /* @__PURE__ */ __name(function(sequence, target) {
7197
7289
  const sequenceLength = sequence.length;
7198
- if (sequenceLength == 0) {
7290
+ if (sequenceLength === 0) {
7199
7291
  return 0;
7200
7292
  }
7201
7293
  let numFound = 0;
7202
7294
  let seqOffset = 0;
7203
7295
  while (true) {
7204
7296
  const foundSeq = sequence.indexOf(target, seqOffset);
7205
- if (foundSeq == -1) {
7297
+ if (foundSeq === -1) {
7206
7298
  break;
7207
7299
  }
7208
7300
  seqOffset = foundSeq + 1;
@@ -7222,7 +7314,7 @@ const calcTmMethods = {
7222
7314
  */
7223
7315
  calculateNumberOfOccurrences: /* @__PURE__ */ __name(function(sequence, target) {
7224
7316
  const sequenceLength = sequence.length;
7225
- if (sequenceLength == 0) {
7317
+ if (sequenceLength === 0) {
7226
7318
  return 0;
7227
7319
  }
7228
7320
  const numberFound = sequence.split(target).length - 1;
@@ -7257,11 +7349,11 @@ function rotateBpsToPosition(bps, caretPosition) {
7257
7349
  __name(rotateBpsToPosition, "rotateBpsToPosition");
7258
7350
  function arrayRotate(arr, count) {
7259
7351
  count -= arr.length * Math.floor(count / arr.length);
7260
- arr.push.apply(arr, arr.splice(0, count));
7352
+ arr.push(...arr.splice(0, count));
7261
7353
  return arr;
7262
7354
  }
7263
7355
  __name(arrayRotate, "arrayRotate");
7264
- function rotateSequenceDataToPosition(sequenceData, caretPosition, options) {
7356
+ function rotateSequenceDataToPosition(sequenceData, caretPosition, options = {}) {
7265
7357
  const newSequenceData = tidyUpSequenceData(sequenceData, __spreadValues({
7266
7358
  doNotRemoveInvalidChars: true
7267
7359
  }, options));
@@ -7309,16 +7401,24 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7309
7401
  }, options));
7310
7402
  const newSequenceData = cloneDeep(existingSequenceData);
7311
7403
  const insertLength = sequenceDataToInsert.isProtein && sequenceDataToInsert.proteinSequence ? sequenceDataToInsert.proteinSequence.length * 3 : sequenceDataToInsert.sequence.length;
7312
- let caretPosition = caretPositionOrRange;
7313
- const isInsertSameLengthAsSelection = sequenceDataToInsert.sequence.length === getRangeLength(caretPositionOrRange, existingSequenceData.sequence.length);
7314
- if (caretPositionOrRange.start > -1 && getRangeLength(
7404
+ let caretPosition = typeof caretPositionOrRange === "number" ? caretPositionOrRange : caretPositionOrRange.start;
7405
+ const isInsertSameLengthAsSelection = typeof caretPositionOrRange !== "number" && sequenceDataToInsert.sequence.length === getRangeLength(
7406
+ caretPositionOrRange,
7407
+ existingSequenceData.sequence.length
7408
+ );
7409
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1 && getRangeLength(
7315
7410
  caretPositionOrRange,
7316
7411
  existingSequenceData.sequence.length
7317
7412
  ) === existingSequenceData.sequence.length) {
7413
+ const emptyAnnotations = modifiableTypes.reduce(
7414
+ (acc, type) => {
7415
+ acc[type] = [];
7416
+ return acc;
7417
+ },
7418
+ {}
7419
+ );
7318
7420
  existingSequenceData = tidyUpSequenceData(
7319
- __spreadProps(__spreadValues(__spreadValues({}, existingSequenceData), modifiableTypes.reduce((acc, type) => {
7320
- return acc[type] = [];
7321
- }, {})), {
7421
+ __spreadProps(__spreadValues(__spreadValues({}, existingSequenceData), emptyAnnotations), {
7322
7422
  sequence: "",
7323
7423
  doNotRemoveInvalidChars: true,
7324
7424
  proteinSequence: "",
@@ -7328,7 +7428,7 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7328
7428
  );
7329
7429
  newSequenceData.chromatogramData = void 0;
7330
7430
  } else if (newSequenceData.chromatogramData && newSequenceData.chromatogramData.baseTraces) {
7331
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7431
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1) {
7332
7432
  if (caretPositionOrRange.start > caretPositionOrRange.end) {
7333
7433
  newSequenceData.chromatogramData = trimChromatogram({
7334
7434
  chromatogramData: newSequenceData.chromatogramData,
@@ -7338,14 +7438,16 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7338
7438
  },
7339
7439
  justBaseCalls: isInsertSameLengthAsSelection
7340
7440
  });
7341
- newSequenceData.chromatogramData = trimChromatogram({
7342
- chromatogramData: newSequenceData.chromatogramData,
7343
- range: {
7344
- start: 0,
7345
- end: caretPositionOrRange.end
7346
- },
7347
- justBaseCalls: isInsertSameLengthAsSelection
7348
- });
7441
+ if (newSequenceData.chromatogramData) {
7442
+ newSequenceData.chromatogramData = trimChromatogram({
7443
+ chromatogramData: newSequenceData.chromatogramData,
7444
+ range: {
7445
+ start: 0,
7446
+ end: caretPositionOrRange.end
7447
+ },
7448
+ justBaseCalls: isInsertSameLengthAsSelection
7449
+ });
7450
+ }
7349
7451
  } else {
7350
7452
  newSequenceData.chromatogramData = trimChromatogram({
7351
7453
  chromatogramData: newSequenceData.chromatogramData,
@@ -7357,10 +7459,10 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7357
7459
  });
7358
7460
  }
7359
7461
  }
7360
- if (sequenceDataToInsert.sequence) {
7462
+ if (sequenceDataToInsert.sequence && newSequenceData.chromatogramData) {
7361
7463
  insertIntoChromatogram({
7362
7464
  chromatogramData: newSequenceData.chromatogramData,
7363
- caretPosition: caretPositionOrRange.start > -1 ? caretPositionOrRange.start : caretPositionOrRange,
7465
+ caretPosition: typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1 ? caretPositionOrRange.start : caretPositionOrRange,
7364
7466
  seqToInsert: sequenceDataToInsert.sequence,
7365
7467
  justBaseCalls: isInsertSameLengthAsSelection
7366
7468
  });
@@ -7373,14 +7475,15 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7373
7475
  );
7374
7476
  newSequenceData.size = newSequenceData.sequence.length;
7375
7477
  newSequenceData.proteinSequence = adjustBpsToReplaceOrInsert(
7376
- existingSequenceData.proteinSequence,
7377
- sequenceDataToInsert.proteinSequence,
7478
+ existingSequenceData.proteinSequence || "",
7479
+ sequenceDataToInsert.proteinSequence || "",
7378
7480
  convertDnaCaretPositionOrRangeToAA(caretPositionOrRange)
7379
7481
  );
7380
- newSequenceData.proteinSize = newSequenceData.proteinSequence.length;
7482
+ newSequenceData.proteinSize = (newSequenceData.proteinSequence || "").length;
7381
7483
  modifiableTypes.forEach((annotationType) => {
7382
7484
  let existingAnnotations = existingSequenceData[annotationType];
7383
- if (caretPositionOrRange && caretPositionOrRange.start > -1) {
7485
+ if (!existingAnnotations) return;
7486
+ if (typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > -1) {
7384
7487
  const range = caretPositionOrRange;
7385
7488
  caretPosition = range.start > range.end ? 0 : range.start;
7386
7489
  existingAnnotations = adjustAnnotationsToDelete(
@@ -7390,22 +7493,23 @@ function insertSequenceDataAtPositionOrRange(_sequenceDataToInsert, _existingSeq
7390
7493
  );
7391
7494
  }
7392
7495
  newSequenceData[annotationType] = [];
7393
- newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7394
- adjustAnnotationsToInsert(
7395
- existingAnnotations,
7396
- caretPosition,
7397
- insertLength
7398
- )
7399
- );
7400
- newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7401
- adjustAnnotationsToInsert(
7402
- sequenceDataToInsert[annotationType],
7403
- 0,
7404
- caretPosition
7405
- )
7406
- );
7496
+ const annotationsToInsert = sequenceDataToInsert[annotationType];
7497
+ if (newSequenceData[annotationType]) {
7498
+ newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7499
+ adjustAnnotationsToInsert(
7500
+ existingAnnotations,
7501
+ caretPosition,
7502
+ insertLength
7503
+ )
7504
+ );
7505
+ if (annotationsToInsert) {
7506
+ newSequenceData[annotationType] = newSequenceData[annotationType].concat(
7507
+ adjustAnnotationsToInsert(annotationsToInsert, 0, caretPosition)
7508
+ );
7509
+ }
7510
+ }
7407
7511
  });
7408
- if (maintainOriginSplit && caretPositionOrRange && caretPositionOrRange.start > caretPositionOrRange.end) {
7512
+ if (maintainOriginSplit && typeof caretPositionOrRange !== "number" && caretPositionOrRange.start > caretPositionOrRange.end) {
7409
7513
  const caretPosToRotateTo = existingSequenceData.sequence.length - caretPositionOrRange.start;
7410
7514
  return rotateSequenceDataToPosition(
7411
7515
  newSequenceData,
@@ -7423,6 +7527,7 @@ function adjustAnnotationsToDelete(annotationsToBeAdjusted, range, maxLength) {
7423
7527
  maxLength
7424
7528
  );
7425
7529
  const newLocations = annotation.locations && annotation.locations.map((loc) => adjustRangeToDeletionOfAnotherRange(loc, range, maxLength)).filter((range2) => !!range2);
7530
+ if (!newRange) return null;
7426
7531
  if (newLocations && newLocations.length) {
7427
7532
  return __spreadValues(__spreadProps(__spreadValues({}, newRange), {
7428
7533
  start: newLocations[0].start,
@@ -7441,11 +7546,13 @@ function insertIntoChromatogram({
7441
7546
  justBaseCalls
7442
7547
  }) {
7443
7548
  if (!seqToInsert.length) return;
7444
- chromatogramData.baseCalls && chromatogramData.baseCalls.splice(
7445
- caretPosition,
7446
- 0,
7447
- ...seqToInsert.split("")
7448
- );
7549
+ if (chromatogramData.baseCalls) {
7550
+ chromatogramData.baseCalls.splice(
7551
+ caretPosition,
7552
+ 0,
7553
+ ...seqToInsert.split("")
7554
+ );
7555
+ }
7449
7556
  if (justBaseCalls) {
7450
7557
  return chromatogramData;
7451
7558
  }
@@ -7461,8 +7568,20 @@ function insertIntoChromatogram({
7461
7568
  tTrace: toPush
7462
7569
  });
7463
7570
  }
7464
- chromatogramData.baseTraces && chromatogramData.baseTraces.splice(caretPosition, 0, ...baseTracesToInsert);
7465
- chromatogramData.qualNums && chromatogramData.qualNums.splice(caretPosition, 0, ...qualNumsToInsert);
7571
+ if (chromatogramData.baseTraces) {
7572
+ chromatogramData.baseTraces.splice(
7573
+ caretPosition,
7574
+ 0,
7575
+ ...baseTracesToInsert
7576
+ );
7577
+ }
7578
+ if (chromatogramData.qualNums) {
7579
+ chromatogramData.qualNums.splice(
7580
+ caretPosition,
7581
+ 0,
7582
+ ...qualNumsToInsert
7583
+ );
7584
+ }
7466
7585
  return chromatogramData;
7467
7586
  }
7468
7587
  __name(insertIntoChromatogram, "insertIntoChromatogram");
@@ -7475,17 +7594,23 @@ function trimChromatogram({
7475
7594
  "baseCalls",
7476
7595
  ...justBaseCalls ? [] : ["qualNums", "baseTraces", "basePos"]
7477
7596
  ].forEach((type) => {
7478
- chromatogramData[type] && chromatogramData[type].splice(start, end - start + 1);
7597
+ if (chromatogramData[type]) {
7598
+ chromatogramData[type].splice(start, end - start + 1);
7599
+ }
7479
7600
  });
7480
7601
  return chromatogramData;
7481
7602
  }
7482
7603
  __name(trimChromatogram, "trimChromatogram");
7483
7604
  function deleteSequenceDataAtRange(sequenceData, range) {
7484
- return insertSequenceDataAtPositionOrRange({}, sequenceData, range);
7605
+ return insertSequenceDataAtPositionOrRange(
7606
+ { sequence: "" },
7607
+ sequenceData,
7608
+ range
7609
+ );
7485
7610
  }
7486
7611
  __name(deleteSequenceDataAtRange, "deleteSequenceDataAtRange");
7487
7612
  function doesEnzymeChopOutsideOfRecognitionSite(enzyme) {
7488
- if (enzyme.topSnipOffset > enzyme.site.length || enzyme.bottomSnipOffset > enzyme.site.length) {
7613
+ if (enzyme.topSnipOffset && enzyme.bottomSnipOffset && (enzyme.topSnipOffset > enzyme.site.length || enzyme.bottomSnipOffset > enzyme.site.length)) {
7489
7614
  return true;
7490
7615
  } else {
7491
7616
  return false;
@@ -15117,10 +15242,10 @@ defaultEnzymes.forEach((name) => {
15117
15242
  defaultEnzymesByName[name] = aliasedEnzymesByName[name];
15118
15243
  });
15119
15244
  function generateAnnotations(numberOfAnnotationsToGenerate, start, end, maxLength) {
15120
- const result = {};
15245
+ const result = [];
15121
15246
  for (let i = 0; i < numberOfAnnotationsToGenerate; i++) {
15122
15247
  const annotation = generateAnnotation(start, end, maxLength);
15123
- result[annotation.id] = annotation;
15248
+ result.push(annotation);
15124
15249
  }
15125
15250
  return result;
15126
15251
  }
@@ -15148,16 +15273,16 @@ function generateSequenceData({
15148
15273
  numPrimers,
15149
15274
  numTranslations
15150
15275
  } = {}) {
15151
- const proteinSequence = isProtein && generateSequence(sequenceLength, true);
15152
- const sequence = !isProtein && generateSequence(sequenceLength);
15276
+ const proteinSequence = isProtein ? generateSequence(sequenceLength, true) : "";
15277
+ const sequence = !isProtein ? generateSequence(sequenceLength) : "";
15153
15278
  return {
15154
15279
  circular: isProtein ? false : Math.random() > 0.5,
15155
- name: "p-" + Math.floor(Math.random * 100),
15280
+ name: "p-" + Math.floor(Math.random() * 100),
15156
15281
  description: "",
15157
- isProtein,
15282
+ isProtein: !!isProtein,
15158
15283
  sequence,
15159
15284
  proteinSequence,
15160
- translations: isProtein ? void 0 : generateAnnotations(
15285
+ translations: isProtein ? [] : generateAnnotations(
15161
15286
  numTranslations || 5,
15162
15287
  0,
15163
15288
  sequenceLength - 1,
@@ -15169,7 +15294,7 @@ function generateSequenceData({
15169
15294
  sequenceLength - 1,
15170
15295
  sequenceLength / 3
15171
15296
  ),
15172
- primers: isProtein ? void 0 : generateAnnotations(numPrimers || 10, 0, sequenceLength - 1, 50),
15297
+ primers: isProtein ? [] : generateAnnotations(numPrimers || 10, 0, sequenceLength - 1, 50),
15173
15298
  parts: generateAnnotations(
15174
15299
  numParts || 10,
15175
15300
  0,
@@ -15181,15 +15306,14 @@ function generateSequenceData({
15181
15306
  __name(generateSequenceData, "generateSequenceData");
15182
15307
  function generateSequence(m = 9, isProtein) {
15183
15308
  let s = "";
15184
- const r = isProtein ? "" : "gatc";
15309
+ const r = isProtein ? "ACDEFGHIKLMNPQRSTVWY" : "gatc";
15185
15310
  for (let i = 0; i < m; i++) {
15186
15311
  s += r.charAt(Math.floor(Math.random() * r.length));
15187
15312
  }
15188
15313
  return s;
15189
15314
  }
15190
15315
  __name(generateSequence, "generateSequence");
15191
- function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSequence, positionStart, isLinear) {
15192
- if (!positionStart) positionStart = 0;
15316
+ function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSequence, positionStart = 0, isLinear) {
15193
15317
  if (sequenceToSearch.length < overlapSequence.length) {
15194
15318
  return null;
15195
15319
  }
@@ -15207,6 +15331,9 @@ function findNearestRangeOfSequenceOverlapToPosition(sequenceToSearch, overlapSe
15207
15331
  index = result.index;
15208
15332
  distance = newDistance;
15209
15333
  }
15334
+ if (index === void 0) {
15335
+ return null;
15336
+ }
15210
15337
  return normalizeRange(
15211
15338
  {
15212
15339
  start: index,
@@ -15251,9 +15378,11 @@ function getOrfsFromSequence(options) {
15251
15378
  internalStartCodonIndices: [],
15252
15379
  frame: start % 3,
15253
15380
  forward,
15254
- annotationTypePlural: "orfs",
15381
+ // annotationTypePlural: "orfs",
15255
15382
  isOrf: true,
15256
- id: shortid()
15383
+ id: shortid(),
15384
+ type: "orf",
15385
+ name: "ORF"
15257
15386
  });
15258
15387
  }
15259
15388
  }
@@ -15294,7 +15423,10 @@ function getOrfsFromSequence(options) {
15294
15423
  return nonDuplicatedOrfRanges;
15295
15424
  }
15296
15425
  __name(getOrfsFromSequence, "getOrfsFromSequence");
15297
- function findOrfsInPlasmid(sequence, circular, minimumOrfSize, useAdditionalOrfStartCodons) {
15426
+ function findOrfsInPlasmid(sequence, circular, minimumOrfSize, useAdditionalOrfStartCodons, isProteinOrOligo) {
15427
+ if (isProteinOrOligo) {
15428
+ return [];
15429
+ }
15298
15430
  const forwardOrfs = getOrfsFromSequence({
15299
15431
  sequence,
15300
15432
  minimumOrfSize,
@@ -15354,7 +15486,10 @@ function findSequenceMatchesTopStrand(sequence, searchString, options = {}) {
15354
15486
  true
15355
15487
  );
15356
15488
  } else {
15357
- searchStringToUse = convertAmbiguousStringToRegex(searchStringToUse);
15489
+ searchStringToUse = convertAmbiguousStringToRegex(
15490
+ searchStringToUse,
15491
+ false
15492
+ );
15358
15493
  }
15359
15494
  }
15360
15495
  if (!searchStringToUse) return [];
@@ -15474,7 +15609,9 @@ function getCodonRangeForAASliver(aminoAcidPositionInSequence, aminoAcidSliver,
15474
15609
  }
15475
15610
  __name(getCodonRangeForAASliver, "getCodonRangeForAASliver");
15476
15611
  function getComplementAminoAcidStringFromSequenceString(sequenceString) {
15477
- const aaString = getAminoAcidStringFromSequenceString(sequenceString, true);
15612
+ const aaString = getAminoAcidStringFromSequenceString(sequenceString, {
15613
+ doNotExcludeAsterisk: true
15614
+ });
15478
15615
  return aaString.split("").reverse().join("");
15479
15616
  }
15480
15617
  __name(getComplementAminoAcidStringFromSequenceString, "getComplementAminoAcidStringFromSequenceString");
@@ -15512,26 +15649,30 @@ function getSequenceDataBetweenRange(seqData, range, options = {}) {
15512
15649
  sequence: getSequenceWithinRange(range, seqDataToUse.sequence),
15513
15650
  proteinSequence: getSequenceWithinRange(
15514
15651
  convertDnaCaretPositionOrRangeToAA(range),
15515
- seqDataToUse.proteinSequence
15652
+ seqDataToUse.proteinSequence || ""
15516
15653
  )
15517
15654
  },
15518
- annotationTypes.reduce((acc, type) => {
15519
- if (exclude[type]) {
15520
- acc[type] = [];
15655
+ annotationTypes.reduce(
15656
+ (acc, type) => {
15657
+ if (exclude[type]) {
15658
+ acc[type] = [];
15659
+ return acc;
15660
+ }
15661
+ acc[type] = getAnnotationsBetweenRange(
15662
+ seqDataToUse[type],
15663
+ range,
15664
+ seqDataToUse.sequence.length,
15665
+ excludePartial[type]
15666
+ );
15521
15667
  return acc;
15522
- }
15523
- acc[type] = getAnnotationsBetweenRange(
15524
- seqDataToUse[type],
15525
- range,
15526
- seqDataToUse.sequence.length,
15527
- excludePartial[type]
15528
- );
15529
- return acc;
15530
- }, {})
15668
+ },
15669
+ {}
15670
+ )
15531
15671
  );
15532
15672
  if (range.overlapsSelf) {
15533
15673
  const extendedSeqData = insertSequenceDataAtPositionOrRange(
15534
15674
  { sequence: seqDataToReturn.sequence },
15675
+ // Wrapping in object as per assumed signature
15535
15676
  seqDataToUse,
15536
15677
  range.start
15537
15678
  );
@@ -15596,7 +15737,8 @@ function getAnnotationsBetweenRange(annotationsToBeAdjusted, range, maxLength, s
15596
15737
  __name(getAnnotationsBetweenRange, "getAnnotationsBetweenRange");
15597
15738
  function getComplementSequenceAndAnnotations(pSeqObj, options = {}) {
15598
15739
  const seqObj = tidyUpSequenceData(
15599
- getSequenceDataBetweenRange(pSeqObj, options.range),
15740
+ getSequenceDataBetweenRange(pSeqObj, options.range || null),
15741
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15600
15742
  options
15601
15743
  );
15602
15744
  const newSeqObj = Object.assign({}, seqObj, {
@@ -15611,7 +15753,7 @@ function getCutsiteType(restrictionEnzyme) {
15611
15753
  const { topSnipOffset, bottomSnipOffset } = restrictionEnzyme;
15612
15754
  if (topSnipOffset === bottomSnipOffset) {
15613
15755
  return "blunt";
15614
- } else if (topSnipOffset < bottomSnipOffset) {
15756
+ } else if (topSnipOffset !== void 0 && bottomSnipOffset !== void 0 && topSnipOffset < bottomSnipOffset) {
15615
15757
  return "5' overhang";
15616
15758
  } else {
15617
15759
  return "3' overhang";
@@ -15645,7 +15787,7 @@ function getLeftAndRightOfSequenceInRangeGivenPosition(range, position, sequence
15645
15787
  leftHandSide: "",
15646
15788
  rightHandSide: ""
15647
15789
  };
15648
- if (isPositionWithinRange(position, range)) {
15790
+ if (isPositionWithinRange(position, range, sequence.length)) {
15649
15791
  result.leftHandSide = getSequenceWithinRange(
15650
15792
  {
15651
15793
  start: range.start,
@@ -15685,13 +15827,13 @@ function getOverlapBetweenTwoSequences(sequenceToFind, sequenceToSearchIn) {
15685
15827
  }
15686
15828
  }
15687
15829
  __name(getOverlapBetweenTwoSequences, "getOverlapBetweenTwoSequences");
15688
- function getPossiblePartsFromSequenceAndEnzyme(seqData, restrictionEnzymes) {
15689
- restrictionEnzymes = restrictionEnzymes.length ? restrictionEnzymes : [restrictionEnzymes];
15830
+ function getPossiblePartsFromSequenceAndEnzymes(seqData, restrictionEnzymes) {
15831
+ const enzymes = Array.isArray(restrictionEnzymes) ? restrictionEnzymes : [restrictionEnzymes];
15690
15832
  const bps = seqData.sequence;
15691
15833
  const seqLen = bps.length;
15692
- const circular = seqData.circular;
15834
+ const circular = seqData.circular || false;
15693
15835
  let cutsites = [];
15694
- restrictionEnzymes.forEach((enzyme) => {
15836
+ enzymes.forEach((enzyme) => {
15695
15837
  const newCutsites = cutSequenceByRestrictionEnzyme(bps, circular, enzyme);
15696
15838
  cutsites = cutsites.concat(newCutsites);
15697
15839
  });
@@ -15732,13 +15874,13 @@ function getPossiblePartsFromSequenceAndEnzyme(seqData, restrictionEnzymes) {
15732
15874
  return parts;
15733
15875
  }
15734
15876
  }
15735
- __name(getPossiblePartsFromSequenceAndEnzyme, "getPossiblePartsFromSequenceAndEnzyme");
15877
+ __name(getPossiblePartsFromSequenceAndEnzymes, "getPossiblePartsFromSequenceAndEnzymes");
15736
15878
  function getPartBetweenEnzymesWithInclusiveOverhangs(cut1, cut2, seqLen) {
15737
15879
  const firstCutOffset = getEnzymeRelativeOffset(cut1.restrictionEnzyme);
15738
15880
  const secondCutOffset = getEnzymeRelativeOffset(cut2.restrictionEnzyme);
15739
- const start = cut1.topSnipBeforeBottom ? cut1.topSnipPosition : cut1.bottomSnipPosition;
15881
+ const start = (cut1.topSnipBeforeBottom ? cut1.topSnipPosition : cut1.bottomSnipPosition) || 0;
15740
15882
  const end = normalizePositionByRangeLength(
15741
- (cut2.topSnipBeforeBottom ? cut2.bottomSnipPosition : cut2.topSnipPosition) - 1,
15883
+ (cut2.topSnipBeforeBottom ? cut2.bottomSnipPosition || 0 : cut2.topSnipPosition || 0) - 1,
15742
15884
  seqLen
15743
15885
  );
15744
15886
  return {
@@ -15749,20 +15891,20 @@ function getPartBetweenEnzymesWithInclusiveOverhangs(cut1, cut2, seqLen) {
15749
15891
  firstCut: cut1,
15750
15892
  //the offset is always counting with 0 being at the top snip position
15751
15893
  firstCutOffset,
15752
- firstCutOverhang: cut1.overhangBps,
15753
- firstCutOverhangTop: firstCutOffset > 0 ? cut1.overhangBps : "",
15754
- firstCutOverhangBottom: firstCutOffset < 0 ? getComplementSequenceString(cut1.overhangBps) : "",
15894
+ firstCutOverhang: cut1.overhangBps || "",
15895
+ firstCutOverhangTop: firstCutOffset > 0 ? cut1.overhangBps || "" : "",
15896
+ firstCutOverhangBottom: firstCutOffset < 0 ? getComplementSequenceString(cut1.overhangBps || "") : "",
15755
15897
  secondCut: cut2,
15756
15898
  //the offset is always counting with 0 being at the top snip position
15757
15899
  secondCutOffset,
15758
- secondCutOverhang: cut2.overhangBps,
15759
- secondCutOverhangTop: secondCutOffset < 0 ? cut2.overhangBps : "",
15760
- secondCutOverhangBottom: secondCutOffset > 0 ? getComplementSequenceString(cut2.overhangBps) : ""
15900
+ secondCutOverhang: cut2.overhangBps || "",
15901
+ secondCutOverhangTop: secondCutOffset < 0 ? cut2.overhangBps || "" : "",
15902
+ secondCutOverhangBottom: secondCutOffset > 0 ? getComplementSequenceString(cut2.overhangBps || "") : ""
15761
15903
  };
15762
15904
  }
15763
15905
  __name(getPartBetweenEnzymesWithInclusiveOverhangs, "getPartBetweenEnzymesWithInclusiveOverhangs");
15764
15906
  function getEnzymeRelativeOffset(enzyme) {
15765
- return enzyme.bottomSnipOffset - enzyme.topSnipOffset;
15907
+ return (enzyme.bottomSnipOffset || 0) - (enzyme.topSnipOffset || 0);
15766
15908
  }
15767
15909
  __name(getEnzymeRelativeOffset, "getEnzymeRelativeOffset");
15768
15910
  function pairwise(list) {
@@ -15778,6 +15920,8 @@ __name(pairwise, "pairwise");
15778
15920
  function getReverseAminoAcidStringFromSequenceString(sequenceString) {
15779
15921
  const aminoAcidsPerBase = getAminoAcidDataForEachBaseOfDna(
15780
15922
  sequenceString,
15923
+ false,
15924
+ null,
15781
15925
  false
15782
15926
  );
15783
15927
  const aaArray = [];
@@ -15816,7 +15960,8 @@ function getReverseComplementAnnotation(annotation, sequenceLength) {
15816
15960
  __name(getReverseComplementAnnotation, "getReverseComplementAnnotation");
15817
15961
  function getReverseComplementSequenceAndAnnoations(pSeqObj, options = {}) {
15818
15962
  const seqObj = tidyUpSequenceData(
15819
- getSequenceDataBetweenRange(pSeqObj, options.range),
15963
+ getSequenceDataBetweenRange(pSeqObj, options.range || null),
15964
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15820
15965
  __spreadValues({ doNotRemoveInvalidChars: true }, options)
15821
15966
  );
15822
15967
  const newSeqObj = Object.assign(
@@ -15825,17 +15970,20 @@ function getReverseComplementSequenceAndAnnoations(pSeqObj, options = {}) {
15825
15970
  {
15826
15971
  sequence: getReverseComplementSequenceString(seqObj.sequence)
15827
15972
  },
15828
- annotationTypes.reduce((acc, type) => {
15829
- if (seqObj[type]) {
15830
- acc[type] = map(seqObj[type], (annotation) => {
15831
- return getReverseComplementAnnotation(
15832
- annotation,
15833
- seqObj.sequence.length
15834
- );
15835
- });
15836
- }
15837
- return acc;
15838
- }, {})
15973
+ annotationTypes.reduce(
15974
+ (acc, type) => {
15975
+ if (seqObj[type]) {
15976
+ acc[type] = map(seqObj[type], (annotation) => {
15977
+ return getReverseComplementAnnotation(
15978
+ annotation,
15979
+ seqObj.sequence.length
15980
+ );
15981
+ });
15982
+ }
15983
+ return acc;
15984
+ },
15985
+ {}
15986
+ )
15839
15987
  );
15840
15988
  return tidyUpSequenceData(newSeqObj, __spreadValues({
15841
15989
  doNotRemoveInvalidChars: true
@@ -15857,10 +16005,13 @@ __name(getReverseSequenceString, "getReverseSequenceString");
15857
16005
  function guessIfSequenceIsDnaAndNotProtein(seq, options = {}) {
15858
16006
  const { threshold = 0.9, loose } = options;
15859
16007
  const dnaLetters = options.dnaLetters || loose ? [...ambiguous_dna_letters.split(""), "U"] : ["G", "A", "T", "C", "U"];
15860
- const dnaLetterMap = dnaLetters.reduce((acc, letter) => {
15861
- acc[letter.toUpperCase()] = true;
15862
- return acc;
15863
- }, {});
16008
+ const dnaLetterMap = dnaLetters.reduce(
16009
+ (acc, letter) => {
16010
+ acc[letter.toUpperCase()] = true;
16011
+ return acc;
16012
+ },
16013
+ {}
16014
+ );
15864
16015
  let count = 0;
15865
16016
  if (!seq || !seq.length) return true;
15866
16017
  for (let index = 0; index < seq.length; index++) {
@@ -15880,15 +16031,17 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15880
16031
  const yOffsetLevelMap = {};
15881
16032
  const wrappedAnnotations = {};
15882
16033
  forEach(annotations, (annotation) => {
16034
+ var _a;
15883
16035
  const containsLocations = !!(annotation.locations && annotation.locations.length);
15884
16036
  if (annotation.overlapsSelf) {
15885
16037
  if (!wrappedAnnotations[annotation.id]) {
15886
16038
  mapAnnotationToRows({
15887
- annotation: {
16039
+ annotation: __spreadProps(__spreadValues({}, annotation), {
15888
16040
  start: 0,
15889
16041
  end: sequenceLength - 1,
15890
- id: `__tempAnnRemoveMe__${annotation.id}`
15891
- },
16042
+ id: `__tempAnnRemoveMe__${annotation.id}`,
16043
+ overlapsSelf: false
16044
+ }),
15892
16045
  sequenceLength,
15893
16046
  bpsPerRow,
15894
16047
  annotationsToRowsMap,
@@ -15909,7 +16062,7 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15909
16062
  splitForwardReverse
15910
16063
  });
15911
16064
  if (containsLocations) {
15912
- annotation.locations.forEach((location) => {
16065
+ (_a = annotation.locations) == null ? void 0 : _a.forEach((location) => {
15913
16066
  mapAnnotationToRows({
15914
16067
  annotation,
15915
16068
  sequenceLength,
@@ -15925,7 +16078,7 @@ function mapAnnotationsToRows(annotations, sequenceLength, bpsPerRow, { splitFor
15925
16078
  forEach(annotationsToRowsMap, (annotationsForRow, i) => {
15926
16079
  annotationsToRowsMap[i] = filter(
15927
16080
  annotationsForRow,
15928
- (ann) => !startsWith(ann.id, "__tempAnnRemoveMe__")
16081
+ (ann) => !startsWith(String(ann.id), "__tempAnnRemoveMe__")
15929
16082
  );
15930
16083
  });
15931
16084
  return annotationsToRowsMap;
@@ -15967,6 +16120,13 @@ function mapAnnotationToRows({
15967
16120
  yOffset = ann.yOffset;
15968
16121
  }
15969
16122
  });
16123
+ if (yOffset === void 0) {
16124
+ annotationsForRow.forEach((ann) => {
16125
+ if (ann.id === annotation.id) {
16126
+ yOffset = ann.yOffset;
16127
+ }
16128
+ });
16129
+ }
15970
16130
  } else {
15971
16131
  if (location) {
15972
16132
  annotationsForRow.forEach((ann) => {
@@ -15975,32 +16135,74 @@ function mapAnnotationToRows({
15975
16135
  }
15976
16136
  });
15977
16137
  } else {
15978
- if (index > 0 && //second half of an annotation range
15979
- annotationsForRow.length && //there are already annotations within the row
15980
- annotationsForRow[annotationsForRow.length - 1].annotation === annotation) {
16138
+ if (index > 0 && annotationsForRow.length && annotationsForRow[annotationsForRow.length - 1].annotation === annotation) {
15981
16139
  yOffset = annotationsForRow[annotationsForRow.length - 1].yOffset;
15982
16140
  } else {
15983
- yOffset = getYOffsetForPotentiallyCircularRange(
15984
- annotation,
15985
- yOffsetsForRow
15986
- );
16141
+ const siblingRangesOnThisRow = ranges.slice(index + 1).filter((r) => {
16142
+ const rStartRow = Math.floor(r.start / bpsPerRow);
16143
+ const rEndRow = Math.floor(r.end / bpsPerRow);
16144
+ return rowNumber >= rStartRow && rowNumber <= rEndRow;
16145
+ });
16146
+ if (siblingRangesOnThisRow.length > 0) {
16147
+ let foundYOffset = -1;
16148
+ yOffsetsForRow.some((rangesAlreadyAddedToYOffset, levelIndex) => {
16149
+ const rangeBlocked = rangesAlreadyAddedToYOffset.some(
16150
+ (comparisonRange) => {
16151
+ return checkIfPotentiallyCircularRangesOverlap(
16152
+ range,
16153
+ comparisonRange
16154
+ );
16155
+ }
16156
+ );
16157
+ if (rangeBlocked) return false;
16158
+ const siblingBlocked = siblingRangesOnThisRow.some(
16159
+ (siblingRange) => {
16160
+ return rangesAlreadyAddedToYOffset.some((comparisonRange) => {
16161
+ return checkIfPotentiallyCircularRangesOverlap(
16162
+ siblingRange,
16163
+ comparisonRange
16164
+ );
16165
+ });
16166
+ }
16167
+ );
16168
+ if (!siblingBlocked) {
16169
+ foundYOffset = levelIndex;
16170
+ return true;
16171
+ }
16172
+ return false;
16173
+ });
16174
+ if (foundYOffset > -1) {
16175
+ yOffset = foundYOffset;
16176
+ yOffsetsForRow[foundYOffset].push(range);
16177
+ } else {
16178
+ yOffset = yOffsetsForRow.length;
16179
+ yOffsetsForRow.push([range]);
16180
+ }
16181
+ } else {
16182
+ yOffset = getYOffsetForPotentiallyCircularRange(
16183
+ range,
16184
+ yOffsetsForRow,
16185
+ false
16186
+ );
16187
+ }
16188
+ }
16189
+ if (yOffset !== void 0) {
16190
+ if (!yOffsetsForRow[yOffset]) yOffsetsForRow[yOffset] = [];
16191
+ yOffsetsForRow[yOffset].push({
16192
+ start,
16193
+ end
16194
+ });
15987
16195
  }
15988
- if (!yOffsetsForRow[yOffset]) yOffsetsForRow[yOffset] = [];
15989
- yOffsetsForRow[yOffset].push({
15990
- start,
15991
- end
15992
- });
15993
16196
  }
15994
16197
  }
15995
- annotationsForRow.push(__spreadProps(__spreadValues(__spreadValues({
16198
+ annotationsForRow.push(__spreadProps(__spreadValues(__spreadValues(__spreadProps(__spreadValues({}, annotation), {
15996
16199
  id: annotation.id,
15997
16200
  annotation,
15998
16201
  start,
15999
16202
  end
16000
- }, containsLocations && { containsLocations }), location && { isJoinedLocation: !!location }), {
16203
+ }), containsLocations && { containsLocations }), location && { isJoinedLocation: !!location }), {
16001
16204
  yOffset,
16002
16205
  enclosingRangeType: range.type
16003
- //either "beginning", "end" or "beginningAndEnd"
16004
16206
  }));
16005
16207
  }
16006
16208
  });
@@ -16010,10 +16212,14 @@ function prepareCircularViewData(sequenceData) {
16010
16212
  const clonedSeqData = cloneDeep(sequenceData);
16011
16213
  annotationTypes.forEach((annotationType) => {
16012
16214
  if (annotationType !== "cutsites") {
16013
- const maxYOffset = getYOffsetsForPotentiallyCircularRanges(
16014
- clonedSeqData[annotationType]
16015
- ).maxYOffset;
16016
- clonedSeqData[annotationType].maxYOffset = maxYOffset;
16215
+ const annotations = clonedSeqData[annotationType];
16216
+ if (annotations) {
16217
+ const maxYOffset = getYOffsetsForPotentiallyCircularRanges(
16218
+ annotations,
16219
+ true
16220
+ ).maxYOffset;
16221
+ clonedSeqData[annotationType].maxYOffset = maxYOffset;
16222
+ }
16017
16223
  }
16018
16224
  });
16019
16225
  return clonedSeqData;
@@ -16026,14 +16232,19 @@ function prepareRowData(sequenceData, bpsPerRow) {
16026
16232
  const rowMap = {};
16027
16233
  annotationTypes.forEach((type) => {
16028
16234
  rowMap[type] = mapAnnotationsToRows(
16029
- sequenceData[type],
16235
+ sequenceData[type] || [],
16030
16236
  sequenceLength,
16031
16237
  bpsPerRow,
16032
16238
  { splitForwardReverse: type === "primers" }
16033
16239
  );
16034
16240
  });
16035
16241
  for (let rowNumber = 0; rowNumber < totalRows; rowNumber++) {
16036
- const row = {};
16242
+ const row = {
16243
+ rowNumber,
16244
+ start: 0,
16245
+ end: 0,
16246
+ sequence: ""
16247
+ };
16037
16248
  row.rowNumber = rowNumber;
16038
16249
  row.start = rowNumber * bpsPerRow;
16039
16250
  row.end = (rowNumber + 1) * bpsPerRow - 1 < sequenceLength ? (rowNumber + 1) * bpsPerRow - 1 : sequenceLength - 1;
@@ -16094,17 +16305,16 @@ function addGapsToSeqReads(refSeq, seqReads) {
16094
16305
  }
16095
16306
  }
16096
16307
  const refSeqWithGaps = insertGapsIntoRefSeq(refSeq.sequence, seqReads);
16097
- const seqReadsWithGaps = [
16098
- { name: refSeq.name, sequence: refSeqWithGaps.toUpperCase() }
16099
- ];
16308
+ const seqReadsWithGaps = [{ name: refSeq.name, sequence: refSeqWithGaps.toUpperCase() }];
16100
16309
  seqReads.forEach((seqRead) => {
16101
16310
  const allInsertionsInSeqReads = [];
16102
16311
  seqReads.forEach((seqRead2) => {
16103
16312
  const splitSeqRead = seqRead2.cigar.match(/([0-9]*[SMDI])/g);
16313
+ if (!splitSeqRead) return;
16104
16314
  let adjustedSeqReadPos2 = cloneDeep(seqRead2.pos);
16105
16315
  if (splitSeqRead[0].slice(-1) === "S") {
16106
16316
  const numOfBeginningSoftClipped = splitSeqRead[0].slice(0, -1);
16107
- adjustedSeqReadPos2 = seqRead2.pos - numOfBeginningSoftClipped;
16317
+ adjustedSeqReadPos2 = seqRead2.pos - Number(numOfBeginningSoftClipped);
16108
16318
  }
16109
16319
  for (let componentI = 0; componentI < splitSeqRead.length; componentI++) {
16110
16320
  if (splitSeqRead[componentI].slice(-1) === "I") {
@@ -16130,10 +16340,11 @@ function addGapsToSeqReads(refSeq, seqReads) {
16130
16340
  }
16131
16341
  });
16132
16342
  const splitSeqReadChunk = seqRead.cigar.match(/([0-9]*[SMDI])/g);
16343
+ if (!splitSeqReadChunk) return;
16133
16344
  let adjustedSeqReadPos = cloneDeep(seqRead.pos);
16134
16345
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16135
16346
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16136
- adjustedSeqReadPos = seqRead.pos - numOfBeginningSoftClipped;
16347
+ adjustedSeqReadPos = seqRead.pos - Number(numOfBeginningSoftClipped);
16137
16348
  }
16138
16349
  let eachSeqReadWithGaps = seqRead.seq.split("");
16139
16350
  if (adjustedSeqReadPos > 0) {
@@ -16321,10 +16532,11 @@ function addGapsToSeqReads(refSeq, seqReads) {
16321
16532
  const seqReadLengthsBeforeRefSeqStart = [];
16322
16533
  seqReads.forEach((seq) => {
16323
16534
  const splitSeqReadChunk = seq.cigar.match(/([0-9]*[SMDI])/g);
16535
+ if (!splitSeqReadChunk) return;
16324
16536
  let adjustedSeqReadPos = cloneDeep(seq.pos);
16325
16537
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16326
16538
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16327
- adjustedSeqReadPos = seq.pos - numOfBeginningSoftClipped;
16539
+ adjustedSeqReadPos = seq.pos - Number(numOfBeginningSoftClipped);
16328
16540
  if (adjustedSeqReadPos < 0) {
16329
16541
  seqReadLengthsBeforeRefSeqStart.push(Math.abs(adjustedSeqReadPos));
16330
16542
  }
@@ -16334,13 +16546,14 @@ function addGapsToSeqReads(refSeq, seqReads) {
16334
16546
  for (let i = 1; i < seqReadsWithGaps.length; i++) {
16335
16547
  const eachSeqReadWithGaps = seqReadsWithGaps[i].sequence.split("");
16336
16548
  const splitSeqReadChunk = seqReads[i - 1].cigar.match(/([0-9]*[SMDI])/g);
16549
+ if (!splitSeqReadChunk) continue;
16337
16550
  let adjustedSeqReadPos = cloneDeep(seqReads[i - 1].pos);
16338
16551
  if (seqReadLengthsBeforeRefSeqStart.length > 0) {
16339
16552
  longestSeqReadLength = Math.max(...seqReadLengthsBeforeRefSeqStart);
16340
16553
  }
16341
16554
  if (splitSeqReadChunk[0].slice(-1) === "S") {
16342
16555
  const numOfBeginningSoftClipped = splitSeqReadChunk[0].slice(0, -1);
16343
- adjustedSeqReadPos = seqReads[i - 1].pos - numOfBeginningSoftClipped;
16556
+ adjustedSeqReadPos = seqReads[i - 1].pos - Number(numOfBeginningSoftClipped);
16344
16557
  if (adjustedSeqReadPos > 0) {
16345
16558
  if (longestSeqReadLength > 0) {
16346
16559
  eachSeqReadWithGaps.unshift("-".repeat(longestSeqReadLength + 1));
@@ -16454,11 +16667,11 @@ function calculateNebTm(sequence, { monovalentCationConc = 0.05, primerConc = 5e
16454
16667
  for (let i = 0; i < seq.length; i++) {
16455
16668
  if (i === 0 || i === seq.length - 1) {
16456
16669
  if (seq[i] === "G" || seq[i] === "C") {
16457
- hi += sequenceToEnthalpyMap.initiationWithTerminalGC;
16458
- si += sequenceToEntropyMap.initiationWithTerminalGC;
16670
+ hi += sequenceToEnthalpyMap["initiationWithTerminalGC"];
16671
+ si += sequenceToEntropyMap["initiationWithTerminalGC"];
16459
16672
  } else if (seq[i] === "A" || seq[i] === "T") {
16460
- hi += sequenceToEnthalpyMap.initiationWithTerminalAT;
16461
- si += sequenceToEntropyMap.initiationWithTerminalAT;
16673
+ hi += sequenceToEnthalpyMap["initiationWithTerminalAT"];
16674
+ si += sequenceToEntropyMap["initiationWithTerminalAT"];
16462
16675
  }
16463
16676
  }
16464
16677
  if (i < seq.length - 1) {
@@ -16501,9 +16714,13 @@ function calculateNebTa(sequences, primerConc, { monovalentCationConc, polymeras
16501
16714
  `${sequences.length} sequences received when 2 primers were expected`
16502
16715
  );
16503
16716
  }
16504
- const meltingTemperatures = sequences.map(
16505
- (seq) => calculateNebTm(seq, primerConc, { monovalentCationConc })
16506
- );
16717
+ const meltingTemperatures = sequences.map((seq) => {
16718
+ const tm = calculateNebTm(seq, { monovalentCationConc, primerConc });
16719
+ if (typeof tm !== "number") {
16720
+ throw new Error(`Invalid Tm calculated for ${seq}: ${tm}`);
16721
+ }
16722
+ return tm;
16723
+ });
16507
16724
  meltingTemperatures.sort((a, b) => a - b);
16508
16725
  const lowerMeltingTemp = meltingTemperatures[0];
16509
16726
  let annealingTemp;
@@ -16580,17 +16797,17 @@ function isValidSequence(sequence) {
16580
16797
  __name(isValidSequence, "isValidSequence");
16581
16798
  function calculateSantaLuciaTm(sequence) {
16582
16799
  try {
16583
- sequence = sequence == null ? void 0 : sequence.toUpperCase().trim();
16584
- if (!isValidSequence(sequence)) {
16800
+ const seq = sequence == null ? void 0 : sequence.toUpperCase().trim();
16801
+ if (!isValidSequence(seq)) {
16585
16802
  throw new Error("Invalid sequence: contains non-DNA characters");
16586
16803
  }
16587
- if (sequence.length < 2) {
16804
+ if (seq.length < 2) {
16588
16805
  throw new Error("Sequence too short: minimum length is 2 bases");
16589
16806
  }
16590
16807
  let deltaH = 0;
16591
16808
  let deltaS = 0;
16592
- for (let i = 0; i < sequence.length - 1; i++) {
16593
- const dinucleotide = sequence.substring(i, i + 2);
16809
+ for (let i = 0; i < seq.length - 1; i++) {
16810
+ const dinucleotide = seq.substring(i, i + 2);
16594
16811
  if (dinucleotide.includes("N")) {
16595
16812
  continue;
16596
16813
  }
@@ -16600,23 +16817,23 @@ function calculateSantaLuciaTm(sequence) {
16600
16817
  deltaS += params.dS;
16601
16818
  }
16602
16819
  }
16603
- const firstBase = sequence[0];
16604
- const lastBase = sequence[sequence.length - 1];
16820
+ const firstBase = seq[0];
16821
+ const lastBase = seq[seq.length - 1];
16605
16822
  if (firstBase === "G" || firstBase === "C") {
16606
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16607
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16823
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16824
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16608
16825
  } else {
16609
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16610
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16826
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16827
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16611
16828
  }
16612
16829
  if (lastBase === "G" || lastBase === "C") {
16613
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16614
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16830
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16831
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16615
16832
  } else {
16616
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16617
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16833
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16834
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16618
16835
  }
16619
- const nnPairs = sequence.length - 1;
16836
+ const nnPairs = seq.length - 1;
16620
16837
  deltaS = applySaltCorrection(deltaS, nnPairs);
16621
16838
  const C = PRIMER3_PARAMS.dnaConc * 1e-9;
16622
16839
  const Tm = deltaH * 1e3 / (deltaS + PRIMER3_PARAMS.R * Math.log(C / 4));
@@ -16628,16 +16845,16 @@ function calculateSantaLuciaTm(sequence) {
16628
16845
  __name(calculateSantaLuciaTm, "calculateSantaLuciaTm");
16629
16846
  function calculateEndStability(sequence) {
16630
16847
  try {
16631
- sequence = sequence == null ? void 0 : sequence.toUpperCase().trim();
16632
- if (!isValidSequence(sequence)) {
16848
+ const seq = sequence == null ? void 0 : sequence.toUpperCase().trim();
16849
+ if (!isValidSequence(seq)) {
16633
16850
  throw new Error("Invalid sequence: contains non-DNA characters");
16634
16851
  }
16635
- if (sequence.length < 5) {
16852
+ if (seq.length < 5) {
16636
16853
  throw new Error(
16637
16854
  "Sequence too short: minimum length is 5 bases for end stability calculation"
16638
16855
  );
16639
16856
  }
16640
- const last5Bases = sequence.substring(sequence.length - 5);
16857
+ const last5Bases = seq.substring(seq.length - 5);
16641
16858
  let deltaH = 0;
16642
16859
  let deltaS = 0;
16643
16860
  for (let i = 0; i < 4; i++) {
@@ -16654,18 +16871,18 @@ function calculateEndStability(sequence) {
16654
16871
  const firstBase = last5Bases[0];
16655
16872
  const lastBase = last5Bases[last5Bases.length - 1];
16656
16873
  if (firstBase === "G" || firstBase === "C") {
16657
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16658
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16874
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16875
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16659
16876
  } else {
16660
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16661
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16877
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16878
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16662
16879
  }
16663
16880
  if (lastBase === "G" || lastBase === "C") {
16664
- deltaH += SANTA_LUCIA_INIT.GC.dH;
16665
- deltaS += SANTA_LUCIA_INIT.GC.dS;
16881
+ deltaH += SANTA_LUCIA_INIT["GC"].dH;
16882
+ deltaS += SANTA_LUCIA_INIT["GC"].dS;
16666
16883
  } else {
16667
- deltaH += SANTA_LUCIA_INIT.AT.dH;
16668
- deltaS += SANTA_LUCIA_INIT.AT.dS;
16884
+ deltaH += SANTA_LUCIA_INIT["AT"].dH;
16885
+ deltaS += SANTA_LUCIA_INIT["AT"].dS;
16669
16886
  }
16670
16887
  const T = 310.15;
16671
16888
  const deltaG = deltaH - T * deltaS / 1e3;
@@ -16680,24 +16897,40 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16680
16897
  const pairs = [];
16681
16898
  if (!cutsites.length) return [];
16682
16899
  let sortedCutsites = cutsites.sort((a, b) => {
16683
- return a.topSnipPosition - b.topSnipPosition;
16900
+ return (a.topSnipPosition || 0) - (b.topSnipPosition || 0);
16684
16901
  });
16685
16902
  if (!circular) {
16686
16903
  sortedCutsites = [
16687
16904
  {
16905
+ start: 0,
16906
+ end: 0,
16688
16907
  topSnipPosition: 0,
16689
16908
  bottomSnipPosition: 0,
16690
16909
  overhangSize: 0,
16691
16910
  type: "START_OR_END_OF_SEQ",
16692
- name: "START_OF_SEQ"
16911
+ name: "START_OF_SEQ",
16912
+ restrictionEnzyme: {
16913
+ name: "START_OF_SEQ",
16914
+ site: "",
16915
+ forwardRegex: "",
16916
+ reverseRegex: ""
16917
+ }
16693
16918
  },
16694
16919
  ...sortedCutsites,
16695
16920
  {
16921
+ start: sequenceLength,
16922
+ end: sequenceLength,
16696
16923
  topSnipPosition: sequenceLength,
16697
16924
  bottomSnipPosition: sequenceLength,
16698
16925
  overhangSize: 0,
16699
16926
  type: "START_OR_END_OF_SEQ",
16700
- name: "END_OF_SEQ"
16927
+ name: "END_OF_SEQ",
16928
+ restrictionEnzyme: {
16929
+ name: "END_OF_SEQ",
16930
+ site: "",
16931
+ forwardRegex: "",
16932
+ reverseRegex: ""
16933
+ }
16701
16934
  }
16702
16935
  ];
16703
16936
  }
@@ -16720,11 +16953,11 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16720
16953
  });
16721
16954
  pairs.forEach(([cut1, cut2]) => {
16722
16955
  const start = normalizePositionByRangeLength(
16723
- cut1.topSnipPosition,
16956
+ cut1.topSnipPosition || 0,
16724
16957
  sequenceLength
16725
16958
  );
16726
16959
  const end = normalizePositionByRangeLength(
16727
- cut2.topSnipPosition - 1,
16960
+ (cut2.topSnipPosition || 0) - 1,
16728
16961
  sequenceLength
16729
16962
  );
16730
16963
  const fragmentRange = { start, end };
@@ -16742,7 +16975,9 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16742
16975
  })
16743
16976
  }, fragmentRange), {
16744
16977
  size,
16745
- id
16978
+ id,
16979
+ name: `${cut1.restrictionEnzyme.name} -- ${cut2.restrictionEnzyme.name} ${size} bps`
16980
+ // Add missing name property
16746
16981
  }));
16747
16982
  });
16748
16983
  fragments.filter((fragment) => {
@@ -16754,21 +16989,33 @@ function getDigestFragmentsForCutsites(sequenceLength, circular, cutsites, opts
16754
16989
  return fragments;
16755
16990
  }
16756
16991
  __name(getDigestFragmentsForCutsites, "getDigestFragmentsForCutsites");
16757
- function getDigestFragmentsForRestrictionEnzymes(sequence, circular, restrictionEnzymeOrEnzymes, opts) {
16758
- const restrictionEnzymes = Array.isArray(restrictionEnzymeOrEnzymes) ? restrictionEnzymeOrEnzymes : [restrictionEnzymeOrEnzymes];
16759
- const cutsites = flatMap(restrictionEnzymes, (restrictionEnzyme) => {
16760
- return cutSequenceByRestrictionEnzyme(
16761
- sequence,
16762
- circular,
16763
- restrictionEnzyme
16764
- );
16765
- });
16766
- return getDigestFragmentsForCutsites(
16767
- sequence.length,
16992
+ function getDigestFragmentsForRestrictionEnzymes(sequence, circular, contextEnzymes, options) {
16993
+ const cutsitesByName = getCutsitesFromSequence(
16994
+ sequence,
16768
16995
  circular,
16769
- cutsites,
16770
- opts
16996
+ Array.isArray(contextEnzymes) ? contextEnzymes : [contextEnzymes]
16771
16997
  );
16998
+ const digest = computeDigestFragments(__spreadProps(__spreadValues({
16999
+ cutsites: flatMap(cutsitesByName),
17000
+ sequenceLength: sequence.length,
17001
+ circular
17002
+ }, options), {
17003
+ computePartialDigest: (options == null ? void 0 : options.computePartialDigest) || (options == null ? void 0 : options.computePartialDigests)
17004
+ }));
17005
+ const fragments = uniqBy(digest.fragments, (fragment) => {
17006
+ return `${fragment.start}-${fragment.end}-${fragment.size}`;
17007
+ });
17008
+ if (circular && ((options == null ? void 0 : options.computePartialDigest) || (options == null ? void 0 : options.computePartialDigests))) {
17009
+ const fullLengthFragmentIndex = fragments.findIndex(
17010
+ (f) => f.size === sequence.length
17011
+ );
17012
+ if (fullLengthFragmentIndex > -1) {
17013
+ fragments.splice(fullLengthFragmentIndex, 1);
17014
+ }
17015
+ }
17016
+ return fragments.sort((a, b) => {
17017
+ return a.start - b.start || b.size - a.size;
17018
+ });
16772
17019
  }
16773
17020
  __name(getDigestFragmentsForRestrictionEnzymes, "getDigestFragmentsForRestrictionEnzymes");
16774
17021
  function convertAACaretPositionOrRangeToDna(rangeOrCaret) {
@@ -16814,11 +17061,13 @@ function shiftAnnotationsByLen({
16814
17061
  }) {
16815
17062
  modifiableTypes.forEach((annotationType) => {
16816
17063
  const existingAnnotations = seqData[annotationType];
16817
- seqData[annotationType] = adjustAnnotationsToInsert(
16818
- existingAnnotations,
16819
- caretPosition,
16820
- insertLength
16821
- );
17064
+ if (existingAnnotations) {
17065
+ seqData[annotationType] = adjustAnnotationsToInsert(
17066
+ existingAnnotations,
17067
+ caretPosition,
17068
+ insertLength
17069
+ );
17070
+ }
16822
17071
  });
16823
17072
  }
16824
17073
  __name(shiftAnnotationsByLen, "shiftAnnotationsByLen");
@@ -16888,7 +17137,7 @@ exports.getMassOfAaString = getMassOfAaString;
16888
17137
  exports.getMergedFeatureMap = getMergedFeatureMap;
16889
17138
  exports.getOrfsFromSequence = getOrfsFromSequence;
16890
17139
  exports.getOverlapBetweenTwoSequences = getOverlapBetweenTwoSequences;
16891
- exports.getPossiblePartsFromSequenceAndEnzymes = getPossiblePartsFromSequenceAndEnzyme;
17140
+ exports.getPossiblePartsFromSequenceAndEnzymes = getPossiblePartsFromSequenceAndEnzymes;
16892
17141
  exports.getReverseAminoAcidStringFromSequenceString = getReverseAminoAcidStringFromSequenceString;
16893
17142
  exports.getReverseComplementAminoAcidStringFromSequenceString = getReverseComplementAminoAcidStringFromSequenceString;
16894
17143
  exports.getReverseComplementAnnotation = getReverseComplementAnnotation;