@teselagen/range-utils 0.3.18 → 0.3.20-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.
- package/README.md +0 -10
- package/RangeAngles.d.ts +7 -0
- package/adjustRangeToDeletionOfAnotherRange.d.ts +2 -1
- package/adjustRangeToInsert.d.ts +2 -1
- package/adjustRangeToRotation.d.ts +2 -1
- package/checkIfNonCircularRangesOverlap.d.ts +2 -1
- package/checkIfPotentiallyCircularRangesOverlap.d.ts +2 -1
- package/collapseOverlapsGeneratedFromRangeComparisonIfPossible.d.ts +2 -1
- package/convertRangeIndices.d.ts +10 -1
- package/convertRangeTo0Based.d.ts +5 -1
- package/convertRangeTo1Based.d.ts +5 -1
- package/doesRangeSpanEntireSequence.d.ts +2 -1
- package/doesRangeSpanOrigin.d.ts +2 -1
- package/expandOrContractCircularRangeToPosition.d.ts +3 -2
- package/expandOrContractNonCircularRangeToPosition.d.ts +3 -2
- package/expandOrContractRangeByLength.d.ts +5 -1
- package/expandOrContractRangeToPosition.d.ts +3 -2
- package/flipContainedRange.d.ts +5 -1
- package/generateRandomRange.d.ts +3 -3
- package/getAnnotationRangeType.d.ts +2 -1
- package/getEachPositionInRangeAsArray.d.ts +2 -1
- package/getLengthOfOverlappingRegionsBetweenTwoRanges.d.ts +2 -1
- package/getMiddleOfRange.d.ts +2 -1
- package/getOverlapOfNonCircularRanges.d.ts +5 -4
- package/getOverlapsOfPotentiallyCircularRanges.d.ts +2 -1
- package/getPositionFromAngle.d.ts +1 -1
- package/getRangeAngles.d.ts +3 -7
- package/getRangeLength.d.ts +5 -1
- package/getRangesBetweenTwoRanges.d.ts +2 -1
- package/getSequenceWithinRange.d.ts +3 -1
- package/getShortestDistanceBetweenTwoPositions.d.ts +1 -1
- package/getYOffsetForPotentiallyCircularRange.d.ts +2 -1
- package/getYOffsetsForPotentiallyCircularRanges.d.ts +3 -2
- package/getZeroedRangeOverlaps.d.ts +2 -1
- package/index.cjs +58 -45
- package/index.d.ts +1 -0
- package/index.js +58 -45
- package/index.umd.cjs +58 -45
- package/invertRange.d.ts +5 -1
- package/isPositionCloserToRangeStartThanRangeEnd.d.ts +2 -1
- package/isPositionWithinRange.d.ts +3 -2
- package/isRangeOrPositionWithinRange.d.ts +2 -1
- package/isRangeWithinRange.d.ts +2 -1
- package/loopEachPositionInRange.d.ts +2 -1
- package/modulatePositionByRange.d.ts +2 -1
- package/modulateRangeBySequenceLength.d.ts +8 -1
- package/normalizePositionByRangeLength.d.ts +1 -1
- package/normalizePositionByRangeLength1Based.d.ts +1 -1
- package/normalizeRange.d.ts +5 -1
- package/package.json +10 -2
- package/provideInclusiveOptions.d.ts +6 -1
- package/reversePositionInRange.d.ts +1 -1
- package/splitRangeIntoTwoPartsIfItIsCircular.d.ts +4 -3
- package/src/RangeAngles.ts +9 -0
- package/src/{adjustRangeToDeletionOfAnotherRange.js → adjustRangeToDeletionOfAnotherRange.ts} +4 -7
- package/src/{adjustRangeToInsert.js → adjustRangeToInsert.ts} +4 -4
- package/src/adjustRangeToRotation.ts +22 -0
- package/src/{checkIfNonCircularRangesOverlap.js → checkIfNonCircularRangesOverlap.ts} +5 -4
- package/src/{checkIfPotentiallyCircularRangesOverlap.js → checkIfPotentiallyCircularRangesOverlap.ts} +4 -4
- package/src/{collapseOverlapsGeneratedFromRangeComparisonIfPossible.js → collapseOverlapsGeneratedFromRangeComparisonIfPossible.ts} +7 -4
- package/src/{convertRangeIndices.js → convertRangeIndices.ts} +11 -3
- package/src/{convertRangeTo0Based.js → convertRangeTo0Based.ts} +2 -1
- package/src/{convertRangeTo1Based.js → convertRangeTo1Based.ts} +2 -1
- package/src/doesRangeSpanEntireSequence.ts +12 -0
- package/src/doesRangeSpanOrigin.ts +5 -0
- package/src/{expandOrContractCircularRangeToPosition.js → expandOrContractCircularRangeToPosition.ts} +5 -3
- package/src/{expandOrContractNonCircularRangeToPosition.js → expandOrContractNonCircularRangeToPosition.ts} +4 -2
- package/src/{expandOrContractRangeByLength.js → expandOrContractRangeByLength.ts} +5 -4
- package/src/{expandOrContractRangeToPosition.js → expandOrContractRangeToPosition.ts} +6 -8
- package/src/{flipContainedRange.js → flipContainedRange.ts} +18 -8
- package/src/{generateRandomRange.js → generateRandomRange.ts} +6 -2
- package/src/{getAnnotationRangeType.js → getAnnotationRangeType.ts} +5 -3
- package/src/{getEachPositionInRangeAsArray.js → getEachPositionInRangeAsArray.ts} +6 -2
- package/src/{getLengthOfOverlappingRegionsBetweenTwoRanges.js → getLengthOfOverlappingRegionsBetweenTwoRanges.ts} +4 -3
- package/src/{getMiddleOfRange.js → getMiddleOfRange.ts} +2 -1
- package/src/{getOverlapOfNonCircularRanges.js → getOverlapOfNonCircularRanges.ts} +7 -1
- package/src/{getOverlapsOfPotentiallyCircularRanges.js → getOverlapsOfPotentiallyCircularRanges.ts} +13 -7
- package/src/{getPositionFromAngle.js → getPositionFromAngle.ts} +3 -3
- package/src/{getRangeAngles.js → getRangeAngles.ts} +8 -3
- package/src/{getRangeLength.js → getRangeLength.ts} +4 -1
- package/src/{getRangesBetweenTwoRanges.js → getRangesBetweenTwoRanges.ts} +7 -2
- package/src/getSequenceWithinRange.ts +33 -0
- package/src/{getShortestDistanceBetweenTwoPositions.js → getShortestDistanceBetweenTwoPositions.ts} +3 -3
- package/src/{getYOffsetForPotentiallyCircularRange.js → getYOffsetForPotentiallyCircularRange.ts} +5 -4
- package/src/getYOffsetsForPotentiallyCircularRanges.test.ts +17 -0
- package/src/{getYOffsetsForPotentiallyCircularRanges.js → getYOffsetsForPotentiallyCircularRanges.ts} +5 -4
- package/src/{getZeroedRangeOverlaps.test.js → getZeroedRangeOverlaps.test.ts} +5 -15
- package/src/{getZeroedRangeOverlaps.js → getZeroedRangeOverlaps.ts} +4 -3
- package/src/{index.test.js → index.test.ts} +11 -3
- package/src/{index.js → index.ts} +1 -0
- package/src/invertRange.ts +25 -0
- package/src/{isPositionCloserToRangeStartThanRangeEnd.js → isPositionCloserToRangeStartThanRangeEnd.ts} +5 -3
- package/src/{isPositionWithinRange.js → isPositionWithinRange.ts} +14 -5
- package/src/{isRangeOrPositionWithinRange.js → isRangeOrPositionWithinRange.ts} +11 -6
- package/src/{isRangeWithinRange.js → isRangeWithinRange.ts} +5 -3
- package/src/loopEachPositionInRange.ts +11 -0
- package/src/{modulatePositionByRange.js → modulatePositionByRange.ts} +6 -1
- package/src/{modulateRangeBySequenceLength.js → modulateRangeBySequenceLength.ts} +3 -1
- package/src/{normalizePositionByRangeLength.js → normalizePositionByRangeLength.ts} +7 -7
- package/src/{normalizePositionByRangeLength1Based.js → normalizePositionByRangeLength1Based.ts} +3 -2
- package/src/{normalizeRange.js → normalizeRange.ts} +2 -1
- package/src/provideInclusiveOptions.ts +79 -0
- package/src/{reversePositionInRange.js → reversePositionInRange.ts} +4 -4
- package/src/{splitRangeIntoTwoPartsIfItIsCircular.js → splitRangeIntoTwoPartsIfItIsCircular.ts} +5 -4
- package/src/{translateRange.js → translateRange.ts} +5 -3
- package/src/{trimAnnStartEndToFitSeqLength.js → trimAnnStartEndToFitSeqLength.ts} +2 -2
- package/src/{trimNonCicularRangeByAnotherNonCircularRange.js → trimNonCicularRangeByAnotherNonCircularRange.ts} +6 -4
- package/src/{trimNumberToFitWithin0ToAnotherNumber.js → trimNumberToFitWithin0ToAnotherNumber.ts} +3 -4
- package/src/{trimRangeByAnotherRange.js → trimRangeByAnotherRange.ts} +9 -9
- package/src/types.ts +12 -0
- package/src/{zeroSubrangeByContainerRange.js → zeroSubrangeByContainerRange.ts} +10 -8
- package/translateRange.d.ts +5 -1
- package/trimAnnStartEndToFitSeqLength.d.ts +1 -1
- package/trimNonCicularRangeByAnotherNonCircularRange.d.ts +2 -4
- package/trimNumberToFitWithin0ToAnotherNumber.d.ts +1 -1
- package/trimRangeByAnotherRange.d.ts +2 -1
- package/types.d.ts +12 -0
- package/zeroSubrangeByContainerRange.d.ts +2 -1
- package/adjustRangeToDeletionOfAnotherRange.test.d.ts +0 -1
- package/adjustRangeToInsert.test.d.ts +0 -1
- package/adjustRangeToRotation.test.d.ts +0 -1
- package/checkIfNonCircularRangesOverlap.test.d.ts +0 -1
- package/checkIfPotentiallyCircularRangesOverlap.test.d.ts +0 -1
- package/collapseOverlapsGeneratedFromRangeComparisonIfPossible.test.d.ts +0 -1
- package/convertRangeIndices.test.d.ts +0 -1
- package/expandOrContractRangeByLength.test.d.ts +0 -1
- package/flipContainedRange.test.d.ts +0 -1
- package/generateRandomRange.test.d.ts +0 -1
- package/getAnnotationRangeType.test.d.ts +0 -1
- package/getEachPositionInRangeAsArray.test.d.ts +0 -1
- package/getLengthOfOverlappingRegionsBetweenTwoRanges.test.d.ts +0 -1
- package/getMiddleOfRange.test.d.ts +0 -1
- package/getOverlapsOfPotentiallyCircularRanges.test.d.ts +0 -1
- package/getRangeAngles.test.d.ts +0 -1
- package/getRangeLength.test.d.ts +0 -1
- package/getSequenceWithinRange.test.d.ts +0 -1
- package/getShortestDistanceBetweenTwoPositions.test.d.ts +0 -1
- package/getYOffsetsForPotentiallyCircularRanges.test.d.ts +0 -1
- package/getZeroedRangeOverlaps.test.d.ts +0 -1
- package/index.test.d.ts +0 -1
- package/invertRange.test.d.ts +0 -1
- package/isPositionCloserToRangeStartThanRangeEnd.test.d.ts +0 -1
- package/isRangeOrPositionWithinRange.test.d.ts +0 -1
- package/modulatePositionByRange.test.d.ts +0 -1
- package/modulateRangeBySequenceLength.test.d.ts +0 -1
- package/normalizePositionByRangeLength.test.d.ts +0 -1
- package/normalizePositionByRangeLength1Based.test.d.ts +0 -1
- package/normalizeRange.test.d.ts +0 -1
- package/splitRangeIntoTwoPartsIfItIsCircular.test.d.ts +0 -1
- package/src/adjustRangeToRotation.js +0 -23
- package/src/doesRangeSpanEntireSequence.js +0 -7
- package/src/doesRangeSpanOrigin.js +0 -3
- package/src/getSequenceWithinRange.js +0 -17
- package/src/getYOffsetsForPotentiallyCircularRanges.test.js +0 -42
- package/src/invertRange.js +0 -21
- package/src/loopEachPositionInRange.js +0 -5
- package/src/provideInclusiveOptions.js +0 -39
- package/translateRange.test.d.ts +0 -1
- package/trimAnnStartEndToFitSeqLength.test.d.ts +0 -1
- package/trimRangeByAnotherRange.test.d.ts +0 -1
- package/zeroSubrangeByContainerRange.test.d.ts +0 -1
- /package/src/{getRangeLength.test.js → getRangeLength.test.ts} +0 -0
- /package/src/{getSequenceWithinRange.test.js → getSequenceWithinRange.test.ts} +0 -0
- /package/src/{getShortestDistanceBetweenTwoPositions.test.js → getShortestDistanceBetweenTwoPositions.test.ts} +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { assign } from "lodash-es";
|
|
2
|
+
|
|
3
|
+
import { Range } from "./types";
|
|
4
|
+
|
|
5
|
+
export default function adjustRangeToRotation<T extends Range>(
|
|
6
|
+
rangeToBeAdjusted: T,
|
|
7
|
+
rotateTo = 0,
|
|
8
|
+
rangeLength?: number
|
|
9
|
+
): T {
|
|
10
|
+
const mod = (n: number) => (rangeLength ? modulo(n, rangeLength) : n);
|
|
11
|
+
|
|
12
|
+
const newRange = assign({}, rangeToBeAdjusted, {
|
|
13
|
+
start: mod(rangeToBeAdjusted.start - (rotateTo || 0)),
|
|
14
|
+
end: mod(rangeToBeAdjusted.end - (rotateTo || 0))
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return newRange as T;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function modulo(n: number, m: number) {
|
|
21
|
+
return ((n % m) + m) % m;
|
|
22
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
1
3
|
//
|
|
2
|
-
|
|
4
|
+
|
|
3
5
|
export default function checkIfNonCircularRangesOverlap(
|
|
4
|
-
range,
|
|
5
|
-
comparisonRange
|
|
6
|
+
range: Range,
|
|
7
|
+
comparisonRange: Range
|
|
6
8
|
) {
|
|
7
|
-
// ac.throw([ac.range, ac.range], arguments);
|
|
8
9
|
if (range.start < comparisonRange.start) {
|
|
9
10
|
if (range.end < comparisonRange.start) {
|
|
10
11
|
//----llll
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//
|
|
2
|
+
//
|
|
2
3
|
import checkIfNonCircularRangesOverlap from "./checkIfNonCircularRangesOverlap";
|
|
3
4
|
|
|
4
5
|
import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
5
|
-
|
|
6
|
+
import { Range } from "./types";
|
|
6
7
|
|
|
7
8
|
export default function checkIfPotentiallyCircularRangesOverlap(
|
|
8
|
-
range,
|
|
9
|
-
comparisonRange
|
|
9
|
+
range: Range,
|
|
10
|
+
comparisonRange: Range
|
|
10
11
|
) {
|
|
11
|
-
// ac.throw([ac.range, ac.range], arguments);
|
|
12
12
|
//split the potentially circular ranges and compare each part for overlap
|
|
13
13
|
return splitRangeIntoTwoPartsIfItIsCircular(range, Infinity).some(
|
|
14
14
|
function (splitRange) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
1
3
|
//this function is a little confusing, but basically it takes an array of overlaps
|
|
2
4
|
//generated from a range overlaps calculation, and it sews them together if possible
|
|
3
5
|
export default function collapseOverlapsGeneratedFromRangeComparisonIfPossible(
|
|
4
|
-
overlaps,
|
|
5
|
-
sequenceLength,
|
|
6
|
-
optionalOriginalRange
|
|
7
|
-
) {
|
|
6
|
+
overlaps: Range[],
|
|
7
|
+
sequenceLength: number,
|
|
8
|
+
optionalOriginalRange?: Range
|
|
9
|
+
): Range[] {
|
|
8
10
|
const originalRangeLinear =
|
|
9
11
|
optionalOriginalRange &&
|
|
10
12
|
optionalOriginalRange.start <= optionalOriginalRange.end;
|
|
@@ -75,4 +77,5 @@ export default function collapseOverlapsGeneratedFromRangeComparisonIfPossible(
|
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
}
|
|
80
|
+
return overlaps;
|
|
78
81
|
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { assign } from "lodash-es";
|
|
2
|
+
import { Range } from "./types";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
interface RangeIndicesOptions {
|
|
5
|
+
inclusive1BasedStart?: boolean;
|
|
6
|
+
inclusive1BasedEnd?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function convertRangeIndices(
|
|
10
|
+
range: Range,
|
|
11
|
+
inputType: RangeIndicesOptions = {},
|
|
12
|
+
outputType: RangeIndicesOptions = {}
|
|
13
|
+
) {
|
|
6
14
|
return assign({}, range, {
|
|
7
15
|
start:
|
|
8
16
|
Number(range.start) +
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import convertRangeIndices from "./convertRangeIndices";
|
|
2
|
+
import { Range } from "./types";
|
|
2
3
|
|
|
3
|
-
export default function convertRangeTo0Based(range) {
|
|
4
|
+
export default function convertRangeTo0Based(range: Range) {
|
|
4
5
|
return convertRangeIndices(range, {
|
|
5
6
|
inclusive1BasedStart: true,
|
|
6
7
|
inclusive1BasedEnd: true
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import getRangeLength from "./getRangeLength";
|
|
2
|
+
import { Range } from "./types";
|
|
3
|
+
|
|
4
|
+
export default function doesRangeSpanEntireSequence(
|
|
5
|
+
range: Range,
|
|
6
|
+
sequenceLength: number
|
|
7
|
+
) {
|
|
8
|
+
if (getRangeLength(range, sequenceLength) === sequenceLength) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
2
2
|
import { assign } from "lodash-es";
|
|
3
3
|
|
|
4
|
+
import { Range } from "./types";
|
|
5
|
+
|
|
4
6
|
export default function expandOrContractCircularRangeToPosition(
|
|
5
|
-
range,
|
|
6
|
-
position,
|
|
7
|
-
maxLength
|
|
7
|
+
range: Range,
|
|
8
|
+
position: number,
|
|
9
|
+
maxLength: number
|
|
8
10
|
) {
|
|
9
11
|
// 0 1 2 3 4 5 6 7 8 9
|
|
10
12
|
// r r r r r - - r r r
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { assign } from "lodash-es";
|
|
2
2
|
|
|
3
|
+
import { Range } from "./types";
|
|
4
|
+
|
|
3
5
|
export default function expandOrContractNonCircularRangeToPosition(
|
|
4
|
-
range,
|
|
5
|
-
position
|
|
6
|
+
range: Range,
|
|
7
|
+
position: number
|
|
6
8
|
) {
|
|
7
9
|
const newRange = assign({}, range);
|
|
8
10
|
let endMoved = true;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { clone } from "lodash-es";
|
|
2
|
+
import { Range } from "./types";
|
|
2
3
|
import normalizeRange from "./normalizeRange";
|
|
3
4
|
|
|
4
5
|
export default function expandOrContractRangeByLength(
|
|
5
|
-
range,
|
|
6
|
-
shiftBy,
|
|
7
|
-
shiftStart,
|
|
8
|
-
sequenceLength
|
|
6
|
+
range: Range,
|
|
7
|
+
shiftBy: number,
|
|
8
|
+
shiftStart: boolean,
|
|
9
|
+
sequenceLength: number
|
|
9
10
|
) {
|
|
10
11
|
const rangeToReturn = clone(range);
|
|
11
12
|
if (shiftStart) {
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import expandOrContractCircularRangeToPosition from "./expandOrContractCircularRangeToPosition";
|
|
2
2
|
import expandOrContractNonCircularRangeToPosition from "./expandOrContractNonCircularRangeToPosition";
|
|
3
3
|
|
|
4
|
+
import { Range } from "./types";
|
|
5
|
+
|
|
4
6
|
export default function expandOrContractRangeToPosition(
|
|
5
|
-
range,
|
|
6
|
-
position,
|
|
7
|
-
maxLength
|
|
7
|
+
range: Range,
|
|
8
|
+
position: number,
|
|
9
|
+
maxLength: number
|
|
8
10
|
) {
|
|
9
11
|
if (range.start > range.end) {
|
|
10
12
|
return expandOrContractCircularRangeToPosition(range, position, maxLength);
|
|
11
13
|
} else {
|
|
12
|
-
return expandOrContractNonCircularRangeToPosition(
|
|
13
|
-
range,
|
|
14
|
-
position,
|
|
15
|
-
maxLength
|
|
16
|
-
);
|
|
14
|
+
return expandOrContractNonCircularRangeToPosition(range, position);
|
|
17
15
|
}
|
|
18
16
|
}
|
|
@@ -4,10 +4,12 @@ import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCi
|
|
|
4
4
|
import translateRange from "./translateRange";
|
|
5
5
|
import getRangeLength from "./getRangeLength";
|
|
6
6
|
|
|
7
|
+
import { Range } from "./types";
|
|
8
|
+
|
|
7
9
|
export default function flipRelativeRange(
|
|
8
|
-
innerRange,
|
|
9
|
-
outerRange,
|
|
10
|
-
sequenceLength
|
|
10
|
+
innerRange: Range,
|
|
11
|
+
outerRange: Range,
|
|
12
|
+
sequenceLength: number
|
|
11
13
|
) {
|
|
12
14
|
const isFullyContained = isRangeWithinRange(
|
|
13
15
|
innerRange,
|
|
@@ -22,7 +24,11 @@ export default function flipRelativeRange(
|
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
function flipNonFullyContainedRange(
|
|
27
|
+
function flipNonFullyContainedRange(
|
|
28
|
+
innerRange: Range,
|
|
29
|
+
outerRange: Range,
|
|
30
|
+
sequenceLength: number
|
|
31
|
+
) {
|
|
26
32
|
const outerFullyContained = isRangeWithinRange(
|
|
27
33
|
outerRange,
|
|
28
34
|
innerRange,
|
|
@@ -97,7 +103,11 @@ function flipNonFullyContainedRange(innerRange, outerRange, sequenceLength) {
|
|
|
97
103
|
return flippedInnerRange;
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
function flipFullyContainedRange(
|
|
106
|
+
function flipFullyContainedRange(
|
|
107
|
+
innerRange: Range,
|
|
108
|
+
outerRange: Range,
|
|
109
|
+
sequenceLength: number
|
|
110
|
+
) {
|
|
101
111
|
//translate both ranges by offset such that outer range start = 0
|
|
102
112
|
const translateBy = -outerRange.start;
|
|
103
113
|
const translatedOuterRange = translateRange(
|
|
@@ -128,9 +138,9 @@ function flipFullyContainedRange(innerRange, outerRange, sequenceLength) {
|
|
|
128
138
|
}
|
|
129
139
|
|
|
130
140
|
function flipNonOriginSpanningContainedRange(
|
|
131
|
-
innerRange,
|
|
132
|
-
outerRange,
|
|
133
|
-
sequenceLength
|
|
141
|
+
innerRange: Range,
|
|
142
|
+
outerRange: Range,
|
|
143
|
+
sequenceLength: number
|
|
134
144
|
) {
|
|
135
145
|
//non origin spanning, fully contained inner
|
|
136
146
|
const offsetFromStart = innerRange.start - outerRange.start;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
2
2
|
|
|
3
|
-
export default function generateRandomRange(
|
|
3
|
+
export default function generateRandomRange(
|
|
4
|
+
minStart: number,
|
|
5
|
+
maxEnd: number,
|
|
6
|
+
maxLength: number
|
|
7
|
+
) {
|
|
4
8
|
const start = getRandomInt(minStart, maxEnd);
|
|
5
9
|
let end;
|
|
6
10
|
if (maxLength) {
|
|
@@ -17,6 +21,6 @@ export default function generateRandomRange(minStart, maxEnd, maxLength) {
|
|
|
17
21
|
};
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
function getRandomInt(min, max) {
|
|
24
|
+
function getRandomInt(min: number, max: number) {
|
|
21
25
|
return Math.floor(Math.random() * (max - min)) + min;
|
|
22
26
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
1
3
|
//function that returns the annotation range type
|
|
2
4
|
export default function getAnnotationRangeType(
|
|
3
|
-
annotationRange,
|
|
4
|
-
enclosingRangeType,
|
|
5
|
-
forward
|
|
5
|
+
annotationRange: Range,
|
|
6
|
+
enclosingRangeType: Range,
|
|
7
|
+
forward: boolean
|
|
6
8
|
) {
|
|
7
9
|
if (annotationRange.start === enclosingRangeType.start) {
|
|
8
10
|
if (annotationRange.end === enclosingRangeType.end) {
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
2
2
|
import getRangeLength from "./getRangeLength";
|
|
3
|
+
import { Range } from "./types";
|
|
3
4
|
|
|
4
|
-
export default function getEachPositionInRangeAsArray(
|
|
5
|
-
|
|
5
|
+
export default function getEachPositionInRangeAsArray(
|
|
6
|
+
range: Range,
|
|
7
|
+
rangeMax: number
|
|
8
|
+
) {
|
|
9
|
+
const output: number[] = [];
|
|
6
10
|
const length = getRangeLength(range, rangeMax);
|
|
7
11
|
if (!(length > 0)) {
|
|
8
12
|
return output;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import getRangeLength from "./getRangeLength";
|
|
2
2
|
import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCircularRanges";
|
|
3
|
+
import { Range } from "./types";
|
|
3
4
|
|
|
4
5
|
export default function getLengthOfOverlappingRegionsBetweenTwoRanges(
|
|
5
|
-
rangeA,
|
|
6
|
-
rangeB,
|
|
7
|
-
maxLength
|
|
6
|
+
rangeA: Range,
|
|
7
|
+
rangeB: Range,
|
|
8
|
+
maxLength: number
|
|
8
9
|
) {
|
|
9
10
|
const overlaps = getOverlapsOfPotentiallyCircularRanges(
|
|
10
11
|
rangeA,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import getRangeLength from "./getRangeLength";
|
|
2
2
|
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
3
|
+
import { Range } from "./types";
|
|
3
4
|
|
|
4
|
-
export default function getMiddleOfRange(range, rangeMax) {
|
|
5
|
+
export default function getMiddleOfRange(range: Range, rangeMax: number) {
|
|
5
6
|
const len = getRangeLength({ start: range.start, end: range.end }, rangeMax);
|
|
6
7
|
return normalizePositionByRangeLength(
|
|
7
8
|
range.start + Math.floor(len / 2),
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
3
|
+
export default function getOverlapOfNonCircularRanges(
|
|
4
|
+
rangeA: Range,
|
|
5
|
+
rangeB: Range
|
|
6
|
+
) {
|
|
2
7
|
if (rangeA.start < rangeB.start) {
|
|
3
8
|
if (rangeA.end < rangeB.start) {
|
|
4
9
|
//no overlap
|
|
@@ -32,4 +37,5 @@ export default function getOverlapOfNonCircularRanges(rangeA, rangeB) {
|
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
}
|
|
40
|
+
return null;
|
|
35
41
|
}
|
package/src/{getOverlapsOfPotentiallyCircularRanges.js → getOverlapsOfPotentiallyCircularRanges.ts}
RENAMED
|
@@ -2,12 +2,15 @@ import { flatMap } from "lodash-es";
|
|
|
2
2
|
import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
3
3
|
import getOverlapOfNonCircularRanges from "./getOverlapOfNonCircularRanges";
|
|
4
4
|
|
|
5
|
+
//returns an array of the overlaps between two potentially circular ranges
|
|
6
|
+
import { Range } from "./types";
|
|
7
|
+
|
|
5
8
|
//returns an array of the overlaps between two potentially circular ranges
|
|
6
9
|
export default function getOverlapsOfPotentiallyCircularRanges(
|
|
7
|
-
rangeA,
|
|
8
|
-
rangeB,
|
|
9
|
-
maxRangeLength,
|
|
10
|
-
joinIfPossible //by default this fn only returns **non-circular** overlaps, if true it will try to join overlaps split on the origin
|
|
10
|
+
rangeA: Range,
|
|
11
|
+
rangeB: Range,
|
|
12
|
+
maxRangeLength: number,
|
|
13
|
+
joinIfPossible = false //by default this fn only returns **non-circular** overlaps, if true it will try to join overlaps split on the origin
|
|
11
14
|
) {
|
|
12
15
|
const normalizedRangeA = splitRangeIntoTwoPartsIfItIsCircular(
|
|
13
16
|
rangeA,
|
|
@@ -18,7 +21,7 @@ export default function getOverlapsOfPotentiallyCircularRanges(
|
|
|
18
21
|
maxRangeLength
|
|
19
22
|
);
|
|
20
23
|
|
|
21
|
-
let overlaps = [];
|
|
24
|
+
let overlaps: Range[] = [];
|
|
22
25
|
|
|
23
26
|
normalizedRangeA.forEach(function (nonCircularRangeA) {
|
|
24
27
|
normalizedRangeB.forEach(function (nonCircularRangeB) {
|
|
@@ -38,7 +41,7 @@ export default function getOverlapsOfPotentiallyCircularRanges(
|
|
|
38
41
|
maxRangeLength
|
|
39
42
|
) {
|
|
40
43
|
//we have 2 circular ranges that will have gotten split on the origin, so we'll manually mend those pieces back together
|
|
41
|
-
const joinedOverlap = {};
|
|
44
|
+
const joinedOverlap: Partial<Range> = {};
|
|
42
45
|
overlaps = flatMap(overlaps, o => {
|
|
43
46
|
if (o.start === 0) {
|
|
44
47
|
joinedOverlap.end = o.end;
|
|
@@ -47,8 +50,11 @@ export default function getOverlapsOfPotentiallyCircularRanges(
|
|
|
47
50
|
joinedOverlap.start = o.start;
|
|
48
51
|
return [];
|
|
49
52
|
}
|
|
53
|
+
return [o];
|
|
50
54
|
});
|
|
51
|
-
|
|
55
|
+
if (Object.keys(joinedOverlap).length > 0) {
|
|
56
|
+
overlaps.push(joinedOverlap as Range);
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
59
|
return overlaps;
|
|
54
60
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default function getPositionFromAngle(
|
|
2
|
-
angle,
|
|
3
|
-
rangeMax,
|
|
4
|
-
isInBetweenPositions
|
|
2
|
+
angle: number,
|
|
3
|
+
rangeMax: number,
|
|
4
|
+
isInBetweenPositions?: boolean
|
|
5
5
|
) {
|
|
6
6
|
//percent through sequence * rangeMax
|
|
7
7
|
const unroundedPostion = (angle / Math.PI / 2) * rangeMax;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import getRangeLength from "./getRangeLength";
|
|
2
|
+
import { Range } from "./types";
|
|
3
|
+
import { RangeAngles } from "./RangeAngles";
|
|
2
4
|
|
|
3
|
-
export default function getRangeAngles(
|
|
5
|
+
export default function getRangeAngles(
|
|
6
|
+
range: Range,
|
|
7
|
+
rangeMax: number
|
|
8
|
+
): RangeAngles {
|
|
4
9
|
const { startAngle, totalAngle, endAngle } = getStartEndAndTotalAngle(
|
|
5
10
|
range,
|
|
6
11
|
rangeMax
|
|
@@ -13,13 +18,13 @@ export default function getRangeAngles(range, rangeMax) {
|
|
|
13
18
|
centerAngle: startAngle + totalAngle / 2,
|
|
14
19
|
locationAngles:
|
|
15
20
|
range.locations &&
|
|
16
|
-
range.locations.map(location => {
|
|
21
|
+
range.locations.map((location: Range) => {
|
|
17
22
|
return getRangeAngles(location, rangeMax);
|
|
18
23
|
})
|
|
19
24
|
};
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
function getStartEndAndTotalAngle(range, rangeMax) {
|
|
27
|
+
function getStartEndAndTotalAngle(range: Range, rangeMax: number) {
|
|
23
28
|
const rangeLength = getRangeLength(
|
|
24
29
|
{ start: range.start, end: range.end },
|
|
25
30
|
rangeMax
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import provideInclusiveOptions from "./provideInclusiveOptions";
|
|
2
|
+
import { Range } from "./types";
|
|
3
|
+
|
|
2
4
|
export default provideInclusiveOptions(getRangeLength);
|
|
3
|
-
|
|
5
|
+
|
|
6
|
+
function getRangeLength(range: Range, rangeMax: number) {
|
|
4
7
|
let toRet;
|
|
5
8
|
if (range.end < range.start) {
|
|
6
9
|
toRet = rangeMax - range.start + range.end + 1;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
3
|
+
export default function getRangesBetweenTwoRanges(
|
|
4
|
+
range1: Range,
|
|
5
|
+
range2: Range
|
|
6
|
+
) {
|
|
2
7
|
// {
|
|
3
8
|
// start: 85,
|
|
4
9
|
// end: 92
|
|
@@ -13,7 +18,7 @@ export default function getRangesBetweenTwoRanges(range1, range2) {
|
|
|
13
18
|
|
|
14
19
|
// start2 - end1
|
|
15
20
|
|
|
16
|
-
const newRanges = [];
|
|
21
|
+
const newRanges: Range[] = [];
|
|
17
22
|
if (
|
|
18
23
|
!(
|
|
19
24
|
range1.start > -1 &&
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Range } from "./types";
|
|
2
|
+
|
|
3
|
+
// overload the function signatures so that TS knows what type to expect back (string or T[])
|
|
4
|
+
export default function getSequenceWithinRange(
|
|
5
|
+
range: Range,
|
|
6
|
+
sequence: string
|
|
7
|
+
): string;
|
|
8
|
+
export default function getSequenceWithinRange<T>(
|
|
9
|
+
range: Range,
|
|
10
|
+
sequence: T[]
|
|
11
|
+
): T[];
|
|
12
|
+
export default function getSequenceWithinRange<T>(
|
|
13
|
+
range: Range,
|
|
14
|
+
sequence: string | T[]
|
|
15
|
+
) {
|
|
16
|
+
if (range.start < 0 || range.end < 0) {
|
|
17
|
+
if (typeof sequence === "string") return "";
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
if (range.start > range.end) {
|
|
21
|
+
//circular range
|
|
22
|
+
const subSequence = sequence.slice(range.start, sequence.length);
|
|
23
|
+
if (typeof subSequence === "string") {
|
|
24
|
+
return subSequence + sequence.slice(0, range.end + 1);
|
|
25
|
+
} else {
|
|
26
|
+
return (subSequence as T[]).concat(
|
|
27
|
+
sequence.slice(0, range.end + 1) as T[]
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
return sequence.slice(range.start, range.end + 1);
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/{getYOffsetForPotentiallyCircularRange.js → getYOffsetForPotentiallyCircularRange.ts}
RENAMED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import checkIfPotentiallyCircularRangesOverlap from "./checkIfPotentiallyCircularRangesOverlap";
|
|
2
|
+
import { Range } from "./types";
|
|
2
3
|
|
|
3
4
|
export default function getYOffsetForPotentiallyCircularRange(
|
|
4
|
-
range,
|
|
5
|
-
YOffsetLevelsWithRanges,
|
|
6
|
-
assignYOffsetToRange
|
|
5
|
+
range: Range,
|
|
6
|
+
YOffsetLevelsWithRanges: Range[][],
|
|
7
|
+
assignYOffsetToRange: boolean
|
|
7
8
|
) {
|
|
8
9
|
//adjust the yOffset of the range being pushed in by checking its range against other range already in the row
|
|
9
|
-
let yOffset =
|
|
10
|
+
let yOffset = 0;
|
|
10
11
|
//YOffsetLevelsWithRanges is an array of arrays (array of yOffset levels holding arrays of range)
|
|
11
12
|
//loop through y offset levels starting with the 0 level until an empty one is found and push the range into it. If none are found, add another level.
|
|
12
13
|
const openYOffsetFound = YOffsetLevelsWithRanges.some(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import getYOffsetsForPotentiallyCircularRanges from "./getYOffsetsForPotentiallyCircularRanges.js";
|
|
3
|
+
describe("getYOffsetsForPotentiallyCircularRanges", function () {
|
|
4
|
+
it("returns correct yOffset for overlapping ranges", function () {
|
|
5
|
+
const ranges = [
|
|
6
|
+
{ start: 0, end: 10, id: "1" },
|
|
7
|
+
{ start: 5, end: 20, id: "2" },
|
|
8
|
+
{ start: 15, end: 25, id: "3" }
|
|
9
|
+
];
|
|
10
|
+
getYOffsetsForPotentiallyCircularRanges(ranges, false);
|
|
11
|
+
expect(ranges).to.deep.equal([
|
|
12
|
+
{ start: 0, end: 10, id: "1", yOffset: 0 },
|
|
13
|
+
{ start: 5, end: 20, id: "2", yOffset: 1 },
|
|
14
|
+
{ start: 15, end: 25, id: "3", yOffset: 0 }
|
|
15
|
+
]);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import getYOffsetForPotentiallyCircularRange from "./getYOffsetForPotentiallyCircularRange";
|
|
2
|
+
import { Range } from "./types";
|
|
2
3
|
|
|
3
4
|
export default function getYOffsetsForPotentiallyCircularRanges(
|
|
4
|
-
ranges,
|
|
5
|
-
assignYOffsetToRange
|
|
5
|
+
ranges: Range[],
|
|
6
|
+
assignYOffsetToRange: boolean
|
|
6
7
|
) {
|
|
7
8
|
//adjust the yOffset of the range being pushed in by checking its range against other ranges already in the row
|
|
8
|
-
const yOffsets = [];
|
|
9
|
+
const yOffsets: number[] = [];
|
|
9
10
|
let maxYOffset = 0;
|
|
10
|
-
const yOffsetLevels = []; //yOffsetLevels is an array of arrays (array of yOffset levels holding arrays of ranges)
|
|
11
|
+
const yOffsetLevels: Range[][] = []; //yOffsetLevels is an array of arrays (array of yOffset levels holding arrays of ranges)
|
|
11
12
|
ranges.forEach(function (range) {
|
|
12
13
|
//loop through y offset levels starting with the 0 level until an empty one is found and push the range into it. If none are found, add another level.
|
|
13
14
|
const yOffset = getYOffsetForPotentiallyCircularRange(
|
|
@@ -5,9 +5,7 @@ describe("getZeroedRangeOverlaps", function () {
|
|
|
5
5
|
const res = getZeroedRangeOverlaps(
|
|
6
6
|
{ start: 0, end: 3 },
|
|
7
7
|
{ start: 2, end: 3 },
|
|
8
|
-
4
|
|
9
|
-
true,
|
|
10
|
-
true
|
|
8
|
+
4
|
|
11
9
|
);
|
|
12
10
|
assert.deepEqual(res, [{ start: 0, end: 1 }]);
|
|
13
11
|
});
|
|
@@ -18,9 +16,7 @@ describe("getZeroedRangeOverlaps", function () {
|
|
|
18
16
|
const res = getZeroedRangeOverlaps(
|
|
19
17
|
{ start: 0, end: 3 },
|
|
20
18
|
{ start: 2, end: 0 },
|
|
21
|
-
5
|
|
22
|
-
true,
|
|
23
|
-
true
|
|
19
|
+
5
|
|
24
20
|
);
|
|
25
21
|
assert.deepEqual(res, [
|
|
26
22
|
{ start: 3, end: 3 },
|
|
@@ -34,9 +30,7 @@ describe("getZeroedRangeOverlaps", function () {
|
|
|
34
30
|
const res = getZeroedRangeOverlaps(
|
|
35
31
|
{ start: 0, end: 3 },
|
|
36
32
|
{ start: 2, end: 1 },
|
|
37
|
-
4
|
|
38
|
-
true,
|
|
39
|
-
true
|
|
33
|
+
4
|
|
40
34
|
);
|
|
41
35
|
assert.deepEqual(res, [
|
|
42
36
|
{ start: 2, end: 3 },
|
|
@@ -50,9 +44,7 @@ describe("getZeroedRangeOverlaps", function () {
|
|
|
50
44
|
const res = getZeroedRangeOverlaps(
|
|
51
45
|
{ start: 3, end: 1 },
|
|
52
46
|
{ start: 0, end: 4 },
|
|
53
|
-
5
|
|
54
|
-
true,
|
|
55
|
-
true
|
|
47
|
+
5
|
|
56
48
|
);
|
|
57
49
|
assert.deepEqual(res, [{ start: 3, end: 1 }]);
|
|
58
50
|
});
|
|
@@ -63,9 +55,7 @@ describe("getZeroedRangeOverlaps", function () {
|
|
|
63
55
|
const res = getZeroedRangeOverlaps(
|
|
64
56
|
{ start: 3, end: 1 },
|
|
65
57
|
{ start: 1, end: 0 },
|
|
66
|
-
5
|
|
67
|
-
true,
|
|
68
|
-
true
|
|
58
|
+
5
|
|
69
59
|
);
|
|
70
60
|
assert.deepEqual(res, [
|
|
71
61
|
{ start: 2, end: 4 },
|