UNPKG

53.9 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var branchingFactor = 32;
4var branchBits = 5;
5var mask = 31;
6var elementEquals = function (a, b) {
7 return a === b;
8};
9function setEquals(equals) {
10 elementEquals = equals;
11}
12exports.setEquals = setEquals;
13function createPath(depth, value) {
14 var current = value;
15 for (var i = 0; i < depth; ++i) {
16 current = new Node(undefined, [current]);
17 }
18 return current;
19}
20// Array helper functions
21function copyArray(source) {
22 var array = [];
23 for (var i = 0; i < source.length; ++i) {
24 array[i] = source[i];
25 }
26 return array;
27}
28function pushElements(source, target, offset, amount) {
29 for (var i = offset; i < offset + amount; ++i) {
30 target.push(source[i]);
31 }
32}
33function copyIndices(source, sourceStart, target, targetStart, length) {
34 for (var i = 0; i < length; ++i) {
35 target[targetStart + i] = source[sourceStart + i];
36 }
37}
38function arrayPrepend(value, array) {
39 var newLength = array.length + 1;
40 var result = new Array(newLength);
41 result[0] = value;
42 for (var i = 1; i < newLength; ++i) {
43 result[i] = array[i - 1];
44 }
45 return result;
46}
47/**
48 * Prepends an element to a node
49 */
50function nodePrepend(value, size, node) {
51 var array = arrayPrepend(value, node.array);
52 var sizes = undefined;
53 if (node.sizes !== undefined) {
54 sizes = new Array(node.sizes.length + 1);
55 sizes[0] = size;
56 for (var i = 0; i < node.sizes.length; ++i) {
57 sizes[i + 1] = node.sizes[i] + size;
58 }
59 }
60 return new Node(sizes, array);
61}
62/**
63 * Create a reverse _copy_ of an array.
64 */
65function reverseArray(array) {
66 return array.slice().reverse();
67}
68function arrayFirst(array) {
69 return array[0];
70}
71function arrayLast(array) {
72 return array[array.length - 1];
73}
74var pathResult = { path: 0, index: 0 };
75function getPath(index, offset, depth, sizes) {
76 var curOffset = (offset >> (depth * branchBits)) & mask;
77 var path = ((index >> (depth * branchBits)) & mask) - curOffset;
78 if (sizes !== undefined) {
79 while (sizes[path] <= index) {
80 path++;
81 }
82 var traversed = path === 0 ? 0 : sizes[path - 1];
83 index -= traversed;
84 }
85 pathResult.path = path;
86 pathResult.index = index;
87 return pathResult;
88}
89function updateNode(node, depth, index, offset, value) {
90 var _a = getPath(index, offset, depth, node.sizes), path = _a.path, newIndex = _a.index;
91 var array;
92 if (path < 0) {
93 // TOOD: Once `prepend` no longer uses `update` this should be removed
94 array = arrayPrepend(createPath(depth, value), node.array);
95 }
96 else {
97 array = copyArray(node.array);
98 if (depth === 0) {
99 array[path] = value;
100 }
101 else {
102 array[path] = updateNode(array[path], depth - 1, newIndex, path === 0 ? offset : 0, value);
103 }
104 }
105 return new Node(node.sizes, array);
106}
107var Node = /** @class */ (function () {
108 function Node(sizes, array) {
109 this.sizes = sizes;
110 this.array = array;
111 }
112 return Node;
113}());
114exports.Node = Node;
115function nodeNthDense(node, depth, index) {
116 var current = node;
117 for (; depth >= 0; --depth) {
118 current = current.array[(index >> (depth * branchBits)) & mask];
119 }
120 return current;
121}
122function handleOffset(depth, offset, index) {
123 index += offset;
124 for (; depth >= 0; --depth) {
125 index = index - (offset & (mask << (depth * branchBits)));
126 if (((index >> (depth * branchBits)) & mask) !== 0) {
127 break;
128 }
129 }
130 return index;
131}
132function nodeNth(node, depth, index) {
133 var path;
134 var current = node;
135 while (current.sizes !== undefined) {
136 path = (index >> (depth * branchBits)) & mask;
137 while (current.sizes[path] <= index) {
138 path++;
139 }
140 var traversed = path === 0 ? 0 : current.sizes[path - 1];
141 index -= traversed;
142 depth--;
143 current = current.array[path];
144 }
145 return nodeNthDense(current, depth, index);
146}
147function nth(index, l) {
148 if (index < 0 || l.length <= index) {
149 return undefined;
150 }
151 var prefixSize = getPrefixSize(l);
152 var suffixSize = getSuffixSize(l);
153 var offset = l.offset;
154 if (index < prefixSize) {
155 return l.prefix[prefixSize - index - 1];
156 }
157 else if (index >= l.length - suffixSize) {
158 return l.suffix[index - (l.length - suffixSize)];
159 }
160 var depth = getDepth(l);
161 return l.root.sizes === undefined
162 ? nodeNthDense(l.root, depth, offset === 0
163 ? index - prefixSize
164 : handleOffset(depth, offset, index - prefixSize))
165 : nodeNth(l.root, depth, index - prefixSize);
166}
167exports.nth = nth;
168function cloneNode(_a) {
169 var sizes = _a.sizes, array = _a.array;
170 return new Node(sizes === undefined ? undefined : copyArray(sizes), copyArray(array));
171}
172function setSizes(node, height) {
173 var sum = 0;
174 var sizeTable = [];
175 for (var i = 0; i < node.array.length; ++i) {
176 sum += sizeOfSubtree(node.array[i], height - 1);
177 sizeTable[i] = sum;
178 }
179 node.sizes = sizeTable;
180 return node;
181}
182/**
183 * Returns the number of elements stored in the node.
184 */
185function sizeOfSubtree(node, height) {
186 if (height !== 0) {
187 if (node.sizes !== undefined) {
188 return arrayLast(node.sizes);
189 }
190 else {
191 // the node is leftwise dense so all all but the last child are full
192 var lastSize = sizeOfSubtree(arrayLast(node.array), height - 1);
193 return ((node.array.length - 1) << (height * branchBits)) + lastSize;
194 }
195 }
196 else {
197 return node.array.length;
198 }
199}
200// This array should not be mutated. Thus a dummy element is placed in
201// it. Thus the affix will not be owned and thus not mutated.
202var emptyAffix = [0];
203function affixPush(a, array, length) {
204 if (array.length === length) {
205 array.push(a);
206 return array;
207 }
208 else {
209 var newArray = [];
210 copyIndices(array, 0, newArray, 0, length);
211 newArray.push(a);
212 return newArray;
213 }
214}
215// We store a bit field in list. From right to left, the first five
216// bits are suffix length, the next five are prefix length and the
217// rest is depth. The functions below are for working with the bits in
218// a sane way.
219var affixBits = 6;
220var affixMask = 63;
221function getSuffixSize(l) {
222 return l.bits & affixMask;
223}
224function getPrefixSize(l) {
225 return (l.bits >> affixBits) & affixMask;
226}
227function getDepth(l) {
228 return l.bits >> (affixBits * 2);
229}
230function setPrefix(size, bits) {
231 return (size << affixBits) | (bits & ~(affixMask << affixBits));
232}
233function setSuffix(size, bits) {
234 return size | (bits & ~affixMask);
235}
236function setDepth(depth, bits) {
237 return ((depth << (affixBits * 2)) | (bits & (affixMask | (affixMask << affixBits))));
238}
239function incrementPrefix(bits) {
240 return bits + (1 << affixBits);
241}
242function incrementSuffix(bits) {
243 return bits + 1;
244}
245function incrementDepth(bits) {
246 return bits + (1 << (affixBits * 2));
247}
248function decrementDepth(bits) {
249 return bits - (1 << (affixBits * 2));
250}
251function createBits(depth, prefixSize, suffixSize) {
252 return (depth << (affixBits * 2)) | (prefixSize << affixBits) | suffixSize;
253}
254/*
255 * Invariants that any list `l` should satisfy
256 *
257 * 1. If `l.root !== undefined` then `getSuffixSize(l) !== 0` and
258 * `getPrefixSize(l) !== 0`. The invariant ensures that `first` and
259 * `last` never have to look in the root and that they therefore
260 * take O(1) time.
261 * 2. If a tree or sub-tree does not have a size-table then all leaf
262 nodes in the tree are of size 32.
263 */
264var List = /** @class */ (function () {
265 function List(bits, offset, length, root, suffix, prefix) {
266 this.bits = bits;
267 this.offset = offset;
268 this.length = length;
269 this.root = root;
270 this.suffix = suffix;
271 this.prefix = prefix;
272 }
273 List.prototype[Symbol.iterator] = function () {
274 return new ListIterator(this);
275 };
276 return List;
277}());
278exports.List = List;
279function cloneList(l) {
280 return new List(l.bits, l.offset, l.length, l.root, l.suffix, l.prefix);
281}
282var ListIterator = /** @class */ (function () {
283 function ListIterator(l) {
284 this.l = l;
285 this.result = { done: false, value: undefined };
286 this.idx = -1;
287 this.prefixSize = getPrefixSize(l);
288 this.middleSize = l.length - getSuffixSize(l);
289 if (l.root !== undefined) {
290 var depth = getDepth(l);
291 this.stack = new Array(depth + 1);
292 this.indices = new Array(depth + 1);
293 var currentNode = l.root.array;
294 for (var i = depth; 0 <= i; --i) {
295 this.stack[i] = currentNode;
296 this.indices[i] = 0;
297 currentNode = currentNode[0].array;
298 }
299 this.indices[0] = -1;
300 }
301 }
302 ListIterator.prototype.nextInTree = function () {
303 var i = 0;
304 while (++this.indices[i] === this.stack[i].length) {
305 this.indices[i] = 0;
306 ++i;
307 }
308 for (; 0 < i; --i) {
309 this.stack[i - 1] = this.stack[i][this.indices[i]].array;
310 }
311 };
312 ListIterator.prototype.next = function () {
313 var newVal;
314 var idx = ++this.idx;
315 if (idx < this.prefixSize) {
316 newVal = this.l.prefix[this.prefixSize - idx - 1];
317 }
318 else if (idx < this.middleSize) {
319 this.nextInTree();
320 newVal = this.stack[0][this.indices[0]];
321 }
322 else if (idx < this.l.length) {
323 newVal = this.l.suffix[idx - this.middleSize];
324 }
325 else {
326 this.result.done = true;
327 }
328 this.result.value = newVal;
329 return this.result;
330 };
331 return ListIterator;
332}());
333// prepend & append
334function prepend(value, l) {
335 var prefixSize = getPrefixSize(l);
336 if (prefixSize < 32) {
337 return new List(incrementPrefix(l.bits), l.offset, l.length + 1, l.root, l.suffix, affixPush(value, l.prefix, prefixSize));
338 }
339 else {
340 var newList = cloneList(l);
341 prependNodeToTree(newList, reverseArray(l.prefix));
342 var newPrefix = [value];
343 newList.prefix = newPrefix;
344 newList.length++;
345 newList.bits = setPrefix(1, newList.bits);
346 return newList;
347 }
348}
349exports.prepend = prepend;
350/**
351 * Traverses down the left edge of the tree and copies k nodes.
352 * Returns the last copied node.
353 * @param l
354 * @param k The number of nodes to copy. Will always be at least 1.
355 * @param leafSize The number of elements in the leaf that will be
356 * inserted.
357 */
358function copyLeft(l, k, leafSize) {
359 var currentNode = cloneNode(l.root); // copy root
360 l.root = currentNode; // install copy of root
361 for (var i = 1; i < k; ++i) {
362 var index = 0; // go left
363 if (currentNode.sizes !== undefined) {
364 for (var i_1 = 0; i_1 < currentNode.sizes.length; ++i_1) {
365 currentNode.sizes[i_1] += leafSize;
366 }
367 }
368 var newNode = cloneNode(currentNode.array[index]);
369 // Install the copied node
370 currentNode.array[index] = newNode;
371 currentNode = newNode;
372 }
373 return currentNode;
374}
375function prependSizes(n, sizes) {
376 if (sizes === undefined) {
377 return undefined;
378 }
379 else {
380 var newSizes = new Array(sizes.length + 1);
381 newSizes[0] = n;
382 for (var i = 0; i < sizes.length; ++i) {
383 newSizes[i + 1] = sizes[i] + n;
384 }
385 return newSizes;
386 }
387}
388/**
389 * Prepends a node to a tree. Either by shifting the nodes in the root
390 * left or by increasing the height
391 */
392function prependTopTree(l, depth, node) {
393 var newOffset;
394 if (l.root.array.length < branchingFactor) {
395 // There is space in the root
396 newOffset = Math.pow(32, depth) - 32;
397 l.root = new Node(prependSizes(32, l.root.sizes), arrayPrepend(createPath(depth - 1, node), l.root.array));
398 }
399 else {
400 // We need to create a new root
401 l.bits = incrementDepth(l.bits);
402 var sizes = l.root.sizes === undefined
403 ? undefined
404 : [32, arrayLast(l.root.sizes) + 32];
405 newOffset = depth === 0 ? 0 : Math.pow(32, (depth + 1)) - 32;
406 l.root = new Node(sizes, [createPath(depth, node), l.root]);
407 }
408 return newOffset;
409}
410/**
411 * Takes a RRB-tree and a node tail. It then prepends the node to the
412 * tree.
413 * @param l The subject for prepending. `l` will be mutated. Nodes in
414 * the tree will _not_ be mutated.
415 * @param node The node that should be prepended to the tree.
416 */
417function prependNodeToTree(l, array) {
418 if (l.root === undefined) {
419 if (getSuffixSize(l) === 0) {
420 // ensure invariant 1
421 l.bits = setSuffix(array.length, l.bits);
422 l.suffix = array;
423 }
424 else {
425 l.root = new Node(undefined, array);
426 }
427 return l;
428 }
429 else {
430 var node = new Node(undefined, array);
431 var depth = getDepth(l);
432 var newOffset = 0;
433 if (l.root.sizes === undefined) {
434 if (l.offset !== 0) {
435 newOffset = l.offset - branchingFactor;
436 l.root = prependDense(l.root, depth - 1, (l.offset - 1) >> 5, l.offset >> 5, node);
437 }
438 else {
439 // in this case we can be sure that the is not room in the tree
440 // for the new node
441 newOffset = prependTopTree(l, depth, node);
442 }
443 }
444 else {
445 // represents how many nodes _with size-tables_ that we should copy.
446 var copyableCount = 0;
447 // go down while there is size tables
448 var nodesTraversed = 0;
449 var currentNode = l.root;
450 while (currentNode.sizes !== undefined && nodesTraversed < depth) {
451 ++nodesTraversed;
452 if (currentNode.array.length < 32) {
453 // there is room if offset is > 0 or if the first node does not
454 // contain as many nodes as it possibly can
455 copyableCount = nodesTraversed;
456 }
457 currentNode = currentNode.array[0];
458 }
459 if (l.offset !== 0) {
460 var copiedNode = copyLeft(l, nodesTraversed, 32);
461 for (var i = 0; i < copiedNode.sizes.length; ++i) {
462 copiedNode.sizes[i] += branchingFactor;
463 }
464 copiedNode.array[0] = prependDense(copiedNode.array[0], depth - nodesTraversed - 1, (l.offset - 1) >> 5, l.offset >> 5, node);
465 l.offset = l.offset - branchingFactor;
466 return l;
467 }
468 else {
469 if (copyableCount === 0) {
470 l.offset = prependTopTree(l, depth, node);
471 }
472 else {
473 var parent_1;
474 var prependableNode = void 0;
475 // Copy the part of the path with size tables
476 if (copyableCount > 1) {
477 parent_1 = copyLeft(l, copyableCount - 1, 32);
478 prependableNode = parent_1.array[0];
479 }
480 else {
481 parent_1 = undefined;
482 prependableNode = l.root;
483 }
484 var path = createPath(depth - copyableCount, node);
485 // add offset
486 l.offset = Math.pow(32, (depth - copyableCount + 1)) - 32;
487 var prepended = nodePrepend(path, 32, prependableNode);
488 if (parent_1 === undefined) {
489 l.root = prepended;
490 }
491 else {
492 parent_1.array[0] = prepended;
493 }
494 }
495 return l;
496 }
497 }
498 l.offset = newOffset;
499 return l;
500 }
501}
502function prependDense(node, depth, index, offset, value) {
503 var curOffset = (offset >> (depth * branchBits)) & mask;
504 var path = ((index >> (depth * branchBits)) & mask) - curOffset;
505 var array;
506 if (path < 0) {
507 array = arrayPrepend(createPath(depth, value), node.array);
508 }
509 else {
510 array = copyArray(node.array);
511 if (depth === 0) {
512 array[path] = value;
513 }
514 else {
515 array[path] = updateNode(array[path], depth - 1, index, path === 0 ? offset : 0, value);
516 }
517 }
518 return new Node(node.sizes, array);
519}
520function append(value, l) {
521 var suffixSize = getSuffixSize(l);
522 if (suffixSize < 32) {
523 return new List(incrementSuffix(l.bits), l.offset, l.length + 1, l.root, affixPush(value, l.suffix, suffixSize), l.prefix);
524 }
525 var newSuffix = [value];
526 var newList = cloneList(l);
527 appendNodeToTree(newList, l.suffix);
528 newList.suffix = newSuffix;
529 newList.length++;
530 newList.bits = setSuffix(1, newList.bits);
531 return newList;
532}
533exports.append = append;
534function list() {
535 var elements = [];
536 for (var _i = 0; _i < arguments.length; _i++) {
537 elements[_i] = arguments[_i];
538 }
539 var l = empty();
540 for (var _a = 0, elements_1 = elements; _a < elements_1.length; _a++) {
541 var element = elements_1[_a];
542 l = append(element, l);
543 }
544 return l;
545}
546exports.list = list;
547function of(a) {
548 return list(a);
549}
550exports.of = of;
551function pair(first, second) {
552 return new List(2, 0, 2, undefined, [first, second], emptyAffix);
553}
554exports.pair = pair;
555function empty() {
556 return new List(0, 0, 0, undefined, emptyAffix, emptyAffix);
557}
558exports.empty = empty;
559function repeat(value, times) {
560 var l = empty();
561 while (--times >= 0) {
562 l = append(value, l);
563 }
564 return l;
565}
566exports.repeat = repeat;
567/**
568 * Generates a new list by calling a function with the current index
569 * `n` times.
570 * @param func Function used to generate list values.
571 * @param times Number of values to generate.
572 */
573function times(func, times) {
574 var l = empty();
575 for (var i = 0; i < times; i++) {
576 l = append(func(i), l);
577 }
578 return l;
579}
580exports.times = times;
581/**
582 * Gets the length of a list.
583 *
584 * @example
585 * length(list(0, 1, 2, 3)); //=> 4
586 *
587 * @param l The list to get the length of.
588 */
589function length(l) {
590 return l.length;
591}
592exports.length = length;
593function first(l) {
594 if (getPrefixSize(l) !== 0) {
595 return arrayLast(l.prefix);
596 }
597 else if (getSuffixSize(l) !== 0) {
598 return arrayFirst(l.suffix);
599 }
600}
601exports.first = first;
602function last(l) {
603 if (getSuffixSize(l) !== 0) {
604 return arrayLast(l.suffix);
605 }
606 else if (getPrefixSize(l) !== 0) {
607 return arrayFirst(l.prefix);
608 }
609}
610exports.last = last;
611// map
612function mapArray(f, array) {
613 var result = new Array(array.length);
614 for (var i = 0; i < array.length; ++i) {
615 result[i] = f(array[i]);
616 }
617 return result;
618}
619function mapNode(f, node, depth) {
620 if (depth !== 0) {
621 var array = node.array;
622 var result = new Array(array.length);
623 for (var i = 0; i < array.length; ++i) {
624 result[i] = mapNode(f, array[i], depth - 1);
625 }
626 return new Node(node.sizes, result);
627 }
628 else {
629 return new Node(undefined, mapArray(f, node.array));
630 }
631}
632function mapAffix(f, suffix, length) {
633 var newSuffix = new Array(length);
634 for (var i = 0; i < length; ++i) {
635 newSuffix[i] = f(suffix[i]);
636 }
637 return newSuffix;
638}
639function map(f, l) {
640 return new List(l.bits, l.offset, l.length, l.root === undefined ? undefined : mapNode(f, l.root, getDepth(l)), mapAffix(f, l.suffix, getSuffixSize(l)), mapAffix(f, l.prefix, getPrefixSize(l)));
641}
642exports.map = map;
643function pluck(key, l) {
644 return map(function (a) { return a[key]; }, l);
645}
646exports.pluck = pluck;
647function range(start, end) {
648 var list = empty();
649 for (var i = start; i < end; ++i) {
650 list = append(i, list);
651 }
652 return list;
653}
654exports.range = range;
655// fold
656function foldlSuffix(f, acc, array, length) {
657 for (var i = 0; i < length; ++i) {
658 acc = f(acc, array[i]);
659 }
660 return acc;
661}
662function foldlPrefix(f, acc, array, length) {
663 for (var i = length - 1; 0 <= i; --i) {
664 acc = f(acc, array[i]);
665 }
666 return acc;
667}
668function foldlNode(f, acc, node, depth) {
669 var array = node.array;
670 if (depth === 0) {
671 return foldlSuffix(f, acc, array, array.length);
672 }
673 for (var i = 0; i < array.length; ++i) {
674 acc = foldlNode(f, acc, array[i], depth - 1);
675 }
676 return acc;
677}
678/**
679 * Folds a function over a list. Left-associative.
680 *
681 * @example
682 * foldl((n, m) => n - m, 1, list(2, 3, 4, 5)); //=> -13
683 */
684function foldl(f, initial, l) {
685 var suffixSize = getSuffixSize(l);
686 var prefixSize = getPrefixSize(l);
687 initial = foldlPrefix(f, initial, l.prefix, prefixSize);
688 if (l.root !== undefined) {
689 initial = foldlNode(f, initial, l.root, getDepth(l));
690 }
691 return foldlSuffix(f, initial, l.suffix, suffixSize);
692}
693exports.foldl = foldl;
694exports.reduce = foldl;
695function forEach(callback, l) {
696 foldl(function (_, element) { return callback(element); }, undefined, l);
697}
698exports.forEach = forEach;
699function filter(predicate, l) {
700 return foldl(function (acc, a) { return (predicate(a) ? append(a, acc) : acc); }, empty(), l);
701}
702exports.filter = filter;
703function reject(predicate, l) {
704 return foldl(function (acc, a) { return (predicate(a) ? acc : append(a, acc)); }, empty(), l);
705}
706exports.reject = reject;
707function partition(predicate, l) {
708 var _a = foldl(function (obj, a) { return (predicate(a)
709 ? (obj.fst = append(a, obj.fst))
710 : (obj.snd = append(a, obj.snd)),
711 obj); }, { fst: empty(), snd: empty() }, l), fst = _a.fst, snd = _a.snd;
712 return pair(fst, snd);
713}
714exports.partition = partition;
715function join(separator, l) {
716 return foldl(function (a, b) { return (a.length === 0 ? b : a + separator + b); }, "", l);
717}
718exports.join = join;
719function foldrSuffix(f, initial, array, length) {
720 var acc = initial;
721 for (var i = length - 1; 0 <= i; --i) {
722 acc = f(array[i], acc);
723 }
724 return acc;
725}
726function foldrPrefix(f, initial, array, length) {
727 var acc = initial;
728 for (var i = 0; i < length; ++i) {
729 acc = f(array[i], acc);
730 }
731 return acc;
732}
733function foldrNode(f, initial, _a, depth) {
734 var array = _a.array;
735 if (depth === 0) {
736 return foldrSuffix(f, initial, array, array.length);
737 }
738 var acc = initial;
739 for (var i = array.length - 1; 0 <= i; --i) {
740 acc = foldrNode(f, acc, array[i], depth - 1);
741 }
742 return acc;
743}
744function foldr(f, initial, l) {
745 var suffixSize = getSuffixSize(l);
746 var prefixSize = getPrefixSize(l);
747 var acc = foldrSuffix(f, initial, l.suffix, suffixSize);
748 if (l.root !== undefined) {
749 acc = foldrNode(f, acc, l.root, getDepth(l));
750 }
751 return foldrPrefix(f, acc, l.prefix, prefixSize);
752}
753exports.foldr = foldr;
754exports.reduceRight = foldr;
755function ap(listF, l) {
756 return flatten(map(function (f) { return map(f, l); }, listF));
757}
758exports.ap = ap;
759function flatten(nested) {
760 return foldl(concat, empty(), nested);
761}
762exports.flatten = flatten;
763function chain(f, l) {
764 return flatten(map(f, l));
765}
766exports.chain = chain;
767function foldlSuffixCb(cb, state, array, length) {
768 for (var i = 0; i < length && cb(array[i], state); ++i) { }
769 return i === length;
770}
771function foldlPrefixCb(cb, state, array, length) {
772 for (var i = length - 1; 0 <= i && cb(array[i], state); --i) { }
773 return i === -1;
774}
775function foldlNodeCb(cb, state, node, depth) {
776 var array = node.array;
777 if (depth === 0) {
778 return foldlSuffixCb(cb, state, array, array.length);
779 }
780 for (var i = 0; i < array.length && foldlNodeCb(cb, state, array[i], depth - 1); ++i) { }
781 return i === array.length;
782}
783/**
784 * This function is a lot like a fold. But the reducer function is
785 * supposed to mutate its state instead of returning it. Instead of
786 * returning a new state it returns a boolean that tells wether or not
787 * to continue the fold. `true` indicates that the folding should
788 * continue.
789 */
790function foldlCb(cb, state, l) {
791 var suffixSize = getSuffixSize(l);
792 var prefixSize = getPrefixSize(l);
793 if (foldlPrefixCb(cb, state, l.prefix, prefixSize)) {
794 if (l.root !== undefined) {
795 if (foldlNodeCb(cb, state, l.root, getDepth(l))) {
796 foldlSuffixCb(cb, state, l.suffix, suffixSize);
797 }
798 }
799 else {
800 foldlSuffixCb(cb, state, l.suffix, suffixSize);
801 }
802 }
803 return state;
804}
805function everyCb(value, state) {
806 return (state.result = state.predicate(value));
807}
808function every(predicate, l) {
809 return foldlCb(everyCb, { predicate: predicate, result: true }, l).result;
810}
811exports.every = every;
812exports.all = every;
813function someCb(value, state) {
814 return !(state.result = state.predicate(value));
815}
816function some(predicate, l) {
817 return foldlCb(someCb, { predicate: predicate, result: false }, l).result;
818}
819exports.some = some;
820// tslint:disable-next-line:variable-name
821exports.any = some;
822function none(predicate, l) {
823 return !some(predicate, l);
824}
825exports.none = none;
826function findCb(value, state) {
827 if (state.predicate(value)) {
828 state.result = value;
829 return false;
830 }
831 else {
832 return true;
833 }
834}
835function find(predicate, l) {
836 return foldlCb(findCb, { predicate: predicate, result: undefined }, l)
837 .result;
838}
839exports.find = find;
840function indexOfCb(value, state) {
841 ++state.index;
842 return !(state.found = elementEquals(value, state.element));
843}
844function indexOf(element, l) {
845 var _a = foldlCb(indexOfCb, { element: element, found: false, index: -1 }, l), found = _a.found, index = _a.index;
846 return found ? index : -1;
847}
848exports.indexOf = indexOf;
849function findIndexCb(value, state) {
850 ++state.index;
851 return !(state.found = state.predicate(value));
852}
853function findIndex(predicate, l) {
854 var _a = foldlCb(findIndexCb, { predicate: predicate, found: false, index: -1 }, l), found = _a.found, index = _a.index;
855 return found ? index : -1;
856}
857exports.findIndex = findIndex;
858var containsState = {
859 element: undefined,
860 result: false
861};
862function containsCb(value, state) {
863 return !(state.result = value === state.element);
864}
865function includes(element, l) {
866 containsState.element = element;
867 containsState.result = false;
868 return foldlCb(containsCb, containsState, l).result;
869}
870exports.includes = includes;
871exports.contains = includes;
872var equalsState = {
873 iterator: undefined,
874 equals: true
875};
876function equalsCb(value2, state) {
877 var value = state.iterator.next().value;
878 return (state.equals = elementEquals(value, value2));
879}
880function equals(firstList, secondList) {
881 if (firstList === secondList) {
882 return true;
883 }
884 else if (firstList.length !== secondList.length) {
885 return false;
886 }
887 else {
888 equalsState.iterator = secondList[Symbol.iterator]();
889 equalsState.equals = true;
890 return foldlCb(equalsCb, equalsState, firstList).equals;
891 }
892}
893exports.equals = equals;
894// concat
895var eMax = 2;
896function createConcatPlan(array) {
897 var sizes = [];
898 var sum = 0;
899 for (var i_2 = 0; i_2 < array.length; ++i_2) {
900 sum += array[i_2].array.length; // FIXME: maybe only access array once
901 sizes[i_2] = array[i_2].array.length;
902 }
903 var optimalLength = Math.ceil(sum / branchingFactor);
904 var n = array.length;
905 var i = 0;
906 if (optimalLength + eMax >= n) {
907 return undefined; // no rebalancing needed
908 }
909 while (optimalLength + eMax < n) {
910 while (sizes[i] > branchingFactor - eMax / 2) {
911 // Skip nodes that are already sufficiently balanced
912 ++i;
913 }
914 // the node at this index is too short
915 var remaining = sizes[i]; // number of elements to re-distribute
916 do {
917 var size = Math.min(remaining + sizes[i + 1], branchingFactor);
918 sizes[i] = size;
919 remaining = remaining - (size - sizes[i + 1]);
920 ++i;
921 } while (remaining > 0);
922 // Shift nodes after
923 for (var j = i; j <= n - 1; ++j) {
924 sizes[j] = sizes[j + 1];
925 }
926 --i;
927 --n;
928 }
929 sizes.length = n;
930 return sizes;
931}
932/**
933 * Combines the children of three nodes into an array. The last child
934 * of `left` and the first child of `right is ignored as they've been
935 * concatenated into `center`.
936 */
937function concatNodeMerge(left, center, right) {
938 var array = [];
939 if (left !== undefined) {
940 for (var i = 0; i < left.array.length - 1; ++i) {
941 array.push(left.array[i]);
942 }
943 }
944 for (var i = 0; i < center.array.length; ++i) {
945 array.push(center.array[i]);
946 }
947 if (right !== undefined) {
948 for (var i = 1; i < right.array.length; ++i) {
949 array.push(right.array[i]);
950 }
951 }
952 return array;
953}
954function executeConcatPlan(merged, plan, height) {
955 var result = [];
956 var sourceIdx = 0; // the current node we're copying from
957 var offset = 0; // elements in source already used
958 for (var _i = 0, plan_1 = plan; _i < plan_1.length; _i++) {
959 var toMove = plan_1[_i];
960 var source = merged[sourceIdx].array;
961 if (toMove === source.length && offset === 0) {
962 // source matches target exactly, reuse source
963 result.push(merged[sourceIdx]);
964 ++sourceIdx;
965 }
966 else {
967 var node = new Node(undefined, []);
968 while (toMove > 0) {
969 var available = source.length - offset;
970 var itemsToCopy = Math.min(toMove, available);
971 pushElements(source, node.array, offset, itemsToCopy);
972 if (toMove >= available) {
973 ++sourceIdx;
974 source = merged[sourceIdx].array;
975 offset = 0;
976 }
977 else {
978 offset += itemsToCopy;
979 }
980 toMove -= itemsToCopy;
981 }
982 if (height > 1) {
983 // Set sizes on children unless they are leaf nodes
984 setSizes(node, height - 1);
985 }
986 result.push(node);
987 }
988 }
989 return result;
990}
991/**
992 * Takes three nodes and returns a new node with the content of the
993 * three nodes. Note: The returned node does not have its size table
994 * set correctly. The caller must do that.
995 */
996function rebalance(left, center, right, height, top) {
997 var merged = concatNodeMerge(left, center, right);
998 var plan = createConcatPlan(merged);
999 var balanced = plan !== undefined ? executeConcatPlan(merged, plan, height) : merged;
1000 if (balanced.length <= branchingFactor) {
1001 if (top === true) {
1002 return new Node(undefined, balanced);
1003 }
1004 else {
1005 // Return a single node with extra height for balancing at next
1006 // level
1007 return new Node(undefined, [
1008 setSizes(new Node(undefined, balanced), height)
1009 ]);
1010 }
1011 }
1012 else {
1013 return new Node(undefined, [
1014 setSizes(new Node(undefined, balanced.slice(0, branchingFactor)), height),
1015 setSizes(new Node(undefined, balanced.slice(branchingFactor)), height)
1016 ]);
1017 }
1018}
1019function concatSubTree(left, lDepth, right, rDepth, isTop) {
1020 if (lDepth > rDepth) {
1021 var c = concatSubTree(arrayLast(left.array), lDepth - 1, right, rDepth, false);
1022 return rebalance(left, c, undefined, lDepth, isTop);
1023 }
1024 else if (lDepth < rDepth) {
1025 var c = concatSubTree(left, lDepth, arrayFirst(right.array), rDepth - 1, false);
1026 return rebalance(undefined, c, right, rDepth, isTop);
1027 }
1028 else if (lDepth === 0) {
1029 return new Node(undefined, [left, right]);
1030 }
1031 else {
1032 var c = concatSubTree(arrayLast(left.array), lDepth - 1, arrayFirst(right.array), rDepth - 1, false);
1033 return rebalance(left, c, right, lDepth, isTop);
1034 }
1035}
1036function getHeight(node) {
1037 if (node.array[0] instanceof Node) {
1038 return 1 + getHeight(node.array[0]);
1039 }
1040 else {
1041 return 0;
1042 }
1043}
1044/**
1045 * Takes a RRB-tree and an affix. It then appends the node to the
1046 * tree.
1047 * @param l The subject for appending. `l` will be mutated. Nodes in
1048 * the tree will _not_ be mutated.
1049 * @param array The affix that should be appended to the tree.
1050 */
1051function appendNodeToTree(l, array) {
1052 if (l.root === undefined) {
1053 // The old list has no content in tree, all content is in affixes
1054 if (getPrefixSize(l) === 0) {
1055 l.bits = setPrefix(array.length, l.bits);
1056 l.prefix = reverseArray(array);
1057 }
1058 else {
1059 l.root = new Node(undefined, array);
1060 }
1061 return l;
1062 }
1063 var depth = getDepth(l);
1064 var index = l.length - 1 - getPrefixSize(l);
1065 var nodesToCopy = 0;
1066 var nodesVisited = 0;
1067 var shift = depth * 5;
1068 var currentNode = l.root;
1069 if (Math.pow(32, (depth + 1)) < index) {
1070 shift = 0; // there is no room
1071 nodesVisited = depth;
1072 }
1073 while (shift > 5) {
1074 var childIndex = void 0;
1075 if (currentNode.sizes === undefined) {
1076 // does not have size table
1077 childIndex = (index >> shift) & mask;
1078 index &= ~(mask << shift); // wipe just used bits
1079 }
1080 else {
1081 childIndex = currentNode.array.length - 1;
1082 index -= currentNode.sizes[childIndex - 1];
1083 }
1084 nodesVisited++;
1085 if (childIndex < mask) {
1086 // we are not going down the far right path, this implies that
1087 // there is still room in the current node
1088 nodesToCopy = nodesVisited;
1089 }
1090 currentNode = currentNode.array[childIndex];
1091 if (currentNode === undefined) {
1092 // This will only happened in a pvec subtree. The index does not
1093 // exist so we'll have to create a new path from here on.
1094 nodesToCopy = nodesVisited;
1095 shift = 5; // Set shift to break out of the while-loop
1096 }
1097 shift -= 5;
1098 }
1099 if (shift !== 0) {
1100 nodesVisited++;
1101 if (currentNode.array.length < branchingFactor) {
1102 // there is room in the found node
1103 nodesToCopy = nodesVisited;
1104 }
1105 }
1106 var node = new Node(undefined, array);
1107 if (nodesToCopy === 0) {
1108 // there was no room in the found node
1109 var newPath = nodesVisited === 0 ? node : createPath(nodesVisited, node);
1110 var newRoot = new Node(undefined, [l.root, newPath]);
1111 l.root = newRoot;
1112 l.bits = incrementDepth(l.bits);
1113 }
1114 else {
1115 var copiedNode = copyFirstK(l, l, nodesToCopy, array.length);
1116 var leaf = appendEmpty(copiedNode, depth - nodesToCopy);
1117 leaf.array.push(node);
1118 }
1119 return l;
1120}
1121/**
1122 * Traverses down the right edge of the tree and copies k nodes
1123 * @param oldList
1124 * @param newList
1125 * @param k The number of nodes to copy. Will always be at least 1.
1126 * @param leafSize The number of elements in the leaf that will be inserted.
1127 */
1128function copyFirstK(oldList, newList, k, leafSize) {
1129 var currentNode = cloneNode(oldList.root); // copy root
1130 newList.root = currentNode; // install root
1131 for (var i = 1; i < k; ++i) {
1132 var index = currentNode.array.length - 1;
1133 if (currentNode.sizes !== undefined) {
1134 currentNode.sizes[index] += leafSize;
1135 }
1136 var newNode = cloneNode(currentNode.array[index]);
1137 // Install the copied node
1138 currentNode.array[index] = newNode;
1139 currentNode = newNode;
1140 }
1141 if (currentNode.sizes !== undefined) {
1142 currentNode.sizes.push(arrayLast(currentNode.sizes) + leafSize);
1143 }
1144 return currentNode;
1145}
1146function appendEmpty(node, depth) {
1147 if (depth === 0) {
1148 return node;
1149 }
1150 var current = new Node(undefined, []);
1151 node.array.push(current);
1152 for (var i = 1; i < depth; ++i) {
1153 var newNode = new Node(undefined, []);
1154 current.array[0] = newNode;
1155 current = newNode;
1156 }
1157 return current;
1158}
1159/*
1160function concatSuffix<A>(
1161 left: A[], lSize: number, right: A[], rSize: number
1162): A[] {
1163 const newArray = new Array(lSize + rSize);
1164 for (let i = 0; i < lSize; ++i) {
1165 newArray[i] = left[i];
1166 }
1167 for (let i = 0; i < rSize; ++i) {
1168 newArray[lSize + i] = right[i];
1169 }
1170 return newArray;
1171}
1172*/
1173var concatBuffer = new Array(3);
1174function concatAffixes(left, right) {
1175 // TODO: Try and find a neat way to reduce the LOC here
1176 var nr = 0;
1177 var arrIdx = 0;
1178 var i = 0;
1179 var length = getSuffixSize(left);
1180 concatBuffer[nr] = [];
1181 for (i = 0; i < length; ++i) {
1182 concatBuffer[nr][arrIdx] = left.suffix[i];
1183 if (++arrIdx === 32) {
1184 arrIdx = 0;
1185 ++nr;
1186 concatBuffer[nr] = [];
1187 }
1188 }
1189 length = getPrefixSize(right);
1190 for (i = 0; i < length; ++i) {
1191 concatBuffer[nr][arrIdx] = right.prefix[length - 1 - i];
1192 if (++arrIdx === 32) {
1193 arrIdx = 0;
1194 ++nr;
1195 concatBuffer[nr] = [];
1196 }
1197 }
1198 length = getSuffixSize(right);
1199 for (i = 0; i < length; ++i) {
1200 concatBuffer[nr][arrIdx] = right.suffix[i];
1201 if (++arrIdx === 32) {
1202 arrIdx = 0;
1203 ++nr;
1204 concatBuffer[nr] = [];
1205 }
1206 }
1207 return nr;
1208}
1209function concat(left, right) {
1210 if (left.length === 0) {
1211 return right;
1212 }
1213 else if (right.length === 0) {
1214 return left;
1215 }
1216 var newSize = left.length + right.length;
1217 var rightSuffixSize = getSuffixSize(right);
1218 var newList = cloneList(left);
1219 if (right.root === undefined) {
1220 // right is nothing but a prefix and a suffix
1221 var nrOfAffixes = concatAffixes(left, right);
1222 for (var i = 0; i < nrOfAffixes; ++i) {
1223 newList = appendNodeToTree(newList, concatBuffer[i]);
1224 newList.length += concatBuffer[i].length;
1225 // wipe pointer, otherwise it might end up keeping the array alive
1226 concatBuffer[i] = undefined;
1227 }
1228 newList.length = newSize;
1229 newList.suffix = concatBuffer[nrOfAffixes];
1230 newList.bits = setSuffix(concatBuffer[nrOfAffixes].length, newList.bits);
1231 concatBuffer[nrOfAffixes] = undefined;
1232 return newList;
1233 }
1234 else {
1235 var leftSuffixSize = getSuffixSize(left);
1236 if (leftSuffixSize > 0) {
1237 newList = appendNodeToTree(newList, left.suffix.slice(0, leftSuffixSize));
1238 newList.length += leftSuffixSize;
1239 }
1240 newList = appendNodeToTree(newList, right.prefix.slice(0, getPrefixSize(right)).reverse());
1241 var newNode = concatSubTree(newList.root, getDepth(newList), right.root, getDepth(right), true);
1242 var newDepth = getHeight(newNode);
1243 setSizes(newNode, newDepth);
1244 var bits = createBits(newDepth, getPrefixSize(newList), rightSuffixSize);
1245 // FIXME: Return `newList` here
1246 return new List(bits, 0, newSize, newNode, right.suffix, newList.prefix);
1247 }
1248}
1249exports.concat = concat;
1250function update(index, a, l) {
1251 if (index < 0 || l.length <= index) {
1252 return l;
1253 }
1254 var prefixSize = getPrefixSize(l);
1255 var suffixSize = getSuffixSize(l);
1256 var newList = cloneList(l);
1257 if (index < prefixSize) {
1258 var newPrefix = copyArray(newList.prefix);
1259 newPrefix[newPrefix.length - index - 1] = a;
1260 newList.prefix = newPrefix;
1261 }
1262 else if (index >= l.length - suffixSize) {
1263 var newSuffix = copyArray(newList.suffix);
1264 newSuffix[index - (l.length - suffixSize)] = a;
1265 newList.suffix = newSuffix;
1266 }
1267 else {
1268 newList.root = updateNode(l.root, getDepth(l), index - prefixSize + l.offset, l.offset, a);
1269 }
1270 return newList;
1271}
1272exports.update = update;
1273function adjust(index, f, l) {
1274 if (index < 0 || l.length <= index) {
1275 return l;
1276 }
1277 return update(index, f(nth(index, l)), l);
1278}
1279exports.adjust = adjust;
1280// slice and slice based functions
1281var newAffix;
1282// function getBitsForDepth(n: number, depth: number): number {
1283// return n & ~(~0 << (depth * branchBits));
1284// }
1285function sliceNode(node,
1286// index: number,
1287depth, pathLeft, pathRight, childLeft, childRight) {
1288 var array = node.array.slice(pathLeft, pathRight + 1);
1289 if (childLeft !== undefined) {
1290 array[0] = childLeft;
1291 }
1292 if (childRight !== undefined) {
1293 array[array.length - 1] = childRight;
1294 }
1295 var sizes = node.sizes;
1296 if (sizes !== undefined) {
1297 sizes = sizes.slice(pathLeft, pathRight + 1);
1298 var slicedOff = void 0;
1299 if (childLeft === undefined) {
1300 slicedOff = node.sizes[pathLeft - 1];
1301 }
1302 else {
1303 slicedOff =
1304 sizeOfSubtree(node.array[pathLeft], depth - 1) -
1305 sizeOfSubtree(childLeft, depth - 1);
1306 // slicedOff = (getBitsForDepth(index, depth) | mask) + 1;
1307 }
1308 for (var i = 0; i < sizes.length; ++i) {
1309 sizes[i] -= slicedOff;
1310 }
1311 }
1312 return new Node(sizes, array);
1313}
1314function sliceLeft(tree, depth, index, offset) {
1315 var _a = getPath(index, offset, depth, tree.sizes), path = _a.path, newIndex = _a.index;
1316 if (depth === 0) {
1317 newAffix = tree.array.slice(path).reverse();
1318 // This leaf node is moved up as a suffix so there is nothing here
1319 // after slicing
1320 return undefined;
1321 }
1322 else {
1323 // Slice the child
1324 var child = sliceLeft(tree.array[path], depth - 1, newIndex, path === 0 ? offset : 0);
1325 if (child === undefined) {
1326 // There is nothing in the child after slicing so we don't include it
1327 ++path;
1328 if (path === tree.array.length) {
1329 return undefined;
1330 }
1331 }
1332 return sliceNode(tree,
1333 // index,
1334 depth, path, tree.array.length - 1, child, undefined);
1335 }
1336}
1337function sliceRight(tree, depth, index, offset) {
1338 var _a = getPath(index, offset, depth, tree.sizes), path = _a.path, newIndex = _a.index;
1339 if (depth === 0) {
1340 newAffix = tree.array.slice(0, path + 1);
1341 // this leaf node is moved up as a suffix so there is nothing here
1342 // after slicing
1343 return undefined;
1344 }
1345 else {
1346 // slice the child, note that we subtract 1 then the radix lookup
1347 // algorithm can find the last element that we want to include
1348 // and sliceRight will do a slice that is inclusive on the index.
1349 var child = sliceRight(tree.array[path], depth - 1, newIndex, path === 0 ? offset : 0);
1350 if (child === undefined) {
1351 // there is nothing in the child after slicing so we don't include it
1352 --path;
1353 if (path === -1) {
1354 return undefined;
1355 }
1356 }
1357 // note that we add 1 to the path since we want the slice to be
1358 // inclusive on the end index. Only at the leaf level do we want
1359 // to do an exclusive slice.
1360 var array = tree.array.slice(0, path + 1);
1361 if (child !== undefined) {
1362 array[array.length - 1] = child;
1363 }
1364 return new Node(tree.sizes, array); // FIXME: handle the size table
1365 }
1366}
1367function sliceTreeList(from, to, tree, depth, offset, l) {
1368 var sizes = tree.sizes;
1369 var _a = getPath(from, offset, depth, sizes), pathLeft = _a.path, newFrom = _a.index;
1370 var _b = getPath(to, offset, depth, sizes), pathRight = _b.path, newTo = _b.index;
1371 if (depth === 0) {
1372 // we are slicing a piece off a leaf node
1373 l.prefix = emptyAffix;
1374 l.suffix = tree.array.slice(pathLeft, pathRight + 1);
1375 l.root = undefined;
1376 l.bits = setSuffix(pathRight - pathLeft + 1, 0);
1377 return l;
1378 }
1379 else if (pathLeft === pathRight) {
1380 // Both ends are located in the same subtree, this means that we
1381 // can reduce the height
1382 l.bits = decrementDepth(l.bits);
1383 return sliceTreeList(newFrom, newTo, tree.array[pathLeft], depth - 1, pathLeft === 0 ? offset : 0, l);
1384 }
1385 else {
1386 var childLeft = sliceLeft(tree.array[pathLeft], depth - 1, newFrom, pathLeft === 0 ? offset : 0);
1387 l.bits = setPrefix(newAffix.length, l.bits);
1388 l.prefix = newAffix;
1389 var childRight = sliceRight(tree.array[pathRight], depth - 1, newTo, 0);
1390 l.bits = setSuffix(newAffix.length, l.bits);
1391 l.suffix = newAffix;
1392 if (childLeft === undefined) {
1393 ++pathLeft;
1394 }
1395 if (childRight === undefined) {
1396 --pathRight;
1397 }
1398 if (pathLeft >= pathRight) {
1399 if (pathLeft > pathRight) {
1400 // This only happens when `pathLeft` originally was equal to
1401 // `pathRight + 1` and `childLeft === childRight === undefined`.
1402 // In this case there is no tree left.
1403 l.bits = setDepth(0, l.bits);
1404 l.root = undefined;
1405 }
1406 else {
1407 // Height can be reduced
1408 l.bits = decrementDepth(l.bits);
1409 var newRoot = childRight !== undefined
1410 ? childRight
1411 : childLeft !== undefined ? childLeft : tree.array[pathLeft];
1412 l.root = new Node(newRoot.sizes, newRoot.array); // Is this size handling good enough?
1413 }
1414 }
1415 else {
1416 l.root = sliceNode(tree,
1417 // from,
1418 depth, pathLeft, pathRight, childLeft, childRight);
1419 }
1420 return l;
1421 }
1422}
1423function slice(from, to, l) {
1424 var bits = l.bits, length = l.length;
1425 to = Math.min(length, to);
1426 // Handle negative indices
1427 if (from < 0) {
1428 from = length + from;
1429 }
1430 if (to < 0) {
1431 to = length + to;
1432 }
1433 // Should we just return the empty list?
1434 if (to <= from || to <= 0 || length <= from) {
1435 return empty();
1436 }
1437 // Return list unchanged if we are slicing nothing off
1438 if (from <= 0 && length <= to) {
1439 return l;
1440 }
1441 var newLength = to - from;
1442 var prefixSize = getPrefixSize(l);
1443 var suffixSize = getSuffixSize(l);
1444 // Both indices lie in the prefix
1445 if (to <= prefixSize) {
1446 return new List(setPrefix(newLength, 0), 0, newLength, undefined, emptyAffix, l.prefix.slice(l.prefix.length - to, l.prefix.length - from));
1447 }
1448 var suffixStart = length - suffixSize;
1449 // Both indices lie in the suffix
1450 if (suffixStart <= from) {
1451 return new List(setSuffix(newLength, 0), 0, newLength, undefined, l.suffix.slice(from - suffixStart, to - suffixStart), emptyAffix);
1452 }
1453 var newList = cloneList(l);
1454 // Both indices lie in the tree
1455 if (prefixSize <= from && to <= suffixStart) {
1456 sliceTreeList(from - prefixSize + l.offset, to - prefixSize + l.offset - 1, l.root, getDepth(l), l.offset, newList);
1457 if (newList.root !== undefined) {
1458 // The height of the tree might have been reduced. The offset
1459 // will be for a deeper tree. By clearing some of the left-most
1460 // bits we can make the offset fit the new height of the tree.
1461 var bits_1 = ~(~0 << (getDepth(newList) * branchBits));
1462 newList.offset =
1463 (newList.offset + from - prefixSize + getPrefixSize(newList)) & bits_1;
1464 }
1465 newList.length = to - from;
1466 return newList;
1467 }
1468 // we need to slice something off of the left
1469 if (0 < from) {
1470 if (from < prefixSize) {
1471 // do a cheap slice by setting prefix length
1472 bits = setPrefix(prefixSize - from, bits);
1473 }
1474 else {
1475 // if we're here `to` can't lie in the tree, so we can set the
1476 // root
1477 newList.root = sliceLeft(newList.root, getDepth(l), from - prefixSize + l.offset, l.offset);
1478 bits = setPrefix(newAffix.length, bits);
1479 newList.offset += from - prefixSize + newAffix.length;
1480 prefixSize = newAffix.length;
1481 newList.prefix = newAffix;
1482 }
1483 newList.length -= from;
1484 }
1485 if (to < length) {
1486 if (length - to < suffixSize) {
1487 bits = setSuffix(suffixSize - (length - to), bits);
1488 }
1489 else {
1490 newList.root = sliceRight(newList.root, getDepth(l), to - prefixSize + newList.offset - 1, newList.offset);
1491 if (newList.root === undefined) {
1492 bits = setDepth(0, bits);
1493 }
1494 bits = setSuffix(newAffix.length, bits);
1495 newList.suffix = newAffix;
1496 }
1497 newList.length -= length - to;
1498 }
1499 newList.bits = bits;
1500 return newList;
1501}
1502exports.slice = slice;
1503function take(n, l) {
1504 return slice(0, n, l);
1505}
1506exports.take = take;
1507function findNotIndexCb(value, state) {
1508 ++state.index;
1509 return state.predicate(value);
1510}
1511function takeWhile(predicate, l) {
1512 var index = foldlCb(findNotIndexCb, { predicate: predicate, index: -1 }, l).index;
1513 return slice(0, index, l);
1514}
1515exports.takeWhile = takeWhile;
1516function dropWhile(predicate, l) {
1517 var index = foldlCb(findNotIndexCb, { predicate: predicate, index: -1 }, l).index;
1518 return slice(index, l.length, l);
1519}
1520exports.dropWhile = dropWhile;
1521function takeLast(n, l) {
1522 return slice(l.length - n, l.length, l);
1523}
1524exports.takeLast = takeLast;
1525function splitAt(index, l) {
1526 return [slice(0, index, l), slice(index, l.length, l)];
1527}
1528exports.splitAt = splitAt;
1529function remove(from, amount, l) {
1530 return concat(slice(0, from, l), slice(from + amount, l.length, l));
1531}
1532exports.remove = remove;
1533function drop(n, l) {
1534 return slice(n, l.length, l);
1535}
1536exports.drop = drop;
1537function dropLast(n, l) {
1538 return slice(0, l.length - n, l);
1539}
1540exports.dropLast = dropLast;
1541function pop(l) {
1542 return slice(0, -1, l);
1543}
1544exports.pop = pop;
1545exports.init = pop;
1546function tail(l) {
1547 return slice(1, l.length, l);
1548}
1549exports.tail = tail;
1550function arrayPush(array, a) {
1551 array.push(a);
1552 return array;
1553}
1554function toArray(l) {
1555 return foldl(arrayPush, [], l);
1556}
1557exports.toArray = toArray;
1558function fromArray(array) {
1559 var l = empty();
1560 for (var i = 0; i < array.length; ++i) {
1561 l = append(array[i], l);
1562 }
1563 return l;
1564}
1565exports.fromArray = fromArray;
1566function fromIterable(iterable) {
1567 var l = empty();
1568 var iterator = iterable[Symbol.iterator]();
1569 var cur;
1570 // tslint:disable-next-line:no-conditional-assignment
1571 while ((cur = iterator.next()).done === false) {
1572 l = append(cur.value, l);
1573 }
1574 return l;
1575}
1576exports.fromIterable = fromIterable;
1577function insert(index, element, l) {
1578 return concat(append(element, slice(0, index, l)), slice(index, l.length, l));
1579}
1580exports.insert = insert;
1581function insertAll(index, elements, l) {
1582 return concat(concat(slice(0, index, l), elements), slice(index, l.length, l));
1583}
1584exports.insertAll = insertAll;
1585/**
1586 * Reverses a list.
1587 * @category Updater
1588 * @param l The list to reverse.
1589 * @returns A reversed list.
1590 */
1591function reverse(l) {
1592 return foldl(function (newL, element) { return prepend(element, newL); }, empty(), l);
1593}
1594exports.reverse = reverse;
1595function isList(l) {
1596 return typeof l === "object" && Array.isArray(l.suffix);
1597}
1598exports.isList = isList;
1599function zipWith(f, as, bs) {
1600 var swapped = bs.length < as.length;
1601 var iterator = (swapped ? as : bs)[Symbol.iterator]();
1602 return map(function (a) {
1603 var b = iterator.next().value;
1604 return swapped ? f(b, a) : f(a, b);
1605 }, (swapped ? bs : as));
1606}
1607exports.zipWith = zipWith;
1608function zip(as, bs) {
1609 return zipWith(function (a, b) { return [a, b]; }, as, bs);
1610}
1611exports.zip = zip;
1612function isPrimitive(value) {
1613 return typeof value === "number" || typeof value === "string";
1614}
1615function comparePrimitive(a, b) {
1616 return a === b ? 0 : a < b ? -1 : 1;
1617}
1618var ord = "fantasy-land/lte";
1619function compareOrd(a, b) {
1620 return a[ord](b) ? (b[ord](a) ? 0 : -1) : 1;
1621}
1622function sort(l) {
1623 if (l.length === 0) {
1624 return l;
1625 }
1626 else if (isPrimitive(first(l))) {
1627 return fromArray(toArray(l).sort(comparePrimitive));
1628 }
1629 else {
1630 return sortWith(compareOrd, l);
1631 }
1632}
1633exports.sort = sort;
1634function sortWith(comparator, l) {
1635 var arr = [];
1636 var i = 0;
1637 forEach(function (elm) { return arr.push({ idx: i++, elm: elm }); }, l);
1638 arr.sort(function (_a, _b) {
1639 var a = _a.elm, i = _a.idx;
1640 var b = _b.elm, j = _b.idx;
1641 var c = comparator(a, b);
1642 return c !== 0 ? c : i < j ? -1 : 1;
1643 });
1644 var newL = empty();
1645 for (var i_3 = 0; i_3 < arr.length; ++i_3) {
1646 newL = append(arr[i_3].elm, newL);
1647 }
1648 return newL;
1649}
1650exports.sortWith = sortWith;
1651function sortBy(f, l) {
1652 if (l.length === 0) {
1653 return l;
1654 }
1655 var arr = [];
1656 var i = 0;
1657 forEach(function (elm) { return arr.push({ idx: i++, elm: elm, prop: f(elm) }); }, l);
1658 var comparator = isPrimitive(arr[0].prop)
1659 ? comparePrimitive
1660 : compareOrd;
1661 arr.sort(function (_a, _b) {
1662 var a = _a.prop, i = _a.idx;
1663 var b = _b.prop, j = _b.idx;
1664 var c = comparator(a, b);
1665 return c !== 0 ? c : i < j ? -1 : 1;
1666 });
1667 var newL = empty();
1668 for (var i_4 = 0; i_4 < arr.length; ++i_4) {
1669 newL = append(arr[i_4].elm, newL);
1670 }
1671 return newL;
1672}
1673exports.sortBy = sortBy;
1674//# sourceMappingURL=index.js.map
\No newline at end of file