binary-tree-typed 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/cjs/index.cjs +609 -0
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +609 -0
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +609 -0
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +609 -0
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/data-structures/base/index.d.ts +1 -0
  10. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  11. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  12. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +252 -0
  13. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +294 -0
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +527 -2
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +505 -1
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +399 -0
  17. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +126 -1
  18. package/dist/types/data-structures/binary-tree/tree-map.d.ts +2881 -382
  19. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2867 -347
  20. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2328 -312
  21. package/dist/types/data-structures/binary-tree/tree-set.d.ts +2671 -277
  22. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  23. package/dist/types/data-structures/graph/directed-graph.d.ts +210 -0
  24. package/dist/types/data-structures/graph/undirected-graph.d.ts +189 -0
  25. package/dist/types/data-structures/hash/hash-map.d.ts +241 -10
  26. package/dist/types/data-structures/heap/heap.d.ts +294 -0
  27. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +360 -3
  28. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +318 -3
  29. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +380 -2
  30. package/dist/types/data-structures/matrix/matrix.d.ts +168 -0
  31. package/dist/types/data-structures/queue/deque.d.ts +319 -4
  32. package/dist/types/data-structures/queue/queue.d.ts +252 -0
  33. package/dist/types/data-structures/stack/stack.d.ts +210 -0
  34. package/dist/types/data-structures/trie/trie.d.ts +256 -4
  35. package/dist/types/interfaces/graph.d.ts +1 -1
  36. package/dist/types/types/common.d.ts +2 -2
  37. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  38. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  39. package/dist/types/types/utils/validate-type.d.ts +4 -4
  40. package/dist/umd/binary-tree-typed.js +609 -0
  41. package/dist/umd/binary-tree-typed.js.map +1 -1
  42. package/dist/umd/binary-tree-typed.min.js +5 -5
  43. package/dist/umd/binary-tree-typed.min.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/data-structures/base/index.ts +1 -0
  46. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  47. package/src/data-structures/base/linear-base.ts +3 -3
  48. package/src/data-structures/binary-tree/avl-tree.ts +252 -0
  49. package/src/data-structures/binary-tree/binary-indexed-tree.ts +295 -1
  50. package/src/data-structures/binary-tree/binary-tree.ts +527 -2
  51. package/src/data-structures/binary-tree/bst.ts +505 -1
  52. package/src/data-structures/binary-tree/red-black-tree.ts +399 -0
  53. package/src/data-structures/binary-tree/segment-tree.ts +127 -2
  54. package/src/data-structures/binary-tree/tree-map.ts +2958 -459
  55. package/src/data-structures/binary-tree/tree-multi-map.ts +3069 -549
  56. package/src/data-structures/binary-tree/tree-multi-set.ts +2476 -460
  57. package/src/data-structures/binary-tree/tree-set.ts +2816 -422
  58. package/src/data-structures/graph/abstract-graph.ts +4 -4
  59. package/src/data-structures/graph/directed-graph.ts +210 -0
  60. package/src/data-structures/graph/undirected-graph.ts +189 -0
  61. package/src/data-structures/hash/hash-map.ts +246 -15
  62. package/src/data-structures/heap/heap.ts +294 -0
  63. package/src/data-structures/linked-list/doubly-linked-list.ts +360 -3
  64. package/src/data-structures/linked-list/singly-linked-list.ts +318 -3
  65. package/src/data-structures/linked-list/skip-linked-list.ts +380 -2
  66. package/src/data-structures/matrix/matrix.ts +169 -1
  67. package/src/data-structures/queue/deque.ts +320 -5
  68. package/src/data-structures/queue/queue.ts +252 -0
  69. package/src/data-structures/stack/stack.ts +210 -0
  70. package/src/data-structures/trie/trie.ts +257 -5
  71. package/src/interfaces/graph.ts +1 -1
  72. package/src/types/common.ts +2 -2
  73. package/src/types/data-structures/heap/heap.ts +1 -0
  74. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  75. package/src/types/utils/validate-type.ts +4 -4
@@ -142,38 +142,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
142
142
 
143
143
 
144
144
 
