UNPKG

113 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lumino_algorithm = {}));
5}(this, (function (exports) { 'use strict';
6
7 // Copyright (c) Jupyter Development Team.
8 // Distributed under the terms of the Modified BSD License.
9 /*-----------------------------------------------------------------------------
10 | Copyright (c) 2014-2017, PhosphorJS Contributors
11 |
12 | Distributed under the terms of the BSD 3-Clause License.
13 |
14 | The full license is in the file LICENSE, distributed with this software.
15 |----------------------------------------------------------------------------*/
16 /**
17 * The namespace for array-specific algorithms.
18 */
19 exports.ArrayExt = void 0;
20 (function (ArrayExt) {
21 /**
22 * Find the index of the first occurrence of a value in an array.
23 *
24 * @param array - The array-like object to search.
25 *
26 * @param value - The value to locate in the array. Values are
27 * compared using strict `===` equality.
28 *
29 * @param start - The index of the first element in the range to be
30 * searched, inclusive. The default value is `0`. Negative values
31 * are taken as an offset from the end of the array.
32 *
33 * @param stop - The index of the last element in the range to be
34 * searched, inclusive. The default value is `-1`. Negative values
35 * are taken as an offset from the end of the array.
36 *
37 * @returns The index of the first occurrence of the value, or `-1`
38 * if the value is not found.
39 *
40 * #### Notes
41 * If `stop < start` the search will wrap at the end of the array.
42 *
43 * #### Complexity
44 * Linear.
45 *
46 * #### Undefined Behavior
47 * A `start` or `stop` which is non-integral.
48 *
49 * #### Example
50 * ```typescript
51 * import { ArrayExt } from '@lumino/algorithm';
52 *
53 * let data = ['one', 'two', 'three', 'four', 'one'];
54 * ArrayExt.firstIndexOf(data, 'red'); // -1
55 * ArrayExt.firstIndexOf(data, 'one'); // 0
56 * ArrayExt.firstIndexOf(data, 'one', 1); // 4
57 * ArrayExt.firstIndexOf(data, 'two', 2); // -1
58 * ArrayExt.firstIndexOf(data, 'two', 2, 1); // 1
59 * ```
60 */
61 function firstIndexOf(array, value, start, stop) {
62 if (start === void 0) { start = 0; }
63 if (stop === void 0) { stop = -1; }
64 var n = array.length;
65 if (n === 0) {
66 return -1;
67 }
68 if (start < 0) {
69 start = Math.max(0, start + n);
70 }
71 else {
72 start = Math.min(start, n - 1);
73 }
74 if (stop < 0) {
75 stop = Math.max(0, stop + n);
76 }
77 else {
78 stop = Math.min(stop, n - 1);
79 }
80 var span;
81 if (stop < start) {
82 span = stop + 1 + (n - start);
83 }
84 else {
85 span = stop - start + 1;
86 }
87 for (var i = 0; i < span; ++i) {
88 var j = (start + i) % n;
89 if (array[j] === value) {
90 return j;
91 }
92 }
93 return -1;
94 }
95 ArrayExt.firstIndexOf = firstIndexOf;
96 /**
97 * Find the index of the last occurrence of a value in an array.
98 *
99 * @param array - The array-like object to search.
100 *
101 * @param value - The value to locate in the array. Values are
102 * compared using strict `===` equality.
103 *
104 * @param start - The index of the first element in the range to be
105 * searched, inclusive. The default value is `-1`. Negative values
106 * are taken as an offset from the end of the array.
107 *
108 * @param stop - The index of the last element in the range to be
109 * searched, inclusive. The default value is `0`. Negative values
110 * are taken as an offset from the end of the array.
111 *
112 * @returns The index of the last occurrence of the value, or `-1`
113 * if the value is not found.
114 *
115 * #### Notes
116 * If `start < stop` the search will wrap at the front of the array.
117 *
118 * #### Complexity
119 * Linear.
120 *
121 * #### Undefined Behavior
122 * A `start` or `stop` which is non-integral.
123 *
124 * #### Example
125 * ```typescript
126 * import { ArrayExt } from '@lumino/algorithm';
127 *
128 * let data = ['one', 'two', 'three', 'four', 'one'];
129 * ArrayExt.lastIndexOf(data, 'red'); // -1
130 * ArrayExt.lastIndexOf(data, 'one'); // 4
131 * ArrayExt.lastIndexOf(data, 'one', 1); // 0
132 * ArrayExt.lastIndexOf(data, 'two', 0); // -1
133 * ArrayExt.lastIndexOf(data, 'two', 0, 1); // 1
134 * ```
135 */
136 function lastIndexOf(array, value, start, stop) {
137 if (start === void 0) { start = -1; }
138 if (stop === void 0) { stop = 0; }
139 var n = array.length;
140 if (n === 0) {
141 return -1;
142 }
143 if (start < 0) {
144 start = Math.max(0, start + n);
145 }
146 else {
147 start = Math.min(start, n - 1);
148 }
149 if (stop < 0) {
150 stop = Math.max(0, stop + n);
151 }
152 else {
153 stop = Math.min(stop, n - 1);
154 }
155 var span;
156 if (start < stop) {
157 span = start + 1 + (n - stop);
158 }
159 else {
160 span = start - stop + 1;
161 }
162 for (var i = 0; i < span; ++i) {
163 var j = (start - i + n) % n;
164 if (array[j] === value) {
165 return j;
166 }
167 }
168 return -1;
169 }
170 ArrayExt.lastIndexOf = lastIndexOf;
171 /**
172 * Find the index of the first value which matches a predicate.
173 *
174 * @param array - The array-like object to search.
175 *
176 * @param fn - The predicate function to apply to the values.
177 *
178 * @param start - The index of the first element in the range to be
179 * searched, inclusive. The default value is `0`. Negative values
180 * are taken as an offset from the end of the array.
181 *
182 * @param stop - The index of the last element in the range to be
183 * searched, inclusive. The default value is `-1`. Negative values
184 * are taken as an offset from the end of the array.
185 *
186 * @returns The index of the first matching value, or `-1` if no
187 * matching value is found.
188 *
189 * #### Notes
190 * If `stop < start` the search will wrap at the end of the array.
191 *
192 * #### Complexity
193 * Linear.
194 *
195 * #### Undefined Behavior
196 * A `start` or `stop` which is non-integral.
197 *
198 * Modifying the length of the array while searching.
199 *
200 * #### Example
201 * ```typescript
202 * import { ArrayExt } from '@lumino/algorithm';
203 *
204 * function isEven(value: number): boolean {
205 * return value % 2 === 0;
206 * }
207 *
208 * let data = [1, 2, 3, 4, 3, 2, 1];
209 * ArrayExt.findFirstIndex(data, isEven); // 1
210 * ArrayExt.findFirstIndex(data, isEven, 4); // 5
211 * ArrayExt.findFirstIndex(data, isEven, 6); // -1
212 * ArrayExt.findFirstIndex(data, isEven, 6, 5); // 1
213 * ```
214 */
215 function findFirstIndex(array, fn, start, stop) {
216 if (start === void 0) { start = 0; }
217 if (stop === void 0) { stop = -1; }
218 var n = array.length;
219 if (n === 0) {
220 return -1;
221 }
222 if (start < 0) {
223 start = Math.max(0, start + n);
224 }
225 else {
226 start = Math.min(start, n - 1);
227 }
228 if (stop < 0) {
229 stop = Math.max(0, stop + n);
230 }
231 else {
232 stop = Math.min(stop, n - 1);
233 }
234 var span;
235 if (stop < start) {
236 span = stop + 1 + (n - start);
237 }
238 else {
239 span = stop - start + 1;
240 }
241 for (var i = 0; i < span; ++i) {
242 var j = (start + i) % n;
243 if (fn(array[j], j)) {
244 return j;
245 }
246 }
247 return -1;
248 }
249 ArrayExt.findFirstIndex = findFirstIndex;
250 /**
251 * Find the index of the last value which matches a predicate.
252 *
253 * @param object - The array-like object to search.
254 *
255 * @param fn - The predicate function to apply to the values.
256 *
257 * @param start - The index of the first element in the range to be
258 * searched, inclusive. The default value is `-1`. Negative values
259 * are taken as an offset from the end of the array.
260 *
261 * @param stop - The index of the last element in the range to be
262 * searched, inclusive. The default value is `0`. Negative values
263 * are taken as an offset from the end of the array.
264 *
265 * @returns The index of the last matching value, or `-1` if no
266 * matching value is found.
267 *
268 * #### Notes
269 * If `start < stop` the search will wrap at the front of the array.
270 *
271 * #### Complexity
272 * Linear.
273 *
274 * #### Undefined Behavior
275 * A `start` or `stop` which is non-integral.
276 *
277 * Modifying the length of the array while searching.
278 *
279 * #### Example
280 * ```typescript
281 * import { ArrayExt } from '@lumino/algorithm';
282 *
283 * function isEven(value: number): boolean {
284 * return value % 2 === 0;
285 * }
286 *
287 * let data = [1, 2, 3, 4, 3, 2, 1];
288 * ArrayExt.findLastIndex(data, isEven); // 5
289 * ArrayExt.findLastIndex(data, isEven, 4); // 3
290 * ArrayExt.findLastIndex(data, isEven, 0); // -1
291 * ArrayExt.findLastIndex(data, isEven, 0, 1); // 5
292 * ```
293 */
294 function findLastIndex(array, fn, start, stop) {
295 if (start === void 0) { start = -1; }
296 if (stop === void 0) { stop = 0; }
297 var n = array.length;
298 if (n === 0) {
299 return -1;
300 }
301 if (start < 0) {
302 start = Math.max(0, start + n);
303 }
304 else {
305 start = Math.min(start, n - 1);
306 }
307 if (stop < 0) {
308 stop = Math.max(0, stop + n);
309 }
310 else {
311 stop = Math.min(stop, n - 1);
312 }
313 var d;
314 if (start < stop) {
315 d = start + 1 + (n - stop);
316 }
317 else {
318 d = start - stop + 1;
319 }
320 for (var i = 0; i < d; ++i) {
321 var j = (start - i + n) % n;
322 if (fn(array[j], j)) {
323 return j;
324 }
325 }
326 return -1;
327 }
328 ArrayExt.findLastIndex = findLastIndex;
329 /**
330 * Find the first value which matches a predicate.
331 *
332 * @param array - The array-like object to search.
333 *
334 * @param fn - The predicate function to apply to the values.
335 *
336 * @param start - The index of the first element in the range to be
337 * searched, inclusive. The default value is `0`. Negative values
338 * are taken as an offset from the end of the array.
339 *
340 * @param stop - The index of the last element in the range to be
341 * searched, inclusive. The default value is `-1`. Negative values
342 * are taken as an offset from the end of the array.
343 *
344 * @returns The first matching value, or `undefined` if no matching
345 * value is found.
346 *
347 * #### Notes
348 * If `stop < start` the search will wrap at the end of the array.
349 *
350 * #### Complexity
351 * Linear.
352 *
353 * #### Undefined Behavior
354 * A `start` or `stop` which is non-integral.
355 *
356 * Modifying the length of the array while searching.
357 *
358 * #### Example
359 * ```typescript
360 * import { ArrayExt } from '@lumino/algorithm';
361 *
362 * function isEven(value: number): boolean {
363 * return value % 2 === 0;
364 * }
365 *
366 * let data = [1, 2, 3, 4, 3, 2, 1];
367 * ArrayExt.findFirstValue(data, isEven); // 2
368 * ArrayExt.findFirstValue(data, isEven, 2); // 4
369 * ArrayExt.findFirstValue(data, isEven, 6); // undefined
370 * ArrayExt.findFirstValue(data, isEven, 6, 5); // 2
371 * ```
372 */
373 function findFirstValue(array, fn, start, stop) {
374 if (start === void 0) { start = 0; }
375 if (stop === void 0) { stop = -1; }
376 var index = findFirstIndex(array, fn, start, stop);
377 return index !== -1 ? array[index] : undefined;
378 }
379 ArrayExt.findFirstValue = findFirstValue;
380 /**
381 * Find the last value which matches a predicate.
382 *
383 * @param object - The array-like object to search.
384 *
385 * @param fn - The predicate function to apply to the values.
386 *
387 * @param start - The index of the first element in the range to be
388 * searched, inclusive. The default value is `-1`. Negative values
389 * are taken as an offset from the end of the array.
390 *
391 * @param stop - The index of the last element in the range to be
392 * searched, inclusive. The default value is `0`. Negative values
393 * are taken as an offset from the end of the array.
394 *
395 * @returns The last matching value, or `undefined` if no matching
396 * value is found.
397 *
398 * #### Notes
399 * If `start < stop` the search will wrap at the front of the array.
400 *
401 * #### Complexity
402 * Linear.
403 *
404 * #### Undefined Behavior
405 * A `start` or `stop` which is non-integral.
406 *
407 * Modifying the length of the array while searching.
408 *
409 * #### Example
410 * ```typescript
411 * import { ArrayExt } from '@lumino/algorithm';
412 *
413 * function isEven(value: number): boolean {
414 * return value % 2 === 0;
415 * }
416 *
417 * let data = [1, 2, 3, 4, 3, 2, 1];
418 * ArrayExt.findLastValue(data, isEven); // 2
419 * ArrayExt.findLastValue(data, isEven, 4); // 4
420 * ArrayExt.findLastValue(data, isEven, 0); // undefined
421 * ArrayExt.findLastValue(data, isEven, 0, 1); // 2
422 * ```
423 */
424 function findLastValue(array, fn, start, stop) {
425 if (start === void 0) { start = -1; }
426 if (stop === void 0) { stop = 0; }
427 var index = findLastIndex(array, fn, start, stop);
428 return index !== -1 ? array[index] : undefined;
429 }
430 ArrayExt.findLastValue = findLastValue;
431 /**
432 * Find the index of the first element which compares `>=` to a value.
433 *
434 * @param array - The sorted array-like object to search.
435 *
436 * @param value - The value to locate in the array.
437 *
438 * @param fn - The 3-way comparison function to apply to the values.
439 * It should return `< 0` if an element is less than a value, `0` if
440 * an element is equal to a value, or `> 0` if an element is greater
441 * than a value.
442 *
443 * @param start - The index of the first element in the range to be
444 * searched, inclusive. The default value is `0`. Negative values
445 * are taken as an offset from the end of the array.
446 *
447 * @param stop - The index of the last element in the range to be
448 * searched, inclusive. The default value is `-1`. Negative values
449 * are taken as an offset from the end of the array.
450 *
451 * @returns The index of the first element which compares `>=` to the
452 * value, or `length` if there is no such element. If the computed
453 * index for `stop` is less than `start`, then the computed index
454 * for `start` is returned.
455 *
456 * #### Notes
457 * The array must already be sorted in ascending order according to
458 * the comparison function.
459 *
460 * #### Complexity
461 * Logarithmic.
462 *
463 * #### Undefined Behavior
464 * Searching a range which is not sorted in ascending order.
465 *
466 * A `start` or `stop` which is non-integral.
467 *
468 * Modifying the length of the array while searching.
469 *
470 * #### Example
471 * ```typescript
472 * import { ArrayExt } from '@lumino/algorithm';
473 *
474 * function numberCmp(a: number, b: number): number {
475 * return a - b;
476 * }
477 *
478 * let data = [0, 3, 4, 7, 7, 9];
479 * ArrayExt.lowerBound(data, 0, numberCmp); // 0
480 * ArrayExt.lowerBound(data, 6, numberCmp); // 3
481 * ArrayExt.lowerBound(data, 7, numberCmp); // 3
482 * ArrayExt.lowerBound(data, -1, numberCmp); // 0
483 * ArrayExt.lowerBound(data, 10, numberCmp); // 6
484 * ```
485 */
486 function lowerBound(array, value, fn, start, stop) {
487 if (start === void 0) { start = 0; }
488 if (stop === void 0) { stop = -1; }
489 var n = array.length;
490 if (n === 0) {
491 return 0;
492 }
493 if (start < 0) {
494 start = Math.max(0, start + n);
495 }
496 else {
497 start = Math.min(start, n - 1);
498 }
499 if (stop < 0) {
500 stop = Math.max(0, stop + n);
501 }
502 else {
503 stop = Math.min(stop, n - 1);
504 }
505 var begin = start;
506 var span = stop - start + 1;
507 while (span > 0) {
508 var half = span >> 1;
509 var middle = begin + half;
510 if (fn(array[middle], value) < 0) {
511 begin = middle + 1;
512 span -= half + 1;
513 }
514 else {
515 span = half;
516 }
517 }
518 return begin;
519 }
520 ArrayExt.lowerBound = lowerBound;
521 /**
522 * Find the index of the first element which compares `>` than a value.
523 *
524 * @param array - The sorted array-like object to search.
525 *
526 * @param value - The value to locate in the array.
527 *
528 * @param fn - The 3-way comparison function to apply to the values.
529 * It should return `< 0` if an element is less than a value, `0` if
530 * an element is equal to a value, or `> 0` if an element is greater
531 * than a value.
532 *
533 * @param start - The index of the first element in the range to be
534 * searched, inclusive. The default value is `0`. Negative values
535 * are taken as an offset from the end of the array.
536 *
537 * @param stop - The index of the last element in the range to be
538 * searched, inclusive. The default value is `-1`. Negative values
539 * are taken as an offset from the end of the array.
540 *
541 * @returns The index of the first element which compares `>` than the
542 * value, or `length` if there is no such element. If the computed
543 * index for `stop` is less than `start`, then the computed index
544 * for `start` is returned.
545 *
546 * #### Notes
547 * The array must already be sorted in ascending order according to
548 * the comparison function.
549 *
550 * #### Complexity
551 * Logarithmic.
552 *
553 * #### Undefined Behavior
554 * Searching a range which is not sorted in ascending order.
555 *
556 * A `start` or `stop` which is non-integral.
557 *
558 * Modifying the length of the array while searching.
559 *
560 * #### Example
561 * ```typescript
562 * import { ArrayExt } from '@lumino/algorithm';
563 *
564 * function numberCmp(a: number, b: number): number {
565 * return a - b;
566 * }
567 *
568 * let data = [0, 3, 4, 7, 7, 9];
569 * ArrayExt.upperBound(data, 0, numberCmp); // 1
570 * ArrayExt.upperBound(data, 6, numberCmp); // 3
571 * ArrayExt.upperBound(data, 7, numberCmp); // 5
572 * ArrayExt.upperBound(data, -1, numberCmp); // 0
573 * ArrayExt.upperBound(data, 10, numberCmp); // 6
574 * ```
575 */
576 function upperBound(array, value, fn, start, stop) {
577 if (start === void 0) { start = 0; }
578 if (stop === void 0) { stop = -1; }
579 var n = array.length;
580 if (n === 0) {
581 return 0;
582 }
583 if (start < 0) {
584 start = Math.max(0, start + n);
585 }
586 else {
587 start = Math.min(start, n - 1);
588 }
589 if (stop < 0) {
590 stop = Math.max(0, stop + n);
591 }
592 else {
593 stop = Math.min(stop, n - 1);
594 }
595 var begin = start;
596 var span = stop - start + 1;
597 while (span > 0) {
598 var half = span >> 1;
599 var middle = begin + half;
600 if (fn(array[middle], value) > 0) {
601 span = half;
602 }
603 else {
604 begin = middle + 1;
605 span -= half + 1;
606 }
607 }
608 return begin;
609 }
610 ArrayExt.upperBound = upperBound;
611 /**
612 * Test whether two arrays are shallowly equal.
613 *
614 * @param a - The first array-like object to compare.
615 *
616 * @param b - The second array-like object to compare.
617 *
618 * @param fn - The comparison function to apply to the elements. It
619 * should return `true` if the elements are "equal". The default
620 * compares elements using strict `===` equality.
621 *
622 * @returns Whether the two arrays are shallowly equal.
623 *
624 * #### Complexity
625 * Linear.
626 *
627 * #### Undefined Behavior
628 * Modifying the length of the arrays while comparing.
629 *
630 * #### Example
631 * ```typescript
632 * import { ArrayExt } from '@lumino/algorithm';
633 *
634 * let d1 = [0, 3, 4, 7, 7, 9];
635 * let d2 = [0, 3, 4, 7, 7, 9];
636 * let d3 = [42];
637 * ArrayExt.shallowEqual(d1, d2); // true
638 * ArrayExt.shallowEqual(d2, d3); // false
639 * ```
640 */
641 function shallowEqual(a, b, fn) {
642 // Check for object identity first.
643 if (a === b) {
644 return true;
645 }
646 // Bail early if the lengths are different.
647 if (a.length !== b.length) {
648 return false;
649 }
650 // Compare each element for equality.
651 for (var i = 0, n = a.length; i < n; ++i) {
652 if (fn ? !fn(a[i], b[i]) : a[i] !== b[i]) {
653 return false;
654 }
655 }
656 // The array are shallowly equal.
657 return true;
658 }
659 ArrayExt.shallowEqual = shallowEqual;
660 /**
661 * Create a slice of an array subject to an optional step.
662 *
663 * @param array - The array-like object of interest.
664 *
665 * @param options - The options for configuring the slice.
666 *
667 * @returns A new array with the specified values.
668 *
669 * @throws An exception if the slice `step` is `0`.
670 *
671 * #### Complexity
672 * Linear.
673 *
674 * #### Undefined Behavior
675 * A `start`, `stop`, or `step` which is non-integral.
676 *
677 * #### Example
678 * ```typescript
679 * import { ArrayExt } from '@lumino/algorithm';
680 *
681 * let data = [0, 3, 4, 7, 7, 9];
682 * ArrayExt.slice(data); // [0, 3, 4, 7, 7, 9]
683 * ArrayExt.slice(data, { start: 2 }); // [4, 7, 7, 9]
684 * ArrayExt.slice(data, { start: 0, stop: 4 }); // [0, 3, 4, 7]
685 * ArrayExt.slice(data, { step: 2 }); // [0, 4, 7]
686 * ArrayExt.slice(data, { step: -1 }); // [9, 7, 7, 4, 3, 0]
687 * ```
688 */
689 function slice(array, options) {
690 if (options === void 0) { options = {}; }
691 // Extract the options.
692 var start = options.start, stop = options.stop, step = options.step;
693 // Set up the `step` value.
694 if (step === undefined) {
695 step = 1;
696 }
697 // Validate the step size.
698 if (step === 0) {
699 throw new Error('Slice `step` cannot be zero.');
700 }
701 // Look up the length of the array.
702 var n = array.length;
703 // Set up the `start` value.
704 if (start === undefined) {
705 start = step < 0 ? n - 1 : 0;
706 }
707 else if (start < 0) {
708 start = Math.max(start + n, step < 0 ? -1 : 0);
709 }
710 else if (start >= n) {
711 start = step < 0 ? n - 1 : n;
712 }
713 // Set up the `stop` value.
714 if (stop === undefined) {
715 stop = step < 0 ? -1 : n;
716 }
717 else if (stop < 0) {
718 stop = Math.max(stop + n, step < 0 ? -1 : 0);
719 }
720 else if (stop >= n) {
721 stop = step < 0 ? n - 1 : n;
722 }
723 // Compute the slice length.
724 var length;
725 if ((step < 0 && stop >= start) || (step > 0 && start >= stop)) {
726 length = 0;
727 }
728 else if (step < 0) {
729 length = Math.floor((stop - start + 1) / step + 1);
730 }
731 else {
732 length = Math.floor((stop - start - 1) / step + 1);
733 }
734 // Compute the sliced result.
735 var result = [];
736 for (var i = 0; i < length; ++i) {
737 result[i] = array[start + i * step];
738 }
739 // Return the result.
740 return result;
741 }
742 ArrayExt.slice = slice;
743 /**
744 * Move an element in an array from one index to another.
745 *
746 * @param array - The mutable array-like object of interest.
747 *
748 * @param fromIndex - The index of the element to move. Negative
749 * values are taken as an offset from the end of the array.
750 *
751 * @param toIndex - The target index of the element. Negative
752 * values are taken as an offset from the end of the array.
753 *
754 * #### Complexity
755 * Linear.
756 *
757 * #### Undefined Behavior
758 * A `fromIndex` or `toIndex` which is non-integral.
759 *
760 * #### Example
761 * ```typescript
762 * import { ArrayExt } from from '@lumino/algorithm';
763 *
764 * let data = [0, 1, 2, 3, 4];
765 * ArrayExt.move(data, 1, 2); // [0, 2, 1, 3, 4]
766 * ArrayExt.move(data, 4, 2); // [0, 2, 4, 1, 3]
767 * ```
768 */
769 function move(array, fromIndex, toIndex) {
770 var n = array.length;
771 if (n <= 1) {
772 return;
773 }
774 if (fromIndex < 0) {
775 fromIndex = Math.max(0, fromIndex + n);
776 }
777 else {
778 fromIndex = Math.min(fromIndex, n - 1);
779 }
780 if (toIndex < 0) {
781 toIndex = Math.max(0, toIndex + n);
782 }
783 else {
784 toIndex = Math.min(toIndex, n - 1);
785 }
786 if (fromIndex === toIndex) {
787 return;
788 }
789 var value = array[fromIndex];
790 var d = fromIndex < toIndex ? 1 : -1;
791 for (var i = fromIndex; i !== toIndex; i += d) {
792 array[i] = array[i + d];
793 }
794 array[toIndex] = value;
795 }
796 ArrayExt.move = move;
797 /**
798 * Reverse an array in-place.
799 *
800 * @param array - The mutable array-like object of interest.
801 *
802 * @param start - The index of the first element in the range to be
803 * reversed, inclusive. The default value is `0`. Negative values
804 * are taken as an offset from the end of the array.
805 *
806 * @param stop - The index of the last element in the range to be
807 * reversed, inclusive. The default value is `-1`. Negative values
808 * are taken as an offset from the end of the array.
809 *
810 * #### Complexity
811 * Linear.
812 *
813 * #### Undefined Behavior
814 * A `start` or `stop` index which is non-integral.
815 *
816 * #### Example
817 * ```typescript
818 * import { ArrayExt } from '@lumino/algorithm';
819 *
820 * let data = [0, 1, 2, 3, 4];
821 * ArrayExt.reverse(data, 1, 3); // [0, 3, 2, 1, 4]
822 * ArrayExt.reverse(data, 3); // [0, 3, 2, 4, 1]
823 * ArrayExt.reverse(data); // [1, 4, 2, 3, 0]
824 * ```
825 */
826 function reverse(array, start, stop) {
827 if (start === void 0) { start = 0; }
828 if (stop === void 0) { stop = -1; }
829 var n = array.length;
830 if (n <= 1) {
831 return;
832 }
833 if (start < 0) {
834 start = Math.max(0, start + n);
835 }
836 else {
837 start = Math.min(start, n - 1);
838 }
839 if (stop < 0) {
840 stop = Math.max(0, stop + n);
841 }
842 else {
843 stop = Math.min(stop, n - 1);
844 }
845 while (start < stop) {
846 var a = array[start];
847 var b = array[stop];
848 array[start++] = b;
849 array[stop--] = a;
850 }
851 }
852 ArrayExt.reverse = reverse;
853 /**
854 * Rotate the elements of an array in-place.
855 *
856 * @param array - The mutable array-like object of interest.
857 *
858 * @param delta - The amount of rotation to apply to the elements. A
859 * positive value will rotate the elements to the left. A negative
860 * value will rotate the elements to the right.
861 *
862 * @param start - The index of the first element in the range to be
863 * rotated, inclusive. The default value is `0`. Negative values
864 * are taken as an offset from the end of the array.
865 *
866 * @param stop - The index of the last element in the range to be
867 * rotated, inclusive. The default value is `-1`. Negative values
868 * are taken as an offset from the end of the array.
869 *
870 * #### Complexity
871 * Linear.
872 *
873 * #### Undefined Behavior
874 * A `delta`, `start`, or `stop` which is non-integral.
875 *
876 * #### Example
877 * ```typescript
878 * import { ArrayExt } from '@lumino/algorithm';
879 *
880 * let data = [0, 1, 2, 3, 4];
881 * ArrayExt.rotate(data, 2); // [2, 3, 4, 0, 1]
882 * ArrayExt.rotate(data, -2); // [0, 1, 2, 3, 4]
883 * ArrayExt.rotate(data, 10); // [0, 1, 2, 3, 4]
884 * ArrayExt.rotate(data, 9); // [4, 0, 1, 2, 3]
885 * ArrayExt.rotate(data, 2, 1, 3); // [4, 2, 0, 1, 3]
886 * ```
887 */
888 function rotate(array, delta, start, stop) {
889 if (start === void 0) { start = 0; }
890 if (stop === void 0) { stop = -1; }
891 var n = array.length;
892 if (n <= 1) {
893 return;
894 }
895 if (start < 0) {
896 start = Math.max(0, start + n);
897 }
898 else {
899 start = Math.min(start, n - 1);
900 }
901 if (stop < 0) {
902 stop = Math.max(0, stop + n);
903 }
904 else {
905 stop = Math.min(stop, n - 1);
906 }
907 if (start >= stop) {
908 return;
909 }
910 var length = stop - start + 1;
911 if (delta > 0) {
912 delta = delta % length;
913 }
914 else if (delta < 0) {
915 delta = ((delta % length) + length) % length;
916 }
917 if (delta === 0) {
918 return;
919 }
920 var pivot = start + delta;
921 reverse(array, start, pivot - 1);
922 reverse(array, pivot, stop);
923 reverse(array, start, stop);
924 }
925 ArrayExt.rotate = rotate;
926 /**
927 * Fill an array with a static value.
928 *
929 * @param array - The mutable array-like object to fill.
930 *
931 * @param value - The static value to use to fill the array.
932 *
933 * @param start - The index of the first element in the range to be
934 * filled, inclusive. The default value is `0`. Negative values
935 * are taken as an offset from the end of the array.
936 *
937 * @param stop - The index of the last element in the range to be
938 * filled, inclusive. The default value is `-1`. Negative values
939 * are taken as an offset from the end of the array.
940 *
941 * #### Notes
942 * If `stop < start` the fill will wrap at the end of the array.
943 *
944 * #### Complexity
945 * Linear.
946 *
947 * #### Undefined Behavior
948 * A `start` or `stop` which is non-integral.
949 *
950 * #### Example
951 * ```typescript
952 * import { ArrayExt } from '@lumino/algorithm';
953 *
954 * let data = ['one', 'two', 'three', 'four'];
955 * ArrayExt.fill(data, 'r'); // ['r', 'r', 'r', 'r']
956 * ArrayExt.fill(data, 'g', 1); // ['r', 'g', 'g', 'g']
957 * ArrayExt.fill(data, 'b', 2, 3); // ['r', 'g', 'b', 'b']
958 * ArrayExt.fill(data, 'z', 3, 1); // ['z', 'z', 'b', 'z']
959 * ```
960 */
961 function fill(array, value, start, stop) {
962 if (start === void 0) { start = 0; }
963 if (stop === void 0) { stop = -1; }
964 var n = array.length;
965 if (n === 0) {
966 return;
967 }
968 if (start < 0) {
969 start = Math.max(0, start + n);
970 }
971 else {
972 start = Math.min(start, n - 1);
973 }
974 if (stop < 0) {
975 stop = Math.max(0, stop + n);
976 }
977 else {
978 stop = Math.min(stop, n - 1);
979 }
980 var span;
981 if (stop < start) {
982 span = stop + 1 + (n - start);
983 }
984 else {
985 span = stop - start + 1;
986 }
987 for (var i = 0; i < span; ++i) {
988 array[(start + i) % n] = value;
989 }
990 }
991 ArrayExt.fill = fill;
992 /**
993 * Insert a value into an array at a specific index.
994 *
995 * @param array - The array of interest.
996 *
997 * @param index - The index at which to insert the value. Negative
998 * values are taken as an offset from the end of the array.
999 *
1000 * @param value - The value to set at the specified index.
1001 *
1002 * #### Complexity
1003 * Linear.
1004 *
1005 * #### Undefined Behavior
1006 * An `index` which is non-integral.
1007 *
1008 * #### Example
1009 * ```typescript
1010 * import { ArrayExt } from '@lumino/algorithm';
1011 *
1012 * let data = [0, 1, 2];
1013 * ArrayExt.insert(data, 0, -1); // [-1, 0, 1, 2]
1014 * ArrayExt.insert(data, 2, 12); // [-1, 0, 12, 1, 2]
1015 * ArrayExt.insert(data, -1, 7); // [-1, 0, 12, 1, 7, 2]
1016 * ArrayExt.insert(data, 6, 19); // [-1, 0, 12, 1, 7, 2, 19]
1017 * ```
1018 */
1019 function insert(array, index, value) {
1020 var n = array.length;
1021 if (index < 0) {
1022 index = Math.max(0, index + n);
1023 }
1024 else {
1025 index = Math.min(index, n);
1026 }
1027 for (var i = n; i > index; --i) {
1028 array[i] = array[i - 1];
1029 }
1030 array[index] = value;
1031 }
1032 ArrayExt.insert = insert;
1033 /**
1034 * Remove and return a value at a specific index in an array.
1035 *
1036 * @param array - The array of interest.
1037 *
1038 * @param index - The index of the value to remove. Negative values
1039 * are taken as an offset from the end of the array.
1040 *
1041 * @returns The value at the specified index, or `undefined` if the
1042 * index is out of range.
1043 *
1044 * #### Complexity
1045 * Linear.
1046 *
1047 * #### Undefined Behavior
1048 * An `index` which is non-integral.
1049 *
1050 * #### Example
1051 * ```typescript
1052 * import { ArrayExt } from '@lumino/algorithm';
1053 *
1054 * let data = [0, 12, 23, 39, 14, 12, 75];
1055 * ArrayExt.removeAt(data, 2); // 23
1056 * ArrayExt.removeAt(data, -2); // 12
1057 * ArrayExt.removeAt(data, 10); // undefined;
1058 * ```
1059 */
1060 function removeAt(array, index) {
1061 var n = array.length;
1062 if (index < 0) {
1063 index += n;
1064 }
1065 if (index < 0 || index >= n) {
1066 return undefined;
1067 }
1068 var value = array[index];
1069 for (var i = index + 1; i < n; ++i) {
1070 array[i - 1] = array[i];
1071 }
1072 array.length = n - 1;
1073 return value;
1074 }
1075 ArrayExt.removeAt = removeAt;
1076 /**
1077 * Remove the first occurrence of a value from an array.
1078 *
1079 * @param array - The array of interest.
1080 *
1081 * @param value - The value to remove from the array. Values are
1082 * compared using strict `===` equality.
1083 *
1084 * @param start - The index of the first element in the range to be
1085 * searched, inclusive. The default value is `0`. Negative values
1086 * are taken as an offset from the end of the array.
1087 *
1088 * @param stop - The index of the last element in the range to be
1089 * searched, inclusive. The default value is `-1`. Negative values
1090 * are taken as an offset from the end of the array.
1091 *
1092 * @returns The index of the removed value, or `-1` if the value
1093 * is not contained in the array.
1094 *
1095 * #### Notes
1096 * If `stop < start` the search will wrap at the end of the array.
1097 *
1098 * #### Complexity
1099 * Linear.
1100 *
1101 * #### Example
1102 * ```typescript
1103 * import { ArrayExt } from '@lumino/algorithm';
1104 *
1105 * let data = [0, 12, 23, 39, 14, 12, 75];
1106 * ArrayExt.removeFirstOf(data, 12); // 1
1107 * ArrayExt.removeFirstOf(data, 17); // -1
1108 * ArrayExt.removeFirstOf(data, 39, 3); // -1
1109 * ArrayExt.removeFirstOf(data, 39, 3, 2); // 2
1110 * ```
1111 */
1112 function removeFirstOf(array, value, start, stop) {
1113 if (start === void 0) { start = 0; }
1114 if (stop === void 0) { stop = -1; }
1115 var index = firstIndexOf(array, value, start, stop);
1116 if (index !== -1) {
1117 removeAt(array, index);
1118 }
1119 return index;
1120 }
1121 ArrayExt.removeFirstOf = removeFirstOf;
1122 /**
1123 * Remove the last occurrence of a value from an array.
1124 *
1125 * @param array - The array of interest.
1126 *
1127 * @param value - The value to remove from the array. Values are
1128 * compared using strict `===` equality.
1129 *
1130 * @param start - The index of the first element in the range to be
1131 * searched, inclusive. The default value is `-1`. Negative values
1132 * are taken as an offset from the end of the array.
1133 *
1134 * @param stop - The index of the last element in the range to be
1135 * searched, inclusive. The default value is `0`. Negative values
1136 * are taken as an offset from the end of the array.
1137 *
1138 * @returns The index of the removed value, or `-1` if the value
1139 * is not contained in the array.
1140 *
1141 * #### Notes
1142 * If `start < stop` the search will wrap at the end of the array.
1143 *
1144 * #### Complexity
1145 * Linear.
1146 *
1147 * #### Example
1148 * ```typescript
1149 * import { ArrayExt } from '@lumino/algorithm';
1150 *
1151 * let data = [0, 12, 23, 39, 14, 12, 75];
1152 * ArrayExt.removeLastOf(data, 12); // 5
1153 * ArrayExt.removeLastOf(data, 17); // -1
1154 * ArrayExt.removeLastOf(data, 39, 2); // -1
1155 * ArrayExt.removeLastOf(data, 39, 2, 3); // 3
1156 * ```
1157 */
1158 function removeLastOf(array, value, start, stop) {
1159 if (start === void 0) { start = -1; }
1160 if (stop === void 0) { stop = 0; }
1161 var index = lastIndexOf(array, value, start, stop);
1162 if (index !== -1) {
1163 removeAt(array, index);
1164 }
1165 return index;
1166 }
1167 ArrayExt.removeLastOf = removeLastOf;
1168 /**
1169 * Remove all occurrences of a value from an array.
1170 *
1171 * @param array - The array of interest.
1172 *
1173 * @param value - The value to remove from the array. Values are
1174 * compared using strict `===` equality.
1175 *
1176 * @param start - The index of the first element in the range to be
1177 * searched, inclusive. The default value is `0`. Negative values
1178 * are taken as an offset from the end of the array.
1179 *
1180 * @param stop - The index of the last element in the range to be
1181 * searched, inclusive. The default value is `-1`. Negative values
1182 * are taken as an offset from the end of the array.
1183 *
1184 * @returns The number of elements removed from the array.
1185 *
1186 * #### Notes
1187 * If `stop < start` the search will conceptually wrap at the end of
1188 * the array, however the array will be traversed front-to-back.
1189 *
1190 * #### Complexity
1191 * Linear.
1192 *
1193 * #### Example
1194 * ```typescript
1195 * import { ArrayExt } from '@lumino/algorithm';
1196 *
1197 * let data = [14, 12, 23, 39, 14, 12, 19, 14];
1198 * ArrayExt.removeAllOf(data, 12); // 2
1199 * ArrayExt.removeAllOf(data, 17); // 0
1200 * ArrayExt.removeAllOf(data, 14, 1, 4); // 1
1201 * ```
1202 */
1203 function removeAllOf(array, value, start, stop) {
1204 if (start === void 0) { start = 0; }
1205 if (stop === void 0) { stop = -1; }
1206 var n = array.length;
1207 if (n === 0) {
1208 return 0;
1209 }
1210 if (start < 0) {
1211 start = Math.max(0, start + n);
1212 }
1213 else {
1214 start = Math.min(start, n - 1);
1215 }
1216 if (stop < 0) {
1217 stop = Math.max(0, stop + n);
1218 }
1219 else {
1220 stop = Math.min(stop, n - 1);
1221 }
1222 var count = 0;
1223 for (var i = 0; i < n; ++i) {
1224 if (start <= stop && i >= start && i <= stop && array[i] === value) {
1225 count++;
1226 }
1227 else if (stop < start &&
1228 (i <= stop || i >= start) &&
1229 array[i] === value) {
1230 count++;
1231 }
1232 else if (count > 0) {
1233 array[i - count] = array[i];
1234 }
1235 }
1236 if (count > 0) {
1237 array.length = n - count;
1238 }
1239 return count;
1240 }
1241 ArrayExt.removeAllOf = removeAllOf;
1242 /**
1243 * Remove the first occurrence of a value which matches a predicate.
1244 *
1245 * @param array - The array of interest.
1246 *
1247 * @param fn - The predicate function to apply to the values.
1248 *
1249 * @param start - The index of the first element in the range to be
1250 * searched, inclusive. The default value is `0`. Negative values
1251 * are taken as an offset from the end of the array.
1252 *
1253 * @param stop - The index of the last element in the range to be
1254 * searched, inclusive. The default value is `-1`. Negative values
1255 * are taken as an offset from the end of the array.
1256 *
1257 * @returns The removed `{ index, value }`, which will be `-1` and
1258 * `undefined` if the value is not contained in the array.
1259 *
1260 * #### Notes
1261 * If `stop < start` the search will wrap at the end of the array.
1262 *
1263 * #### Complexity
1264 * Linear.
1265 *
1266 * #### Example
1267 * ```typescript
1268 * import { ArrayExt } from '@lumino/algorithm';
1269 *
1270 * function isEven(value: number): boolean {
1271 * return value % 2 === 0;
1272 * }
1273 *
1274 * let data = [0, 12, 23, 39, 14, 12, 75];
1275 * ArrayExt.removeFirstWhere(data, isEven); // { index: 0, value: 0 }
1276 * ArrayExt.removeFirstWhere(data, isEven, 2); // { index: 3, value: 14 }
1277 * ArrayExt.removeFirstWhere(data, isEven, 4); // { index: -1, value: undefined }
1278 * ```
1279 */
1280 function removeFirstWhere(array, fn, start, stop) {
1281 if (start === void 0) { start = 0; }
1282 if (stop === void 0) { stop = -1; }
1283 var value;
1284 var index = findFirstIndex(array, fn, start, stop);
1285 if (index !== -1) {
1286 value = removeAt(array, index);
1287 }
1288 return { index: index, value: value };
1289 }
1290 ArrayExt.removeFirstWhere = removeFirstWhere;
1291 /**
1292 * Remove the last occurrence of a value which matches a predicate.
1293 *
1294 * @param array - The array of interest.
1295 *
1296 * @param fn - The predicate function to apply to the values.
1297 *
1298 * @param start - The index of the first element in the range to be
1299 * searched, inclusive. The default value is `-1`. Negative values
1300 * are taken as an offset from the end of the array.
1301 *
1302 * @param stop - The index of the last element in the range to be
1303 * searched, inclusive. The default value is `0`. Negative values
1304 * are taken as an offset from the end of the array.
1305 *
1306 * @returns The removed `{ index, value }`, which will be `-1` and
1307 * `undefined` if the value is not contained in the array.
1308 *
1309 * #### Notes
1310 * If `start < stop` the search will wrap at the end of the array.
1311 *
1312 * #### Complexity
1313 * Linear.
1314 *
1315 * #### Example
1316 * ```typescript
1317 * import { ArrayExt } from '@lumino/algorithm';
1318 *
1319 * function isEven(value: number): boolean {
1320 * return value % 2 === 0;
1321 * }
1322 *
1323 * let data = [0, 12, 23, 39, 14, 12, 75];
1324 * ArrayExt.removeLastWhere(data, isEven); // { index: 5, value: 12 }
1325 * ArrayExt.removeLastWhere(data, isEven, 2); // { index: 1, value: 12 }
1326 * ArrayExt.removeLastWhere(data, isEven, 2, 1); // { index: -1, value: undefined }
1327 * ```
1328 */
1329 function removeLastWhere(array, fn, start, stop) {
1330 if (start === void 0) { start = -1; }
1331 if (stop === void 0) { stop = 0; }
1332 var value;
1333 var index = findLastIndex(array, fn, start, stop);
1334 if (index !== -1) {
1335 value = removeAt(array, index);
1336 }
1337 return { index: index, value: value };
1338 }
1339 ArrayExt.removeLastWhere = removeLastWhere;
1340 /**
1341 * Remove all occurrences of values which match a predicate.
1342 *
1343 * @param array - The array of interest.
1344 *
1345 * @param fn - The predicate function to apply to the values.
1346 *
1347 * @param start - The index of the first element in the range to be
1348 * searched, inclusive. The default value is `0`. Negative values
1349 * are taken as an offset from the end of the array.
1350 *
1351 * @param stop - The index of the last element in the range to be
1352 * searched, inclusive. The default value is `-1`. Negative values
1353 * are taken as an offset from the end of the array.
1354 *
1355 * @returns The number of elements removed from the array.
1356 *
1357 * #### Notes
1358 * If `stop < start` the search will conceptually wrap at the end of
1359 * the array, however the array will be traversed front-to-back.
1360 *
1361 * #### Complexity
1362 * Linear.
1363 *
1364 * #### Example
1365 * ```typescript
1366 * import { ArrayExt } from '@lumino/algorithm';
1367 *
1368 * function isEven(value: number): boolean {
1369 * return value % 2 === 0;
1370 * }
1371 *
1372 * function isNegative(value: number): boolean {
1373 * return value < 0;
1374 * }
1375 *
1376 * let data = [0, 12, -13, -9, 23, 39, 14, -15, 12, 75];
1377 * ArrayExt.removeAllWhere(data, isEven); // 4
1378 * ArrayExt.removeAllWhere(data, isNegative, 0, 3); // 2
1379 * ```
1380 */
1381 function removeAllWhere(array, fn, start, stop) {
1382 if (start === void 0) { start = 0; }
1383 if (stop === void 0) { stop = -1; }
1384 var n = array.length;
1385 if (n === 0) {
1386 return 0;
1387 }
1388 if (start < 0) {
1389 start = Math.max(0, start + n);
1390 }
1391 else {
1392 start = Math.min(start, n - 1);
1393 }
1394 if (stop < 0) {
1395 stop = Math.max(0, stop + n);
1396 }
1397 else {
1398 stop = Math.min(stop, n - 1);
1399 }
1400 var count = 0;
1401 for (var i = 0; i < n; ++i) {
1402 if (start <= stop && i >= start && i <= stop && fn(array[i], i)) {
1403 count++;
1404 }
1405 else if (stop < start && (i <= stop || i >= start) && fn(array[i], i)) {
1406 count++;
1407 }
1408 else if (count > 0) {
1409 array[i - count] = array[i];
1410 }
1411 }
1412 if (count > 0) {
1413 array.length = n - count;
1414 }
1415 return count;
1416 }
1417 ArrayExt.removeAllWhere = removeAllWhere;
1418 })(exports.ArrayExt || (exports.ArrayExt = {}));
1419
1420 // Copyright (c) Jupyter Development Team.
1421 // Distributed under the terms of the Modified BSD License.
1422 /*-----------------------------------------------------------------------------
1423 | Copyright (c) 2014-2017, PhosphorJS Contributors
1424 |
1425 | Distributed under the terms of the BSD 3-Clause License.
1426 |
1427 | The full license is in the file LICENSE, distributed with this software.
1428 |----------------------------------------------------------------------------*/
1429 /**
1430 * Create an iterator for an iterable object.
1431 *
1432 * @param object - The iterable or array-like object of interest.
1433 *
1434 * @returns A new iterator for the given object.
1435 *
1436 * #### Notes
1437 * This function allows iteration algorithms to operate on user-defined
1438 * iterable types and builtin array-like objects in a uniform fashion.
1439 */
1440 function iter(object) {
1441 var it;
1442 if (typeof object.iter === 'function') {
1443 it = object.iter();
1444 }
1445 else {
1446 it = new ArrayIterator(object);
1447 }
1448 return it;
1449 }
1450 /**
1451 * Create an iterator for the keys in an object.
1452 *
1453 * @param object - The object of interest.
1454 *
1455 * @returns A new iterator for the keys in the given object.
1456 *
1457 * #### Complexity
1458 * Linear.
1459 *
1460 * #### Example
1461 * ```typescript
1462 * import { each, keys } from '@lumino/algorithm';
1463 *
1464 * let data = { one: 1, two: 2, three: 3 };
1465 *
1466 * each(keys(data), key => { console.log(key); }); // 'one', 'two', 'three'
1467 * ```
1468 */
1469 function iterKeys(object) {
1470 return new KeyIterator(object);
1471 }
1472 /**
1473 * Create an iterator for the values in an object.
1474 *
1475 * @param object - The object of interest.
1476 *
1477 * @returns A new iterator for the values in the given object.
1478 *
1479 * #### Complexity
1480 * Linear.
1481 *
1482 * #### Example
1483 * ```typescript
1484 * import { each, values } from '@lumino/algorithm';
1485 *
1486 * let data = { one: 1, two: 2, three: 3 };
1487 *
1488 * each(values(data), value => { console.log(value); }); // 1, 2, 3
1489 * ```
1490 */
1491 function iterValues(object) {
1492 return new ValueIterator(object);
1493 }
1494 /**
1495 * Create an iterator for the items in an object.
1496 *
1497 * @param object - The object of interest.
1498 *
1499 * @returns A new iterator for the items in the given object.
1500 *
1501 * #### Complexity
1502 * Linear.
1503 *
1504 * #### Example
1505 * ```typescript
1506 * import { each, items } from '@lumino/algorithm';
1507 *
1508 * let data = { one: 1, two: 2, three: 3 };
1509 *
1510 * each(items(data), value => { console.log(value); }); // ['one', 1], ['two', 2], ['three', 3]
1511 * ```
1512 */
1513 function iterItems(object) {
1514 return new ItemIterator(object);
1515 }
1516 /**
1517 * Create an iterator for an iterator-like function.
1518 *
1519 * @param fn - A function which behaves like an iterator `next` method.
1520 *
1521 * @returns A new iterator for the given function.
1522 *
1523 * #### Notes
1524 * The returned iterator **cannot** be cloned.
1525 *
1526 * #### Example
1527 * ```typescript
1528 * import { each, iterFn } from '@lumino/algorithm';
1529 *
1530 * let it = iterFn((() => {
1531 * let i = 0;
1532 * return () => i > 3 ? undefined : i++;
1533 * })());
1534 *
1535 * each(it, v => { console.log(v); }); // 0, 1, 2, 3
1536 * ```
1537 */
1538 function iterFn(fn) {
1539 return new FnIterator(fn);
1540 }
1541 /**
1542 * Invoke a function for each value in an iterable.
1543 *
1544 * @param object - The iterable or array-like object of interest.
1545 *
1546 * @param fn - The callback function to invoke for each value.
1547 *
1548 * #### Notes
1549 * Iteration can be terminated early by returning `false` from the
1550 * callback function.
1551 *
1552 * #### Complexity
1553 * Linear.
1554 *
1555 * #### Example
1556 * ```typescript
1557 * import { each } from '@lumino/algorithm';
1558 *
1559 * let data = [5, 7, 0, -2, 9];
1560 *
1561 * each(data, value => { console.log(value); });
1562 * ```
1563 */
1564 function each(object, fn) {
1565 var index = 0;
1566 var it = iter(object);
1567 var value;
1568 while ((value = it.next()) !== undefined) {
1569 if (fn(value, index++) === false) {
1570 return;
1571 }
1572 }
1573 }
1574 /**
1575 * Test whether all values in an iterable satisfy a predicate.
1576 *
1577 * @param object - The iterable or array-like object of interest.
1578 *
1579 * @param fn - The predicate function to invoke for each value.
1580 *
1581 * @returns `true` if all values pass the test, `false` otherwise.
1582 *
1583 * #### Notes
1584 * Iteration terminates on the first `false` predicate result.
1585 *
1586 * #### Complexity
1587 * Linear.
1588 *
1589 * #### Example
1590 * ```typescript
1591 * import { every } from '@lumino/algorithm';
1592 *
1593 * let data = [5, 7, 1];
1594 *
1595 * every(data, value => value % 2 === 0); // false
1596 * every(data, value => value % 2 === 1); // true
1597 * ```
1598 */
1599 function every(object, fn) {
1600 var index = 0;
1601 var it = iter(object);
1602 var value;
1603 while ((value = it.next()) !== undefined) {
1604 if (!fn(value, index++)) {
1605 return false;
1606 }
1607 }
1608 return true;
1609 }
1610 /**
1611 * Test whether any value in an iterable satisfies a predicate.
1612 *
1613 * @param object - The iterable or array-like object of interest.
1614 *
1615 * @param fn - The predicate function to invoke for each value.
1616 *
1617 * @returns `true` if any value passes the test, `false` otherwise.
1618 *
1619 * #### Notes
1620 * Iteration terminates on the first `true` predicate result.
1621 *
1622 * #### Complexity
1623 * Linear.
1624 *
1625 * #### Example
1626 * ```typescript
1627 * import { some } from '@lumino/algorithm';
1628 *
1629 * let data = [5, 7, 1];
1630 *
1631 * some(data, value => value === 7); // true
1632 * some(data, value => value === 3); // false
1633 * ```
1634 */
1635 function some(object, fn) {
1636 var index = 0;
1637 var it = iter(object);
1638 var value;
1639 while ((value = it.next()) !== undefined) {
1640 if (fn(value, index++)) {
1641 return true;
1642 }
1643 }
1644 return false;
1645 }
1646 /**
1647 * Create an array from an iterable of values.
1648 *
1649 * @param object - The iterable or array-like object of interest.
1650 *
1651 * @returns A new array of values from the given object.
1652 *
1653 * #### Example
1654 * ```typescript
1655 * import { iter, toArray } from '@lumino/algorithm';
1656 *
1657 * let data = [1, 2, 3, 4, 5, 6];
1658 *
1659 * let stream = iter(data);
1660 *
1661 * toArray(stream); // [1, 2, 3, 4, 5, 6];
1662 * ```
1663 */
1664 function toArray(object) {
1665 var index = 0;
1666 var result = [];
1667 var it = iter(object);
1668 var value;
1669 while ((value = it.next()) !== undefined) {
1670 result[index++] = value;
1671 }
1672 return result;
1673 }
1674 /**
1675 * Create an object from an iterable of key/value pairs.
1676 *
1677 * @param object - The iterable or array-like object of interest.
1678 *
1679 * @returns A new object mapping keys to values.
1680 *
1681 * #### Example
1682 * ```typescript
1683 * import { toObject } from '@lumino/algorithm';
1684 *
1685 * let data = [['one', 1], ['two', 2], ['three', 3]];
1686 *
1687 * toObject(data); // { one: 1, two: 2, three: 3 }
1688 * ```
1689 */
1690 function toObject(object) {
1691 var it = iter(object);
1692 var pair;
1693 var result = {};
1694 while ((pair = it.next()) !== undefined) {
1695 result[pair[0]] = pair[1];
1696 }
1697 return result;
1698 }
1699 /**
1700 * An iterator for an array-like object.
1701 *
1702 * #### Notes
1703 * This iterator can be used for any builtin JS array-like object.
1704 */
1705 var ArrayIterator = /** @class */ (function () {
1706 /**
1707 * Construct a new array iterator.
1708 *
1709 * @param source - The array-like object of interest.
1710 */
1711 function ArrayIterator(source) {
1712 this._index = 0;
1713 this._source = source;
1714 }
1715 /**
1716 * Get an iterator over the object's values.
1717 *
1718 * @returns An iterator which yields the object's values.
1719 */
1720 ArrayIterator.prototype.iter = function () {
1721 return this;
1722 };
1723 /**
1724 * Create an independent clone of the iterator.
1725 *
1726 * @returns A new independent clone of the iterator.
1727 */
1728 ArrayIterator.prototype.clone = function () {
1729 var result = new ArrayIterator(this._source);
1730 result._index = this._index;
1731 return result;
1732 };
1733 /**
1734 * Get the next value from the iterator.
1735 *
1736 * @returns The next value from the iterator, or `undefined`.
1737 */
1738 ArrayIterator.prototype.next = function () {
1739 if (this._index >= this._source.length) {
1740 return undefined;
1741 }
1742 return this._source[this._index++];
1743 };
1744 return ArrayIterator;
1745 }());
1746 /**
1747 * An iterator for the keys in an object.
1748 *
1749 * #### Notes
1750 * This iterator can be used for any JS object.
1751 */
1752 var KeyIterator = /** @class */ (function () {
1753 /**
1754 * Construct a new key iterator.
1755 *
1756 * @param source - The object of interest.
1757 *
1758 * @param keys - The keys to iterate, if known.
1759 */
1760 function KeyIterator(source, keys) {
1761 if (keys === void 0) { keys = Object.keys(source); }
1762 this._index = 0;
1763 this._source = source;
1764 this._keys = keys;
1765 }
1766 /**
1767 * Get an iterator over the object's values.
1768 *
1769 * @returns An iterator which yields the object's values.
1770 */
1771 KeyIterator.prototype.iter = function () {
1772 return this;
1773 };
1774 /**
1775 * Create an independent clone of the iterator.
1776 *
1777 * @returns A new independent clone of the iterator.
1778 */
1779 KeyIterator.prototype.clone = function () {
1780 var result = new KeyIterator(this._source, this._keys);
1781 result._index = this._index;
1782 return result;
1783 };
1784 /**
1785 * Get the next value from the iterator.
1786 *
1787 * @returns The next value from the iterator, or `undefined`.
1788 */
1789 KeyIterator.prototype.next = function () {
1790 if (this._index >= this._keys.length) {
1791 return undefined;
1792 }
1793 var key = this._keys[this._index++];
1794 if (key in this._source) {
1795 return key;
1796 }
1797 return this.next();
1798 };
1799 return KeyIterator;
1800 }());
1801 /**
1802 * An iterator for the values in an object.
1803 *
1804 * #### Notes
1805 * This iterator can be used for any JS object.
1806 */
1807 var ValueIterator = /** @class */ (function () {
1808 /**
1809 * Construct a new value iterator.
1810 *
1811 * @param source - The object of interest.
1812 *
1813 * @param keys - The keys to iterate, if known.
1814 */
1815 function ValueIterator(source, keys) {
1816 if (keys === void 0) { keys = Object.keys(source); }
1817 this._index = 0;
1818 this._source = source;
1819 this._keys = keys;
1820 }
1821 /**
1822 * Get an iterator over the object's values.
1823 *
1824 * @returns An iterator which yields the object's values.
1825 */
1826 ValueIterator.prototype.iter = function () {
1827 return this;
1828 };
1829 /**
1830 * Create an independent clone of the iterator.
1831 *
1832 * @returns A new independent clone of the iterator.
1833 */
1834 ValueIterator.prototype.clone = function () {
1835 var result = new ValueIterator(this._source, this._keys);
1836 result._index = this._index;
1837 return result;
1838 };
1839 /**
1840 * Get the next value from the iterator.
1841 *
1842 * @returns The next value from the iterator, or `undefined`.
1843 */
1844 ValueIterator.prototype.next = function () {
1845 if (this._index >= this._keys.length) {
1846 return undefined;
1847 }
1848 var key = this._keys[this._index++];
1849 if (key in this._source) {
1850 return this._source[key];
1851 }
1852 return this.next();
1853 };
1854 return ValueIterator;
1855 }());
1856 /**
1857 * An iterator for the items in an object.
1858 *
1859 * #### Notes
1860 * This iterator can be used for any JS object.
1861 */
1862 var ItemIterator = /** @class */ (function () {
1863 /**
1864 * Construct a new item iterator.
1865 *
1866 * @param source - The object of interest.
1867 *
1868 * @param keys - The keys to iterate, if known.
1869 */
1870 function ItemIterator(source, keys) {
1871 if (keys === void 0) { keys = Object.keys(source); }
1872 this._index = 0;
1873 this._source = source;
1874 this._keys = keys;
1875 }
1876 /**
1877 * Get an iterator over the object's values.
1878 *
1879 * @returns An iterator which yields the object's values.
1880 */
1881 ItemIterator.prototype.iter = function () {
1882 return this;
1883 };
1884 /**
1885 * Create an independent clone of the iterator.
1886 *
1887 * @returns A new independent clone of the iterator.
1888 */
1889 ItemIterator.prototype.clone = function () {
1890 var result = new ItemIterator(this._source, this._keys);
1891 result._index = this._index;
1892 return result;
1893 };
1894 /**
1895 * Get the next value from the iterator.
1896 *
1897 * @returns The next value from the iterator, or `undefined`.
1898 */
1899 ItemIterator.prototype.next = function () {
1900 if (this._index >= this._keys.length) {
1901 return undefined;
1902 }
1903 var key = this._keys[this._index++];
1904 if (key in this._source) {
1905 return [key, this._source[key]];
1906 }
1907 return this.next();
1908 };
1909 return ItemIterator;
1910 }());
1911 /**
1912 * An iterator for an iterator-like function.
1913 */
1914 var FnIterator = /** @class */ (function () {
1915 /**
1916 * Construct a new function iterator.
1917 *
1918 * @param fn - The iterator-like function of interest.
1919 */
1920 function FnIterator(fn) {
1921 this._fn = fn;
1922 }
1923 /**
1924 * Get an iterator over the object's values.
1925 *
1926 * @returns An iterator which yields the object's values.
1927 */
1928 FnIterator.prototype.iter = function () {
1929 return this;
1930 };
1931 /**
1932 * Create an independent clone of the iterator.
1933 *
1934 * @returns A new independent clone of the iterator.
1935 */
1936 FnIterator.prototype.clone = function () {
1937 throw new Error('An `FnIterator` cannot be cloned.');
1938 };
1939 /**
1940 * Get the next value from the iterator.
1941 *
1942 * @returns The next value from the iterator, or `undefined`.
1943 */
1944 FnIterator.prototype.next = function () {
1945 return this._fn.call(undefined);
1946 };
1947 return FnIterator;
1948 }());
1949
1950 // Copyright (c) Jupyter Development Team.
1951 /**
1952 * Chain together several iterables.
1953 *
1954 * @param objects - The iterable or array-like objects of interest.
1955 *
1956 * @returns An iterator which yields the values of the iterables
1957 * in the order in which they are supplied.
1958 *
1959 * #### Example
1960 * ```typescript
1961 * import { chain, toArray } from '@lumino/algorithm';
1962 *
1963 * let data1 = [1, 2, 3];
1964 * let data2 = [4, 5, 6];
1965 *
1966 * let stream = chain(data1, data2);
1967 *
1968 * toArray(stream); // [1, 2, 3, 4, 5, 6]
1969 * ```
1970 */
1971 function chain() {
1972 var objects = [];
1973 for (var _i = 0; _i < arguments.length; _i++) {
1974 objects[_i] = arguments[_i];
1975 }
1976 return new ChainIterator(iter(objects.map(iter)));
1977 }
1978 /**
1979 * An iterator which chains together several iterators.
1980 */
1981 var ChainIterator = /** @class */ (function () {
1982 /**
1983 * Construct a new chain iterator.
1984 *
1985 * @param source - The iterator of iterators of interest.
1986 */
1987 function ChainIterator(source) {
1988 this._cloned = false;
1989 this._source = source;
1990 this._active = undefined;
1991 }
1992 /**
1993 * Get an iterator over the object's values.
1994 *
1995 * @returns An iterator which yields the object's values.
1996 */
1997 ChainIterator.prototype.iter = function () {
1998 return this;
1999 };
2000 /**
2001 * Create an independent clone of the iterator.
2002 *
2003 * @returns A new independent clone of the iterator.
2004 */
2005 ChainIterator.prototype.clone = function () {
2006 var result = new ChainIterator(this._source.clone());
2007 result._active = this._active && this._active.clone();
2008 result._cloned = true;
2009 this._cloned = true;
2010 return result;
2011 };
2012 /**
2013 * Get the next value from the iterator.
2014 *
2015 * @returns The next value from the iterator, or `undefined`.
2016 */
2017 ChainIterator.prototype.next = function () {
2018 if (this._active === undefined) {
2019 var active = this._source.next();
2020 if (active === undefined) {
2021 return undefined;
2022 }
2023 this._active = this._cloned ? active.clone() : active;
2024 }
2025 var value = this._active.next();
2026 if (value !== undefined) {
2027 return value;
2028 }
2029 this._active = undefined;
2030 return this.next();
2031 };
2032 return ChainIterator;
2033 }());
2034
2035 /**
2036 * Create an empty iterator.
2037 *
2038 * @returns A new iterator which yields nothing.
2039 *
2040 * #### Example
2041 * ```typescript
2042 * import { empty, toArray } from '@lumino/algorithm';
2043 *
2044 * let stream = empty<number>();
2045 *
2046 * toArray(stream); // []
2047 * ```
2048 */
2049 function empty() {
2050 return new EmptyIterator();
2051 }
2052 /**
2053 * An iterator which is always empty.
2054 */
2055 var EmptyIterator = /** @class */ (function () {
2056 function EmptyIterator() {
2057 }
2058 /**
2059 * Get an iterator over the object's values.
2060 *
2061 * @returns An iterator which yields the object's values.
2062 */
2063 EmptyIterator.prototype.iter = function () {
2064 return this;
2065 };
2066 /**
2067 * Create an independent clone of the iterator.
2068 *
2069 * @returns A new independent clone of the iterator.
2070 */
2071 EmptyIterator.prototype.clone = function () {
2072 return new EmptyIterator();
2073 };
2074 /**
2075 * Get the next value from the iterator.
2076 *
2077 * @returns The next value from the iterator, or `undefined`.
2078 */
2079 EmptyIterator.prototype.next = function () {
2080 return undefined;
2081 };
2082 return EmptyIterator;
2083 }());
2084
2085 // Copyright (c) Jupyter Development Team.
2086 /**
2087 * Enumerate an iterable object.
2088 *
2089 * @param object - The iterable or array-like object of interest.
2090 *
2091 * @param start - The starting enum value. The default is `0`.
2092 *
2093 * @returns An iterator which yields the enumerated values.
2094 *
2095 * #### Example
2096 * ```typescript
2097 * import { enumerate, toArray } from '@lumino/algorithm';
2098 *
2099 * let data = ['foo', 'bar', 'baz'];
2100 *
2101 * let stream = enumerate(data, 1);
2102 *
2103 * toArray(stream); // [[1, 'foo'], [2, 'bar'], [3, 'baz']]
2104 * ```
2105 */
2106 function enumerate(object, start) {
2107 if (start === void 0) { start = 0; }
2108 return new EnumerateIterator(iter(object), start);
2109 }
2110 /**
2111 * An iterator which enumerates the source values.
2112 */
2113 var EnumerateIterator = /** @class */ (function () {
2114 /**
2115 * Construct a new enumerate iterator.
2116 *
2117 * @param source - The iterator of values of interest.
2118 *
2119 * @param start - The starting enum value.
2120 */
2121 function EnumerateIterator(source, start) {
2122 this._source = source;
2123 this._index = start;
2124 }
2125 /**
2126 * Get an iterator over the object's values.
2127 *
2128 * @returns An iterator which yields the object's values.
2129 */
2130 EnumerateIterator.prototype.iter = function () {
2131 return this;
2132 };
2133 /**
2134 * Create an independent clone of the iterator.
2135 *
2136 * @returns A new independent clone of the iterator.
2137 */
2138 EnumerateIterator.prototype.clone = function () {
2139 return new EnumerateIterator(this._source.clone(), this._index);
2140 };
2141 /**
2142 * Get the next value from the iterator.
2143 *
2144 * @returns The next value from the iterator, or `undefined`.
2145 */
2146 EnumerateIterator.prototype.next = function () {
2147 var value = this._source.next();
2148 if (value === undefined) {
2149 return undefined;
2150 }
2151 return [this._index++, value];
2152 };
2153 return EnumerateIterator;
2154 }());
2155
2156 // Copyright (c) Jupyter Development Team.
2157 /**
2158 * Filter an iterable for values which pass a test.
2159 *
2160 * @param object - The iterable or array-like object of interest.
2161 *
2162 * @param fn - The predicate function to invoke for each value.
2163 *
2164 * @returns An iterator which yields the values which pass the test.
2165 *
2166 * #### Example
2167 * ```typescript
2168 * import { filter, toArray } from '@lumino/algorithm';
2169 *
2170 * let data = [1, 2, 3, 4, 5, 6];
2171 *
2172 * let stream = filter(data, value => value % 2 === 0);
2173 *
2174 * toArray(stream); // [2, 4, 6]
2175 * ```
2176 */
2177 function filter(object, fn) {
2178 return new FilterIterator(iter(object), fn);
2179 }
2180 /**
2181 * An iterator which yields values which pass a test.
2182 */
2183 var FilterIterator = /** @class */ (function () {
2184 /**
2185 * Construct a new filter iterator.
2186 *
2187 * @param source - The iterator of values of interest.
2188 *
2189 * @param fn - The predicate function to invoke for each value.
2190 */
2191 function FilterIterator(source, fn) {
2192 this._index = 0;
2193 this._source = source;
2194 this._fn = fn;
2195 }
2196 /**
2197 * Get an iterator over the object's values.
2198 *
2199 * @returns An iterator which yields the object's values.
2200 */
2201 FilterIterator.prototype.iter = function () {
2202 return this;
2203 };
2204 /**
2205 * Create an independent clone of the iterator.
2206 *
2207 * @returns A new independent clone of the iterator.
2208 */
2209 FilterIterator.prototype.clone = function () {
2210 var result = new FilterIterator(this._source.clone(), this._fn);
2211 result._index = this._index;
2212 return result;
2213 };
2214 /**
2215 * Get the next value from the iterator.
2216 *
2217 * @returns The next value from the iterator, or `undefined`.
2218 */
2219 FilterIterator.prototype.next = function () {
2220 var fn = this._fn;
2221 var it = this._source;
2222 var value;
2223 while ((value = it.next()) !== undefined) {
2224 if (fn(value, this._index++)) {
2225 return value;
2226 }
2227 }
2228 return undefined;
2229 };
2230 return FilterIterator;
2231 }());
2232
2233 // Copyright (c) Jupyter Development Team.
2234 /**
2235 * Find the first value in an iterable which matches a predicate.
2236 *
2237 * @param object - The iterable or array-like object to search.
2238 *
2239 * @param fn - The predicate function to apply to the values.
2240 *
2241 * @returns The first matching value, or `undefined` if no matching
2242 * value is found.
2243 *
2244 * #### Complexity
2245 * Linear.
2246 *
2247 * #### Example
2248 * ```typescript
2249 * import { find } from '@lumino/algorithm';
2250 *
2251 * interface IAnimal { species: string, name: string };
2252 *
2253 * function isCat(value: IAnimal): boolean {
2254 * return value.species === 'cat';
2255 * }
2256 *
2257 * let data: IAnimal[] = [
2258 * { species: 'dog', name: 'spot' },
2259 * { species: 'cat', name: 'fluffy' },
2260 * { species: 'alligator', name: 'pocho' }
2261 * ];
2262 *
2263 * find(data, isCat).name; // 'fluffy'
2264 * ```
2265 */
2266 function find(object, fn) {
2267 var index = 0;
2268 var it = iter(object);
2269 var value;
2270 while ((value = it.next()) !== undefined) {
2271 if (fn(value, index++)) {
2272 return value;
2273 }
2274 }
2275 return undefined;
2276 }
2277 /**
2278 * Find the index of the first value which matches a predicate.
2279 *
2280 * @param object - The iterable or array-like object to search.
2281 *
2282 * @param fn - The predicate function to apply to the values.
2283 *
2284 * @returns The index of the first matching value, or `-1` if no
2285 * matching value is found.
2286 *
2287 * #### Complexity
2288 * Linear.
2289 *
2290 * #### Example
2291 * ```typescript
2292 * import { findIndex } from '@lumino/algorithm';
2293 *
2294 * interface IAnimal { species: string, name: string };
2295 *
2296 * function isCat(value: IAnimal): boolean {
2297 * return value.species === 'cat';
2298 * }
2299 *
2300 * let data: IAnimal[] = [
2301 * { species: 'dog', name: 'spot' },
2302 * { species: 'cat', name: 'fluffy' },
2303 * { species: 'alligator', name: 'pocho' }
2304 * ];
2305 *
2306 * findIndex(data, isCat); // 1
2307 * ```
2308 */
2309 function findIndex(object, fn) {
2310 var index = 0;
2311 var it = iter(object);
2312 var value;
2313 while ((value = it.next()) !== undefined) {
2314 if (fn(value, index++)) {
2315 return index - 1;
2316 }
2317 }
2318 return -1;
2319 }
2320 /**
2321 * Find the minimum value in an iterable.
2322 *
2323 * @param object - The iterable or array-like object to search.
2324 *
2325 * @param fn - The 3-way comparison function to apply to the values.
2326 * It should return `< 0` if the first value is less than the second.
2327 * `0` if the values are equivalent, or `> 0` if the first value is
2328 * greater than the second.
2329 *
2330 * @returns The minimum value in the iterable. If multiple values are
2331 * equivalent to the minimum, the left-most value is returned. If
2332 * the iterable is empty, this returns `undefined`.
2333 *
2334 * #### Complexity
2335 * Linear.
2336 *
2337 * #### Example
2338 * ```typescript
2339 * import { min } from '@lumino/algorithm';
2340 *
2341 * function numberCmp(a: number, b: number): number {
2342 * return a - b;
2343 * }
2344 *
2345 * min([7, 4, 0, 3, 9, 4], numberCmp); // 0
2346 * ```
2347 */
2348 function min(object, fn) {
2349 var it = iter(object);
2350 var value = it.next();
2351 if (value === undefined) {
2352 return undefined;
2353 }
2354 var result = value;
2355 while ((value = it.next()) !== undefined) {
2356 if (fn(value, result) < 0) {
2357 result = value;
2358 }
2359 }
2360 return result;
2361 }
2362 /**
2363 * Find the maximum value in an iterable.
2364 *
2365 * @param object - The iterable or array-like object to search.
2366 *
2367 * @param fn - The 3-way comparison function to apply to the values.
2368 * It should return `< 0` if the first value is less than the second.
2369 * `0` if the values are equivalent, or `> 0` if the first value is
2370 * greater than the second.
2371 *
2372 * @returns The maximum value in the iterable. If multiple values are
2373 * equivalent to the maximum, the left-most value is returned. If
2374 * the iterable is empty, this returns `undefined`.
2375 *
2376 * #### Complexity
2377 * Linear.
2378 *
2379 * #### Example
2380 * ```typescript
2381 * import { max } from '@lumino/algorithm';
2382 *
2383 * function numberCmp(a: number, b: number): number {
2384 * return a - b;
2385 * }
2386 *
2387 * max([7, 4, 0, 3, 9, 4], numberCmp); // 9
2388 * ```
2389 */
2390 function max(object, fn) {
2391 var it = iter(object);
2392 var value = it.next();
2393 if (value === undefined) {
2394 return undefined;
2395 }
2396 var result = value;
2397 while ((value = it.next()) !== undefined) {
2398 if (fn(value, result) > 0) {
2399 result = value;
2400 }
2401 }
2402 return result;
2403 }
2404 /**
2405 * Find the minimum and maximum values in an iterable.
2406 *
2407 * @param object - The iterable or array-like object to search.
2408 *
2409 * @param fn - The 3-way comparison function to apply to the values.
2410 * It should return `< 0` if the first value is less than the second.
2411 * `0` if the values are equivalent, or `> 0` if the first value is
2412 * greater than the second.
2413 *
2414 * @returns A 2-tuple of the `[min, max]` values in the iterable. If
2415 * multiple values are equivalent, the left-most values are returned.
2416 * If the iterable is empty, this returns `undefined`.
2417 *
2418 * #### Complexity
2419 * Linear.
2420 *
2421 * #### Example
2422 * ```typescript
2423 * import { minmax } from '@lumino/algorithm';
2424 *
2425 * function numberCmp(a: number, b: number): number {
2426 * return a - b;
2427 * }
2428 *
2429 * minmax([7, 4, 0, 3, 9, 4], numberCmp); // [0, 9]
2430 * ```
2431 */
2432 function minmax(object, fn) {
2433 var it = iter(object);
2434 var value = it.next();
2435 if (value === undefined) {
2436 return undefined;
2437 }
2438 var vmin = value;
2439 var vmax = value;
2440 while ((value = it.next()) !== undefined) {
2441 if (fn(value, vmin) < 0) {
2442 vmin = value;
2443 }
2444 else if (fn(value, vmax) > 0) {
2445 vmax = value;
2446 }
2447 }
2448 return [vmin, vmax];
2449 }
2450
2451 // Copyright (c) Jupyter Development Team.
2452 /**
2453 * Transform the values of an iterable with a mapping function.
2454 *
2455 * @param object - The iterable or array-like object of interest.
2456 *
2457 * @param fn - The mapping function to invoke for each value.
2458 *
2459 * @returns An iterator which yields the transformed values.
2460 *
2461 * #### Example
2462 * ```typescript
2463 * import { map, toArray } from '@lumino/algorithm';
2464 *
2465 * let data = [1, 2, 3];
2466 *
2467 * let stream = map(data, value => value * 2);
2468 *
2469 * toArray(stream); // [2, 4, 6]
2470 * ```
2471 */
2472 function map(object, fn) {
2473 return new MapIterator(iter(object), fn);
2474 }
2475 /**
2476 * An iterator which transforms values using a mapping function.
2477 */
2478 var MapIterator = /** @class */ (function () {
2479 /**
2480 * Construct a new map iterator.
2481 *
2482 * @param source - The iterator of values of interest.
2483 *
2484 * @param fn - The mapping function to invoke for each value.
2485 */
2486 function MapIterator(source, fn) {
2487 this._index = 0;
2488 this._source = source;
2489 this._fn = fn;
2490 }
2491 /**
2492 * Get an iterator over the object's values.
2493 *
2494 * @returns An iterator which yields the object's values.
2495 */
2496 MapIterator.prototype.iter = function () {
2497 return this;
2498 };
2499 /**
2500 * Create an independent clone of the iterator.
2501 *
2502 * @returns A new independent clone of the iterator.
2503 */
2504 MapIterator.prototype.clone = function () {
2505 var result = new MapIterator(this._source.clone(), this._fn);
2506 result._index = this._index;
2507 return result;
2508 };
2509 /**
2510 * Get the next value from the iterator.
2511 *
2512 * @returns The next value from the iterator, or `undefined`.
2513 */
2514 MapIterator.prototype.next = function () {
2515 var value = this._source.next();
2516 if (value === undefined) {
2517 return undefined;
2518 }
2519 return this._fn.call(undefined, value, this._index++);
2520 };
2521 return MapIterator;
2522 }());
2523
2524 /**
2525 * Create an iterator of evenly spaced values.
2526 *
2527 * @param start - The starting value for the range, inclusive.
2528 *
2529 * @param stop - The stopping value for the range, exclusive.
2530 *
2531 * @param step - The distance between each value.
2532 *
2533 * @returns An iterator which produces evenly spaced values.
2534 *
2535 * #### Notes
2536 * In the single argument form of `range(stop)`, `start` defaults to
2537 * `0` and `step` defaults to `1`.
2538 *
2539 * In the two argument form of `range(start, stop)`, `step` defaults
2540 * to `1`.
2541 */
2542 function range(start, stop, step) {
2543 if (stop === undefined) {
2544 return new RangeIterator(0, start, 1);
2545 }
2546 if (step === undefined) {
2547 return new RangeIterator(start, stop, 1);
2548 }
2549 return new RangeIterator(start, stop, step);
2550 }
2551 /**
2552 * An iterator which produces a range of evenly spaced values.
2553 */
2554 var RangeIterator = /** @class */ (function () {
2555 /**
2556 * Construct a new range iterator.
2557 *
2558 * @param start - The starting value for the range, inclusive.
2559 *
2560 * @param stop - The stopping value for the range, exclusive.
2561 *
2562 * @param step - The distance between each value.
2563 */
2564 function RangeIterator(start, stop, step) {
2565 this._index = 0;
2566 this._start = start;
2567 this._stop = stop;
2568 this._step = step;
2569 this._length = Private.rangeLength(start, stop, step);
2570 }
2571 /**
2572 * Get an iterator over the object's values.
2573 *
2574 * @returns An iterator which yields the object's values.
2575 */
2576 RangeIterator.prototype.iter = function () {
2577 return this;
2578 };
2579 /**
2580 * Create an independent clone of the iterator.
2581 *
2582 * @returns A new independent clone of the iterator.
2583 */
2584 RangeIterator.prototype.clone = function () {
2585 var result = new RangeIterator(this._start, this._stop, this._step);
2586 result._index = this._index;
2587 return result;
2588 };
2589 /**
2590 * Get the next value from the iterator.
2591 *
2592 * @returns The next value from the iterator, or `undefined`.
2593 */
2594 RangeIterator.prototype.next = function () {
2595 if (this._index >= this._length) {
2596 return undefined;
2597 }
2598 return this._start + this._step * this._index++;
2599 };
2600 return RangeIterator;
2601 }());
2602 /**
2603 * The namespace for the module implementation details.
2604 */
2605 var Private;
2606 (function (Private) {
2607 /**
2608 * Compute the effective length of a range.
2609 *
2610 * @param start - The starting value for the range, inclusive.
2611 *
2612 * @param stop - The stopping value for the range, exclusive.
2613 *
2614 * @param step - The distance between each value.
2615 *
2616 * @returns The number of steps need to traverse the range.
2617 */
2618 function rangeLength(start, stop, step) {
2619 if (step === 0) {
2620 return Infinity;
2621 }
2622 if (start > stop && step > 0) {
2623 return 0;
2624 }
2625 if (start < stop && step < 0) {
2626 return 0;
2627 }
2628 return Math.ceil((stop - start) / step);
2629 }
2630 Private.rangeLength = rangeLength;
2631 })(Private || (Private = {}));
2632
2633 // Copyright (c) Jupyter Development Team.
2634 function reduce(object, fn, initial) {
2635 // Setup the iterator and fetch the first value.
2636 var index = 0;
2637 var it = iter(object);
2638 var first = it.next();
2639 // An empty iterator and no initial value is an error.
2640 if (first === undefined && initial === undefined) {
2641 throw new TypeError('Reduce of empty iterable with no initial value.');
2642 }
2643 // If the iterator is empty, return the initial value.
2644 if (first === undefined) {
2645 return initial;
2646 }
2647 // If the iterator has a single item and no initial value, the
2648 // reducer is not invoked and the first item is the return value.
2649 var second = it.next();
2650 if (second === undefined && initial === undefined) {
2651 return first;
2652 }
2653 // If iterator has a single item and an initial value is provided,
2654 // the reducer is invoked and that result is the return value.
2655 if (second === undefined) {
2656 return fn(initial, first, index++);
2657 }
2658 // Setup the initial accumlated value.
2659 var accumulator;
2660 if (initial === undefined) {
2661 accumulator = fn(first, second, index++);
2662 }
2663 else {
2664 accumulator = fn(fn(initial, first, index++), second, index++);
2665 }
2666 // Iterate the rest of the values, updating the accumulator.
2667 var next;
2668 while ((next = it.next()) !== undefined) {
2669 accumulator = fn(accumulator, next, index++);
2670 }
2671 // Return the final accumulated value.
2672 return accumulator;
2673 }
2674
2675 /**
2676 * Create an iterator which repeats a value a number of times.
2677 *
2678 * @param value - The value to repeat.
2679 *
2680 * @param count - The number of times to repeat the value.
2681 *
2682 * @returns A new iterator which repeats the specified value.
2683 *
2684 * #### Example
2685 * ```typescript
2686 * import { repeat, toArray } from '@lumino/algorithm';
2687 *
2688 * let stream = repeat(7, 3);
2689 *
2690 * toArray(stream); // [7, 7, 7]
2691 * ```
2692 */
2693 function repeat(value, count) {
2694 return new RepeatIterator(value, count);
2695 }
2696 /**
2697 * Create an iterator which yields a value a single time.
2698 *
2699 * @param value - The value to wrap in an iterator.
2700 *
2701 * @returns A new iterator which yields the value a single time.
2702 *
2703 * #### Example
2704 * ```typescript
2705 * import { once, toArray } from '@lumino/algorithm';
2706 *
2707 * let stream = once(7);
2708 *
2709 * toArray(stream); // [7]
2710 * ```
2711 */
2712 function once(value) {
2713 return new RepeatIterator(value, 1);
2714 }
2715 /**
2716 * An iterator which repeats a value a specified number of times.
2717 */
2718 var RepeatIterator = /** @class */ (function () {
2719 /**
2720 * Construct a new repeat iterator.
2721 *
2722 * @param value - The value to repeat.
2723 *
2724 * @param count - The number of times to repeat the value.
2725 */
2726 function RepeatIterator(value, count) {
2727 this._value = value;
2728 this._count = count;
2729 }
2730 /**
2731 * Get an iterator over the object's values.
2732 *
2733 * @returns An iterator which yields the object's values.
2734 */
2735 RepeatIterator.prototype.iter = function () {
2736 return this;
2737 };
2738 /**
2739 * Create an independent clone of the iterator.
2740 *
2741 * @returns A new independent clone of the iterator.
2742 */
2743 RepeatIterator.prototype.clone = function () {
2744 return new RepeatIterator(this._value, this._count);
2745 };
2746 /**
2747 * Get the next value from the iterator.
2748 *
2749 * @returns The next value from the iterator, or `undefined`.
2750 */
2751 RepeatIterator.prototype.next = function () {
2752 if (this._count <= 0) {
2753 return undefined;
2754 }
2755 this._count--;
2756 return this._value;
2757 };
2758 return RepeatIterator;
2759 }());
2760
2761 /**
2762 * Create an iterator for a retroable object.
2763 *
2764 * @param object - The retroable or array-like object of interest.
2765 *
2766 * @returns An iterator which traverses the object's values in reverse.
2767 *
2768 * #### Example
2769 * ```typescript
2770 * import { retro, toArray } from '@lumino/algorithm';
2771 *
2772 * let data = [1, 2, 3, 4, 5, 6];
2773 *
2774 * let stream = retro(data);
2775 *
2776 * toArray(stream); // [6, 5, 4, 3, 2, 1]
2777 * ```
2778 */
2779 function retro(object) {
2780 var it;
2781 if (typeof object.retro === 'function') {
2782 it = object.retro();
2783 }
2784 else {
2785 it = new RetroArrayIterator(object);
2786 }
2787 return it;
2788 }
2789 /**
2790 * An iterator which traverses an array-like object in reverse.
2791 *
2792 * #### Notes
2793 * This iterator can be used for any builtin JS array-like object.
2794 */
2795 var RetroArrayIterator = /** @class */ (function () {
2796 /**
2797 * Construct a new retro iterator.
2798 *
2799 * @param source - The array-like object of interest.
2800 */
2801 function RetroArrayIterator(source) {
2802 this._source = source;
2803 this._index = source.length - 1;
2804 }
2805 /**
2806 * Get an iterator over the object's values.
2807 *
2808 * @returns An iterator which yields the object's values.
2809 */
2810 RetroArrayIterator.prototype.iter = function () {
2811 return this;
2812 };
2813 /**
2814 * Create an independent clone of the iterator.
2815 *
2816 * @returns A new independent clone of the iterator.
2817 */
2818 RetroArrayIterator.prototype.clone = function () {
2819 var result = new RetroArrayIterator(this._source);
2820 result._index = this._index;
2821 return result;
2822 };
2823 /**
2824 * Get the next value from the iterator.
2825 *
2826 * @returns The next value from the iterator, or `undefined`.
2827 */
2828 RetroArrayIterator.prototype.next = function () {
2829 if (this._index < 0 || this._index >= this._source.length) {
2830 return undefined;
2831 }
2832 return this._source[this._index--];
2833 };
2834 return RetroArrayIterator;
2835 }());
2836
2837 // Copyright (c) Jupyter Development Team.
2838 /**
2839 * Topologically sort an iterable of edges.
2840 *
2841 * @param edges - The iterable or array-like object of edges to sort.
2842 * An edge is represented as a 2-tuple of `[fromNode, toNode]`.
2843 *
2844 * @returns The topologically sorted array of nodes.
2845 *
2846 * #### Notes
2847 * If a cycle is present in the graph, the cycle will be ignored and
2848 * the return value will be only approximately sorted.
2849 *
2850 * #### Example
2851 * ```typescript
2852 * import { topologicSort } from '@lumino/algorithm';
2853 *
2854 * let data = [
2855 * ['d', 'e'],
2856 * ['c', 'd'],
2857 * ['a', 'b'],
2858 * ['b', 'c']
2859 * ];
2860 *
2861 * topologicSort(data); // ['a', 'b', 'c', 'd', 'e']
2862 * ```
2863 */
2864 function topologicSort(edges) {
2865 // Setup the shared sorting state.
2866 var sorted = [];
2867 var visited = new Set();
2868 var graph = new Map();
2869 // Add the edges to the graph.
2870 each(edges, addEdge);
2871 // Visit each node in the graph.
2872 graph.forEach(function (v, k) {
2873 visit(k);
2874 });
2875 // Return the sorted results.
2876 return sorted;
2877 // Add an edge to the graph.
2878 function addEdge(edge) {
2879 var fromNode = edge[0], toNode = edge[1];
2880 var children = graph.get(toNode);
2881 if (children) {
2882 children.push(fromNode);
2883 }
2884 else {
2885 graph.set(toNode, [fromNode]);
2886 }
2887 }
2888 // Recursively visit the node.
2889 function visit(node) {
2890 if (visited.has(node)) {
2891 return;
2892 }
2893 visited.add(node);
2894 var children = graph.get(node);
2895 if (children) {
2896 children.forEach(visit);
2897 }
2898 sorted.push(node);
2899 }
2900 }
2901
2902 // Copyright (c) Jupyter Development Team.
2903 /**
2904 * Iterate over an iterable using a stepped increment.
2905 *
2906 * @param object - The iterable or array-like object of interest.
2907 *
2908 * @param step - The distance to step on each iteration. A value
2909 * of less than `1` will behave the same as a value of `1`.
2910 *
2911 * @returns An iterator which traverses the iterable step-wise.
2912 *
2913 * #### Example
2914 * ```typescript
2915 * import { stride, toArray } from '@lumino/algorithm';
2916 *
2917 * let data = [1, 2, 3, 4, 5, 6];
2918 *
2919 * let stream = stride(data, 2);
2920 *
2921 * toArray(stream); // [1, 3, 5];
2922 * ```
2923 */
2924 function stride(object, step) {
2925 return new StrideIterator(iter(object), step);
2926 }
2927 /**
2928 * An iterator which traverses a source iterator step-wise.
2929 */
2930 var StrideIterator = /** @class */ (function () {
2931 /**
2932 * Construct a new stride iterator.
2933 *
2934 * @param source - The iterator of values of interest.
2935 *
2936 * @param step - The distance to step on each iteration. A value
2937 * of less than `1` will behave the same as a value of `1`.
2938 */
2939 function StrideIterator(source, step) {
2940 this._source = source;
2941 this._step = step;
2942 }
2943 /**
2944 * Get an iterator over the object's values.
2945 *
2946 * @returns An iterator which yields the object's values.
2947 */
2948 StrideIterator.prototype.iter = function () {
2949 return this;
2950 };
2951 /**
2952 * Create an independent clone of the iterator.
2953 *
2954 * @returns A new independent clone of the iterator.
2955 */
2956 StrideIterator.prototype.clone = function () {
2957 return new StrideIterator(this._source.clone(), this._step);
2958 };
2959 /**
2960 * Get the next value from the iterator.
2961 *
2962 * @returns The next value from the iterator, or `undefined`.
2963 */
2964 StrideIterator.prototype.next = function () {
2965 var value = this._source.next();
2966 for (var n = this._step - 1; n > 0; --n) {
2967 this._source.next();
2968 }
2969 return value;
2970 };
2971 return StrideIterator;
2972 }());
2973
2974 // Copyright (c) Jupyter Development Team.
2975 // Distributed under the terms of the Modified BSD License.
2976 /*-----------------------------------------------------------------------------
2977 | Copyright (c) 2014-2017, PhosphorJS Contributors
2978 |
2979 | Distributed under the terms of the BSD 3-Clause License.
2980 |
2981 | The full license is in the file LICENSE, distributed with this software.
2982 |----------------------------------------------------------------------------*/
2983 /**
2984 * The namespace for string-specific algorithms.
2985 */
2986 exports.StringExt = void 0;
2987 (function (StringExt) {
2988 /**
2989 * Find the indices of characters in a source text.
2990 *
2991 * @param source - The source text which should be searched.
2992 *
2993 * @param query - The characters to locate in the source text.
2994 *
2995 * @param start - The index to start the search.
2996 *
2997 * @returns The matched indices, or `null` if there is no match.
2998 *
2999 * #### Complexity
3000 * Linear on `sourceText`.
3001 *
3002 * #### Notes
3003 * In order for there to be a match, all of the characters in `query`
3004 * **must** appear in `source` in the order given by `query`.
3005 *
3006 * Characters are matched using strict `===` equality.
3007 */
3008 function findIndices(source, query, start) {
3009 if (start === void 0) { start = 0; }
3010 var indices = new Array(query.length);
3011 for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
3012 j = source.indexOf(query[i], j);
3013 if (j === -1) {
3014 return null;
3015 }
3016 indices[i] = j;
3017 }
3018 return indices;
3019 }
3020 StringExt.findIndices = findIndices;
3021 /**
3022 * A string matcher which uses a sum-of-squares algorithm.
3023 *
3024 * @param source - The source text which should be searched.
3025 *
3026 * @param query - The characters to locate in the source text.
3027 *
3028 * @param start - The index to start the search.
3029 *
3030 * @returns The match result, or `null` if there is no match.
3031 * A lower `score` represents a stronger match.
3032 *
3033 * #### Complexity
3034 * Linear on `sourceText`.
3035 *
3036 * #### Notes
3037 * This scoring algorithm uses a sum-of-squares approach to determine
3038 * the score. In order for there to be a match, all of the characters
3039 * in `query` **must** appear in `source` in order. The index of each
3040 * matching character is squared and added to the score. This means
3041 * that early and consecutive character matches are preferred, while
3042 * late matches are heavily penalized.
3043 */
3044 function matchSumOfSquares(source, query, start) {
3045 if (start === void 0) { start = 0; }
3046 var indices = findIndices(source, query, start);
3047 if (!indices) {
3048 return null;
3049 }
3050 var score = 0;
3051 for (var i = 0, n = indices.length; i < n; ++i) {
3052 var j = indices[i] - start;
3053 score += j * j;
3054 }
3055 return { score: score, indices: indices };
3056 }
3057 StringExt.matchSumOfSquares = matchSumOfSquares;
3058 /**
3059 * A string matcher which uses a sum-of-deltas algorithm.
3060 *
3061 * @param source - The source text which should be searched.
3062 *
3063 * @param query - The characters to locate in the source text.
3064 *
3065 * @param start - The index to start the search.
3066 *
3067 * @returns The match result, or `null` if there is no match.
3068 * A lower `score` represents a stronger match.
3069 *
3070 * #### Complexity
3071 * Linear on `sourceText`.
3072 *
3073 * #### Notes
3074 * This scoring algorithm uses a sum-of-deltas approach to determine
3075 * the score. In order for there to be a match, all of the characters
3076 * in `query` **must** appear in `source` in order. The delta between
3077 * the indices are summed to create the score. This means that groups
3078 * of matched characters are preferred, while fragmented matches are
3079 * penalized.
3080 */
3081 function matchSumOfDeltas(source, query, start) {
3082 if (start === void 0) { start = 0; }
3083 var indices = findIndices(source, query, start);
3084 if (!indices) {
3085 return null;
3086 }
3087 var score = 0;
3088 var last = start - 1;
3089 for (var i = 0, n = indices.length; i < n; ++i) {
3090 var j = indices[i];
3091 score += j - last - 1;
3092 last = j;
3093 }
3094 return { score: score, indices: indices };
3095 }
3096 StringExt.matchSumOfDeltas = matchSumOfDeltas;
3097 /**
3098 * Highlight the matched characters of a source text.
3099 *
3100 * @param source - The text which should be highlighted.
3101 *
3102 * @param indices - The indices of the matched characters. They must
3103 * appear in increasing order and must be in bounds of the source.
3104 *
3105 * @param fn - The function to apply to the matched chunks.
3106 *
3107 * @returns An array of unmatched and highlighted chunks.
3108 */
3109 function highlight(source, indices, fn) {
3110 // Set up the result array.
3111 var result = [];
3112 // Set up the counter variables.
3113 var k = 0;
3114 var last = 0;
3115 var n = indices.length;
3116 // Iterator over each index.
3117 while (k < n) {
3118 // Set up the chunk indices.
3119 var i = indices[k];
3120 var j = indices[k];
3121 // Advance the right chunk index until it's non-contiguous.
3122 while (++k < n && indices[k] === j + 1) {
3123 j++;
3124 }
3125 // Extract the unmatched text.
3126 if (last < i) {
3127 result.push(source.slice(last, i));
3128 }
3129 // Extract and highlight the matched text.
3130 if (i < j + 1) {
3131 result.push(fn(source.slice(i, j + 1)));
3132 }
3133 // Update the last visited index.
3134 last = j + 1;
3135 }
3136 // Extract any remaining unmatched text.
3137 if (last < source.length) {
3138 result.push(source.slice(last));
3139 }
3140 // Return the highlighted result.
3141 return result;
3142 }
3143 StringExt.highlight = highlight;
3144 /**
3145 * A 3-way string comparison function.
3146 *
3147 * @param a - The first string of interest.
3148 *
3149 * @param b - The second string of interest.
3150 *
3151 * @returns `-1` if `a < b`, else `1` if `a > b`, else `0`.
3152 */
3153 function cmp(a, b) {
3154 return a < b ? -1 : a > b ? 1 : 0;
3155 }
3156 StringExt.cmp = cmp;
3157 })(exports.StringExt || (exports.StringExt = {}));
3158
3159 // Copyright (c) Jupyter Development Team.
3160 /**
3161 * Take a fixed number of items from an iterable.
3162 *
3163 * @param object - The iterable or array-like object of interest.
3164 *
3165 * @param count - The number of items to take from the iterable.
3166 *
3167 * @returns An iterator which yields the specified number of items
3168 * from the source iterable.
3169 *
3170 * #### Notes
3171 * The returned iterator will exhaust early if the source iterable
3172 * contains an insufficient number of items.
3173 */
3174 function take(object, count) {
3175 return new TakeIterator(iter(object), count);
3176 }
3177 /**
3178 * An iterator which takes a fixed number of items from a source.
3179 */
3180 var TakeIterator = /** @class */ (function () {
3181 /**
3182 * Construct a new take iterator.
3183 *
3184 * @param source - The iterator of interest.
3185 *
3186 * @param count - The number of items to take from the source.
3187 */
3188 function TakeIterator(source, count) {
3189 this._source = source;
3190 this._count = count;
3191 }
3192 /**
3193 * Get an iterator over the object's values.
3194 *
3195 * @returns An iterator which yields the object's values.
3196 */
3197 TakeIterator.prototype.iter = function () {
3198 return this;
3199 };
3200 /**
3201 * Create an independent clone of the iterator.
3202 *
3203 * @returns A new independent clone of the iterator.
3204 */
3205 TakeIterator.prototype.clone = function () {
3206 return new TakeIterator(this._source.clone(), this._count);
3207 };
3208 /**
3209 * Get the next value from the iterator.
3210 *
3211 * @returns The next value from the iterator, or `undefined`.
3212 */
3213 TakeIterator.prototype.next = function () {
3214 if (this._count <= 0) {
3215 return undefined;
3216 }
3217 var value = this._source.next();
3218 if (value === undefined) {
3219 return undefined;
3220 }
3221 this._count--;
3222 return value;
3223 };
3224 return TakeIterator;
3225 }());
3226
3227 // Copyright (c) Jupyter Development Team.
3228 /**
3229 * Iterate several iterables in lockstep.
3230 *
3231 * @param objects - The iterable or array-like objects of interest.
3232 *
3233 * @returns An iterator which yields successive tuples of values where
3234 * each value is taken in turn from the provided iterables. It will
3235 * be as long as the shortest provided iterable.
3236 *
3237 * #### Example
3238 * ```typescript
3239 * import { zip, toArray } from '@lumino/algorithm';
3240 *
3241 * let data1 = [1, 2, 3];
3242 * let data2 = [4, 5, 6];
3243 *
3244 * let stream = zip(data1, data2);
3245 *
3246 * toArray(stream); // [[1, 4], [2, 5], [3, 6]]
3247 * ```
3248 */
3249 function zip() {
3250 var objects = [];
3251 for (var _i = 0; _i < arguments.length; _i++) {
3252 objects[_i] = arguments[_i];
3253 }
3254 return new ZipIterator(objects.map(iter));
3255 }
3256 /**
3257 * An iterator which iterates several sources in lockstep.
3258 */
3259 var ZipIterator = /** @class */ (function () {
3260 /**
3261 * Construct a new zip iterator.
3262 *
3263 * @param source - The iterators of interest.
3264 */
3265 function ZipIterator(source) {
3266 this._source = source;
3267 }
3268 /**
3269 * Get an iterator over the object's values.
3270 *
3271 * @returns An iterator which yields the object's values.
3272 */
3273 ZipIterator.prototype.iter = function () {
3274 return this;
3275 };
3276 /**
3277 * Create an independent clone of the iterator.
3278 *
3279 * @returns A new independent clone of the iterator.
3280 */
3281 ZipIterator.prototype.clone = function () {
3282 return new ZipIterator(this._source.map(function (it) { return it.clone(); }));
3283 };
3284 /**
3285 * Get the next value from the iterator.
3286 *
3287 * @returns The next value from the iterator, or `undefined`.
3288 */
3289 ZipIterator.prototype.next = function () {
3290 var result = new Array(this._source.length);
3291 for (var i = 0, n = this._source.length; i < n; ++i) {
3292 var value = this._source[i].next();
3293 if (value === undefined) {
3294 return undefined;
3295 }
3296 result[i] = value;
3297 }
3298 return result;
3299 };
3300 return ZipIterator;
3301 }());
3302
3303 exports.ArrayIterator = ArrayIterator;
3304 exports.ChainIterator = ChainIterator;
3305 exports.EmptyIterator = EmptyIterator;
3306 exports.EnumerateIterator = EnumerateIterator;
3307 exports.FilterIterator = FilterIterator;
3308 exports.FnIterator = FnIterator;
3309 exports.ItemIterator = ItemIterator;
3310 exports.KeyIterator = KeyIterator;
3311 exports.MapIterator = MapIterator;
3312 exports.RangeIterator = RangeIterator;
3313 exports.RepeatIterator = RepeatIterator;
3314 exports.RetroArrayIterator = RetroArrayIterator;
3315 exports.StrideIterator = StrideIterator;
3316 exports.TakeIterator = TakeIterator;
3317 exports.ValueIterator = ValueIterator;
3318 exports.ZipIterator = ZipIterator;
3319 exports.chain = chain;
3320 exports.each = each;
3321 exports.empty = empty;
3322 exports.enumerate = enumerate;
3323 exports.every = every;
3324 exports.filter = filter;
3325 exports.find = find;
3326 exports.findIndex = findIndex;
3327 exports.iter = iter;
3328 exports.iterFn = iterFn;
3329 exports.iterItems = iterItems;
3330 exports.iterKeys = iterKeys;
3331 exports.iterValues = iterValues;
3332 exports.map = map;
3333 exports.max = max;
3334 exports.min = min;
3335 exports.minmax = minmax;
3336 exports.once = once;
3337 exports.range = range;
3338 exports.reduce = reduce;
3339 exports.repeat = repeat;
3340 exports.retro = retro;
3341 exports.some = some;
3342 exports.stride = stride;
3343 exports.take = take;
3344 exports.toArray = toArray;
3345 exports.toObject = toObject;
3346 exports.topologicSort = topologicSort;
3347 exports.zip = zip;
3348
3349 Object.defineProperty(exports, '__esModule', { value: true });
3350
3351})));
3352//# sourceMappingURL=index.js.map