@teselagen/range-utils 0.1.21 → 0.1.22

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 (90) hide show
  1. package/index.js +6542 -18010
  2. package/index.mjs +6593 -18007
  3. package/index.umd.js +6836 -18306
  4. package/package.json +1 -1
  5. package/src/adjustRangeToDeletionOfAnotherRange.js +53 -0
  6. package/src/adjustRangeToDeletionOfAnotherRange.test.js +107 -0
  7. package/src/adjustRangeToInsert.js +28 -0
  8. package/src/adjustRangeToInsert.test.js +111 -0
  9. package/src/adjustRangeToRotation.js +24 -0
  10. package/src/adjustRangeToRotation.test.js +123 -0
  11. package/src/checkIfNonCircularRangesOverlap.js +30 -0
  12. package/src/checkIfNonCircularRangesOverlap.test.js +45 -0
  13. package/src/checkIfPotentiallyCircularRangesOverlap.js +16 -0
  14. package/src/checkIfPotentiallyCircularRangesOverlap.test.js +73 -0
  15. package/src/collapseOverlapsGeneratedFromRangeComparisonIfPossible.js +47 -0
  16. package/src/collapseOverlapsGeneratedFromRangeComparisonIfPossible.test.js +124 -0
  17. package/src/convertRangeIndices.js +22 -0
  18. package/src/convertRangeIndices.test.js +22 -0
  19. package/src/convertRangeTo0Based.js +5 -0
  20. package/src/convertRangeTo1Based.js +5 -0
  21. package/src/doesRangeSpanEntireSequence.js +7 -0
  22. package/src/doesRangeSpanOrigin.js +3 -0
  23. package/src/expandOrContractCircularRangeToPosition.js +41 -0
  24. package/src/expandOrContractNonCircularRangeToPosition.js +25 -0
  25. package/src/expandOrContractRangeByLength.js +12 -0
  26. package/src/expandOrContractRangeByLength.test.js +77 -0
  27. package/src/expandOrContractRangeToPosition.js +10 -0
  28. package/src/flipContainedRange.js +85 -0
  29. package/src/flipContainedRange.test.js +124 -0
  30. package/src/generateRandomRange.js +20 -0
  31. package/src/generateRandomRange.test.js +24 -0
  32. package/src/getAnnotationRangeType.js +24 -0
  33. package/src/getAnnotationRangeType.test.js +59 -0
  34. package/src/getEachPositionInRangeAsArray.js +15 -0
  35. package/src/getEachPositionInRangeAsArray.test.js +9 -0
  36. package/src/getLengthOfOverlappingRegionsBetweenTwoRanges.js +9 -0
  37. package/src/getLengthOfOverlappingRegionsBetweenTwoRanges.test.js +24 -0
  38. package/src/getMiddleOfRange.js +10 -0
  39. package/src/getMiddleOfRange.test.js +44 -0
  40. package/src/getOverlapOfNonCircularRanges.js +35 -0
  41. package/src/getOverlapsOfPotentiallyCircularRanges.js +54 -0
  42. package/src/getOverlapsOfPotentiallyCircularRanges.test.js +199 -0
  43. package/src/getPositionFromAngle.js +7 -0
  44. package/src/getRangeAngles.js +33 -0
  45. package/src/getRangeAngles.test.js +77 -0
  46. package/src/getRangeLength.js +14 -0
  47. package/src/getRangeLength.test.js +30 -0
  48. package/src/getRangesBetweenTwoRanges.js +28 -0
  49. package/src/getSequenceWithinRange.js +17 -0
  50. package/src/getSequenceWithinRange.test.js +49 -0
  51. package/src/getShortestDistanceBetweenTwoPositions.js +12 -0
  52. package/src/getShortestDistanceBetweenTwoPositions.test.js +14 -0
  53. package/src/getYOffsetForPotentiallyCircularRange.js +24 -0
  54. package/src/getYOffsetsForPotentiallyCircularRanges.js +20 -0
  55. package/src/getYOffsetsForPotentiallyCircularRanges.test.js +29 -0
  56. package/src/getZeroedRangeOverlaps.js +17 -0
  57. package/src/getZeroedRangeOverlaps.test.js +36 -0
  58. package/src/index.js +51 -0
  59. package/src/index.test.js +33 -0
  60. package/src/invertRange.js +21 -0
  61. package/src/invertRange.test.js +96 -0
  62. package/src/isPositionCloserToRangeStartThanRangeEnd.js +8 -0
  63. package/src/isPositionCloserToRangeStartThanRangeEnd.test.js +17 -0
  64. package/src/isPositionWithinRange.js +31 -0
  65. package/src/isRangeOrPositionWithinRange.js +29 -0
  66. package/src/isRangeOrPositionWithinRange.test.js +150 -0
  67. package/src/isRangeWithinRange.js +17 -0
  68. package/src/loopEachPositionInRange.js +5 -0
  69. package/src/modulatePositionByRange.js +10 -0
  70. package/src/modulatePositionByRange.test.js +12 -0
  71. package/src/modulateRangeBySequenceLength.js +11 -0
  72. package/src/modulateRangeBySequenceLength.test.js +16 -0
  73. package/src/normalizePositionByRangeLength.js +20 -0
  74. package/src/normalizePositionByRangeLength.test.js +23 -0
  75. package/src/normalizePositionByRangeLength1Based.js +5 -0
  76. package/src/normalizePositionByRangeLength1Based.test.js +9 -0
  77. package/src/normalizeRange.js +11 -0
  78. package/src/normalizeRange.test.js +9 -0
  79. package/src/provideInclusiveOptions.js +26 -0
  80. package/src/reversePositionInRange.js +13 -0
  81. package/src/splitRangeIntoTwoPartsIfItIsCircular.js +31 -0
  82. package/src/splitRangeIntoTwoPartsIfItIsCircular.test.js +33 -0
  83. package/src/translateRange.js +9 -0
  84. package/src/translateRange.test.js +20 -0
  85. package/src/trimNonCicularRangeByAnotherNonCircularRange.js +57 -0
  86. package/src/trimNumberToFitWithin0ToAnotherNumber.js +12 -0
  87. package/src/trimRangeByAnotherRange.js +102 -0
  88. package/src/trimRangeByAnotherRange.test.js +314 -0
  89. package/src/zeroSubrangeByContainerRange.js +36 -0
  90. package/src/zeroSubrangeByContainerRange.test.js +51 -0