145
- * @example
146
- * // Check empty
147
- * console.log(new TreeSet().isEmpty()); // true;
148
- */
149
- isEmpty(): boolean {
150
- return this.size === 0;
151
- }
152
-
153
- private _validateKey(key: K): void {
154
- if (!this.#isDefaultComparator) return;
155
-
156
- if (typeof key === 'number') {
157
- if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeSet'));
158
- return;
159
- }
160
-
161
- if (typeof key === 'string') return;
162
-
163
- if (key instanceof Date) {
164
- if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeSet'));
165
- return;
166
- }
167
-
168
- // Other key types should have provided a comparator, so reaching here means misuse.
169
- throw new TypeError(ERR.comparatorRequired('TreeSet'));
170
- }
171
-
172
- /**
173
- * Add a key to the set (no-op if already present).
174
- * @remarks Expected time O(log n)
175
-
176
-
177
145
 
178
146
 
179
147
 
@@ -213,28 +181,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
213
181
 
214
182
 
215
183
 
216
- * @example
217
- * // Unique tags with sorted order
218
- * const tags = new TreeSet<string>(['javascript', 'typescript', 'react', 'typescript', 'node']);
219
- *
220
- * // Duplicates removed, sorted alphabetically
221
- * console.log([...tags]); // ['javascript', 'node', 'react', 'typescript'];
222
- * console.log(tags.size); // 4;
223
- *
224
- * tags.add('angular');
225
- * console.log(tags.first()); // 'angular';
226
- * console.log(tags.last()); // 'typescript';
227
- */
228
- add(key: K): this {
229
- this._validateKey(key);
230
- // RBT.set returns boolean; Set.add returns this.
231
- this.#core.set(key, undefined);
232
- return this;
233
- }
234
-
235
- /**
236
- * Test whether a key exists.
237
- * @remarks Expected time O(log n)
238
184
 
239
185
 
240
186
 
@@ -284,22 +230,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
284
230
 
285
231
 
286
232
 
287
- * @example
288
- * // Checking membership in a sorted collection
289
- * const allowed = new TreeSet<string>(['admin', 'editor', 'viewer']);
290
- *
291
- * console.log(allowed.has('admin')); // true;
292
- * console.log(allowed.has('guest')); // false;
293
- */
294
- has(key: K): boolean {
295
- this._validateKey(key);
296
- return this.#core.has(key);
297
- }
298
-
299
- /**
300
- * Delete a key.
301
- * @returns `true` if the key existed; otherwise `false`.
302
- * @remarks Expected time O(log n)
303
233
 
304
234
 
305
235
 
@@ -317,6 +247,36 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
317
247
 
318
248
 
319
249
 
250
+ * @example
251
+ * // Check empty
252
+ * console.log(new TreeSet().isEmpty()); // true;
253
+ */
254
+ isEmpty(): boolean {
255
+ return this.size === 0;
256
+ }
257
+
258
+ private _validateKey(key: K): void {
259
+ if (!this.#isDefaultComparator) return;
260
+
261
+ if (typeof key === 'number') {
262
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeSet'));
263
+ return;
264
+ }
265
+
266
+ if (typeof key === 'string') return;
267
+
268
+ if (key instanceof Date) {
269
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeSet'));
270
+ return;
271
+ }
272
+
273
+ // Other key types should have provided a comparator, so reaching here means misuse.
274
+ throw new TypeError(ERR.comparatorRequired('TreeSet'));
275
+ }
276
+
277
+ /**
278
+ * Add a key to the set (no-op if already present).
279
+ * @remarks Expected time O(log n)
320
280
 
321
281
 
322
282
 
@@ -349,22 +309,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
349
309
 
350
310
 
351
311
 
352
- * @example
353
- * // Removing elements while maintaining order
354
- * const nums = new TreeSet<number>([1, 3, 5, 7, 9]);
355
- *
356
- * console.log(nums.delete(5)); // true;
357
- * console.log(nums.delete(5)); // false; // already gone
358
- * console.log([...nums]); // [1, 3, 7, 9];
359
- */
360
- delete(key: K): boolean {
361
- this._validateKey(key);
362
- const res = this.#core.delete(key);
363
- return Array.isArray(res) && res.length > 0 && !!res[0]?.deleted;
364
- }
365
-
366
- /**
367
- * Remove all keys.
368
312
 
369
313
 
370
314
 
@@ -403,18 +347,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
403
347
 
404
348
 
405
349
 
406
- * @example
407
- * // Remove all
408
- * const ts = new TreeSet<number>([1, 2]);
409
- * ts.clear();
410
- * console.log(ts.isEmpty()); // true;
411
- */
412
- clear(): void {
413
- this.#core.clear();
414
- }
415
-
416
- /**
417
- * Iterate over keys in ascending order.
418
350
 
419
351
 
420
352
 
@@ -453,19 +385,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
453
385
 
454
386
 
455
387
 
456
- * @example
457
- * // Get sorted keys
458
- * const ts = new TreeSet<number>([30, 10, 20]);
459
- * console.log([...ts.keys()]); // [10, 20, 30];
460
- */
461
- keys(): IterableIterator<K> {
462
- return this.#core.keys();
463
- }
464
-
465
- /**
466
- * Iterate over values in ascending order.
467
- *
468
- * Note: for Set-like containers, `values()` is the same as `keys()`.
469
388
 
470
389
 
471
390
 
@@ -505,18 +424,29 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
505
424
 
506
425
 
507
426
  * @example
508
- * // Get values (same as keys for Set)
509
- * const ts = new TreeSet<number>([2, 1, 3]);
510
- * console.log([...ts.values()]); // [1, 2, 3];
427
+ * // Unique tags with sorted order
428
+ * const tags = new TreeSet<string>(['javascript', 'typescript', 'react', 'typescript', 'node']);
429
+ *
430
+ * // Duplicates removed, sorted alphabetically
431
+ * console.log([...tags]); // ['javascript', 'node', 'react', 'typescript'];
432
+ * console.log(tags.size); // 4;
433
+ *
434
+ * tags.add('angular');
435
+ * console.log(tags.first()); // 'angular';
436
+ * console.log(tags.last()); // 'typescript';
511
437
  */
512
- values(): IterableIterator<K> {
513
- return this.keys();
438
+ add(key: K): this {
439
+ this._validateKey(key);
440
+ // RBT.set returns boolean; Set.add returns this.
441
+ this.#core.set(key, undefined);
442
+ return this;
514
443
  }
515
444
 
516
445
  /**
517
- * Iterate over `[value, value]` pairs (native Set convention).
518
- *
519
- * Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
446
+ * Test whether a key exists.
447
+ * @remarks Expected time O(log n)
448
+
449
+
520
450
 
521
451
 
522
452
 
@@ -555,23 +485,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
555
485
 
556
486
 
557
487
 
558
- * @example
559
- * // Iterate entries
560
- * const ts = new TreeSet<number>([3, 1, 2]);
561
- * console.log([...ts.entries()].map(([k]) => k)); // [1, 2, 3];
562
- */
563
- *entries(): IterableIterator<[K, K]> {
564
- for (const k of this.keys()) yield [k, k];
565
- }
566
-
567
- [Symbol.iterator](): IterableIterator<K> {
568
- return this.keys();
569
- }
570
-
571
- /**
572
- * Visit each value in ascending order.
573
- *
574
- * Callback follows native Set convention: `(value, value2, set)`.
575
488
 
576
489
 
577
490
 
@@ -610,22 +523,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
610
523
 
611
524
 
612
525
 
613
- * @example
614
- * // Execute for each
615
- * const ts = new TreeSet<number>([3, 1, 2]);
616
- * const keys: number[] = [];
617
- * ts.forEach(k => keys.push(k));
618
- * console.log(keys); // [1, 2, 3];
619
- */
620
- forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
621
- for (const k of this) cb.call(thisArg, k, k, this);
622
- }
623
-
624
- /**
625
- * Create a new TreeSet by mapping each value to a new key.
626
- *
627
- * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
628
- * @remarks Time O(n log n) expected, Space O(n)
629
526
 
630
527
 
631
528
 
@@ -664,31 +561,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
664
561
 
665
562
 
666
563
 
667
- * @example
668
- * // Transform
669
- * const ts = new TreeSet<number>([1, 2, 3]);
670
- * const doubled = ts.map(k => k * 2);
671
- * console.log([...doubled]); // [2, 4, 6];
672
- */
673
- map<MK>(
674
- callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
675
- options: Omit<TreeSetOptions<MK>, 'toElementFn'> & { comparator?: (a: MK, b: MK) => number } = {},
676
- thisArg?: unknown
677
- ): TreeSet<MK> {
678
- const out = new TreeSet<MK>([], options as TreeSetOptions<MK>);
679
- let index = 0;
680
- for (const v of this) {
681
- const mk = thisArg === undefined
682
- ? callbackfn(v, index++, this)
683
- : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => MK).call(thisArg, v, index++, this);
684
- out.add(mk);
685
- }
686
- return out;
687
- }
688
-
689
- /**
690
- * Create a new TreeSet containing only values that satisfy the predicate.
691
- * @remarks Time O(n log n) expected, Space O(n)
692
564
 
693
565
 
694
566
 
@@ -728,26 +600,29 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
728
600
 
729
601
 
730
602
  * @example
731
- * // Filter
732
- * const ts = new TreeSet<number>([1, 2, 3, 4, 5]);
733
- * const evens = ts.filter(k => k % 2 === 0);
734
- * console.log([...evens]); // [2, 4];
603
+ * // Checking membership in a sorted collection
604
+ * const allowed = new TreeSet<string>(['admin', 'editor', 'viewer']);
605
+ *
606
+ * console.log(allowed.has('admin')); // true;
607
+ * console.log(allowed.has('guest')); // false;
735
608
  */
736
- filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
737
- const out = new TreeSet<K>([], { comparator: this.#userComparator });
738
- let index = 0;
739
- for (const v of this) {
740
- const ok = thisArg === undefined
741
- ? callbackfn(v, index++, this)
742
- : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
743
- if (ok) out.add(v);
744
- }
745
- return out;
609
+ has(key: K): boolean {
610
+ this._validateKey(key);
611
+ return this.#core.has(key);
746
612
  }
747
613
 
748
614
  /**
749
- * Reduce values into a single accumulator.
750
- * @remarks Time O(n), Space O(1)
615
+ * Delete a key.
616
+ * @returns `true` if the key existed; otherwise `false`.
617
+ * @remarks Expected time O(log n)
618
+
619
+
620
+
621
+
622
+
623
+
624
+
625
+
751
626
 
752
627
 
753
628
 
@@ -786,22 +661,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
786
661
 
787
662
 
788
663
 
789
- * @example
790
- * // Aggregate
791
- * const ts = new TreeSet<number>([1, 2, 3]);
792
- * const sum = ts.reduce((acc, k) => acc + k, 0);
793
- * console.log(sum); // 6;
794
- */
795
- reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
796
- let acc = initialValue;
797
- let index = 0;
798
- for (const v of this) acc = callbackfn(acc, v, index++, this);
799
- return acc;
800
- }
801
-
802
- /**
803
- * Test whether all values satisfy a predicate.
804
- * @remarks Time O(n), Space O(1)
805
664
 
806
665
 
807
666
 
@@ -838,25 +697,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
838
697
 
839
698
 
840
699
 
841
- * @example
842
- * // Test all
843
- * const ts = new TreeSet<number>([2, 4, 6]);
844
- * console.log(ts.every(k => k > 0)); // true;
845
- */
846
- every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
847
- let index = 0;
848
- for (const v of this) {
849
- const ok = thisArg === undefined
850
- ? callbackfn(v, index++, this)
851
- : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
852
- if (!ok) return false;
853
- }
854
- return true;
855
- }
856
-
857
- /**
858
- * Test whether any value satisfies a predicate.
859
- * @remarks Time O(n), Space O(1)
860
700
 
861
701
 
862
702
 
@@ -893,25 +733,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
893
733
 
894
734
 
895
735
 
896
- * @example
897
- * // Test any
898
- * const ts = new TreeSet<number>([1, 3, 5]);
899
- * console.log(ts.some(k => k === 3)); // true;
900
- */
901
- some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
902
- let index = 0;
903
- for (const v of this) {
904
- const ok = thisArg === undefined
905
- ? callbackfn(v, index++, this)
906
- : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
907
- if (ok) return true;
908
- }
909
- return false;
910
- }
911
-
912
- /**
913
- * Find the first value that satisfies a predicate.
914
- * @remarks Time O(n), Space O(1)
915
736
 
916
737
 
917
738
 
@@ -949,25 +770,21 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
949
770
 
950
771
 
951
772
  * @example
952
- * // Find entry
953
- * const ts = new TreeSet<number>([1, 2, 3]);
954
- * const found = ts.find(k => k === 2);
955
- * console.log(found); // 2;
773
+ * // Removing elements while maintaining order
774
+ * const nums = new TreeSet<number>([1, 3, 5, 7, 9]);
775
+ *
776
+ * console.log(nums.delete(5)); // true;
777
+ * console.log(nums.delete(5)); // false; // already gone
778
+ * console.log([...nums]); // [1, 3, 7, 9];
956
779
  */
