summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/MochiKit/Iter.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/MochiKit/Iter.js') (more/less context) (show whitespace changes)
-rw-r--r--frontend/gamma/js/MochiKit/Iter.js790
1 files changed, 790 insertions, 0 deletions
diff --git a/frontend/gamma/js/MochiKit/Iter.js b/frontend/gamma/js/MochiKit/Iter.js
new file mode 100644
index 0000000..524b2bc
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Iter.js
@@ -0,0 +1,790 @@
1/***
2
3MochiKit.Iter 1.5
4
5See <http://mochikit.com/> for documentation, downloads, license, etc.
6
7(c) 2005 Bob Ippolito. All rights Reserved.
8
9***/
10
11MochiKit.Base._module('Iter', '1.5', ['Base']);
12
13MochiKit.Base.update(MochiKit.Iter, {
14 /** @id MochiKit.Iter.registerIteratorFactory */
15 registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) {
16 MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override);
17 },
18
19 /** @id MochiKit.Iter.isIterable */
20 isIterable: function(o) {
21 return o != null &&
22 (typeof(o.next) == "function" || typeof(o.iter) == "function");
23 },
24
25 /** @id MochiKit.Iter.iter */
26 iter: function (iterable, /* optional */ sentinel) {
27 var self = MochiKit.Iter;
28 if (arguments.length == 2) {
29 return self.takewhile(
30 function (a) { return a != sentinel; },
31 iterable
32 );
33 }
34 if (typeof(iterable.next) == 'function') {
35 return iterable;
36 } else if (typeof(iterable.iter) == 'function') {
37 return iterable.iter();
38 /*
39 } else if (typeof(iterable.__iterator__) == 'function') {
40 //
41 // XXX: We can't support JavaScript 1.7 __iterator__ directly
42 // because of Object.prototype.__iterator__
43 //
44 return iterable.__iterator__();
45 */
46 }
47
48 try {
49 return self.iteratorRegistry.match(iterable);
50 } catch (e) {
51 var m = MochiKit.Base;
52 if (e == m.NotFound) {
53 e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable");
54 }
55 throw e;
56 }
57 },
58
59 /** @id MochiKit.Iter.count */
60 count: function (n) {
61 if (!n) {
62 n = 0;
63 }
64 var m = MochiKit.Base;
65 return {
66 repr: function () { return "count(" + n + ")"; },
67 toString: m.forwardCall("repr"),
68 next: m.counter(n)
69 };
70 },
71
72 /** @id MochiKit.Iter.cycle */
73 cycle: function (p) {
74 var self = MochiKit.Iter;
75 var m = MochiKit.Base;
76 var lst = [];
77 var iterator = self.iter(p);
78 return {
79 repr: function () { return "cycle(...)"; },
80 toString: m.forwardCall("repr"),
81 next: function () {
82 try {
83 var rval = iterator.next();
84 lst.push(rval);
85 return rval;
86 } catch (e) {
87 if (e != self.StopIteration) {
88 throw e;
89 }
90 if (lst.length === 0) {
91 this.next = function () {
92 throw self.StopIteration;
93 };
94 } else {
95 var i = -1;
96 this.next = function () {
97 i = (i + 1) % lst.length;
98 return lst[i];
99 };
100 }
101 return this.next();
102 }
103 }
104 };
105 },
106
107 /** @id MochiKit.Iter.repeat */
108 repeat: function (elem, /* optional */n) {
109 var m = MochiKit.Base;
110 if (typeof(n) == 'undefined') {
111 return {
112 repr: function () {
113 return "repeat(" + m.repr(elem) + ")";
114 },
115 toString: m.forwardCall("repr"),
116 next: function () {
117 return elem;
118 }
119 };
120 }
121 return {
122 repr: function () {
123 return "repeat(" + m.repr(elem) + ", " + n + ")";
124 },
125 toString: m.forwardCall("repr"),
126 next: function () {
127 if (n <= 0) {
128 throw MochiKit.Iter.StopIteration;
129 }
130 n -= 1;
131 return elem;
132 }
133 };
134 },
135
136 /** @id MochiKit.Iter.next */
137 next: function (iterator) {
138 return iterator.next();
139 },
140
141 /** @id MochiKit.Iter.izip */
142 izip: function (p, q/*, ...*/) {
143 var m = MochiKit.Base;
144 var self = MochiKit.Iter;
145 var next = self.next;
146 var iterables = m.map(self.iter, arguments);
147 return {
148 repr: function () { return "izip(...)"; },
149 toString: m.forwardCall("repr"),
150 next: function () { return m.map(next, iterables); }
151 };
152 },
153
154 /** @id MochiKit.Iter.ifilter */
155 ifilter: function (pred, seq) {
156 var m = MochiKit.Base;
157 seq = MochiKit.Iter.iter(seq);
158 if (pred === null) {
159 pred = m.operator.truth;
160 }
161 return {
162 repr: function () { return "ifilter(...)"; },
163 toString: m.forwardCall("repr"),
164 next: function () {
165 while (true) {
166 var rval = seq.next();
167 if (pred(rval)) {
168 return rval;
169 }
170 }
171 // mozilla warnings aren't too bright
172 return undefined;
173 }
174 };
175 },
176
177 /** @id MochiKit.Iter.ifilterfalse */
178 ifilterfalse: function (pred, seq) {
179 var m = MochiKit.Base;
180 seq = MochiKit.Iter.iter(seq);
181 if (pred === null) {
182 pred = m.operator.truth;
183 }
184 return {
185 repr: function () { return "ifilterfalse(...)"; },
186 toString: m.forwardCall("repr"),
187 next: function () {
188 while (true) {
189 var rval = seq.next();
190 if (!pred(rval)) {
191 return rval;
192 }
193 }
194 // mozilla warnings aren't too bright
195 return undefined;
196 }
197 };
198 },
199
200 /** @id MochiKit.Iter.islice */
201 islice: function (seq/*, [start,] stop[, step] */) {
202 var self = MochiKit.Iter;
203 var m = MochiKit.Base;
204 seq = self.iter(seq);
205 var start = 0;
206 var stop = 0;
207 var step = 1;
208 var i = -1;
209 if (arguments.length == 2) {
210 stop = arguments[1];
211 } else if (arguments.length == 3) {
212 start = arguments[1];
213 stop = arguments[2];
214 } else {
215 start = arguments[1];
216 stop = arguments[2];
217 step = arguments[3];
218 }
219 return {
220 repr: function () {
221 return "islice(" + ["...", start, stop, step].join(", ") + ")";
222 },
223 toString: m.forwardCall("repr"),
224 next: function () {
225 var rval;
226 while (i < start) {
227 rval = seq.next();
228 i++;
229 }
230 if (start >= stop) {
231 throw self.StopIteration;
232 }
233 start += step;
234 return rval;
235 }
236 };
237 },
238
239 /** @id MochiKit.Iter.imap */
240 imap: function (fun, p, q/*, ...*/) {
241 var m = MochiKit.Base;
242 var self = MochiKit.Iter;
243 var iterables = m.map(self.iter, m.extend(null, arguments, 1));
244 var map = m.map;
245 var next = self.next;
246 return {
247 repr: function () { return "imap(...)"; },
248 toString: m.forwardCall("repr"),
249 next: function () {
250 return fun.apply(this, map(next, iterables));
251 }
252 };
253 },
254
255 /** @id MochiKit.Iter.applymap */
256 applymap: function (fun, seq, self) {
257 seq = MochiKit.Iter.iter(seq);
258 var m = MochiKit.Base;
259 return {
260 repr: function () { return "applymap(...)"; },
261 toString: m.forwardCall("repr"),
262 next: function () {
263 return fun.apply(self, seq.next());
264 }
265 };
266 },
267
268 /** @id MochiKit.Iter.chain */
269 chain: function (p, q/*, ...*/) {
270 // dumb fast path
271 var self = MochiKit.Iter;
272 var m = MochiKit.Base;
273 if (arguments.length == 1) {
274 return self.iter(arguments[0]);
275 }
276 var argiter = m.map(self.iter, arguments);
277 return {
278 repr: function () { return "chain(...)"; },
279 toString: m.forwardCall("repr"),
280 next: function () {
281 while (argiter.length > 1) {
282 try {
283 var result = argiter[0].next();
284 return result;
285 } catch (e) {
286 if (e != self.StopIteration) {
287 throw e;
288 }
289 argiter.shift();
290 var result = argiter[0].next();
291 return result;
292 }
293 }
294 if (argiter.length == 1) {
295 // optimize last element
296 var arg = argiter.shift();
297 this.next = m.bind("next", arg);
298 return this.next();
299 }
300 throw self.StopIteration;
301 }
302 };
303 },
304
305 /** @id MochiKit.Iter.takewhile */
306 takewhile: function (pred, seq) {
307 var self = MochiKit.Iter;
308 seq = self.iter(seq);
309 return {
310 repr: function () { return "takewhile(...)"; },
311 toString: MochiKit.Base.forwardCall("repr"),
312 next: function () {
313 var rval = seq.next();
314 if (!pred(rval)) {
315 this.next = function () {
316 throw self.StopIteration;
317 };
318 this.next();
319 }
320 return rval;
321 }
322 };
323 },
324
325 /** @id MochiKit.Iter.dropwhile */
326 dropwhile: function (pred, seq) {
327 seq = MochiKit.Iter.iter(seq);
328 var m = MochiKit.Base;
329 var bind = m.bind;
330 return {
331 "repr": function () { return "dropwhile(...)"; },
332 "toString": m.forwardCall("repr"),
333 "next": function () {
334 while (true) {
335 var rval = seq.next();
336 if (!pred(rval)) {
337 break;
338 }
339 }
340 this.next = bind("next", seq);
341 return rval;
342 }
343 };
344 },
345
346 _tee: function (ident, sync, iterable) {
347 sync.pos[ident] = -1;
348 var m = MochiKit.Base;
349 var listMin = m.listMin;
350 return {
351 repr: function () { return "tee(" + ident + ", ...)"; },
352 toString: m.forwardCall("repr"),
353 next: function () {
354 var rval;
355 var i = sync.pos[ident];
356
357 if (i == sync.max) {
358 rval = iterable.next();
359 sync.deque.push(rval);
360 sync.max += 1;
361 sync.pos[ident] += 1;
362 } else {
363 rval = sync.deque[i - sync.min];
364 sync.pos[ident] += 1;
365 if (i == sync.min && listMin(sync.pos) != sync.min) {
366 sync.min += 1;
367 sync.deque.shift();
368 }
369 }
370 return rval;
371 }
372 };
373 },
374
375 /** @id MochiKit.Iter.tee */
376 tee: function (iterable, n/* = 2 */) {
377 var rval = [];
378 var sync = {
379 "pos": [],
380 "deque": [],
381 "max": -1,
382 "min": -1
383 };
384 if (arguments.length == 1 || typeof(n) == "undefined" || n === null) {
385 n = 2;
386 }
387 var self = MochiKit.Iter;
388 iterable = self.iter(iterable);
389 var _tee = self._tee;
390 for (var i = 0; i < n; i++) {
391 rval.push(_tee(i, sync, iterable));
392 }
393 return rval;
394 },
395
396 /** @id MochiKit.Iter.list */
397 list: function (iterable) {
398 // Fast-path for Array and Array-like
399 var rval;
400 if (iterable instanceof Array) {
401 return iterable.slice();
402 }
403 // this is necessary to avoid a Safari crash
404 if (typeof(iterable) == "function" &&
405 !(iterable instanceof Function) &&
406 typeof(iterable.length) == 'number') {
407 rval = [];
408 for (var i = 0; i < iterable.length; i++) {
409 rval.push(iterable[i]);
410 }
411 return rval;
412 }
413
414 var self = MochiKit.Iter;
415 iterable = self.iter(iterable);
416 var rval = [];
417 var a_val;
418 try {
419 while (true) {
420 a_val = iterable.next();
421 rval.push(a_val);
422 }
423 } catch (e) {
424 if (e != self.StopIteration) {
425 throw e;
426 }
427 return rval;
428 }
429 // mozilla warnings aren't too bright
430 return undefined;
431 },
432
433
434 /** @id MochiKit.Iter.reduce */
435 reduce: function (fn, iterable, /* optional */initial) {
436 var i = 0;
437 var x = initial;
438 var self = MochiKit.Iter;
439 iterable = self.iter(iterable);
440 if (arguments.length < 3) {
441 try {
442 x = iterable.next();
443 } catch (e) {
444 if (e == self.StopIteration) {
445 e = new TypeError("reduce() of empty sequence with no initial value");
446 }
447 throw e;
448 }
449 i++;
450 }
451 try {
452 while (true) {
453 x = fn(x, iterable.next());
454 }
455 } catch (e) {
456 if (e != self.StopIteration) {
457 throw e;
458 }
459 }
460 return x;
461 },
462
463 /** @id MochiKit.Iter.range */
464 range: function (/* [start,] stop[, step] */) {
465 var start = 0;
466 var stop = 0;
467 var step = 1;
468 if (arguments.length == 1) {
469 stop = arguments[0];
470 } else if (arguments.length == 2) {
471 start = arguments[0];
472 stop = arguments[1];
473 } else if (arguments.length == 3) {
474 start = arguments[0];
475 stop = arguments[1];
476 step = arguments[2];
477 } else {
478 throw new TypeError("range() takes 1, 2, or 3 arguments!");
479 }
480 if (step === 0) {
481 throw new TypeError("range() step must not be 0");
482 }
483 return {
484 next: function () {
485 if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
486 throw MochiKit.Iter.StopIteration;
487 }
488 var rval = start;
489 start += step;
490 return rval;
491 },
492 repr: function () {
493 return "range(" + [start, stop, step].join(", ") + ")";
494 },
495 toString: MochiKit.Base.forwardCall("repr")
496 };
497 },
498
499 /** @id MochiKit.Iter.sum */
500 sum: function (iterable, start/* = 0 */) {
501 if (typeof(start) == "undefined" || start === null) {
502 start = 0;
503 }
504 var x = start;
505 var self = MochiKit.Iter;
506 iterable = self.iter(iterable);
507 try {
508 while (true) {
509 x += iterable.next();
510 }
511 } catch (e) {
512 if (e != self.StopIteration) {
513 throw e;
514 }
515 }
516 return x;
517 },
518
519 /** @id MochiKit.Iter.exhaust */
520 exhaust: function (iterable) {
521 var self = MochiKit.Iter;
522 iterable = self.iter(iterable);
523 try {
524 while (true) {
525 iterable.next();
526 }
527 } catch (e) {
528 if (e != self.StopIteration) {
529 throw e;
530 }
531 }
532 },
533
534 /** @id MochiKit.Iter.forEach */
535 forEach: function (iterable, func, /* optional */obj) {
536 var m = MochiKit.Base;
537 var self = MochiKit.Iter;
538 if (arguments.length > 2) {
539 func = m.bind(func, obj);
540 }
541 // fast path for array
542 if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
543 try {
544 for (var i = 0; i < iterable.length; i++) {
545 func(iterable[i]);
546 }
547 } catch (e) {
548 if (e != self.StopIteration) {
549 throw e;
550 }
551 }
552 } else {
553 self.exhaust(self.imap(func, iterable));
554 }
555 },
556
557 /** @id MochiKit.Iter.every */
558 every: function (iterable, func) {
559 var self = MochiKit.Iter;
560 try {
561 self.ifilterfalse(func, iterable).next();
562 return false;
563 } catch (e) {
564 if (e != self.StopIteration) {
565 throw e;
566 }
567 return true;
568 }
569 },
570
571 /** @id MochiKit.Iter.sorted */
572 sorted: function (iterable, /* optional */cmp) {
573 var rval = MochiKit.Iter.list(iterable);
574 if (arguments.length == 1) {
575 cmp = MochiKit.Base.compare;
576 }
577 rval.sort(cmp);
578 return rval;
579 },
580
581 /** @id MochiKit.Iter.reversed */
582 reversed: function (iterable) {
583 var rval = MochiKit.Iter.list(iterable);
584 rval.reverse();
585 return rval;
586 },
587
588 /** @id MochiKit.Iter.some */
589 some: function (iterable, func) {
590 var self = MochiKit.Iter;
591 try {
592 self.ifilter(func, iterable).next();
593 return true;
594 } catch (e) {
595 if (e != self.StopIteration) {
596 throw e;
597 }
598 return false;
599 }
600 },
601
602 /** @id MochiKit.Iter.iextend */
603 iextend: function (lst, iterable) {
604 var m = MochiKit.Base;
605 var self = MochiKit.Iter;
606 if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
607 // fast-path for array-like
608 for (var i = 0; i < iterable.length; i++) {
609 lst.push(iterable[i]);
610 }
611 } else {
612 iterable = self.iter(iterable);
613 try {
614 while (true) {
615 lst.push(iterable.next());
616 }
617 } catch (e) {
618 if (e != self.StopIteration) {
619 throw e;
620 }
621 }
622 }
623 return lst;
624 },
625
626 /** @id MochiKit.Iter.groupby */
627 groupby: function(iterable, /* optional */ keyfunc) {
628 var m = MochiKit.Base;
629 var self = MochiKit.Iter;
630 if (arguments.length < 2) {
631 keyfunc = m.operator.identity;
632 }
633 iterable = self.iter(iterable);
634
635 // shared
636 var pk = undefined;
637 var k = undefined;
638 var v;
639
640 function fetch() {
641 v = iterable.next();
642 k = keyfunc(v);
643 };
644
645 function eat() {
646 var ret = v;
647 v = undefined;
648 return ret;
649 };
650
651 var first = true;
652 var compare = m.compare;
653 return {
654 repr: function () { return "groupby(...)"; },
655 next: function() {
656 // iterator-next
657
658 // iterate until meet next group
659 while (compare(k, pk) === 0) {
660 fetch();
661 if (first) {
662 first = false;
663 break;
664 }
665 }
666 pk = k;
667 return [k, {
668 next: function() {
669 // subiterator-next
670 if (v == undefined) { // Is there something to eat?
671 fetch();
672 }
673 if (compare(k, pk) !== 0) {
674 throw self.StopIteration;
675 }
676 return eat();
677 }
678 }];
679 }
680 };
681 },
682
683 /** @id MochiKit.Iter.groupby_as_array */
684 groupby_as_array: function (iterable, /* optional */ keyfunc) {
685 var m = MochiKit.Base;
686 var self = MochiKit.Iter;
687 if (arguments.length < 2) {
688 keyfunc = m.operator.identity;
689 }
690
691 iterable = self.iter(iterable);
692 var result = [];
693 var first = true;
694 var prev_key;
695 var compare = m.compare;
696 while (true) {
697 try {
698 var value = iterable.next();
699 var key = keyfunc(value);
700 } catch (e) {
701 if (e == self.StopIteration) {
702 break;
703 }
704 throw e;
705 }
706 if (first || compare(key, prev_key) !== 0) {
707 var values = [];
708 result.push([key, values]);
709 }
710 values.push(value);
711 first = false;
712 prev_key = key;
713 }
714 return result;
715 },
716
717 /** @id MochiKit.Iter.arrayLikeIter */
718 arrayLikeIter: function (iterable) {
719 var i = 0;
720 return {
721 repr: function () { return "arrayLikeIter(...)"; },
722 toString: MochiKit.Base.forwardCall("repr"),
723 next: function () {
724 if (i >= iterable.length) {
725 throw MochiKit.Iter.StopIteration;
726 }
727 return iterable[i++];
728 }
729 };
730 },
731
732 /** @id MochiKit.Iter.hasIterateNext */
733 hasIterateNext: function (iterable) {
734 return (iterable && typeof(iterable.iterateNext) == "function");
735 },
736
737 /** @id MochiKit.Iter.iterateNextIter */
738 iterateNextIter: function (iterable) {
739 return {
740 repr: function () { return "iterateNextIter(...)"; },
741 toString: MochiKit.Base.forwardCall("repr"),
742 next: function () {
743 var rval = iterable.iterateNext();
744 if (rval === null || rval === undefined) {
745 throw MochiKit.Iter.StopIteration;
746 }
747 return rval;
748 }
749 };
750 }
751});
752
753
754MochiKit.Iter.__new__ = function () {
755 var m = MochiKit.Base;
756 // Re-use StopIteration if exists (e.g. SpiderMonkey)
757 if (typeof(StopIteration) != "undefined") {
758 this.StopIteration = StopIteration;
759 } else {
760 /** @id MochiKit.Iter.StopIteration */
761 this.StopIteration = new m.NamedError("StopIteration");
762 }
763 this.iteratorRegistry = new m.AdapterRegistry();
764 // Register the iterator factory for arrays
765 this.registerIteratorFactory(
766 "arrayLike",
767 m.isArrayLike,
768 this.arrayLikeIter
769 );
770
771 this.registerIteratorFactory(
772 "iterateNext",
773 this.hasIterateNext,
774 this.iterateNextIter
775 );
776
777 m.nameFunctions(this);
778
779};
780
781MochiKit.Iter.__new__();
782
783//
784// XXX: Internet Explorer blows
785//
786if (MochiKit.__export__) {
787 reduce = MochiKit.Iter.reduce;
788}
789
790MochiKit.Base._exportSymbols(this, MochiKit.Iter);