UNPKG

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