957
- find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
958
- let index = 0;
959
- for (const v of this) {
960
- const ok = thisArg === undefined
961
- ? callbackfn(v, index++, this)
962
- : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
963
- if (ok) return v;
964
- }
965
- return undefined;
780
+ delete(key: K): boolean {
781
+ this._validateKey(key);
782
+ const res = this.#core.delete(key);
783
+ return Array.isArray(res) && res.length > 0 && !!res[0]?.deleted;
966
784
  }
967
785
 
968
786
  /**
969
- * Materialize the set into an array of keys.
970
- * @remarks Time O(n), Space O(n)
787
+ * Remove all keys.
971
788
 
972
789
 
973
790
 
@@ -1006,18 +823,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1006
823
 
1007
824
 
1008
825
 
1009
- * @example
1010
- * // Convert to array
1011
- * const ts = new TreeSet<number>([3, 1, 2]);
1012
- * console.log(ts.toArray()); // [1, 2, 3];
1013
- */
1014
- toArray(): K[] {
1015
- return [...this];
1016
- }
1017
-
1018
- /**
1019
- * Print a human-friendly representation.
1020
- * @remarks Time O(n), Space O(n)
1021
826
 
1022
827
 
1023
828
 
@@ -1056,20 +861,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1056
861
 
1057
862
 
1058
863
 
1059
- * @example
1060
- * // Display tree
1061
- * const ts = new TreeSet<number>([1, 2, 3]);
1062
- * expect(() => ts.print()).not.toThrow();
1063
- */
1064
- print(): void {
1065
- // Delegate to the underlying tree's visualization.
1066
- this.#core.print();
1067
- }
1068
-
1069
- // Navigable operations
1070
-
1071
- /**
1072
- * Smallest key in the set.
1073
864
 
1074
865
 
1075
866
 
@@ -1081,40 +872,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1081
872
 
1082
873
 
1083
874
 
1084
- * @example
1085
- * // Student grade ranking with custom comparator
1086
- * interface Student {
1087
- * name: string;
1088
- * gpa: number;
1089
- * }
1090
- *
1091
- * const ranking = new TreeSet<Student>(
1092
- * [
1093
- * { name: 'Alice', gpa: 3.8 },
1094
- * { name: 'Bob', gpa: 3.5 },
1095
- * { name: 'Charlie', gpa: 3.9 },
1096
- * { name: 'Diana', gpa: 3.5 }
1097
- * ],
1098
- * { comparator: (a, b) => b.gpa - a.gpa || a.name.localeCompare(b.name) }
1099
- * );
1100
- *
1101
- * // Sorted by GPA descending, then name ascending
1102
- * const names = [...ranking].map(s => s.name);
1103
- * console.log(names); // ['Charlie', 'Alice', 'Bob', 'Diana'];
1104
- *
1105
- * // Top student
1106
- * console.log(ranking.first()?.name); // 'Charlie';
1107
- *
1108
- * // Filter students with GPA >= 3.8
1109
- * const honors = ranking.filter(s => s.gpa >= 3.8);
1110
- * console.log(honors.toArray().map(s => s.name)); // ['Charlie', 'Alice'];
1111
- */
1112
- first(): K | undefined {
1113
- return this.#core.getLeftMost();
1114
- }
1115
-
1116
- /**
1117
- * Largest key in the set.
1118
875
 
1119
876
 
1120
877
 
@@ -1126,18 +883,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1126
883
 
1127
884
 
1128
885
 
1129
- * @example
1130
- * // Get the maximum element
1131
- * const temps = new TreeSet<number>([18, 22, 15, 30, 25]);
1132
- * console.log(temps.last()); // 30;
1133
- * console.log(temps.first()); // 15;
1134
- */
1135
- last(): K | undefined {
1136
- return this.#core.getRightMost();
1137
- }
1138
-
1139
- /**
1140
- * Remove and return the smallest key.
1141
886
 
1142
887
 
1143
888
 
@@ -1149,23 +894,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1149
894
 
1150
895
 
1151
896
 
1152
- * @example
1153
- * // Remove and return minimum
1154
- * const queue = new TreeSet<number>([5, 1, 8, 3]);
1155
- *
1156
- * console.log(queue.pollFirst()); // 1;
1157
- * console.log(queue.pollFirst()); // 3;
1158
- * console.log(queue.size); // 2;
1159
- */
1160
- pollFirst(): K | undefined {
1161
- const k = this.first();
1162
- if (k === undefined) return undefined;
1163
- this.delete(k);
1164
- return k;
1165
- }
1166
-
1167
- /**
1168
- * Remove and return the largest key.
1169
897
 
1170
898
 
1171
899
 
@@ -1177,22 +905,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1177
905
 
1178
906
 
1179
907
 
1180
- * @example
1181
- * // Remove and return maximum
1182
- * const stack = new TreeSet<number>([10, 20, 30]);
1183
- *
1184
- * console.log(stack.pollLast()); // 30;
1185
- * console.log(stack.size); // 2;
1186
- */
1187
- pollLast(): K | undefined {
1188
- const k = this.last();
1189
- if (k === undefined) return undefined;
1190
- this.delete(k);
1191
- return k;
1192
- }
1193
-
1194
- /**
1195
- * Smallest key that is >= the given key.
1196
908
 
1197
909
 
1198
910
 
@@ -1216,6 +928,18 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1216
928
 
1217
929
 
1218
930
 
931
+ * @example
932
+ * // Remove all
933
+ * const ts = new TreeSet<number>([1, 2]);
934
+ * ts.clear();
935
+ * console.log(ts.isEmpty()); // true;
936
+ */
937
+ clear(): void {
938
+ this.#core.clear();
939
+ }
940
+
941
+ /**
942
+ * Iterate over keys in ascending order.
1219
943
 
1220
944
 
1221
945
 
@@ -1231,30 +955,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1231
955
 
1232
956
 
1233
957
 
1234
- * @example
1235
- * // Finding nearest available time slot
1236
- * // Available appointment times (minutes from midnight)
1237
- * const slots = new TreeSet<number>([540, 600, 660, 720, 840, 900]);
1238
- *
1239
- * // Customer wants something around 10:30 (630 min)
1240
- * const nearest = slots.ceiling(630);
1241
- * console.log(nearest); // 660; // 11:00 AM
1242
- *
1243
- * // What's the latest slot before 2:00 PM (840)?
1244
- * const before2pm = slots.lower(840);
1245
- * console.log(before2pm); // 720; // 12:00 PM
1246
- *
1247
- * // Book the 11:00 slot
1248
- * slots.delete(660);
1249
- * console.log(slots.ceiling(630)); // 720;
1250
- */
1251
- ceiling(key: K): K | undefined {
1252
- this._validateKey(key);
1253
- return this.#core.ceiling(key);
1254
- }
1255
-
1256
- /**
1257
- * Largest key that is <= the given key.
1258
958
 
1259
959
 
1260
960
 
@@ -1293,22 +993,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1293
993
 
1294
994
 
1295
995
 
1296
- * @example
1297
- * // Largest element ≤ target
1298
- * const breakpoints = new TreeSet<number>([320, 768, 1024, 1280, 1920]);
1299
- *
1300
- * // Current width is 800 → which breakpoint applies?
1301
- * console.log(breakpoints.floor(800)); // 768;
1302
- * console.log(breakpoints.floor(1024)); // 1024; // exact match
1303
- * console.log(breakpoints.floor(100)); // undefined;
1304
- */
1305
- floor(key: K): K | undefined {
1306
- this._validateKey(key);
1307
- return this.#core.floor(key);
1308
- }
1309
-
1310
- /**
1311
- * Smallest key that is > the given key.
1312
996
 
1313
997
 
1314
998
 
@@ -1347,20 +1031,6 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1347
1031
 
1348
1032
 
1349
1033
 
1350
- * @example
1351
- * // Smallest element strictly > target
1352
- * const levels = new TreeSet<number>([1, 5, 10, 25, 50, 100]);
1353
- *
1354
- * console.log(levels.higher(10)); // 25;
1355
- * console.log(levels.higher(100)); // undefined;
1356
- */
1357
- higher(key: K): K | undefined {
1358
- this._validateKey(key);
1359
- return this.#core.higher(key);
1360
- }
1361
-
1362
- /**
1363
- * Largest key that is < the given key.
1364
1034
 
1365
1035
 
1366
1036
 
@@ -1399,7 +1069,2542 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1399
1069
 
1400
1070
 
1401
1071
 
1402
- * @example
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+ * @example
1087
+ * // Get sorted keys
1088
+ * const ts = new TreeSet<number>([30, 10, 20]);
1089
+ * console.log([...ts.keys()]); // [10, 20, 30];
1090
+ */
1091
+ keys(): IterableIterator<K> {
1092
+ return this.#core.keys();
1093
+ }
1094
+
1095
+ /**
1096
+ * Iterate over values in ascending order.
1097
+ *
1098
+ * Note: for Set-like containers, `values()` is the same as `keys()`.
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+
1181
+
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+
1193
+
1194
+
1195
+
1196
+
1197
+
1198
+
1199
+
1200
+
1201
+
1202
+
1203
+
1204
+
1205
+
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+ * @example
1243
+ * // Get values (same as keys for Set)
1244
+ * const ts = new TreeSet<number>([2, 1, 3]);
1245
+ * console.log([...ts.values()]); // [1, 2, 3];
1246
+ */
1247
+ values(): IterableIterator<K> {
1248
+ return this.keys();
1249
+ }
1250
+
1251
+ /**
1252
+ * Iterate over `[value, value]` pairs (native Set convention).
1253
+ *
1254
+ * Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+ * @example
1399
+ * // Iterate entries
1400
+ * const ts = new TreeSet<number>([3, 1, 2]);
1401
+ * console.log([...ts.entries()].map(([k]) => k)); // [1, 2, 3];
1402
+ */
1403
+ *entries(): IterableIterator<[K, K]> {
1404
+ for (const k of this.keys()) yield [k, k];
1405
+ }
1406
+
1407
+ [Symbol.iterator](): IterableIterator<K> {
1408
+ return this.keys();
1409
+ }
1410
+
1411
+ /**
1412
+ * Visit each value in ascending order.
1413
+ *
1414
+ * Callback follows native Set convention: `(value, value2, set)`.
1415
+
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+ * @example
1559
+ * // Execute for each
1560
+ * const ts = new TreeSet<number>([3, 1, 2]);
1561
+ * const keys: number[] = [];
1562
+ * ts.forEach(k => keys.push(k));
1563
+ * console.log(keys); // [1, 2, 3];
1564
+ */
1565
+ forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: unknown): void {
1566
+ for (const k of this) cb.call(thisArg, k, k, this);
1567
+ }
1568
+
1569
+ /**
1570
+ * Create a new TreeSet by mapping each value to a new key.
1571
+ *
1572
+ * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
1573
+ * @remarks Time O(n log n) expected, Space O(n)
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+
1676
+
1677
+
1678
+
1679
+
1680
+
1681
+
1682
+
1683
+
1684
+
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+ * @example
1718
+ * // Transform
1719
+ * const ts = new TreeSet<number>([1, 2, 3]);
1720
+ * const doubled = ts.map(k => k * 2);
1721
+ * console.log([...doubled]); // [2, 4, 6];
1722
+ */
1723
+ map<MK>(
1724
+ callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
1725
+ options: Omit<TreeSetOptions<MK>, 'toElementFn'> & { comparator?: (a: MK, b: MK) => number } = {},
1726
+ thisArg?: unknown
1727
+ ): TreeSet<MK> {
1728
+ const out = new TreeSet<MK>([], options as TreeSetOptions<MK>);
1729
+ let index = 0;
1730
+ for (const v of this) {
1731
+ const mk = thisArg === undefined
1732
+ ? callbackfn(v, index++, this)
1733
+ : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => MK).call(thisArg, v, index++, this);
1734
+ out.add(mk);
1735
+ }
1736
+ return out;
1737
+ }
1738
+
1739
+ /**
1740
+ * Create a new TreeSet containing only values that satisfy the predicate.
1741
+ * @remarks Time O(n log n) expected, Space O(n)
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+
1751
+
1752
+
1753
+
1754
+
1755
+
1756
+
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+
1763
+
1764
+
1765
+
1766
+
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+
1794
+
1795
+
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+
1808
+
1809
+
1810
+
1811
+
1812
+
1813
+
1814
+
1815
+
1816
+
1817
+
1818
+
1819
+
1820
+
1821
+
1822
+
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+
1836
+
1837
+
1838
+
1839
+
1840
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+
1847
+
1848
+
1849
+
1850
+
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1881
+
1882
+
1883
+
1884
+
1885
+ * @example
1886
+ * // Filter
1887
+ * const ts = new TreeSet<number>([1, 2, 3, 4, 5]);
1888
+ * const evens = ts.filter(k => k % 2 === 0);
1889
+ * console.log([...evens]); // [2, 4];
1890
+ */
1891
+ filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
1892
+ const out = new TreeSet<K>([], { comparator: this.#userComparator });
1893
+ let index = 0;
1894
+ for (const v of this) {
1895
+ const ok = thisArg === undefined
1896
+ ? callbackfn(v, index++, this)
1897
+ : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
1898
+ if (ok) out.add(v);
1899
+ }
1900
+ return out;
1901
+ }
1902
+
1903
+ /**
1904
+ * Reduce values into a single accumulator.
1905
+ * @remarks Time O(n), Space O(1)
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+
1938
+
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+
1992
+
1993
+
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+
2000
+
2001
+
2002
+
2003
+
2004
+
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+
2049
+ * @example
2050
+ * // Aggregate
2051
+ * const ts = new TreeSet<number>([1, 2, 3]);
2052
+ * const sum = ts.reduce((acc, k) => acc + k, 0);
2053
+ * console.log(sum); // 6;
2054
+ */
2055
+ reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
2056
+ let acc = initialValue;
2057
+ let index = 0;
2058
+ for (const v of this) acc = callbackfn(acc, v, index++, this);
2059
+ return acc;
2060
+ }
2061
+
2062
+ /**
2063
+ * Test whether all values satisfy a predicate.
2064
+ * @remarks Time O(n), Space O(1)
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+
2091
+
2092
+
2093
+
2094
+
2095
+
2096
+
2097
+
2098
+
2099
+
2100
+
2101
+
2102
+
2103
+
2104
+
2105
+
2106
+
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+
2119
+
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+
2162
+
2163
+
2164
+
2165
+
2166
+
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+
2181
+
2182
+
2183
+
2184
+
2185
+
2186
+
2187
+
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+ * @example
2207
+ * // Test all
2208
+ * const ts = new TreeSet<number>([2, 4, 6]);
2209
+ * console.log(ts.every(k => k > 0)); // true;
2210
+ */
2211
+ every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
2212
+ let index = 0;
2213
+ for (const v of this) {
2214
+ const ok = thisArg === undefined
2215
+ ? callbackfn(v, index++, this)
2216
+ : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
2217
+ if (!ok) return false;
2218
+ }
2219
+ return true;
2220
+ }
2221
+
2222
+ /**
2223
+ * Test whether any value satisfies a predicate.
2224
+ * @remarks Time O(n), Space O(1)
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+
2234
+
2235
+
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+
2285
+
2286
+
2287
+
2288
+
2289
+
2290
+
2291
+
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+
2299
+
2300
+
2301
+
2302
+
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+
2309
+
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+
2347
+
2348
+
2349
+
2350
+
2351
+
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+
2361
+
2362
+
2363
+
2364
+
2365
+
2366
+ * @example
2367
+ * // Test any
2368
+ * const ts = new TreeSet<number>([1, 3, 5]);
2369
+ * console.log(ts.some(k => k === 3)); // true;
2370
+ */
2371
+ some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
2372
+ let index = 0;
2373
+ for (const v of this) {
2374
+ const ok = thisArg === undefined
2375
+ ? callbackfn(v, index++, this)
2376
+ : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
2377
+ if (ok) return true;
2378
+ }
2379
+ return false;
2380
+ }
2381
+
2382
+ /**
2383
+ * Find the first value that satisfies a predicate.
2384
+ * @remarks Time O(n), Space O(1)
2385
+
2386
+
2387
+
2388
+
2389
+
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+
2411
+
2412
+
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+
2423
+
2424
+
2425
+
2426
+
2427
+
2428
+
2429
+
2430
+
2431
+
2432
+
2433
+
2434
+
2435
+
2436
+
2437
+
2438
+
2439
+
2440
+
2441
+
2442
+
2443
+
2444
+
2445
+
2446
+
2447
+
2448
+
2449
+
2450
+
2451
+
2452
+
2453
+
2454
+
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+
2461
+
2462
+
2463
+
2464
+
2465
+
2466
+
2467
+
2468
+
2469
+
2470
+
2471
+
2472
+
2473
+
2474
+
2475
+
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+ * @example
2527
+ * // Find entry
2528
+ * const ts = new TreeSet<number>([1, 2, 3]);
2529
+ * const found = ts.find(k => k === 2);
2530
+ * console.log(found); // 2;
2531
+ */
2532
+ find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
2533
+ let index = 0;
2534
+ for (const v of this) {
2535
+ const ok = thisArg === undefined
2536
+ ? callbackfn(v, index++, this)
2537
+ : (callbackfn as (this: unknown, v: K, i: number, self: TreeSet<K>) => boolean).call(thisArg, v, index++, this);
2538
+ if (ok) return v;
2539
+ }
2540
+ return undefined;
2541
+ }
2542
+
2543
+ /**
2544
+ * Materialize the set into an array of keys.
2545
+ * @remarks Time O(n), Space O(n)
2546
+
2547
+
2548
+
2549
+
2550
+
2551
+
2552
+
2553
+
2554
+
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+
2562
+
2563
+
2564
+
2565
+
2566
+
2567
+
2568
+
2569
+
2570
+
2571
+
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+
2591
+
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+
2611
+
2612
+
2613
+
2614
+
2615
+
2616
+
2617
+
2618
+
2619
+
2620
+
2621
+
2622
+
2623
+
2624
+
2625
+
2626
+
2627
+
2628
+
2629
+
2630
+
2631
+
2632
+
2633
+
2634
+
2635
+
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+ * @example
2690
+ * // Convert to array
2691
+ * const ts = new TreeSet<number>([3, 1, 2]);
2692
+ * console.log(ts.toArray()); // [1, 2, 3];
2693
+ */
2694
+ toArray(): K[] {
2695
+ return [...this];
2696
+ }
2697
+
2698
+ /**
2699
+ * Print a human-friendly representation.
2700
+ * @remarks Time O(n), Space O(n)
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+
2726
+
2727
+
2728
+
2729
+
2730
+
2731
+
2732
+
2733
+
2734
+
2735
+
2736
+
2737
+
2738
+
2739
+
2740
+
2741
+
2742
+
2743
+
2744
+
2745
+
2746
+
2747
+
2748
+
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+
2755
+
2756
+
2757
+
2758
+
2759
+
2760
+
2761
+
2762
+
2763
+
2764
+
2765
+
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+
2786
+
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+
2808
+
2809
+
2810
+
2811
+
2812
+
2813
+
2814
+
2815
+
2816
+
2817
+
2818
+
2819
+
2820
+
2821
+
2822
+
2823
+
2824
+
2825
+
2826
+
2827
+
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+ * @example
2845
+ * // Display tree
2846
+ * const ts = new TreeSet<number>([1, 2, 3]);
2847
+ * expect(() => ts.print()).not.toThrow();
2848
+ */
2849
+ print(): void {
2850
+ // Delegate to the underlying tree's visualization.
2851
+ this.#core.print();
2852
+ }
2853
+
2854
+ // Navigable operations
2855
+
2856
+ /**
2857
+ * Smallest key in the set.
2858
+
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+
2885
+
2886
+
2887
+
2888
+
2889
+
2890
+ * @example
2891
+ * // Student grade ranking with custom comparator
2892
+ * interface Student {
2893
+ * name: string;
2894
+ * gpa: number;
2895
+ * }
2896
+ *
2897
+ * const ranking = new TreeSet<Student>(
2898
+ * [
2899
+ * { name: 'Alice', gpa: 3.8 },
2900
+ * { name: 'Bob', gpa: 3.5 },
2901
+ * { name: 'Charlie', gpa: 3.9 },
2902
+ * { name: 'Diana', gpa: 3.5 }
2903
+ * ],
2904
+ * { comparator: (a, b) => b.gpa - a.gpa || a.name.localeCompare(b.name) }
2905
+ * );
2906
+ *
2907
+ * // Sorted by GPA descending, then name ascending
2908
+ * const names = [...ranking].map(s => s.name);
2909
+ * console.log(names); // ['Charlie', 'Alice', 'Bob', 'Diana'];
2910
+ *
2911
+ * // Top student
2912
+ * console.log(ranking.first()?.name); // 'Charlie';
2913
+ *
2914
+ * // Filter students with GPA >= 3.8
2915
+ * const honors = ranking.filter(s => s.gpa >= 3.8);
2916
+ * console.log(honors.toArray().map(s => s.name)); // ['Charlie', 'Alice'];
2917
+ */
2918
+ first(): K | undefined {
2919
+ return this.#core.getLeftMost();
2920
+ }
2921
+
2922
+ /**
2923
+ * Largest key in the set.
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+
2930
+
2931
+
2932
+
2933
+
2934
+
2935
+
2936
+
2937
+
2938
+
2939
+
2940
+
2941
+
2942
+
2943
+
2944
+
2945
+
2946
+
2947
+
2948
+
2949
+
2950
+
2951
+
2952
+
2953
+
2954
+
2955
+
2956
+ * @example
2957
+ * // Get the maximum element
2958
+ * const temps = new TreeSet<number>([18, 22, 15, 30, 25]);
2959
+ * console.log(temps.last()); // 30;
2960
+ * console.log(temps.first()); // 15;
2961
+ */
2962
+ last(): K | undefined {
2963
+ return this.#core.getRightMost();
2964
+ }
2965
+
2966
+ /**
2967
+ * Remove and return the smallest key.
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+
2978
+
2979
+
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+
2990
+
2991
+
2992
+
2993
+
2994
+
2995
+
2996
+
2997
+
2998
+
2999
+
3000
+ * @example
3001
+ * // Remove and return minimum
3002
+ * const queue = new TreeSet<number>([5, 1, 8, 3]);
3003
+ *
3004
+ * console.log(queue.pollFirst()); // 1;
3005
+ * console.log(queue.pollFirst()); // 3;
3006
+ * console.log(queue.size); // 2;
3007
+ */
3008
+ pollFirst(): K | undefined {
3009
+ const k = this.first();
3010
+ if (k === undefined) return undefined;
3011
+ this.delete(k);
3012
+ return k;
3013
+ }
3014
+
3015
+ /**
3016
+ * Remove and return the largest key.
3017
+
3018
+
3019
+
3020
+
3021
+
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+ * @example
3050
+ * // Remove and return maximum
3051
+ * const stack = new TreeSet<number>([10, 20, 30]);
3052
+ *
3053
+ * console.log(stack.pollLast()); // 30;
3054
+ * console.log(stack.size); // 2;
3055
+ */
3056
+ pollLast(): K | undefined {
3057
+ const k = this.last();
3058
+ if (k === undefined) return undefined;
3059
+ this.delete(k);
3060
+ return k;
3061
+ }
3062
+
3063
+ /**
3064
+ * Smallest key that is >= the given key.
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+
3087
+
3088
+
3089
+
3090
+
3091
+
3092
+
3093
+
3094
+
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+
3102
+
3103
+
3104
+
3105
+
3106
+
3107
+
3108
+
3109
+
3110
+
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+
3154
+
3155
+
3156
+
3157
+
3158
+
3159
+
3160
+
3161
+
3162
+
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+
3170
+
3171
+
3172
+
3173
+
3174
+
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+ * @example
3188
+ * // Finding nearest available time slot
3189
+ * // Available appointment times (minutes from midnight)
3190
+ * const slots = new TreeSet<number>([540, 600, 660, 720, 840, 900]);
3191
+ *
3192
+ * // Customer wants something around 10:30 (630 min)
3193
+ * const nearest = slots.ceiling(630);
3194
+ * console.log(nearest); // 660; // 11:00 AM
3195
+ *
3196
+ * // What's the latest slot before 2:00 PM (840)?
3197
+ * const before2pm = slots.lower(840);
3198
+ * console.log(before2pm); // 720; // 12:00 PM
3199
+ *
3200
+ * // Book the 11:00 slot
3201
+ * slots.delete(660);
3202
+ * console.log(slots.ceiling(630)); // 720;
3203
+ */
3204
+ ceiling(key: K): K | undefined {
3205
+ this._validateKey(key);
3206
+ return this.#core.ceiling(key);
3207
+ }
3208
+
3209
+ /**
3210
+ * Largest key that is <= the given key.
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+
3222
+
3223
+
3224
+
3225
+
3226
+
3227
+
3228
+
3229
+
3230
+
3231
+
3232
+
3233
+
3234
+
3235
+
3236
+
3237
+
3238
+
3239
+
3240
+
3241
+
3242
+
3243
+
3244
+
3245
+
3246
+
3247
+
3248
+
3249
+
3250
+
3251
+
3252
+
3253
+
3254
+
3255
+
3256
+
3257
+
3258
+
3259
+
3260
+
3261
+
3262
+
3263
+
3264
+
3265
+
3266
+
3267
+
3268
+
3269
+
3270
+
3271
+
3272
+
3273
+
3274
+
3275
+
3276
+
3277
+
3278
+
3279
+
3280
+
3281
+
3282
+
3283
+
3284
+
3285
+
3286
+
3287
+
3288
+
3289
+
3290
+
3291
+
3292
+
3293
+
3294
+
3295
+
3296
+
3297
+
3298
+
3299
+
3300
+
3301
+
3302
+
3303
+
3304
+
3305
+
3306
+
3307
+
3308
+
3309
+
3310
+
3311
+
3312
+
3313
+
3314
+
3315
+
3316
+
3317
+
3318
+
3319
+
3320
+
3321
+
3322
+
3323
+
3324
+
3325
+
3326
+
3327
+
3328
+
3329
+
3330
+
3331
+
3332
+
3333
+ * @example
3334
+ * // Largest element ≤ target
3335
+ * const breakpoints = new TreeSet<number>([320, 768, 1024, 1280, 1920]);
3336
+ *
3337
+ * // Current width is 800 → which breakpoint applies?
3338
+ * console.log(breakpoints.floor(800)); // 768;
3339
+ * console.log(breakpoints.floor(1024)); // 1024; // exact match
3340
+ * console.log(breakpoints.floor(100)); // undefined;
3341
+ */
3342
+ floor(key: K): K | undefined {
3343
+ this._validateKey(key);
3344
+ return this.#core.floor(key);
3345
+ }
3346
+
3347
+ /**
3348
+ * Smallest key that is > the given key.
3349
+
3350
+
3351
+
3352
+
3353
+
3354
+
3355
+
3356
+
3357
+
3358
+
3359
+
3360
+
3361
+
3362
+
3363
+
3364
+
3365
+
3366
+
3367
+
3368
+
3369
+
3370
+
3371
+
3372
+
3373
+
3374
+
3375
+
3376
+
3377
+
3378
+
3379
+
3380
+
3381
+
3382
+
3383
+
3384
+
3385
+
3386
+
3387
+
3388
+
3389
+
3390
+
3391
+
3392
+
3393
+
3394
+
3395
+
3396
+
3397
+
3398
+
3399
+
3400
+
3401
+
3402
+
3403
+
3404
+
3405
+
3406
+
3407
+
3408
+
3409
+
3410
+
3411
+
3412
+
3413
+
3414
+
3415
+
3416
+
3417
+
3418
+
3419
+
3420
+
3421
+
3422
+
3423
+
3424
+
3425
+
3426
+
3427
+
3428
+
3429
+
3430
+
3431
+
3432
+
3433
+
3434
+
3435
+
3436
+
3437
+
3438
+
3439
+
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+
3449
+
3450
+
3451
+
3452
+
3453
+
3454
+
3455
+
3456
+
3457
+
3458
+
3459
+
3460
+
3461
+
3462
+
3463
+
3464
+
3465
+
3466
+
3467
+
3468
+
3469
+
3470
+
3471
+ * @example
3472
+ * // Smallest element strictly > target
3473
+ * const levels = new TreeSet<number>([1, 5, 10, 25, 50, 100]);
3474
+ *
3475
+ * console.log(levels.higher(10)); // 25;
3476
+ * console.log(levels.higher(100)); // undefined;
3477
+ */
3478
+ higher(key: K): K | undefined {
3479
+ this._validateKey(key);
3480
+ return this.#core.higher(key);
3481
+ }
3482
+
3483
+ /**
3484
+ * Largest key that is < the given key.
3485
+
3486
+
3487
+
3488
+
3489
+
3490
+
3491
+
3492
+
3493
+
3494
+
3495
+
3496
+
3497
+
3498
+
3499
+
3500
+
3501
+
3502
+
3503
+
3504
+
3505
+
3506
+
3507
+
3508
+
3509
+
3510
+
3511
+
3512
+
3513
+
3514
+
3515
+
3516
+
3517
+
3518
+
3519
+
3520
+
3521
+
3522
+
3523
+
3524
+
3525
+
3526
+
3527
+
3528
+
3529
+
3530
+
3531
+
3532
+
3533
+
3534
+
3535
+
3536
+
3537
+
3538
+
3539
+
3540
+
3541
+
3542
+
3543
+
3544
+
3545
+
3546
+
3547
+
3548
+
3549
+
3550
+
3551
+
3552
+
3553
+
3554
+
3555
+
3556
+
3557
+
3558
+
3559
+
3560
+
3561
+
3562
+
3563
+
3564
+
3565
+
3566
+
3567
+
3568
+
3569
+
3570
+
3571
+
3572
+
3573
+
3574
+
3575
+
3576
+
3577
+
3578
+
3579
+
3580
+
3581
+
3582
+
3583
+
3584
+
3585
+
3586
+
3587
+
3588
+
3589
+
3590
+
3591
+
3592
+
3593
+
3594
+
3595
+
3596
+
3597
+
3598
+
3599
+
3600
+
3601
+
3602
+
3603
+
3604
+
3605
+
3606
+
3607
+ * @example
1403
3608
  * // Largest element strictly < target
1404
3609
  * const tiers = new TreeSet<number>([100, 200, 500, 1000]);
1405
3610
  *
@@ -1433,6 +3638,90 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1433
3638
 
1434
3639
 
1435
3640
 
3641
+
3642
+
3643
+
3644
+
3645
+
3646
+
3647
+
3648
+
3649
+
3650
+
3651
+
3652
+
3653
+
3654
+
3655
+
3656
+
3657
+
3658
+
3659
+
3660
+
3661
+
3662
+
3663
+
3664
+
3665
+
3666
+
3667
+
3668
+
3669
+
3670
+
3671
+
3672
+
3673
+
3674
+
3675
+
3676
+
3677
+
3678
+
3679
+
3680
+
3681
+
3682
+
3683
+
3684
+
3685
+
3686
+
3687
+
3688
+
3689
+
3690
+
3691
+
3692
+
3693
+
3694
+
3695
+
3696
+
3697
+
3698
+
3699
+
3700
+
3701
+
3702
+
3703
+
3704
+
3705
+
3706
+
3707
+
3708
+
3709
+
3710
+
3711
+
3712
+
3713
+
3714
+
3715
+
3716
+
3717
+
3718
+
3719
+
3720
+
3721
+
3722
+
3723
+
3724
+
1436
3725
 
1437
3726
 
1438
3727
 
@@ -1514,6 +3803,111 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
1514
3803
 
1515
3804
 
1516
3805
 
3806
+
3807
+
3808
+
3809
+
3810
+
3811
+
3812
+
3813
+
3814
+
3815
+
3816
+
3817
+
3818
+
3819
+
3820
+
3821
+
3822
+
3823
+
3824
+
3825
+
3826
+
3827
+
3828
+
3829
+
3830
+
3831
+
3832
+
3833
+
3834
+
3835
+
3836
+
3837
+
3838
+
3839
+
3840
+
3841
+
3842
+
3843
+
3844
+
3845
+
3846
+
3847
+
3848
+
3849
+
3850
+
3851
+
3852
+
3853
+
3854
+
3855
+
3856
+
3857
+
3858
+
3859
+
3860
+
3861
+
3862
+
3863
+
3864
+
3865
+
3866
+
3867
+
3868
+
3869
+
3870
+
3871
+
3872
+
3873
+
3874
+
3875
+
3876
+
3877
+
3878
+
3879
+
3880
+
3881
+
3882
+
3883
+
3884
+
3885
+
3886
+
3887
+
3888
+
3889
+
3890
+
3891
+
3892
+
3893
+
3894
+
3895
+
3896
+
3897
+
3898
+
3899
+
3900
+
3901
+
3902
+
3903
+
3904
+
3905
+
3906
+
3907
+
3908
+
3909
+
3910
+
1517
3911
 
1518
3912
 
1519
3913