@@ -0,0 +1,59 @@
1
+ import getAnnotationRangeType from './getAnnotationRangeType';
2
+ import chai from 'chai';
3
+ chai.should();
4
+
5
+ describe('getAnnotationRangeType', function () {
6
+ it('should get the correct sub range type give a sub range and its enclosing range', function () {
7
+ getAnnotationRangeType(
8
+ {start: 4, end: 7},
9
+ {start: 4, end: 7},
10
+ true
11
+ ).should.equal('beginningAndEnd')
12
+ getAnnotationRangeType(
13
+ {start: 4, end: 7},
14
+ {start: 4, end: 7},
15
+ false
16
+ ).should.equal('beginningAndEnd')
17
+ getAnnotationRangeType(
18
+ {start: 4, end: 7},
19
+ {start: 4, end: 8},
20
+ true
21
+ ).should.equal('start')
22
+ getAnnotationRangeType(
23
+ {start: 4, end: 7},
24
+ {start: 4, end: 8},
25
+ false
26
+ ).should.equal('end')
27
+ getAnnotationRangeType(
28
+ {start: 4, end: 7},
29
+ {start: 3, end: 8},
30
+ true
31
+ ).should.equal('middle')
32
+ getAnnotationRangeType(
33
+ {start: 4, end: 7},
34
+ {start: 3, end: 8},
35
+ false
36
+ ).should.equal('middle')
37
+ getAnnotationRangeType(
38
+ {start: 4, end: 7},
39
+ {start: 3, end: 1},
40
+ true
41
+ ).should.equal('middle')
42
+ getAnnotationRangeType(
43
+ {start: 4, end: 7},
44
+ {start: 3, end: 2},
45
+ false
46
+ ).should.equal('middle')
47
+ getAnnotationRangeType(
48
+ {start: 4, end: 7},
49
+ {start: 4, end: 1},
50
+ true
51
+ ).should.equal('start')
52
+ getAnnotationRangeType(
53
+ {start: 4, end: 7},
54
+ {start: 9, end: 7},
55
+ false
56
+ ).should.equal('start')
57
+
58
+ });
59
+ });
@@ -0,0 +1,15 @@
1
+ import normalizePositionByRangeLength from './normalizePositionByRangeLength';
2
+ import getRangeLength from './getRangeLength';
3
+
4
+ export default function getEachPositionInRangeAsArray(range, rangeMax) {
5
+ const output = [];
6
+ const length = getRangeLength(range, rangeMax);
7
+ if (!(length > 0)) {
8
+ return output
9
+ }
10
+ for (let i = range.start; i < (length + range.start); i++) {
11
+ const position = normalizePositionByRangeLength(i, rangeMax);
12
+ output.push(position)
13
+ }
14
+ return output
15
+ };
@@ -0,0 +1,9 @@
1
+ import getEachPositionInRangeAsArray from './getEachPositionInRangeAsArray';
2
+ import {expect} from 'chai';
3
+
4
+ describe('getEachPositionInRangeAsArray', function() {
5
+ it('should correctly determine whether a position is within a range', function() {
6
+ expect(getEachPositionInRangeAsArray({start: 1, end: 10}, 30)).to.deep.equal([1,2,3,4,5,6,7,8,9,10])
7
+ expect(getEachPositionInRangeAsArray({start: 10, end: 5}, 13)).to.deep.equal([10,11,12,0,1,2,3,4,5])
8
+ })
9
+ })
@@ -0,0 +1,9 @@
1
+ import getRangeLength from './getRangeLength';
2
+ import getOverlapsOfPotentiallyCircularRanges from './getOverlapsOfPotentiallyCircularRanges';
3
+
4
+ export default function getLengthOfOverlappingRegionsBetweenTwoRanges(rangeA, rangeB, maxLength) {
5
+ const overlaps = getOverlapsOfPotentiallyCircularRanges(rangeA,rangeB,maxLength);
6
+ return overlaps.reduce(function (counter, overlap) {
7
+ return counter + getRangeLength(overlap, maxLength)
8
+ }, 0)
9
+ };
@@ -0,0 +1,24 @@
1
+ import assert from 'assert';
2
+ import getLengthOfOverlappingRegionsBetweenTwoRanges from './getLengthOfOverlappingRegionsBetweenTwoRanges';
3
+ describe('getLengthOfOverlappingRegionsBetweenTwoRanges', function () {
4
+ it('should get the length of the overlaps in a simple case', function () {
5
+ const length = getLengthOfOverlappingRegionsBetweenTwoRanges({
6
+ start: 4,
7
+ end: 8
8
+ }, {
9
+ start: 5,
10
+ end: 10
11
+ }, 20);
12
+ assert.equal(length, 4)
13
+ });
14
+ it('should get the length of the overlaps', function () {
15
+ const length = getLengthOfOverlappingRegionsBetweenTwoRanges({
16
+ start: 4,
17
+ end: 8
18
+ }, {
19
+ start: 7,
20
+ end: 5
21
+ }, 20);
22
+ assert.equal(length, 4)
23
+ });
24
+ });
@@ -0,0 +1,10 @@
1
+ import getRangeLength from "./getRangeLength";
2
+ import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
3
+
4
+ export default function getMiddleOfRange(range, rangeMax) {
5
+ const len = getRangeLength({ start: range.start, end: range.end }, rangeMax);
6
+ return normalizePositionByRangeLength(
7
+ range.start + Math.floor(len / 2),
8
+ rangeMax
9
+ );
10
+ };
@@ -0,0 +1,44 @@
1
+ //0123456789
2
+ //r--------r
3
+ //
4
+ //0123
5
+ //r--r
6
+ // 0
7
+ // 3 1
8
+ // 2
9
+
10
+ import assert from "assert";
11
+
12
+ import getMiddleOfRange from "./getMiddleOfRange";
13
+ describe("getMiddleOfRange", function() {
14
+ it("should return the correct length for ranges that cross the origin", function() {
15
+ const midpoint = getMiddleOfRange({ start: 9, end: 0 }, 10);
16
+ console.log(`midpoint:`,midpoint)
17
+ assert(midpoint === 0);
18
+
19
+ });
20
+ it("should return the correct midpoint for ranges that do not cross the origin", function() {
21
+ const midpoint = getMiddleOfRange({ start: 4, end: 6 }, 10);
22
+ console.log(`midpoint:`,midpoint)
23
+ assert(midpoint === 5);
24
+
25
+ });
26
+ it("should return the correct midpoint for ranges that overlapSelf", function() {
27
+ const midpoint = getMiddleOfRange(
28
+ { start: 4, end: 9, overlapsSelf: true },
29
+ 10
30
+ );
31
+ console.log(`midpoint:`,midpoint)
32
+ assert(midpoint === 7);
33
+
34
+ });
35
+ it("should return the correct midpoint for ranges that overlapSelf and origin", function() {
36
+ const midpoint = getMiddleOfRange(
37
+ { start: 9, end: 1, overlapsSelf: true },
38
+ 10
39
+ );
40
+ console.log(`midpoint:`,midpoint)
41
+ assert(midpoint === 0);
42
+
43
+ });
44
+ });
@@ -0,0 +1,35 @@
1
+ export default function getOverlapOfNonCircularRanges(rangeA, rangeB) {
2
+ if (rangeA.start < rangeB.start) {
3
+ if (rangeA.end < rangeB.start) {
4
+ //no overlap
5
+ } else {
6
+ if (rangeA.end < rangeB.end) {
7
+ return {
8
+ start: rangeB.start,
9
+ end: rangeA.end
10
+ };
11
+ } else {
12
+ return {
13
+ start: rangeB.start,
14
+ end: rangeB.end
15
+ };
16
+ }
17
+ }
18
+ } else {
19
+ if (rangeA.start > rangeB.end) {
20
+ //no overlap
21
+ } else {
22
+ if (rangeA.end < rangeB.end) {
23
+ return {
24
+ start: rangeA.start,
25
+ end: rangeA.end
26
+ };
27
+ } else {
28
+ return {
29
+ start: rangeA.start,
30
+ end: rangeB.end
31
+ };
32
+ }
33
+ }
34
+ }
35
+ };
@@ -0,0 +1,54 @@
1
+ import {flatMap} from "lodash";
2
+ import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
3
+ import getOverlapOfNonCircularRanges from "./getOverlapOfNonCircularRanges";
4
+
5
+ //returns an array of the overlaps between two potentially circular ranges
6
+ 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
11
+ ) {
12
+ const normalizedRangeA = splitRangeIntoTwoPartsIfItIsCircular(
13
+ rangeA,
14
+ maxRangeLength
15
+ );
16
+ const normalizedRangeB = splitRangeIntoTwoPartsIfItIsCircular(
17
+ rangeB,
18
+ maxRangeLength
19
+ );
20
+
21
+ let overlaps = [];
22
+
23
+ normalizedRangeA.forEach(function(nonCircularRangeA, iA) {
24
+ normalizedRangeB.forEach(function(nonCircularRangeB, iB) {
25
+ const overlap = getOverlapOfNonCircularRanges(
26
+ nonCircularRangeA,
27
+ nonCircularRangeB
28
+ );
29
+ if (overlap) {
30
+ overlaps.push(overlap);
31
+ }
32
+ });
33
+ });
34
+ if (
35
+ joinIfPossible &&
36
+ normalizedRangeA.length === 2 &&
37
+ normalizedRangeB.length === 2 &&
38
+ maxRangeLength
39
+ ) {
40
+ //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 = {};
42
+ overlaps = flatMap(overlaps, (o, i) => {
43
+ if (o.start === 0) {
44
+ joinedOverlap.end = o.end;
45
+ return [];
46
+ } else if (o.end === maxRangeLength - 1) {
47
+ joinedOverlap.start = o.start;
48
+ return [];
49
+ }
50
+ });
51
+ overlaps.push(joinedOverlap);
52
+ }
53
+ return overlaps;
54
+ };
@@ -0,0 +1,199 @@
1
+ import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCircularRanges.js";
2
+
3
+ import assert from "assert";
4
+
5
+ describe("getOverlapsOfPotentiallyCircularRanges", function() {
6
+ it("doesnt return an overlap for non overlapping ranges", function() {
7
+ assert.deepEqual(
8
+ getOverlapsOfPotentiallyCircularRanges(
9
+ {
10
+ start: 0,
11
+ end: 100
12
+ },
13
+ {
14
+ start: 105,
15
+ end: 999
16
+ },
17
+ 1000
18
+ ),
19
+ []
20
+ );
21
+ });
22
+ it("does return overlaps for overlapping ranges", function() {
23
+ assert.deepEqual(
24
+ getOverlapsOfPotentiallyCircularRanges(
25
+ {
26
+ start: 0,
27
+ end: 100
28
+ },
29
+ {
30
+ start: 90,
31
+ end: 100
32
+ },
33
+ 1000
34
+ ),
35
+ [
36
+ {
37
+ start: 90,
38
+ end: 100
39
+ }
40
+ ]
41
+ );
42
+
43
+ assert.deepEqual(
44
+ getOverlapsOfPotentiallyCircularRanges(
45
+ {
46
+ start: 12,
47
+ end: 9
48
+ },
49
+ {
50
+ start: 0,
51
+ end: 24
52
+ },
53
+ 25
54
+ ),
55
+ [
56
+ {
57
+ start: 0,
58
+ end: 9
59
+ },
60
+ {
61
+ start: 12,
62
+ end: 24
63
+ }
64
+ ]
65
+ );
66
+ assert.deepEqual(
67
+ getOverlapsOfPotentiallyCircularRanges(
68
+ {
69
+ start: 900,
70
+ end: 100
71
+ },
72
+ {
73
+ start: 90,
74
+ end: 100
75
+ },
76
+ 1000
77
+ ),
78
+ [
79
+ {
80
+ start: 90,
81
+ end: 100
82
+ }
83
+ ]
84
+ );
85
+ assert.deepEqual(
86
+ getOverlapsOfPotentiallyCircularRanges(
87
+ {
88
+ start: 900,
89
+ end: 100
90
+ },
91
+ {
92
+ start: 900,
93
+ end: 100
94
+ },
95
+ 1000
96
+ ),
97
+ [
98
+ {
99
+ start: 0,
100
+ end: 100
101
+ },
102
+ {
103
+ start: 900,
104
+ end: 999
105
+ }
106
+ ]
107
+ );
108
+ assert.deepEqual(
109
+ getOverlapsOfPotentiallyCircularRanges(
110
+ {
111
+ start: 900,
112
+ end: 100
113
+ },
114
+ {
115
+ start: 90,
116
+ end: 910
117
+ },
118
+ 1000
119
+ ),
120
+ [
121
+ {
122
+ start: 90,
123
+ end: 100
124
+ },
125
+ {
126
+ start: 900,
127
+ end: 910
128
+ }
129
+ ]
130
+ );
131
+ assert.deepEqual(
132
+ getOverlapsOfPotentiallyCircularRanges(
133
+ {
134
+ start: 900,
135
+ end: 100
136
+ },
137
+ {
138
+ start: 90,
139
+ end: 10
140
+ },
141
+ 1000
142
+ ),
143
+ [
144
+ {
145
+ start: 0,
146
+ end: 10
147
+ },
148
+ {
149
+ start: 90,
150
+ end: 100
151
+ },
152
+ {
153
+ start: 900,
154
+ end: 999
155
+ }
156
+ ]
157
+ );
158
+ console.log(
159
+ `getOverlapsOfPotentiallyCircularRanges({
160
+ start: 5,
161
+ end: 3
162
+ }, {
163
+ start: 5,
164
+ end: 3
165
+ }, 10):`,
166
+ getOverlapsOfPotentiallyCircularRanges(
167
+ {
168
+ start: 5,
169
+ end: 3
170
+ },
171
+ {
172
+ start: 5,
173
+ end: 3
174
+ },
175
+ 10
176
+ )
177
+ );
178
+ assert.deepEqual(
179
+ getOverlapsOfPotentiallyCircularRanges(
180
+ {
181
+ start: 5,
182
+ end: 3
183
+ },
184
+ {
185
+ start: 5,
186
+ end: 3
187
+ },
188
+ 10,
189
+ true
190
+ ),
191
+ [
192
+ {
193
+ start: 5,
194
+ end: 3
195
+ }
196
+ ]
197
+ );
198
+ });
199
+ });
@@ -0,0 +1,7 @@
1
+ export default function getPositionFromAngle(angle, rangeMax, isInBetweenPositions) {
2
+ //percent through sequence * rangeMax
3
+ const unroundedPostion = angle / Math.PI / 2 * rangeMax
4
+ //return either the nearest position, or the nearest "inBetween" postion
5
+ return isInBetweenPositions ? Math.round(unroundedPostion) : Math.floor(unroundedPostion)
6
+ };
7
+
@@ -0,0 +1,33 @@
1
+ import getRangeLength from "./getRangeLength";
2
+
3
+ export default function getRangeAngles(range, rangeMax) {
4
+ const { startAngle, totalAngle, endAngle } = getStartEndAndTotalAngle(
5
+ range,
6
+ rangeMax
7
+ );
8
+
9
+ return {
10
+ startAngle,
11
+ totalAngle,
12
+ endAngle,
13
+ centerAngle: startAngle + totalAngle / 2,
14
+ locationAngles:
15
+ range.locations &&
16
+ range.locations.map((location) => {
17
+ return getRangeAngles(location, rangeMax);
18
+ })
19
+ };
20
+ }
21
+
22
+ function getStartEndAndTotalAngle(range, rangeMax) {
23
+ const rangeLength = getRangeLength(
24
+ { start: range.start, end: range.end },
25
+ rangeMax
26
+ );
27
+
28
+ return {
29
+ startAngle: 2 * Math.PI * (range.start / rangeMax),
30
+ totalAngle: (rangeLength / rangeMax) * Math.PI * 2,
31
+ endAngle: (2 * Math.PI * (range.end + 1)) / rangeMax //use a +1 here because the angle must encompass the end of the annotation
32
+ };
33
+ }
@@ -0,0 +1,77 @@
1
+ //0123456789
2
+ //r--------r
3
+ //
4
+ //0123
5
+ //r--r
6
+ // 0
7
+ // 3 1
8
+ // 2
9
+ import getRangeAngles from "./getRangeAngles";
10
+
11
+ import assert from "assert";
12
+ describe("getRangeAngles", function() {
13
+ //tnrtodo set this up
14
+
15
+ it("should return the correct angles for ranges that have joined locations", function() {
16
+ const angles = getRangeAngles(
17
+ {
18
+ start: 1,
19
+ end: 6,
20
+ locations: [
21
+ { start: 1, end: 2 },
22
+ { start: 3, end: 6 },
23
+ ],
24
+ },
25
+ 10
26
+ );
27
+ // console.log('angles: ' + JSON.stringify(angles,null,4));
28
+ const anglesInRadians = {};
29
+ Object.keys(angles).forEach(function(key) {
30
+ anglesInRadians[key] = (angles[key] * 360) / Math.PI / 2;
31
+ });
32
+
33
+ // console.log('anglesInRadians: ' + JSON.stringify(anglesInRadians,null,4));
34
+ assert(anglesInRadians.startAngle === 36);
35
+ assert(anglesInRadians.endAngle === 252);
36
+ assert(anglesInRadians.totalAngle === 216);
37
+ angles.locationAngles &&
38
+ angles.locationAngles.forEach((angles, i) => {
39
+ const anglesInRadians = {};
40
+ Object.keys(angles).forEach(function(key) {
41
+ anglesInRadians[key] = (angles[key] * 360) / Math.PI / 2;
42
+ });
43
+ // console.log('anglesInRadians:',anglesInRadians)
44
+
45
+ // console.log('anglesInRadians: ' + JSON.stringify(anglesInRadians,null,4));
46
+ assert((anglesInRadians.startAngle === i) === 0 ? 36 : 108);
47
+ assert((anglesInRadians.endAngle === i) === 0 ? 108 : 252);
48
+ assert((anglesInRadians.totalAngle === i) === 0 ? 72 : 144);
49
+ });
50
+
51
+ });
52
+ it("should return the correct angles for ranges that cross the origin", function() {
53
+ const angles = getRangeAngles({ start: 9, end: 0 }, 10);
54
+ // console.log('angles: ' + JSON.stringify(angles,null,4));
55
+ const anglesInRadians = {};
56
+ Object.keys(angles).forEach(function(key) {
57
+ anglesInRadians[key] = (angles[key] * 360) / Math.PI / 2;
58
+ });
59
+ assert(anglesInRadians.startAngle === 324);
60
+ assert(anglesInRadians.endAngle === 36);
61
+ assert(anglesInRadians.totalAngle === 72);
62
+ // console.log('anglesInRadians: ' + JSON.stringify(anglesInRadians,null,4));
63
+ });
64
+ it("should return the correct angles for ranges that do not cross the origin", function() {
65
+ const angles = getRangeAngles({ start: 1, end: 2, overlapsSelf: true }, 10);
66
+ // console.log('angles: ' + JSON.stringify(angles,null,4));
67
+ const anglesInRadians = {};
68
+ Object.keys(angles).forEach(function(key) {
69
+ anglesInRadians[key] = (angles[key] * 360) / Math.PI / 2;
70
+ });
71
+ // console.log('anglesInRadians: ' + JSON.stringify(anglesInRadians,null,4));
72
+ assert(anglesInRadians.startAngle === 36);
73
+ assert(anglesInRadians.centerAngle === 72); //even if overlapsSelf=true the center angle should still be 72
74
+ assert(anglesInRadians.endAngle === 108);
75
+ assert(anglesInRadians.totalAngle === 72);
76
+ });
77
+ });
@@ -0,0 +1,14 @@
1
+ import provideInclusiveOptions from "./provideInclusiveOptions";
2
+ export default provideInclusiveOptions(getRangeLength);
3
+ function getRangeLength(range, rangeMax) {
4
+ let toRet;
5
+ if (range.end < range.start) {
6
+ toRet = rangeMax - range.start + range.end + 1;
7
+ } else {
8
+ toRet = range.end - range.start + 1;
9
+ }
10
+ if (range.overlapsSelf && rangeMax) {
11
+ toRet += rangeMax;
12
+ }
13
+ return toRet;
14
+ }
@@ -0,0 +1,30 @@
1
+ //0123456789
2
+ //r--------r
3
+ //
4
+ //0123
5
+ //r--r
6
+ // 0
7
+ // 3 1
8
+ // 2
9
+
10
+ import assert from "assert";
11
+
12
+ import getRangeLength from "./getRangeLength";
13
+ describe("getRangeLength", function() {
14
+ it("should return the correct length for ranges that cross the origin", function() {
15
+ const length = getRangeLength({ start: 9, end: 0 }, 10);
16
+ assert(length === 2);
17
+ });
18
+ it("should return the correct length for ranges that do not cross the origin", function() {
19
+ const length = getRangeLength({ start: 4, end: 6 }, 10);
20
+ assert(length === 3);
21
+ });
22
+ it("should return the correct length for ranges that overlapSelf", function() {
23
+ const length = getRangeLength({ start: 4, end: 6, overlapsSelf: true }, 10);
24
+ assert(length === 13);
25
+ });
26
+ it("should return the correct length for ranges that overlapSelf and origin", function() {
27
+ const length = getRangeLength({ start: 9, end: 1, overlapsSelf: true }, 10);
28
+ assert(length === 13);
29
+ });
30
+ });
@@ -0,0 +1,28 @@
1
+ export default function getRangesBetweenTwoRanges(range1, range2) {
2
+ // {
3
+ // start: 85,
4
+ // end: 92
5
+ // }
6
+
7
+ // {
8
+ // start: 130,
9
+ // end: 189
10
+ // }
11
+
12
+ // start1 - end2
13
+
14
+ // start2 - end1
15
+
16
+ const newRanges = [];
17
+ if (!(range1.start > -1 && range1.end > -1 && range2.start > -1 && range2.end > -1)) {
18
+ return newRanges
19
+ }
20
+ return [{
21
+ start: range1.start,
22
+ end: range2.end,
23
+ },{
24
+ start: range2.start,
25
+ end: range1.end,
26
+ }]
27
+ };
28
+
@@ -0,0 +1,17 @@
1
+ //
2
+ export default function getSequenceWithinRange(range, sequence) {
3
+ // ac.throw([ac.range, ac.oneOfType([ac.array, ac.string])], arguments);
4
+ if (range.start < 0 || range.end < 0) return ''
5
+ if (range.start > range.end) {
6
+ //circular range
7
+ let subSequence = sequence.slice(range.start, sequence.length);
8
+ if (typeof subSequence === 'string') {
9
+ subSequence += sequence.slice(0, range.end + 1);
10
+ } else {
11
+ subSequence = subSequence.concat(sequence.slice(0, range.end + 1));
12
+ }
13
+ return subSequence;
14
+ } else {
15
+ return sequence.slice(range.start, range.end + 1);
16
+ }
17
+ };