57a5e6a15f4947edfdb1394c1bb98d41f376010c
[dygraphs.git] / dygraph-combined.js
1 /***
2
3 MochiKit.MochiKit 1.4 : PACKED VERSION
4
5 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
6 diff against the source tree, not this file.
7
8 See <http://mochikit.com/> for documentation, downloads, license, etc.
9
10 (c) 2005 Bob Ippolito. All rights Reserved.
11
12 ***/
13
14 if(typeof (dojo)!="undefined"){
15 dojo.provide("MochiKit.Base");
16 }
17 if(typeof (MochiKit)=="undefined"){
18 MochiKit={};
19 }
20 if(typeof (MochiKit.Base)=="undefined"){
21 MochiKit.Base={};
22 }
23 if(typeof (MochiKit.__export__)=="undefined"){
24 MochiKit.__export__=(MochiKit.__compat__||(typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined"));
25 }
26 MochiKit.Base.VERSION="1.4";
27 MochiKit.Base.NAME="MochiKit.Base";
28 MochiKit.Base.update=function(_1,_2){
29 if(_1===null){
30 _1={};
31 }
32 for(var i=1;i<arguments.length;i++){
33 var o=arguments[i];
34 if(typeof (o)!="undefined"&&o!==null){
35 for(var k in o){
36 _1[k]=o[k];
37 }
38 }
39 }
40 return _1;
41 };
42 MochiKit.Base.update(MochiKit.Base,{__repr__:function(){
43 return "["+this.NAME+" "+this.VERSION+"]";
44 },toString:function(){
45 return this.__repr__();
46 },camelize:function(_6){
47 var _7=_6.split("-");
48 var cc=_7[0];
49 for(var i=1;i<_7.length;i++){
50 cc+=_7[i].charAt(0).toUpperCase()+_7[i].substring(1);
51 }
52 return cc;
53 },counter:function(n){
54 if(arguments.length===0){
55 n=1;
56 }
57 return function(){
58 return n++;
59 };
60 },clone:function(_b){
61 var me=arguments.callee;
62 if(arguments.length==1){
63 me.prototype=_b;
64 return new me();
65 }
66 },_flattenArray:function(_d,_e){
67 for(var i=0;i<_e.length;i++){
68 var o=_e[i];
69 if(o instanceof Array){
70 arguments.callee(_d,o);
71 }else{
72 _d.push(o);
73 }
74 }
75 return _d;
76 },flattenArray:function(lst){
77 return MochiKit.Base._flattenArray([],lst);
78 },flattenArguments:function(lst){
79 var res=[];
80 var m=MochiKit.Base;
81 var _15=m.extend(null,arguments);
82 while(_15.length){
83 var o=_15.shift();
84 if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
85 for(var i=o.length-1;i>=0;i--){
86 _15.unshift(o[i]);
87 }
88 }else{
89 res.push(o);
90 }
91 }
92 return res;
93 },extend:function(_18,obj,_1a){
94 if(!_1a){
95 _1a=0;
96 }
97 if(obj){
98 var l=obj.length;
99 if(typeof (l)!="number"){
100 if(typeof (MochiKit.Iter)!="undefined"){
101 obj=MochiKit.Iter.list(obj);
102 l=obj.length;
103 }else{
104 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
105 }
106 }
107 if(!_18){
108 _18=[];
109 }
110 for(var i=_1a;i<l;i++){
111 _18.push(obj[i]);
112 }
113 }
114 return _18;
115 },updatetree:function(_1d,obj){
116 if(_1d===null){
117 _1d={};
118 }
119 for(var i=1;i<arguments.length;i++){
120 var o=arguments[i];
121 if(typeof (o)!="undefined"&&o!==null){
122 for(var k in o){
123 var v=o[k];
124 if(typeof (_1d[k])=="object"&&typeof (v)=="object"){
125 arguments.callee(_1d[k],v);
126 }else{
127 _1d[k]=v;
128 }
129 }
130 }
131 }
132 return _1d;
133 },setdefault:function(_23,obj){
134 if(_23===null){
135 _23={};
136 }
137 for(var i=1;i<arguments.length;i++){
138 var o=arguments[i];
139 for(var k in o){
140 if(!(k in _23)){
141 _23[k]=o[k];
142 }
143 }
144 }
145 return _23;
146 },keys:function(obj){
147 var _29=[];
148 for(var _2a in obj){
149 _29.push(_2a);
150 }
151 return _29;
152 },values:function(obj){
153 var _2c=[];
154 for(var _2d in obj){
155 _2c.push(obj[_2d]);
156 }
157 return _2c;
158 },items:function(obj){
159 var _2f=[];
160 var e;
161 for(var _31 in obj){
162 var v;
163 try{
164 v=obj[_31];
165 }
166 catch(e){
167 continue;
168 }
169 _2f.push([_31,v]);
170 }
171 return _2f;
172 },_newNamedError:function(_33,_34,_35){
173 _35.prototype=new MochiKit.Base.NamedError(_33.NAME+"."+_34);
174 _33[_34]=_35;
175 },operator:{truth:function(a){
176 return !!a;
177 },lognot:function(a){
178 return !a;
179 },identity:function(a){
180 return a;
181 },not:function(a){
182 return ~a;
183 },neg:function(a){
184 return -a;
185 },add:function(a,b){
186 return a+b;
187 },sub:function(a,b){
188 return a-b;
189 },div:function(a,b){
190 return a/b;
191 },mod:function(a,b){
192 return a%b;
193 },mul:function(a,b){
194 return a*b;
195 },and:function(a,b){
196 return a&b;
197 },or:function(a,b){
198 return a|b;
199 },xor:function(a,b){
200 return a^b;
201 },lshift:function(a,b){
202 return a<<b;
203 },rshift:function(a,b){
204 return a>>b;
205 },zrshift:function(a,b){
206 return a>>>b;
207 },eq:function(a,b){
208 return a==b;
209 },ne:function(a,b){
210 return a!=b;
211 },gt:function(a,b){
212 return a>b;
213 },ge:function(a,b){
214 return a>=b;
215 },lt:function(a,b){
216 return a<b;
217 },le:function(a,b){
218 return a<=b;
219 },seq:function(a,b){
220 return a===b;
221 },sne:function(a,b){
222 return a!==b;
223 },ceq:function(a,b){
224 return MochiKit.Base.compare(a,b)===0;
225 },cne:function(a,b){
226 return MochiKit.Base.compare(a,b)!==0;
227 },cgt:function(a,b){
228 return MochiKit.Base.compare(a,b)==1;
229 },cge:function(a,b){
230 return MochiKit.Base.compare(a,b)!=-1;
231 },clt:function(a,b){
232 return MochiKit.Base.compare(a,b)==-1;
233 },cle:function(a,b){
234 return MochiKit.Base.compare(a,b)!=1;
235 },logand:function(a,b){
236 return a&&b;
237 },logor:function(a,b){
238 return a||b;
239 },contains:function(a,b){
240 return b in a;
241 }},forwardCall:function(_73){
242 return function(){
243 return this[_73].apply(this,arguments);
244 };
245 },itemgetter:function(_74){
246 return function(arg){
247 return arg[_74];
248 };
249 },typeMatcher:function(){
250 var _76={};
251 for(var i=0;i<arguments.length;i++){
252 var typ=arguments[i];
253 _76[typ]=typ;
254 }
255 return function(){
256 for(var i=0;i<arguments.length;i++){
257 if(!(typeof (arguments[i]) in _76)){
258 return false;
259 }
260 }
261 return true;
262 };
263 },isNull:function(){
264 for(var i=0;i<arguments.length;i++){
265 if(arguments[i]!==null){
266 return false;
267 }
268 }
269 return true;
270 },isUndefinedOrNull:function(){
271 for(var i=0;i<arguments.length;i++){
272 var o=arguments[i];
273 if(!(typeof (o)=="undefined"||o===null)){
274 return false;
275 }
276 }
277 return true;
278 },isEmpty:function(obj){
279 return !MochiKit.Base.isNotEmpty.apply(this,arguments);
280 },isNotEmpty:function(obj){
281 for(var i=0;i<arguments.length;i++){
282 var o=arguments[i];
283 if(!(o&&o.length)){
284 return false;
285 }
286 }
287 return true;
288 },isArrayLike:function(){
289 for(var i=0;i<arguments.length;i++){
290 var o=arguments[i];
291 var typ=typeof (o);
292 if((typ!="object"&&!(typ=="function"&&typeof (o.item)=="function"))||o===null||typeof (o.length)!="number"||o.nodeType===3){
293 return false;
294 }
295 }
296 return true;
297 },isDateLike:function(){
298 for(var i=0;i<arguments.length;i++){
299 var o=arguments[i];
300 if(typeof (o)!="object"||o===null||typeof (o.getTime)!="function"){
301 return false;
302 }
303 }
304 return true;
305 },xmap:function(fn){
306 if(fn===null){
307 return MochiKit.Base.extend(null,arguments,1);
308 }
309 var _87=[];
310 for(var i=1;i<arguments.length;i++){
311 _87.push(fn(arguments[i]));
312 }
313 return _87;
314 },map:function(fn,lst){
315 var m=MochiKit.Base;
316 var itr=MochiKit.Iter;
317 var _8d=m.isArrayLike;
318 if(arguments.length<=2){
319 if(!_8d(lst)){
320 if(itr){
321 lst=itr.list(lst);
322 if(fn===null){
323 return lst;
324 }
325 }else{
326 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
327 }
328 }
329 if(fn===null){
330 return m.extend(null,lst);
331 }
332 var _8e=[];
333 for(var i=0;i<lst.length;i++){
334 _8e.push(fn(lst[i]));
335 }
336 return _8e;
337 }else{
338 if(fn===null){
339 fn=Array;
340 }
341 var _90=null;
342 for(i=1;i<arguments.length;i++){
343 if(!_8d(arguments[i])){
344 if(itr){
345 return itr.list(itr.imap.apply(null,arguments));
346 }else{
347 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
348 }
349 }
350 var l=arguments[i].length;
351 if(_90===null||_90>l){
352 _90=l;
353 }
354 }
355 _8e=[];
356 for(i=0;i<_90;i++){
357 var _92=[];
358 for(var j=1;j<arguments.length;j++){
359 _92.push(arguments[j][i]);
360 }
361 _8e.push(fn.apply(this,_92));
362 }
363 return _8e;
364 }
365 },xfilter:function(fn){
366 var _95=[];
367 if(fn===null){
368 fn=MochiKit.Base.operator.truth;
369 }
370 for(var i=1;i<arguments.length;i++){
371 var o=arguments[i];
372 if(fn(o)){
373 _95.push(o);
374 }
375 }
376 return _95;
377 },filter:function(fn,lst,_9a){
378 var _9b=[];
379 var m=MochiKit.Base;
380 if(!m.isArrayLike(lst)){
381 if(MochiKit.Iter){
382 lst=MochiKit.Iter.list(lst);
383 }else{
384 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
385 }
386 }
387 if(fn===null){
388 fn=m.operator.truth;
389 }
390 if(typeof (Array.prototype.filter)=="function"){
391 return Array.prototype.filter.call(lst,fn,_9a);
392 }else{
393 if(typeof (_9a)=="undefined"||_9a===null){
394 for(var i=0;i<lst.length;i++){
395 var o=lst[i];
396 if(fn(o)){
397 _9b.push(o);
398 }
399 }
400 }else{
401 for(i=0;i<lst.length;i++){
402 o=lst[i];
403 if(fn.call(_9a,o)){
404 _9b.push(o);
405 }
406 }
407 }
408 }
409 return _9b;
410 },_wrapDumbFunction:function(_9f){
411 return function(){
412 switch(arguments.length){
413 case 0:
414 return _9f();
415 case 1:
416 return _9f(arguments[0]);
417 case 2:
418 return _9f(arguments[0],arguments[1]);
419 case 3:
420 return _9f(arguments[0],arguments[1],arguments[2]);
421 }
422 var _a0=[];
423 for(var i=0;i<arguments.length;i++){
424 _a0.push("arguments["+i+"]");
425 }
426 return eval("(func("+_a0.join(",")+"))");
427 };
428 },methodcaller:function(_a2){
429 var _a3=MochiKit.Base.extend(null,arguments,1);
430 if(typeof (_a2)=="function"){
431 return function(obj){
432 return _a2.apply(obj,_a3);
433 };
434 }else{
435 return function(obj){
436 return obj[_a2].apply(obj,_a3);
437 };
438 }
439 },method:function(_a6,_a7){
440 var m=MochiKit.Base;
441 return m.bind.apply(this,m.extend([_a7,_a6],arguments,2));
442 },compose:function(f1,f2){
443 var _ab=[];
444 var m=MochiKit.Base;
445 if(arguments.length===0){
446 throw new TypeError("compose() requires at least one argument");
447 }
448 for(var i=0;i<arguments.length;i++){
449 var fn=arguments[i];
450 if(typeof (fn)!="function"){
451 throw new TypeError(m.repr(fn)+" is not a function");
452 }
453 _ab.push(fn);
454 }
455 return function(){
456 var _af=arguments;
457 for(var i=_ab.length-1;i>=0;i--){
458 _af=[_ab[i].apply(this,_af)];
459 }
460 return _af[0];
461 };
462 },bind:function(_b1,_b2){
463 if(typeof (_b1)=="string"){
464 _b1=_b2[_b1];
465 }
466 var _b3=_b1.im_func;
467 var _b4=_b1.im_preargs;
468 var _b5=_b1.im_self;
469 var m=MochiKit.Base;
470 if(typeof (_b1)=="function"&&typeof (_b1.apply)=="undefined"){
471 _b1=m._wrapDumbFunction(_b1);
472 }
473 if(typeof (_b3)!="function"){
474 _b3=_b1;
475 }
476 if(typeof (_b2)!="undefined"){
477 _b5=_b2;
478 }
479 if(typeof (_b4)=="undefined"){
480 _b4=[];
481 }else{
482 _b4=_b4.slice();
483 }
484 m.extend(_b4,arguments,2);
485 var _b7=function(){
486 var _b8=arguments;
487 var me=arguments.callee;
488 if(me.im_preargs.length>0){
489 _b8=m.concat(me.im_preargs,_b8);
490 }
491 var _ba=me.im_self;
492 if(!_ba){
493 _ba=this;
494 }
495 return me.im_func.apply(_ba,_b8);
496 };
497 _b7.im_self=_b5;
498 _b7.im_func=_b3;
499 _b7.im_preargs=_b4;
500 return _b7;
501 },bindMethods:function(_bb){
502 var _bc=MochiKit.Base.bind;
503 for(var k in _bb){
504 var _be=_bb[k];
505 if(typeof (_be)=="function"){
506 _bb[k]=_bc(_be,_bb);
507 }
508 }
509 },registerComparator:function(_bf,_c0,_c1,_c2){
510 MochiKit.Base.comparatorRegistry.register(_bf,_c0,_c1,_c2);
511 },_primitives:{"boolean":true,"string":true,"number":true},compare:function(a,b){
512 if(a==b){
513 return 0;
514 }
515 var _c5=(typeof (a)=="undefined"||a===null);
516 var _c6=(typeof (b)=="undefined"||b===null);
517 if(_c5&&_c6){
518 return 0;
519 }else{
520 if(_c5){
521 return -1;
522 }else{
523 if(_c6){
524 return 1;
525 }
526 }
527 }
528 var m=MochiKit.Base;
529 var _c8=m._primitives;
530 if(!(typeof (a) in _c8&&typeof (b) in _c8)){
531 try{
532 return m.comparatorRegistry.match(a,b);
533 }
534 catch(e){
535 if(e!=m.NotFound){
536 throw e;
537 }
538 }
539 }
540 if(a<b){
541 return -1;
542 }else{
543 if(a>b){
544 return 1;
545 }
546 }
547 var _c9=m.repr;
548 throw new TypeError(_c9(a)+" and "+_c9(b)+" can not be compared");
549 },compareDateLike:function(a,b){
550 return MochiKit.Base.compare(a.getTime(),b.getTime());
551 },compareArrayLike:function(a,b){
552 var _ce=MochiKit.Base.compare;
553 var _cf=a.length;
554 var _d0=0;
555 if(_cf>b.length){
556 _d0=1;
557 _cf=b.length;
558 }else{
559 if(_cf<b.length){
560 _d0=-1;
561 }
562 }
563 for(var i=0;i<_cf;i++){
564 var cmp=_ce(a[i],b[i]);
565 if(cmp){
566 return cmp;
567 }
568 }
569 return _d0;
570 },registerRepr:function(_d3,_d4,_d5,_d6){
571 MochiKit.Base.reprRegistry.register(_d3,_d4,_d5,_d6);
572 },repr:function(o){
573 if(typeof (o)=="undefined"){
574 return "undefined";
575 }else{
576 if(o===null){
577 return "null";
578 }
579 }
580 try{
581 if(typeof (o.__repr__)=="function"){
582 return o.__repr__();
583 }else{
584 if(typeof (o.repr)=="function"&&o.repr!=arguments.callee){
585 return o.repr();
586 }
587 }
588 return MochiKit.Base.reprRegistry.match(o);
589 }
590 catch(e){
591 if(typeof (o.NAME)=="string"&&(o.toString==Function.prototype.toString||o.toString==Object.prototype.toString)){
592 return o.NAME;
593 }
594 }
595 try{
596 var _d8=(o+"");
597 }
598 catch(e){
599 return "["+typeof (o)+"]";
600 }
601 if(typeof (o)=="function"){
602 o=_d8.replace(/^\s+/,"");
603 var idx=o.indexOf("{");
604 if(idx!=-1){
605 o=o.substr(0,idx)+"{...}";
606 }
607 }
608 return _d8;
609 },reprArrayLike:function(o){
610 var m=MochiKit.Base;
611 return "["+m.map(m.repr,o).join(", ")+"]";
612 },reprString:function(o){
613 return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
614 },reprNumber:function(o){
615 return o+"";
616 },registerJSON:function(_de,_df,_e0,_e1){
617 MochiKit.Base.jsonRegistry.register(_de,_df,_e0,_e1);
618 },evalJSON:function(){
619 return eval("("+arguments[0]+")");
620 },serializeJSON:function(o){
621 var _e3=typeof (o);
622 if(_e3=="number"||_e3=="boolean"){
623 return o+"";
624 }else{
625 if(o===null){
626 return "null";
627 }
628 }
629 var m=MochiKit.Base;
630 var _e5=m.reprString;
631 if(_e3=="string"){
632 return _e5(o);
633 }
634 var me=arguments.callee;
635 var _e7;
636 if(typeof (o.__json__)=="function"){
637 _e7=o.__json__();
638 if(o!==_e7){
639 return me(_e7);
640 }
641 }
642 if(typeof (o.json)=="function"){
643 _e7=o.json();
644 if(o!==_e7){
645 return me(_e7);
646 }
647 }
648 if(_e3!="function"&&typeof (o.length)=="number"){
649 var res=[];
650 for(var i=0;i<o.length;i++){
651 var val=me(o[i]);
652 if(typeof (val)!="string"){
653 val="undefined";
654 }
655 res.push(val);
656 }
657 return "["+res.join(", ")+"]";
658 }
659 try{
660 _e7=m.jsonRegistry.match(o);
661 if(o!==_e7){
662 return me(_e7);
663 }
664 }
665 catch(e){
666 if(e!=m.NotFound){
667 throw e;
668 }
669 }
670 if(_e3=="undefined"){
671 throw new TypeError("undefined can not be serialized as JSON");
672 }
673 if(_e3=="function"){
674 return null;
675 }
676 res=[];
677 for(var k in o){
678 var _ec;
679 if(typeof (k)=="number"){
680 _ec="\""+k+"\"";
681 }else{
682 if(typeof (k)=="string"){
683 _ec=_e5(k);
684 }else{
685 continue;
686 }
687 }
688 val=me(o[k]);
689 if(typeof (val)!="string"){
690 continue;
691 }
692 res.push(_ec+":"+val);
693 }
694 return "{"+res.join(", ")+"}";
695 },objEqual:function(a,b){
696 return (MochiKit.Base.compare(a,b)===0);
697 },arrayEqual:function(_ef,arr){
698 if(_ef.length!=arr.length){
699 return false;
700 }
701 return (MochiKit.Base.compare(_ef,arr)===0);
702 },concat:function(){
703 var _f1=[];
704 var _f2=MochiKit.Base.extend;
705 for(var i=0;i<arguments.length;i++){
706 _f2(_f1,arguments[i]);
707 }
708 return _f1;
709 },keyComparator:function(key){
710 var m=MochiKit.Base;
711 var _f6=m.compare;
712 if(arguments.length==1){
713 return function(a,b){
714 return _f6(a[key],b[key]);
715 };
716 }
717 var _f9=m.extend(null,arguments);
718 return function(a,b){
719 var _fc=0;
720 for(var i=0;(_fc===0)&&(i<_f9.length);i++){
721 var key=_f9[i];
722 _fc=_f6(a[key],b[key]);
723 }
724 return _fc;
725 };
726 },reverseKeyComparator:function(key){
727 var _100=MochiKit.Base.keyComparator.apply(this,arguments);
728 return function(a,b){
729 return _100(b,a);
730 };
731 },partial:function(func){
732 var m=MochiKit.Base;
733 return m.bind.apply(this,m.extend([func,undefined],arguments,1));
734 },listMinMax:function(_105,lst){
735 if(lst.length===0){
736 return null;
737 }
738 var cur=lst[0];
739 var _108=MochiKit.Base.compare;
740 for(var i=1;i<lst.length;i++){
741 var o=lst[i];
742 if(_108(o,cur)==_105){
743 cur=o;
744 }
745 }
746 return cur;
747 },objMax:function(){
748 return MochiKit.Base.listMinMax(1,arguments);
749 },objMin:function(){
750 return MochiKit.Base.listMinMax(-1,arguments);
751 },findIdentical:function(lst,_10c,_10d,end){
752 if(typeof (end)=="undefined"||end===null){
753 end=lst.length;
754 }
755 if(typeof (_10d)=="undefined"||_10d===null){
756 _10d=0;
757 }
758 for(var i=_10d;i<end;i++){
759 if(lst[i]===_10c){
760 return i;
761 }
762 }
763 return -1;
764 },mean:function(){
765 var sum=0;
766 var m=MochiKit.Base;
767 var args=m.extend(null,arguments);
768 var _113=args.length;
769 while(args.length){
770 var o=args.shift();
771 if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
772 _113+=o.length-1;
773 for(var i=o.length-1;i>=0;i--){
774 sum+=o[i];
775 }
776 }else{
777 sum+=o;
778 }
779 }
780 if(_113<=0){
781 throw new TypeError("mean() requires at least one argument");
782 }
783 return sum/_113;
784 },median:function(){
785 var data=MochiKit.Base.flattenArguments(arguments);
786 if(data.length===0){
787 throw new TypeError("median() requires at least one argument");
788 }
789 data.sort(compare);
790 if(data.length%2==0){
791 var _117=data.length/2;
792 return (data[_117]+data[_117-1])/2;
793 }else{
794 return data[(data.length-1)/2];
795 }
796 },findValue:function(lst,_119,_11a,end){
797 if(typeof (end)=="undefined"||end===null){
798 end=lst.length;
799 }
800 if(typeof (_11a)=="undefined"||_11a===null){
801 _11a=0;
802 }
803 var cmp=MochiKit.Base.compare;
804 for(var i=_11a;i<end;i++){
805 if(cmp(lst[i],_119)===0){
806 return i;
807 }
808 }
809 return -1;
810 },nodeWalk:function(node,_11f){
811 var _120=[node];
812 var _121=MochiKit.Base.extend;
813 while(_120.length){
814 var res=_11f(_120.shift());
815 if(res){
816 _121(_120,res);
817 }
818 }
819 },nameFunctions:function(_123){
820 var base=_123.NAME;
821 if(typeof (base)=="undefined"){
822 base="";
823 }else{
824 base=base+".";
825 }
826 for(var name in _123){
827 var o=_123[name];
828 if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
829 try{
830 o.NAME=base+name;
831 }
832 catch(e){
833 }
834 }
835 }
836 },queryString:function(_127,_128){
837 if(typeof (MochiKit.DOM)!="undefined"&&arguments.length==1&&(typeof (_127)=="string"||(typeof (_127.nodeType)!="undefined"&&_127.nodeType>0))){
838 var kv=MochiKit.DOM.formContents(_127);
839 _127=kv[0];
840 _128=kv[1];
841 }else{
842 if(arguments.length==1){
843 if(typeof (_127.length)=="number"&&_127.length==2){
844 return arguments.callee(_127[0],_127[1]);
845 }
846 var o=_127;
847 _127=[];
848 _128=[];
849 for(var k in o){
850 var v=o[k];
851 if(typeof (v)=="function"){
852 continue;
853 }else{
854 if(typeof (v)!="string"&&typeof (v.length)=="number"){
855 for(var i=0;i<v.length;i++){
856 _127.push(k);
857 _128.push(v[i]);
858 }
859 }else{
860 _127.push(k);
861 _128.push(v);
862 }
863 }
864 }
865 }
866 }
867 var rval=[];
868 var len=Math.min(_127.length,_128.length);
869 var _130=MochiKit.Base.urlEncode;
870 for(var i=0;i<len;i++){
871 v=_128[i];
872 if(typeof (v)!="undefined"&&v!==null){
873 rval.push(_130(_127[i])+"="+_130(v));
874 }
875 }
876 return rval.join("&");
877 },parseQueryString:function(_131,_132){
878 var qstr=(_131.charAt(0)=="?")?_131.substring(1):_131;
879 var _134=qstr.replace(/\+/g,"%20").split(/(\&amp\;|\&\#38\;|\&#x26;|\&)/);
880 var o={};
881 var _136;
882 if(typeof (decodeURIComponent)!="undefined"){
883 _136=decodeURIComponent;
884 }else{
885 _136=unescape;
886 }
887 if(_132){
888 for(var i=0;i<_134.length;i++){
889 var pair=_134[i].split("=");
890 var name=_136(pair.shift());
891 if(!name){
892 continue;
893 }
894 var arr=o[name];
895 if(!(arr instanceof Array)){
896 arr=[];
897 o[name]=arr;
898 }
899 arr.push(_136(pair.join("=")));
900 }
901 }else{
902 for(i=0;i<_134.length;i++){
903 pair=_134[i].split("=");
904 var name=pair.shift();
905 if(!name){
906 continue;
907 }
908 o[_136(name)]=_136(pair.join("="));
909 }
910 }
911 return o;
912 }});
913 MochiKit.Base.AdapterRegistry=function(){
914 this.pairs=[];
915 };
916 MochiKit.Base.AdapterRegistry.prototype={register:function(name,_13c,wrap,_13e){
917 if(_13e){
918 this.pairs.unshift([name,_13c,wrap]);
919 }else{
920 this.pairs.push([name,_13c,wrap]);
921 }
922 },match:function(){
923 for(var i=0;i<this.pairs.length;i++){
924 var pair=this.pairs[i];
925 if(pair[1].apply(this,arguments)){
926 return pair[2].apply(this,arguments);
927 }
928 }
929 throw MochiKit.Base.NotFound;
930 },unregister:function(name){
931 for(var i=0;i<this.pairs.length;i++){
932 var pair=this.pairs[i];
933 if(pair[0]==name){
934 this.pairs.splice(i,1);
935 return true;
936 }
937 }
938 return false;
939 }};
940 MochiKit.Base.EXPORT=["flattenArray","noop","camelize","counter","clone","extend","update","updatetree","setdefault","keys","values","items","NamedError","operator","forwardCall","itemgetter","typeMatcher","isCallable","isUndefined","isUndefinedOrNull","isNull","isEmpty","isNotEmpty","isArrayLike","isDateLike","xmap","map","xfilter","filter","methodcaller","compose","bind","bindMethods","NotFound","AdapterRegistry","registerComparator","compare","registerRepr","repr","objEqual","arrayEqual","concat","keyComparator","reverseKeyComparator","partial","merge","listMinMax","listMax","listMin","objMax","objMin","nodeWalk","zip","urlEncode","queryString","serializeJSON","registerJSON","evalJSON","parseQueryString","findValue","findIdentical","flattenArguments","method","average","mean","median"];
941 MochiKit.Base.EXPORT_OK=["nameFunctions","comparatorRegistry","reprRegistry","jsonRegistry","compareDateLike","compareArrayLike","reprArrayLike","reprString","reprNumber"];
942 MochiKit.Base._exportSymbols=function(_144,_145){
943 if(!MochiKit.__export__){
944 return;
945 }
946 var all=_145.EXPORT_TAGS[":all"];
947 for(var i=0;i<all.length;i++){
948 _144[all[i]]=_145[all[i]];
949 }
950 };
951 MochiKit.Base.__new__=function(){
952 var m=this;
953 m.noop=m.operator.identity;
954 m.forward=m.forwardCall;
955 m.find=m.findValue;
956 if(typeof (encodeURIComponent)!="undefined"){
957 m.urlEncode=function(_149){
958 return encodeURIComponent(_149).replace(/\'/g,"%27");
959 };
960 }else{
961 m.urlEncode=function(_14a){
962 return escape(_14a).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval.replace(/\'/g,"%27");
963 };
964 }
965 m.NamedError=function(name){
966 this.message=name;
967 this.name=name;
968 };
969 m.NamedError.prototype=new Error();
970 m.update(m.NamedError.prototype,{repr:function(){
971 if(this.message&&this.message!=this.name){
972 return this.name+"("+m.repr(this.message)+")";
973 }else{
974 return this.name+"()";
975 }
976 },toString:m.forwardCall("repr")});
977 m.NotFound=new m.NamedError("MochiKit.Base.NotFound");
978 m.listMax=m.partial(m.listMinMax,1);
979 m.listMin=m.partial(m.listMinMax,-1);
980 m.isCallable=m.typeMatcher("function");
981 m.isUndefined=m.typeMatcher("undefined");
982 m.merge=m.partial(m.update,null);
983 m.zip=m.partial(m.map,null);
984 m.average=m.mean;
985 m.comparatorRegistry=new m.AdapterRegistry();
986 m.registerComparator("dateLike",m.isDateLike,m.compareDateLike);
987 m.registerComparator("arrayLike",m.isArrayLike,m.compareArrayLike);
988 m.reprRegistry=new m.AdapterRegistry();
989 m.registerRepr("arrayLike",m.isArrayLike,m.reprArrayLike);
990 m.registerRepr("string",m.typeMatcher("string"),m.reprString);
991 m.registerRepr("numbers",m.typeMatcher("number","boolean"),m.reprNumber);
992 m.jsonRegistry=new m.AdapterRegistry();
993 var all=m.concat(m.EXPORT,m.EXPORT_OK);
994 m.EXPORT_TAGS={":common":m.concat(m.EXPORT_OK),":all":all};
995 m.nameFunctions(this);
996 };
997 MochiKit.Base.__new__();
998 if(MochiKit.__export__){
999 compare=MochiKit.Base.compare;
1000 compose=MochiKit.Base.compose;
1001 serializeJSON=MochiKit.Base.serializeJSON;
1002 }
1003 MochiKit.Base._exportSymbols(this,MochiKit.Base);
1004 if(typeof (dojo)!="undefined"){
1005 dojo.provide("MochiKit.Iter");
1006 dojo.require("MochiKit.Base");
1007 }
1008 if(typeof (JSAN)!="undefined"){
1009 JSAN.use("MochiKit.Base",[]);
1010 }
1011 try{
1012 if(typeof (MochiKit.Base)=="undefined"){
1013 throw "";
1014 }
1015 }
1016 catch(e){
1017 throw "MochiKit.Iter depends on MochiKit.Base!";
1018 }
1019 if(typeof (MochiKit.Iter)=="undefined"){
1020 MochiKit.Iter={};
1021 }
1022 MochiKit.Iter.NAME="MochiKit.Iter";
1023 MochiKit.Iter.VERSION="1.4";
1024 MochiKit.Base.update(MochiKit.Iter,{__repr__:function(){
1025 return "["+this.NAME+" "+this.VERSION+"]";
1026 },toString:function(){
1027 return this.__repr__();
1028 },registerIteratorFactory:function(name,_14e,_14f,_150){
1029 MochiKit.Iter.iteratorRegistry.register(name,_14e,_14f,_150);
1030 },iter:function(_151,_152){
1031 var self=MochiKit.Iter;
1032 if(arguments.length==2){
1033 return self.takewhile(function(a){
1034 return a!=_152;
1035 },_151);
1036 }
1037 if(typeof (_151.next)=="function"){
1038 return _151;
1039 }else{
1040 if(typeof (_151.iter)=="function"){
1041 return _151.iter();
1042 }
1043 }
1044 try{
1045 return self.iteratorRegistry.match(_151);
1046 }
1047 catch(e){
1048 var m=MochiKit.Base;
1049 if(e==m.NotFound){
1050 e=new TypeError(typeof (_151)+": "+m.repr(_151)+" is not iterable");
1051 }
1052 throw e;
1053 }
1054 },count:function(n){
1055 if(!n){
1056 n=0;
1057 }
1058 var m=MochiKit.Base;
1059 return {repr:function(){
1060 return "count("+n+")";
1061 },toString:m.forwardCall("repr"),next:m.counter(n)};
1062 },cycle:function(p){
1063 var self=MochiKit.Iter;
1064 var m=MochiKit.Base;
1065 var lst=[];
1066 var _15c=self.iter(p);
1067 return {repr:function(){
1068 return "cycle(...)";
1069 },toString:m.forwardCall("repr"),next:function(){
1070 try{
1071 var rval=_15c.next();
1072 lst.push(rval);
1073 return rval;
1074 }
1075 catch(e){
1076 if(e!=self.StopIteration){
1077 throw e;
1078 }
1079 if(lst.length===0){
1080 this.next=function(){
1081 throw self.StopIteration;
1082 };
1083 }else{
1084 var i=-1;
1085 this.next=function(){
1086 i=(i+1)%lst.length;
1087 return lst[i];
1088 };
1089 }
1090 return this.next();
1091 }
1092 }};
1093 },repeat:function(elem,n){
1094 var m=MochiKit.Base;
1095 if(typeof (n)=="undefined"){
1096 return {repr:function(){
1097 return "repeat("+m.repr(elem)+")";
1098 },toString:m.forwardCall("repr"),next:function(){
1099 return elem;
1100 }};
1101 }
1102 return {repr:function(){
1103 return "repeat("+m.repr(elem)+", "+n+")";
1104 },toString:m.forwardCall("repr"),next:function(){
1105 if(n<=0){
1106 throw MochiKit.Iter.StopIteration;
1107 }
1108 n-=1;
1109 return elem;
1110 }};
1111 },next:function(_162){
1112 return _162.next();
1113 },izip:function(p,q){
1114 var m=MochiKit.Base;
1115 var self=MochiKit.Iter;
1116 var next=self.next;
1117 var _168=m.map(self.iter,arguments);
1118 return {repr:function(){
1119 return "izip(...)";
1120 },toString:m.forwardCall("repr"),next:function(){
1121 return m.map(next,_168);
1122 }};
1123 },ifilter:function(pred,seq){
1124 var m=MochiKit.Base;
1125 seq=MochiKit.Iter.iter(seq);
1126 if(pred===null){
1127 pred=m.operator.truth;
1128 }
1129 return {repr:function(){
1130 return "ifilter(...)";
1131 },toString:m.forwardCall("repr"),next:function(){
1132 while(true){
1133 var rval=seq.next();
1134 if(pred(rval)){
1135 return rval;
1136 }
1137 }
1138 return undefined;
1139 }};
1140 },ifilterfalse:function(pred,seq){
1141 var m=MochiKit.Base;
1142 seq=MochiKit.Iter.iter(seq);
1143 if(pred===null){
1144 pred=m.operator.truth;
1145 }
1146 return {repr:function(){
1147 return "ifilterfalse(...)";
1148 },toString:m.forwardCall("repr"),next:function(){
1149 while(true){
1150 var rval=seq.next();
1151 if(!pred(rval)){
1152 return rval;
1153 }
1154 }
1155 return undefined;
1156 }};
1157 },islice:function(seq){
1158 var self=MochiKit.Iter;
1159 var m=MochiKit.Base;
1160 seq=self.iter(seq);
1161 var _174=0;
1162 var stop=0;
1163 var step=1;
1164 var i=-1;
1165 if(arguments.length==2){
1166 stop=arguments[1];
1167 }else{
1168 if(arguments.length==3){
1169 _174=arguments[1];
1170 stop=arguments[2];
1171 }else{
1172 _174=arguments[1];
1173 stop=arguments[2];
1174 step=arguments[3];
1175 }
1176 }
1177 return {repr:function(){
1178 return "islice("+["...",_174,stop,step].join(", ")+")";
1179 },toString:m.forwardCall("repr"),next:function(){
1180 var rval;
1181 while(i<_174){
1182 rval=seq.next();
1183 i++;
1184 }
1185 if(_174>=stop){
1186 throw self.StopIteration;
1187 }
1188 _174+=step;
1189 return rval;
1190 }};
1191 },imap:function(fun,p,q){
1192 var m=MochiKit.Base;
1193 var self=MochiKit.Iter;
1194 var _17e=m.map(self.iter,m.extend(null,arguments,1));
1195 var map=m.map;
1196 var next=self.next;
1197 return {repr:function(){
1198 return "imap(...)";
1199 },toString:m.forwardCall("repr"),next:function(){
1200 return fun.apply(this,map(next,_17e));
1201 }};
1202 },applymap:function(fun,seq,self){
1203 seq=MochiKit.Iter.iter(seq);
1204 var m=MochiKit.Base;
1205 return {repr:function(){
1206 return "applymap(...)";
1207 },toString:m.forwardCall("repr"),next:function(){
1208 return fun.apply(self,seq.next());
1209 }};
1210 },chain:function(p,q){
1211 var self=MochiKit.Iter;
1212 var m=MochiKit.Base;
1213 if(arguments.length==1){
1214 return self.iter(arguments[0]);
1215 }
1216 var _189=m.map(self.iter,arguments);
1217 return {repr:function(){
1218 return "chain(...)";
1219 },toString:m.forwardCall("repr"),next:function(){
1220 while(_189.length>1){
1221 try{
1222 return _189[0].next();
1223 }
1224 catch(e){
1225 if(e!=self.StopIteration){
1226 throw e;
1227 }
1228 _189.shift();
1229 }
1230 }
1231 if(_189.length==1){
1232 var arg=_189.shift();
1233 this.next=m.bind("next",arg);
1234 return this.next();
1235 }
1236 throw self.StopIteration;
1237 }};
1238 },takewhile:function(pred,seq){
1239 var self=MochiKit.Iter;
1240 seq=self.iter(seq);
1241 return {repr:function(){
1242 return "takewhile(...)";
1243 },toString:MochiKit.Base.forwardCall("repr"),next:function(){
1244 var rval=seq.next();
1245 if(!pred(rval)){
1246 this.next=function(){
1247 throw self.StopIteration;
1248 };
1249 this.next();
1250 }
1251 return rval;
1252 }};
1253 },dropwhile:function(pred,seq){
1254 seq=MochiKit.Iter.iter(seq);
1255 var m=MochiKit.Base;
1256 var bind=m.bind;
1257 return {"repr":function(){
1258 return "dropwhile(...)";
1259 },"toString":m.forwardCall("repr"),"next":function(){
1260 while(true){
1261 var rval=seq.next();
1262 if(!pred(rval)){
1263 break;
1264 }
1265 }
1266 this.next=bind("next",seq);
1267 return rval;
1268 }};
1269 },_tee:function(_194,sync,_196){
1270 sync.pos[_194]=-1;
1271 var m=MochiKit.Base;
1272 var _198=m.listMin;
1273 return {repr:function(){
1274 return "tee("+_194+", ...)";
1275 },toString:m.forwardCall("repr"),next:function(){
1276 var rval;
1277 var i=sync.pos[_194];
1278 if(i==sync.max){
1279 rval=_196.next();
1280 sync.deque.push(rval);
1281 sync.max+=1;
1282 sync.pos[_194]+=1;
1283 }else{
1284 rval=sync.deque[i-sync.min];
1285 sync.pos[_194]+=1;
1286 if(i==sync.min&&_198(sync.pos)!=sync.min){
1287 sync.min+=1;
1288 sync.deque.shift();
1289 }
1290 }
1291 return rval;
1292 }};
1293 },tee:function(_19b,n){
1294 var rval=[];
1295 var sync={"pos":[],"deque":[],"max":-1,"min":-1};
1296 if(arguments.length==1||typeof (n)=="undefined"||n===null){
1297 n=2;
1298 }
1299 var self=MochiKit.Iter;
1300 _19b=self.iter(_19b);
1301 var _tee=self._tee;
1302 for(var i=0;i<n;i++){
1303 rval.push(_tee(i,sync,_19b));
1304 }
1305 return rval;
1306 },list:function(_1a2){
1307 var rval;
1308 if(_1a2 instanceof Array){
1309 return _1a2.slice();
1310 }
1311 if(typeof (_1a2)=="function"&&!(_1a2 instanceof Function)&&typeof (_1a2.length)=="number"){
1312 rval=[];
1313 for(var i=0;i<_1a2.length;i++){
1314 rval.push(_1a2[i]);
1315 }
1316 return rval;
1317 }
1318 var self=MochiKit.Iter;
1319 _1a2=self.iter(_1a2);
1320 var rval=[];
1321 try{
1322 while(true){
1323 rval.push(_1a2.next());
1324 }
1325 }
1326 catch(e){
1327 if(e!=self.StopIteration){
1328 throw e;
1329 }
1330 return rval;
1331 }
1332 return undefined;
1333 },reduce:function(fn,_1a7,_1a8){
1334 var i=0;
1335 var x=_1a8;
1336 var self=MochiKit.Iter;
1337 _1a7=self.iter(_1a7);
1338 if(arguments.length<3){
1339 try{
1340 x=_1a7.next();
1341 }
1342 catch(e){
1343 if(e==self.StopIteration){
1344 e=new TypeError("reduce() of empty sequence with no initial value");
1345 }
1346 throw e;
1347 }
1348 i++;
1349 }
1350 try{
1351 while(true){
1352 x=fn(x,_1a7.next());
1353 }
1354 }
1355 catch(e){
1356 if(e!=self.StopIteration){
1357 throw e;
1358 }
1359 }
1360 return x;
1361 },range:function(){
1362 var _1ac=0;
1363 var stop=0;
1364 var step=1;
1365 if(arguments.length==1){
1366 stop=arguments[0];
1367 }else{
1368 if(arguments.length==2){
1369 _1ac=arguments[0];
1370 stop=arguments[1];
1371 }else{
1372 if(arguments.length==3){
1373 _1ac=arguments[0];
1374 stop=arguments[1];
1375 step=arguments[2];
1376 }else{
1377 throw new TypeError("range() takes 1, 2, or 3 arguments!");
1378 }
1379 }
1380 }
1381 if(step===0){
1382 throw new TypeError("range() step must not be 0");
1383 }
1384 return {next:function(){
1385 if((step>0&&_1ac>=stop)||(step<0&&_1ac<=stop)){
1386 throw MochiKit.Iter.StopIteration;
1387 }
1388 var rval=_1ac;
1389 _1ac+=step;
1390 return rval;
1391 },repr:function(){
1392 return "range("+[_1ac,stop,step].join(", ")+")";
1393 },toString:MochiKit.Base.forwardCall("repr")};
1394 },sum:function(_1b0,_1b1){
1395 if(typeof (_1b1)=="undefined"||_1b1===null){
1396 _1b1=0;
1397 }
1398 var x=_1b1;
1399 var self=MochiKit.Iter;
1400 _1b0=self.iter(_1b0);
1401 try{
1402 while(true){
1403 x+=_1b0.next();
1404 }
1405 }
1406 catch(e){
1407 if(e!=self.StopIteration){
1408 throw e;
1409 }
1410 }
1411 return x;
1412 },exhaust:function(_1b4){
1413 var self=MochiKit.Iter;
1414 _1b4=self.iter(_1b4);
1415 try{
1416 while(true){
1417 _1b4.next();
1418 }
1419 }
1420 catch(e){
1421 if(e!=self.StopIteration){
1422 throw e;
1423 }
1424 }
1425 },forEach:function(_1b6,func,self){
1426 var m=MochiKit.Base;
1427 if(arguments.length>2){
1428 func=m.bind(func,self);
1429 }
1430 if(m.isArrayLike(_1b6)){
1431 try{
1432 for(var i=0;i<_1b6.length;i++){
1433 func(_1b6[i]);
1434 }
1435 }
1436 catch(e){
1437 if(e!=MochiKit.Iter.StopIteration){
1438 throw e;
1439 }
1440 }
1441 }else{
1442 self=MochiKit.Iter;
1443 self.exhaust(self.imap(func,_1b6));
1444 }
1445 },every:function(_1bb,func){
1446 var self=MochiKit.Iter;
1447 try{
1448 self.ifilterfalse(func,_1bb).next();
1449 return false;
1450 }
1451 catch(e){
1452 if(e!=self.StopIteration){
1453 throw e;
1454 }
1455 return true;
1456 }
1457 },sorted:function(_1be,cmp){
1458 var rval=MochiKit.Iter.list(_1be);
1459 if(arguments.length==1){
1460 cmp=MochiKit.Base.compare;
1461 }
1462 rval.sort(cmp);
1463 return rval;
1464 },reversed:function(_1c1){
1465 var rval=MochiKit.Iter.list(_1c1);
1466 rval.reverse();
1467 return rval;
1468 },some:function(_1c3,func){
1469 var self=MochiKit.Iter;
1470 try{
1471 self.ifilter(func,_1c3).next();
1472 return true;
1473 }
1474 catch(e){
1475 if(e!=self.StopIteration){
1476 throw e;
1477 }
1478 return false;
1479 }
1480 },iextend:function(lst,_1c7){
1481 if(MochiKit.Base.isArrayLike(_1c7)){
1482 for(var i=0;i<_1c7.length;i++){
1483 lst.push(_1c7[i]);
1484 }
1485 }else{
1486 var self=MochiKit.Iter;
1487 _1c7=self.iter(_1c7);
1488 try{
1489 while(true){
1490 lst.push(_1c7.next());
1491 }
1492 }
1493 catch(e){
1494 if(e!=self.StopIteration){
1495 throw e;
1496 }
1497 }
1498 }
1499 return lst;
1500 },groupby:function(_1ca,_1cb){
1501 var m=MochiKit.Base;
1502 var self=MochiKit.Iter;
1503 if(arguments.length<2){
1504 _1cb=m.operator.identity;
1505 }
1506 _1ca=self.iter(_1ca);
1507 var pk=undefined;
1508 var k=undefined;
1509 var v;
1510 function fetch(){
1511 v=_1ca.next();
1512 k=_1cb(v);
1513 }
1514 function eat(){
1515 var ret=v;
1516 v=undefined;
1517 return ret;
1518 }
1519 var _1d2=true;
1520 var _1d3=m.compare;
1521 return {repr:function(){
1522 return "groupby(...)";
1523 },next:function(){
1524 while(_1d3(k,pk)===0){
1525 fetch();
1526 if(_1d2){
1527 _1d2=false;
1528 break;
1529 }
1530 }
1531 pk=k;
1532 return [k,{next:function(){
1533 if(v==undefined){
1534 fetch();
1535 }
1536 if(_1d3(k,pk)!==0){
1537 throw self.StopIteration;
1538 }
1539 return eat();
1540 }}];
1541 }};
1542 },groupby_as_array:function(_1d4,_1d5){
1543 var m=MochiKit.Base;
1544 var self=MochiKit.Iter;
1545 if(arguments.length<2){
1546 _1d5=m.operator.identity;
1547 }
1548 _1d4=self.iter(_1d4);
1549 var _1d8=[];
1550 var _1d9=true;
1551 var _1da;
1552 var _1db=m.compare;
1553 while(true){
1554 try{
1555 var _1dc=_1d4.next();
1556 var key=_1d5(_1dc);
1557 }
1558 catch(e){
1559 if(e==self.StopIteration){
1560 break;
1561 }
1562 throw e;
1563 }
1564 if(_1d9||_1db(key,_1da)!==0){
1565 var _1de=[];
1566 _1d8.push([key,_1de]);
1567 }
1568 _1de.push(_1dc);
1569 _1d9=false;
1570 _1da=key;
1571 }
1572 return _1d8;
1573 },arrayLikeIter:function(_1df){
1574 var i=0;
1575 return {repr:function(){
1576 return "arrayLikeIter(...)";
1577 },toString:MochiKit.Base.forwardCall("repr"),next:function(){
1578 if(i>=_1df.length){
1579 throw MochiKit.Iter.StopIteration;
1580 }
1581 return _1df[i++];
1582 }};
1583 },hasIterateNext:function(_1e1){
1584 return (_1e1&&typeof (_1e1.iterateNext)=="function");
1585 },iterateNextIter:function(_1e2){
1586 return {repr:function(){
1587 return "iterateNextIter(...)";
1588 },toString:MochiKit.Base.forwardCall("repr"),next:function(){
1589 var rval=_1e2.iterateNext();
1590 if(rval===null||rval===undefined){
1591 throw MochiKit.Iter.StopIteration;
1592 }
1593 return rval;
1594 }};
1595 }});
1596 MochiKit.Iter.EXPORT_OK=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",];
1597 MochiKit.Iter.EXPORT=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"];
1598 MochiKit.Iter.__new__=function(){
1599 var m=MochiKit.Base;
1600 if(typeof (StopIteration)!="undefined"){
1601 this.StopIteration=StopIteration;
1602 }else{
1603 this.StopIteration=new m.NamedError("StopIteration");
1604 }
1605 this.iteratorRegistry=new m.AdapterRegistry();
1606 this.registerIteratorFactory("arrayLike",m.isArrayLike,this.arrayLikeIter);
1607 this.registerIteratorFactory("iterateNext",this.hasIterateNext,this.iterateNextIter);
1608 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
1609 m.nameFunctions(this);
1610 };
1611 MochiKit.Iter.__new__();
1612 if(MochiKit.__export__){
1613 reduce=MochiKit.Iter.reduce;
1614 }
1615 MochiKit.Base._exportSymbols(this,MochiKit.Iter);
1616 if(typeof (dojo)!="undefined"){
1617 dojo.provide("MochiKit.Format");
1618 }
1619 if(typeof (MochiKit)=="undefined"){
1620 MochiKit={};
1621 }
1622 if(typeof (MochiKit.Format)=="undefined"){
1623 MochiKit.Format={};
1624 }
1625 MochiKit.Format.NAME="MochiKit.Format";
1626 MochiKit.Format.VERSION="1.4";
1627 MochiKit.Format.__repr__=function(){
1628 return "["+this.NAME+" "+this.VERSION+"]";
1629 };
1630 MochiKit.Format.toString=function(){
1631 return this.__repr__();
1632 };
1633 MochiKit.Format._numberFormatter=function(_1e5,_1e6,_1e7,_1e8,_1e9,_1ea,_1eb,_1ec,_1ed){
1634 return function(num){
1635 num=parseFloat(num);
1636 if(typeof (num)=="undefined"||num===null||isNaN(num)){
1637 return _1e5;
1638 }
1639 var _1ef=_1e6;
1640 var _1f0=_1e7;
1641 if(num<0){
1642 num=-num;
1643 }else{
1644 _1ef=_1ef.replace(/-/,"");
1645 }
1646 var me=arguments.callee;
1647 var fmt=MochiKit.Format.formatLocale(_1e8);
1648 if(_1e9){
1649 num=num*100;
1650 _1f0=fmt.percent+_1f0;
1651 }
1652 num=MochiKit.Format.roundToFixed(num,_1ea);
1653 var _1f3=num.split(/\./);
1654 var _1f4=_1f3[0];
1655 var frac=(_1f3.length==1)?"":_1f3[1];
1656 var res="";
1657 while(_1f4.length<_1eb){
1658 _1f4="0"+_1f4;
1659 }
1660 if(_1ec){
1661 while(_1f4.length>_1ec){
1662 var i=_1f4.length-_1ec;
1663 res=fmt.separator+_1f4.substring(i,_1f4.length)+res;
1664 _1f4=_1f4.substring(0,i);
1665 }
1666 }
1667 res=_1f4+res;
1668 if(_1ea>0){
1669 while(frac.length<_1ed){
1670 frac=frac+"0";
1671 }
1672 res=res+fmt.decimal+frac;
1673 }
1674 return _1ef+res+_1f0;
1675 };
1676 };
1677 MochiKit.Format.numberFormatter=function(_1f8,_1f9,_1fa){
1678 if(typeof (_1f9)=="undefined"){
1679 _1f9="";
1680 }
1681 var _1fb=_1f8.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
1682 if(!_1fb){
1683 throw TypeError("Invalid pattern");
1684 }
1685 var _1fc=_1f8.substr(0,_1fb.index);
1686 var _1fd=_1f8.substr(_1fb.index+_1fb[0].length);
1687 if(_1fc.search(/-/)==-1){
1688 _1fc=_1fc+"-";
1689 }
1690 var _1fe=_1fb[1];
1691 var frac=(typeof (_1fb[2])=="string"&&_1fb[2]!="")?_1fb[2]:"";
1692 var _200=(typeof (_1fb[3])=="string"&&_1fb[3]!="");
1693 var tmp=_1fe.split(/,/);
1694 var _202;
1695 if(typeof (_1fa)=="undefined"){
1696 _1fa="default";
1697 }
1698 if(tmp.length==1){
1699 _202=null;
1700 }else{
1701 _202=tmp[1].length;
1702 }
1703 var _203=_1fe.length-_1fe.replace(/0/g,"").length;
1704 var _204=frac.length-frac.replace(/0/g,"").length;
1705 var _205=frac.length;
1706 var rval=MochiKit.Format._numberFormatter(_1f9,_1fc,_1fd,_1fa,_200,_205,_203,_202,_204);
1707 var m=MochiKit.Base;
1708 if(m){
1709 var fn=arguments.callee;
1710 var args=m.concat(arguments);
1711 rval.repr=function(){
1712 return [self.NAME,"(",map(m.repr,args).join(", "),")"].join("");
1713 };
1714 }
1715 return rval;
1716 };
1717 MochiKit.Format.formatLocale=function(_20a){
1718 if(typeof (_20a)=="undefined"||_20a===null){
1719 _20a="default";
1720 }
1721 if(typeof (_20a)=="string"){
1722 var rval=MochiKit.Format.LOCALE[_20a];
1723 if(typeof (rval)=="string"){
1724 rval=arguments.callee(rval);
1725 MochiKit.Format.LOCALE[_20a]=rval;
1726 }
1727 return rval;
1728 }else{
1729 return _20a;
1730 }
1731 };
1732 MochiKit.Format.twoDigitAverage=function(_20c,_20d){
1733 if(_20d){
1734 var res=_20c/_20d;
1735 if(!isNaN(res)){
1736 return MochiKit.Format.twoDigitFloat(_20c/_20d);
1737 }
1738 }
1739 return "0";
1740 };
1741 MochiKit.Format.twoDigitFloat=function(_20f){
1742 var sign=(_20f<0?"-":"");
1743 var s=Math.floor(Math.abs(_20f)*100).toString();
1744 if(s=="0"){
1745 return s;
1746 }
1747 if(s.length<3){
1748 while(s.charAt(s.length-1)=="0"){
1749 s=s.substring(0,s.length-1);
1750 }
1751 return sign+"0."+s;
1752 }
1753 var head=sign+s.substring(0,s.length-2);
1754 var tail=s.substring(s.length-2,s.length);
1755 if(tail=="00"){
1756 return head;
1757 }else{
1758 if(tail.charAt(1)=="0"){
1759 return head+"."+tail.charAt(0);
1760 }else{
1761 return head+"."+tail;
1762 }
1763 }
1764 };
1765 MochiKit.Format.lstrip=function(str,_215){
1766 str=str+"";
1767 if(typeof (str)!="string"){
1768 return null;
1769 }
1770 if(!_215){
1771 return str.replace(/^\s+/,"");
1772 }else{
1773 return str.replace(new RegExp("^["+_215+"]+"),"");
1774 }
1775 };
1776 MochiKit.Format.rstrip=function(str,_217){
1777 str=str+"";
1778 if(typeof (str)!="string"){
1779 return null;
1780 }
1781 if(!_217){
1782 return str.replace(/\s+$/,"");
1783 }else{
1784 return str.replace(new RegExp("["+_217+"]+$"),"");
1785 }
1786 };
1787 MochiKit.Format.strip=function(str,_219){
1788 var self=MochiKit.Format;
1789 return self.rstrip(self.lstrip(str,_219),_219);
1790 };
1791 MochiKit.Format.truncToFixed=function(_21b,_21c){
1792 _21b=Math.floor(_21b*Math.pow(10,_21c));
1793 var res=(_21b*Math.pow(10,-_21c)).toFixed(_21c);
1794 if(res.charAt(0)=="."){
1795 res="0"+res;
1796 }
1797 return res;
1798 };
1799 MochiKit.Format.roundToFixed=function(_21e,_21f){
1800 return MochiKit.Format.truncToFixed(_21e+0.5*Math.pow(10,-_21f),_21f);
1801 };
1802 MochiKit.Format.percentFormat=function(_220){
1803 return MochiKit.Format.twoDigitFloat(100*_220)+"%";
1804 };
1805 MochiKit.Format.EXPORT=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
1806 MochiKit.Format.LOCALE={en_US:{separator:",",decimal:".",percent:"%"},de_DE:{separator:".",decimal:",",percent:"%"},fr_FR:{separator:" ",decimal:",",percent:"%"},"default":"en_US"};
1807 MochiKit.Format.EXPORT_OK=[];
1808 MochiKit.Format.EXPORT_TAGS={":all":MochiKit.Format.EXPORT,":common":MochiKit.Format.EXPORT};
1809 MochiKit.Format.__new__=function(){
1810 var base=this.NAME+".";
1811 var k,v,o;
1812 for(k in this.LOCALE){
1813 o=this.LOCALE[k];
1814 if(typeof (o)=="object"){
1815 o.repr=function(){
1816 return this.NAME;
1817 };
1818 o.NAME=base+"LOCALE."+k;
1819 }
1820 }
1821 for(k in this){
1822 o=this[k];
1823 if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
1824 try{
1825 o.NAME=base+k;
1826 }
1827 catch(e){
1828 }
1829 }
1830 }
1831 };
1832 MochiKit.Format.__new__();
1833 if(typeof (MochiKit.Base)!="undefined"){
1834 MochiKit.Base._exportSymbols(this,MochiKit.Format);
1835 }else{
1836 (function(_225,_226){
1837 if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(MochiKit.__export__===false)){
1838 var all=_226.EXPORT_TAGS[":all"];
1839 for(var i=0;i<all.length;i++){
1840 _225[all[i]]=_226[all[i]];
1841 }
1842 }
1843 })(this,MochiKit.Format);
1844 }
1845 if(typeof (dojo)!="undefined"){
1846 dojo.provide("MochiKit.DOM");
1847 dojo.require("MochiKit.Base");
1848 }
1849 if(typeof (JSAN)!="undefined"){
1850 JSAN.use("MochiKit.Base",[]);
1851 }
1852 try{
1853 if(typeof (MochiKit.Base)=="undefined"){
1854 throw "";
1855 }
1856 }
1857 catch(e){
1858 throw "MochiKit.DOM depends on MochiKit.Base!";
1859 }
1860 if(typeof (MochiKit.DOM)=="undefined"){
1861 MochiKit.DOM={};
1862 }
1863 MochiKit.DOM.NAME="MochiKit.DOM";
1864 MochiKit.DOM.VERSION="1.4";
1865 MochiKit.DOM.__repr__=function(){
1866 return "["+this.NAME+" "+this.VERSION+"]";
1867 };
1868 MochiKit.DOM.toString=function(){
1869 return this.__repr__();
1870 };
1871 MochiKit.DOM.EXPORT=["removeEmptyTextNodes","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","isChildNode","getNodeAttribute","removeNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","insertSiblingNodesAfter","insertSiblingNodesBefore","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","scrapeText","isParent","getFirstParentByTagAndClassName","makeClipping","undoClipping","makePositioned","undoPositioned","getFirstElementByTagAndClassName"];
1872 MochiKit.DOM.EXPORT_OK=["domConverters"];
1873 MochiKit.DOM.DEPRECATED=[["computedStyle","MochiKit.Style.getStyle","1.4"],["elementDimensions","MochiKit.Style.getElementDimensions","1.4"],["elementPosition","MochiKit.Style.getElementPosition","1.4"],["hideElement","MochiKit.Style.hideElement","1.4"],["setElementDimensions","MochiKit.Style.setElementDimensions","1.4"],["setElementPosition","MochiKit.Style.setElementPosition","1.4"],["setDisplayForElement","MochiKit.Style.setDisplayForElement","1.4"],["setOpacity","MochiKit.Style.setOpacity","1.4"],["showElement","MochiKit.Style.showElement","1.4"],["Coordinates","MochiKit.Style.Coordinates","1.4"],["Dimensions","MochiKit.Style.Dimensions","1.4"]];
1874 MochiKit.DOM.getViewportDimensions=new Function(""+"if (!MochiKit[\"Style\"]) {"+" throw new Error(\"This function has been deprecated and depends on MochiKit.Style.\");"+"}"+"return MochiKit.Style.getViewportDimensions.apply(this, arguments);");
1875 MochiKit.Base.update(MochiKit.DOM,{currentWindow:function(){
1876 return MochiKit.DOM._window;
1877 },currentDocument:function(){
1878 return MochiKit.DOM._document;
1879 },withWindow:function(win,func){
1880 var self=MochiKit.DOM;
1881 var _22c=self._document;
1882 var _22d=self._window;
1883 var rval;
1884 try{
1885 self._window=win;
1886 self._document=win.document;
1887 rval=func();
1888 }
1889 catch(e){
1890 self._window=_22d;
1891 self._document=_22c;
1892 throw e;
1893 }
1894 self._window=_22d;
1895 self._document=_22c;
1896 return rval;
1897 },formContents:function(elem){
1898 var _230=[];
1899 var _231=[];
1900 var m=MochiKit.Base;
1901 var self=MochiKit.DOM;
1902 if(typeof (elem)=="undefined"||elem===null){
1903 elem=self._document.body;
1904 }else{
1905 elem=self.getElement(elem);
1906 }
1907 m.nodeWalk(elem,function(elem){
1908 var name=elem.name;
1909 if(m.isNotEmpty(name)){
1910 var _236=elem.tagName.toUpperCase();
1911 if(_236==="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){
1912 return null;
1913 }
1914 if(_236==="SELECT"){
1915 if(elem.type=="select-one"){
1916 if(elem.selectedIndex>=0){
1917 var opt=elem.options[elem.selectedIndex];
1918 var v=opt.value;
1919 if(!v){
1920 var h=opt.outerHTML;
1921 if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
1922 v=opt.text;
1923 }
1924 }
1925 _230.push(name);
1926 _231.push(v);
1927 return null;
1928 }
1929 _230.push(name);
1930 _231.push("");
1931 return null;
1932 }else{
1933 var opts=elem.options;
1934 if(!opts.length){
1935 _230.push(name);
1936 _231.push("");
1937 return null;
1938 }
1939 for(var i=0;i<opts.length;i++){
1940 var opt=opts[i];
1941 if(!opt.selected){
1942 continue;
1943 }
1944 var v=opt.value;
1945 if(!v){
1946 var h=opt.outerHTML;
1947 if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
1948 v=opt.text;
1949 }
1950 }
1951 _230.push(name);
1952 _231.push(v);
1953 }
1954 return null;
1955 }
1956 }
1957 if(_236==="FORM"||_236==="P"||_236==="SPAN"||_236==="DIV"){
1958 return elem.childNodes;
1959 }
1960 _230.push(name);
1961 _231.push(elem.value||"");
1962 return null;
1963 }
1964 return elem.childNodes;
1965 });
1966 return [_230,_231];
1967 },withDocument:function(doc,func){
1968 var self=MochiKit.DOM;
1969 var _23f=self._document;
1970 var rval;
1971 try{
1972 self._document=doc;
1973 rval=func();
1974 }
1975 catch(e){
1976 self._document=_23f;
1977 throw e;
1978 }
1979 self._document=_23f;
1980 return rval;
1981 },registerDOMConverter:function(name,_242,wrap,_244){
1982 MochiKit.DOM.domConverters.register(name,_242,wrap,_244);
1983 },coerceToDOM:function(node,ctx){
1984 var m=MochiKit.Base;
1985 var im=MochiKit.Iter;
1986 var self=MochiKit.DOM;
1987 if(im){
1988 var iter=im.iter;
1989 var _24b=im.repeat;
1990 var map=m.map;
1991 }
1992 var _24d=self.domConverters;
1993 var _24e=arguments.callee;
1994 var _24f=m.NotFound;
1995 while(true){
1996 if(typeof (node)=="undefined"||node===null){
1997 return null;
1998 }
1999 if(typeof (node)=="function"&&typeof (node.length)=="number"&&!(node instanceof Function)){
2000 node=im.list(node);
2001 }
2002 if(typeof (node.nodeType)!="undefined"&&node.nodeType>0){
2003 return node;
2004 }
2005 if(typeof (node)=="number"||typeof (node)=="boolean"){
2006 node=node.toString();
2007 }
2008 if(typeof (node)=="string"){
2009 return self._document.createTextNode(node);
2010 }
2011 if(typeof (node.__dom__)=="function"){
2012 node=node.__dom__(ctx);
2013 continue;
2014 }
2015 if(typeof (node.dom)=="function"){
2016 node=node.dom(ctx);
2017 continue;
2018 }
2019 if(typeof (node)=="function"){
2020 node=node.apply(ctx,[ctx]);
2021 continue;
2022 }
2023 if(im){
2024 var _250=null;
2025 try{
2026 _250=iter(node);
2027 }
2028 catch(e){
2029 }
2030 if(_250){
2031 return map(_24e,_250,_24b(ctx));
2032 }
2033 }
2034 try{
2035 node=_24d.match(node,ctx);
2036 continue;
2037 }
2038 catch(e){
2039 if(e!=_24f){
2040 throw e;
2041 }
2042 }
2043 return self._document.createTextNode(node.toString());
2044 }
2045 return undefined;
2046 },isChildNode:function(node,_252){
2047 var self=MochiKit.DOM;
2048 if(typeof (node)=="string"){
2049 node=self.getElement(node);
2050 }
2051 if(typeof (_252)=="string"){
2052 _252=self.getElement(_252);
2053 }
2054 if(node===_252){
2055 return true;
2056 }
2057 while(node&&node.tagName.toUpperCase()!="BODY"){
2058 node=node.parentNode;
2059 if(node===_252){
2060 return true;
2061 }
2062 }
2063 return false;
2064 },setNodeAttribute:function(node,attr,_256){
2065 var o={};
2066 o[attr]=_256;
2067 try{
2068 return MochiKit.DOM.updateNodeAttributes(node,o);
2069 }
2070 catch(e){
2071 }
2072 return null;
2073 },getNodeAttribute:function(node,attr){
2074 var self=MochiKit.DOM;
2075 var _25b=self.attributeArray.renames[attr];
2076 node=self.getElement(node);
2077 try{
2078 if(_25b){
2079 return node[_25b];
2080 }
2081 return node.getAttribute(attr);
2082 }
2083 catch(e){
2084 }
2085 return null;
2086 },removeNodeAttribute:function(node,attr){
2087 var self=MochiKit.DOM;
2088 var _25f=self.attributeArray.renames[attr];
2089 node=self.getElement(node);
2090 try{
2091 if(_25f){
2092 return node[_25f];
2093 }
2094 return node.removeAttribute(attr);
2095 }
2096 catch(e){
2097 }
2098 return null;
2099 },updateNodeAttributes:function(node,_261){
2100 var elem=node;
2101 var self=MochiKit.DOM;
2102 if(typeof (node)=="string"){
2103 elem=self.getElement(node);
2104 }
2105 if(_261){
2106 var _264=MochiKit.Base.updatetree;
2107 if(self.attributeArray.compliant){
2108 for(var k in _261){
2109 var v=_261[k];
2110 if(typeof (v)=="object"&&typeof (elem[k])=="object"){
2111 if(k=="style"&&MochiKit.Style){
2112 MochiKit.Style.setStyle(elem,v);
2113 }else{
2114 _264(elem[k],v);
2115 }
2116 }else{
2117 if(k.substring(0,2)=="on"){
2118 if(typeof (v)=="string"){
2119 v=new Function(v);
2120 }
2121 elem[k]=v;
2122 }else{
2123 elem.setAttribute(k,v);
2124 }
2125 }
2126 }
2127 }else{
2128 var _267=self.attributeArray.renames;
2129 for(var k in _261){
2130 v=_261[k];
2131 var _268=_267[k];
2132 if(k=="style"&&typeof (v)=="string"){
2133 elem.style.cssText=v;
2134 }else{
2135 if(typeof (_268)=="string"){
2136 elem[_268]=v;
2137 }else{
2138 if(typeof (elem[k])=="object"&&typeof (v)=="object"){
2139 if(k=="style"&&MochiKit.Style){
2140 MochiKit.Style.setStyle(elem,v);
2141 }else{
2142 _264(elem[k],v);
2143 }
2144 }else{
2145 if(k.substring(0,2)=="on"){
2146 if(typeof (v)=="string"){
2147 v=new Function(v);
2148 }
2149 elem[k]=v;
2150 }else{
2151 elem.setAttribute(k,v);
2152 }
2153 }
2154 }
2155 }
2156 }
2157 }
2158 }
2159 return elem;
2160 },appendChildNodes:function(node){
2161 var elem=node;
2162 var self=MochiKit.DOM;
2163 if(typeof (node)=="string"){
2164 elem=self.getElement(node);
2165 }
2166 var _26c=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
2167 var _26d=MochiKit.Base.concat;
2168 while(_26c.length){
2169 var n=_26c.shift();
2170 if(typeof (n)=="undefined"||n===null){
2171 }else{
2172 if(typeof (n.nodeType)=="number"){
2173 elem.appendChild(n);
2174 }else{
2175 _26c=_26d(n,_26c);
2176 }
2177 }
2178 }
2179 return elem;
2180 },insertSiblingNodesBefore:function(node){
2181 var elem=node;
2182 var self=MochiKit.DOM;
2183 if(typeof (node)=="string"){
2184 elem=self.getElement(node);
2185 }
2186 var _272=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
2187 var _273=elem.parentNode;
2188 var _274=MochiKit.Base.concat;
2189 while(_272.length){
2190 var n=_272.shift();
2191 if(typeof (n)=="undefined"||n===null){
2192 }else{
2193 if(typeof (n.nodeType)=="number"){
2194 _273.insertBefore(n,elem);
2195 }else{
2196 _272=_274(n,_272);
2197 }
2198 }
2199 }
2200 return _273;
2201 },insertSiblingNodesAfter:function(node){
2202 var elem=node;
2203 var self=MochiKit.DOM;
2204 if(typeof (node)=="string"){
2205 elem=self.getElement(node);
2206 }
2207 var _279=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
2208 if(elem.nextSibling){
2209 return self.insertSiblingNodesBefore(elem.nextSibling,_279);
2210 }else{
2211 return self.appendChildNodes(elem.parentNode,_279);
2212 }
2213 },replaceChildNodes:function(node){
2214 var elem=node;
2215 var self=MochiKit.DOM;
2216 if(typeof (node)=="string"){
2217 elem=self.getElement(node);
2218 arguments[0]=elem;
2219 }
2220 var _27d;
2221 while((_27d=elem.firstChild)){
2222 elem.removeChild(_27d);
2223 }
2224 if(arguments.length<2){
2225 return elem;
2226 }else{
2227 return self.appendChildNodes.apply(this,arguments);
2228 }
2229 },createDOM:function(name,_27f){
2230 var elem;
2231 var self=MochiKit.DOM;
2232 var m=MochiKit.Base;
2233 if(typeof (_27f)=="string"||typeof (_27f)=="number"){
2234 var args=m.extend([name,null],arguments,1);
2235 return arguments.callee.apply(this,args);
2236 }
2237 if(typeof (name)=="string"){
2238 var _284=self._xhtml;
2239 if(_27f&&!self.attributeArray.compliant){
2240 var _285="";
2241 if("name" in _27f){
2242 _285+=" name=\""+self.escapeHTML(_27f.name)+"\"";
2243 }
2244 if(name=="input"&&"type" in _27f){
2245 _285+=" type=\""+self.escapeHTML(_27f.type)+"\"";
2246 }
2247 if(_285){
2248 name="<"+name+_285+">";
2249 _284=false;
2250 }
2251 }
2252 var d=self._document;
2253 if(_284&&d===document){
2254 elem=d.createElementNS("http://www.w3.org/1999/xhtml",name);
2255 }else{
2256 elem=d.createElement(name);
2257 }
2258 }else{
2259 elem=name;
2260 }
2261 if(_27f){
2262 self.updateNodeAttributes(elem,_27f);
2263 }
2264 if(arguments.length<=2){
2265 return elem;
2266 }else{
2267 var args=m.extend([elem],arguments,2);
2268 return self.appendChildNodes.apply(this,args);
2269 }
2270 },createDOMFunc:function(){
2271 var m=MochiKit.Base;
2272 return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments));
2273 },removeElement:function(elem){
2274 var e=MochiKit.DOM.getElement(elem);
2275 e.parentNode.removeChild(e);
2276 return e;
2277 },swapDOM:function(dest,src){
2278 var self=MochiKit.DOM;
2279 dest=self.getElement(dest);
2280 var _28d=dest.parentNode;
2281 if(src){
2282 src=self.getElement(src);
2283 _28d.replaceChild(src,dest);
2284 }else{
2285 _28d.removeChild(dest);
2286 }
2287 return src;
2288 },getElement:function(id){
2289 var self=MochiKit.DOM;
2290 if(arguments.length==1){
2291 return ((typeof (id)=="string")?self._document.getElementById(id):id);
2292 }else{
2293 return MochiKit.Base.map(self.getElement,arguments);
2294 }
2295 },getElementsByTagAndClassName:function(_290,_291,_292){
2296 var self=MochiKit.DOM;
2297 if(typeof (_290)=="undefined"||_290===null){
2298 _290="*";
2299 }
2300 if(typeof (_292)=="undefined"||_292===null){
2301 _292=self._document;
2302 }
2303 _292=self.getElement(_292);
2304 var _294=(_292.getElementsByTagName(_290)||self._document.all);
2305 if(typeof (_291)=="undefined"||_291===null){
2306 return MochiKit.Base.extend(null,_294);
2307 }
2308 var _295=[];
2309 for(var i=0;i<_294.length;i++){
2310 var _297=_294[i];
2311 var cls=_297.className;
2312 if(!cls){
2313 continue;
2314 }
2315 var _299=cls.split(" ");
2316 for(var j=0;j<_299.length;j++){
2317 if(_299[j]==_291){
2318 _295.push(_297);
2319 break;
2320 }
2321 }
2322 }
2323 return _295;
2324 },_newCallStack:function(path,once){
2325 var rval=function(){
2326 var _29e=arguments.callee.callStack;
2327 for(var i=0;i<_29e.length;i++){
2328 if(_29e[i].apply(this,arguments)===false){
2329 break;
2330 }
2331 }
2332 if(once){
2333 try{
2334 this[path]=null;
2335 }
2336 catch(e){
2337 }
2338 }
2339 };
2340 rval.callStack=[];
2341 return rval;
2342 },addToCallStack:function(_2a0,path,func,once){
2343 var self=MochiKit.DOM;
2344 var _2a5=_2a0[path];
2345 var _2a6=_2a5;
2346 if(!(typeof (_2a5)=="function"&&typeof (_2a5.callStack)=="object"&&_2a5.callStack!==null)){
2347 _2a6=self._newCallStack(path,once);
2348 if(typeof (_2a5)=="function"){
2349 _2a6.callStack.push(_2a5);
2350 }
2351 _2a0[path]=_2a6;
2352 }
2353 _2a6.callStack.push(func);
2354 },addLoadEvent:function(func){
2355 var self=MochiKit.DOM;
2356 self.addToCallStack(self._window,"onload",func,true);
2357 },focusOnLoad:function(_2a9){
2358 var self=MochiKit.DOM;
2359 self.addLoadEvent(function(){
2360 _2a9=self.getElement(_2a9);
2361 if(_2a9){
2362 _2a9.focus();
2363 }
2364 });
2365 },setElementClass:function(_2ab,_2ac){
2366 var self=MochiKit.DOM;
2367 var obj=self.getElement(_2ab);
2368 if(self.attributeArray.compliant){
2369 obj.setAttribute("class",_2ac);
2370 }else{
2371 obj.setAttribute("className",_2ac);
2372 }
2373 },toggleElementClass:function(_2af){
2374 var self=MochiKit.DOM;
2375 for(var i=1;i<arguments.length;i++){
2376 var obj=self.getElement(arguments[i]);
2377 if(!self.addElementClass(obj,_2af)){
2378 self.removeElementClass(obj,_2af);
2379 }
2380 }
2381 },addElementClass:function(_2b3,_2b4){
2382 var self=MochiKit.DOM;
2383 var obj=self.getElement(_2b3);
2384 var cls=obj.className;
2385 if(cls==undefined||cls.length===0){
2386 self.setElementClass(obj,_2b4);
2387 return true;
2388 }
2389 if(cls==_2b4){
2390 return false;
2391 }
2392 var _2b8=cls.split(" ");
2393 for(var i=0;i<_2b8.length;i++){
2394 if(_2b8[i]==_2b4){
2395 return false;
2396 }
2397 }
2398 self.setElementClass(obj,cls+" "+_2b4);
2399 return true;
2400 },removeElementClass:function(_2ba,_2bb){
2401 var self=MochiKit.DOM;
2402 var obj=self.getElement(_2ba);
2403 var cls=obj.className;
2404 if(cls==undefined||cls.length===0){
2405 return false;
2406 }
2407 if(cls==_2bb){
2408 self.setElementClass(obj,"");
2409 return true;
2410 }
2411 var _2bf=cls.split(" ");
2412 for(var i=0;i<_2bf.length;i++){
2413 if(_2bf[i]==_2bb){
2414 _2bf.splice(i,1);
2415 self.setElementClass(obj,_2bf.join(" "));
2416 return true;
2417 }
2418 }
2419 return false;
2420 },swapElementClass:function(_2c1,_2c2,_2c3){
2421 var obj=MochiKit.DOM.getElement(_2c1);
2422 var res=MochiKit.DOM.removeElementClass(obj,_2c2);
2423 if(res){
2424 MochiKit.DOM.addElementClass(obj,_2c3);
2425 }
2426 return res;
2427 },hasElementClass:function(_2c6,_2c7){
2428 var obj=MochiKit.DOM.getElement(_2c6);
2429 var cls=obj.className;
2430 if(!cls){
2431 return false;
2432 }
2433 var _2ca=cls.split(" ");
2434 for(var i=1;i<arguments.length;i++){
2435 var good=false;
2436 for(var j=0;j<_2ca.length;j++){
2437 if(_2ca[j]==arguments[i]){
2438 good=true;
2439 break;
2440 }
2441 }
2442 if(!good){
2443 return false;
2444 }
2445 }
2446 return true;
2447 },escapeHTML:function(s){
2448 return s.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
2449 },toHTML:function(dom){
2450 return MochiKit.DOM.emitHTML(dom).join("");
2451 },emitHTML:function(dom,lst){
2452 if(typeof (lst)=="undefined"||lst===null){
2453 lst=[];
2454 }
2455 var _2d2=[dom];
2456 var self=MochiKit.DOM;
2457 var _2d4=self.escapeHTML;
2458 var _2d5=self.attributeArray;
2459 while(_2d2.length){
2460 dom=_2d2.pop();
2461 if(typeof (dom)=="string"){
2462 lst.push(dom);
2463 }else{
2464 if(dom.nodeType==1){
2465 lst.push("<"+dom.tagName.toLowerCase());
2466 var _2d6=[];
2467 var _2d7=_2d5(dom);
2468 for(var i=0;i<_2d7.length;i++){
2469 var a=_2d7[i];
2470 _2d6.push([" ",a.name,"=\"",_2d4(a.value),"\""]);
2471 }
2472 _2d6.sort();
2473 for(i=0;i<_2d6.length;i++){
2474 var _2da=_2d6[i];
2475 for(var j=0;j<_2da.length;j++){
2476 lst.push(_2da[j]);
2477 }
2478 }
2479 if(dom.hasChildNodes()){
2480 lst.push(">");
2481 _2d2.push("</"+dom.tagName.toLowerCase()+">");
2482 var _2dc=dom.childNodes;
2483 for(i=_2dc.length-1;i>=0;i--){
2484 _2d2.push(_2dc[i]);
2485 }
2486 }else{
2487 lst.push("/>");
2488 }
2489 }else{
2490 if(dom.nodeType==3){
2491 lst.push(_2d4(dom.nodeValue));
2492 }
2493 }
2494 }
2495 }
2496 return lst;
2497 },scrapeText:function(node,_2de){
2498 var rval=[];
2499 (function(node){
2500 var cn=node.childNodes;
2501 if(cn){
2502 for(var i=0;i<cn.length;i++){
2503 arguments.callee.call(this,cn[i]);
2504 }
2505 }
2506 var _2e3=node.nodeValue;
2507 if(typeof (_2e3)=="string"){
2508 rval.push(_2e3);
2509 }
2510 })(MochiKit.DOM.getElement(node));
2511 if(_2de){
2512 return rval;
2513 }else{
2514 return rval.join("");
2515 }
2516 },removeEmptyTextNodes:function(_2e4){
2517 _2e4=MochiKit.DOM.getElement(_2e4);
2518 for(var i=0;i<_2e4.childNodes.length;i++){
2519 var node=_2e4.childNodes[i];
2520 if(node.nodeType==3&&!/\S/.test(node.nodeValue)){
2521 node.parentNode.removeChild(node);
2522 }
2523 }
2524 },makeClipping:function(_2e7){
2525 _2e7=MochiKit.DOM.getElement(_2e7);
2526 var _2e8=_2e7.style.overflow;
2527 if((MochiKit.Style.getStyle(_2e7,"overflow")||"visible")!="hidden"){
2528 _2e7.style.overflow="hidden";
2529 }
2530 return _2e8;
2531 },undoClipping:function(_2e9,_2ea){
2532 _2e9=MochiKit.DOM.getElement(_2e9);
2533 if(!_2ea){
2534 return;
2535 }
2536 _2e9.style.overflow=_2ea;
2537 },makePositioned:function(_2eb){
2538 _2eb=MochiKit.DOM.getElement(_2eb);
2539 var pos=MochiKit.Style.getStyle(_2eb,"position");
2540 if(pos=="static"||!pos){
2541 _2eb.style.position="relative";
2542 if(/Opera/.test(navigator.userAgent)){
2543 _2eb.style.top=0;
2544 _2eb.style.left=0;
2545 }
2546 }
2547 },undoPositioned:function(_2ed){
2548 _2ed=MochiKit.DOM.getElement(_2ed);
2549 if(_2ed.style.position=="relative"){
2550 _2ed.style.position=_2ed.style.top=_2ed.style.left=_2ed.style.bottom=_2ed.style.right="";
2551 }
2552 },getFirstElementByTagAndClassName:function(_2ee,_2ef,_2f0){
2553 var self=MochiKit.DOM;
2554 if(typeof (_2ee)=="undefined"||_2ee===null){
2555 _2ee="*";
2556 }
2557 if(typeof (_2f0)=="undefined"||_2f0===null){
2558 _2f0=self._document;
2559 }
2560 _2f0=self.getElement(_2f0);
2561 var _2f2=(_2f0.getElementsByTagName(_2ee)||self._document.all);
2562 if(typeof (_2ef)=="undefined"||_2ef===null){
2563 return _2f2[0];
2564 }
2565 for(var i=0;i<_2f2.length;i++){
2566 var _2f4=_2f2[i];
2567 var _2f5=_2f4.className.split(" ");
2568 for(var j=0;j<_2f5.length;j++){
2569 if(_2f5[j]==_2ef){
2570 return _2f4;
2571 }
2572 }
2573 }
2574 },getFirstParentByTagAndClassName:function(elem,_2f8,_2f9){
2575 var self=MochiKit.DOM;
2576 elem=self.getElement(elem);
2577 if(typeof (_2f8)=="undefined"||_2f8===null){
2578 _2f8="*";
2579 }else{
2580 _2f8=_2f8.toUpperCase();
2581 }
2582 if(typeof (_2f9)=="undefined"||_2f9===null){
2583 _2f9=null;
2584 }
2585 var _2fb="";
2586 var _2fc="";
2587 while(elem&&elem.tagName){
2588 elem=elem.parentNode;
2589 if(_2f8=="*"&&_2f9===null){
2590 return elem;
2591 }
2592 _2fb=elem.className.split(" ");
2593 _2fc=elem.tagName.toUpperCase();
2594 if(_2f9===null&&_2f8==_2fc){
2595 return elem;
2596 }else{
2597 if(_2f9!==null){
2598 for(var i=0;i<_2fb.length;i++){
2599 if(_2f8=="*"&&_2fb[i]==_2f9){
2600 return elem;
2601 }else{
2602 if(_2f8==_2fc&&_2fb[i]==_2f9){
2603 return elem;
2604 }
2605 }
2606 }
2607 }
2608 }
2609 }
2610 return elem;
2611 },isParent:function(_2fe,_2ff){
2612 if(!_2fe.parentNode||_2fe==_2ff){
2613 return false;
2614 }
2615 if(_2fe.parentNode==_2ff){
2616 return true;
2617 }
2618 return MochiKit.DOM.isParent(_2fe.parentNode,_2ff);
2619 },__new__:function(win){
2620 var m=MochiKit.Base;
2621 if(typeof (document)!="undefined"){
2622 this._document=document;
2623 var _302="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
2624 this._xhtml=(document.documentElement&&document.createElementNS&&document.documentElement.namespaceURI===_302);
2625 }else{
2626 if(MochiKit.MockDOM){
2627 this._document=MochiKit.MockDOM.document;
2628 }
2629 }
2630 this._window=win;
2631 this.domConverters=new m.AdapterRegistry();
2632 var _303=this._document.createElement("span");
2633 var _304;
2634 if(_303&&_303.attributes&&_303.attributes.length>0){
2635 var _305=m.filter;
2636 _304=function(node){
2637 return _305(_304.ignoreAttrFilter,node.attributes);
2638 };
2639 _304.ignoreAttr={};
2640 var _307=_303.attributes;
2641 var _308=_304.ignoreAttr;
2642 for(var i=0;i<_307.length;i++){
2643 var a=_307[i];
2644 _308[a.name]=a.value;
2645 }
2646 _304.ignoreAttrFilter=function(a){
2647 return (_304.ignoreAttr[a.name]!=a.value);
2648 };
2649 _304.compliant=false;
2650 _304.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor","cellspacing":"cellSpacing","cellpadding":"cellPadding"};
2651 }else{
2652 _304=function(node){
2653 return node.attributes;
2654 };
2655 _304.compliant=true;
2656 _304.renames={};
2657 }
2658 this.attributeArray=_304;
2659 var _30d=function(_30e,arr){
2660 var _310=arr[1].split(".");
2661 var str="";
2662 var obj={};
2663 str+="if (!MochiKit."+_310[1]+") { throw new Error(\"";
2664 str+="This function has been deprecated and depends on MochiKit.";
2665 str+=_310[1]+".\");}";
2666 str+="return MochiKit."+_310[1]+"."+arr[0];
2667 str+=".apply(this, arguments);";
2668 obj[_310[2]]=new Function(str);
2669 MochiKit.Base.update(MochiKit[_30e],obj);
2670 };
2671 for(var i;i<MochiKit.DOM.DEPRECATED.length;i++){
2672 _30d("DOM",MochiKit.DOM.DEPRECATED[i]);
2673 }
2674 var _313=this.createDOMFunc;
2675 this.UL=_313("ul");
2676 this.OL=_313("ol");
2677 this.LI=_313("li");
2678 this.TD=_313("td");
2679 this.TR=_313("tr");
2680 this.TBODY=_313("tbody");
2681 this.THEAD=_313("thead");
2682 this.TFOOT=_313("tfoot");
2683 this.TABLE=_313("table");
2684 this.TH=_313("th");
2685 this.INPUT=_313("input");
2686 this.SPAN=_313("span");
2687 this.A=_313("a");
2688 this.DIV=_313("div");
2689 this.IMG=_313("img");
2690 this.BUTTON=_313("button");
2691 this.TT=_313("tt");
2692 this.PRE=_313("pre");
2693 this.H1=_313("h1");
2694 this.H2=_313("h2");
2695 this.H3=_313("h3");
2696 this.BR=_313("br");
2697 this.HR=_313("hr");
2698 this.LABEL=_313("label");
2699 this.TEXTAREA=_313("textarea");
2700 this.FORM=_313("form");
2701 this.P=_313("p");
2702 this.SELECT=_313("select");
2703 this.OPTION=_313("option");
2704 this.OPTGROUP=_313("optgroup");
2705 this.LEGEND=_313("legend");
2706 this.FIELDSET=_313("fieldset");
2707 this.STRONG=_313("strong");
2708 this.CANVAS=_313("canvas");
2709 this.$=this.getElement;
2710 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
2711 m.nameFunctions(this);
2712 }});
2713 MochiKit.DOM.__new__(((typeof (window)=="undefined")?this:window));
2714 if(MochiKit.__export__){
2715 withWindow=MochiKit.DOM.withWindow;
2716 withDocument=MochiKit.DOM.withDocument;
2717 }
2718 MochiKit.Base._exportSymbols(this,MochiKit.DOM);
2719 if(typeof (dojo)!="undefined"){
2720 dojo.provide("MochiKit.Style");
2721 dojo.require("MochiKit.Base");
2722 dojo.require("MochiKit.DOM");
2723 }
2724 if(typeof (JSAN)!="undefined"){
2725 JSAN.use("MochiKit.Base",[]);
2726 JSAN.use("MochiKit.DOM",[]);
2727 }
2728 try{
2729 if(typeof (MochiKit.Base)=="undefined"){
2730 throw "";
2731 }
2732 }
2733 catch(e){
2734 throw "MochiKit.Style depends on MochiKit.Base!";
2735 }
2736 try{
2737 if(typeof (MochiKit.DOM)=="undefined"){
2738 throw "";
2739 }
2740 }
2741 catch(e){
2742 throw "MochiKit.Style depends on MochiKit.DOM!";
2743 }
2744 if(typeof (MochiKit.Style)=="undefined"){
2745 MochiKit.Style={};
2746 }
2747 MochiKit.Style.NAME="MochiKit.Style";
2748 MochiKit.Style.VERSION="1.4";
2749 MochiKit.Style.__repr__=function(){
2750 return "["+this.NAME+" "+this.VERSION+"]";
2751 };
2752 MochiKit.Style.toString=function(){
2753 return this.__repr__();
2754 };
2755 MochiKit.Style.EXPORT_OK=[];
2756 MochiKit.Style.EXPORT=["setStyle","setOpacity","getStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
2757 MochiKit.Style.Dimensions=function(w,h){
2758 this.w=w;
2759 this.h=h;
2760 };
2761 MochiKit.Style.Dimensions.prototype.__repr__=function(){
2762 var repr=MochiKit.Base.repr;
2763 return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}";
2764 };
2765 MochiKit.Style.Dimensions.prototype.toString=function(){
2766 return this.__repr__();
2767 };
2768 MochiKit.Style.Coordinates=function(x,y){
2769 this.x=x;
2770 this.y=y;
2771 };
2772 MochiKit.Style.Coordinates.prototype.__repr__=function(){
2773 var repr=MochiKit.Base.repr;
2774 return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}";
2775 };
2776 MochiKit.Style.Coordinates.prototype.toString=function(){
2777 return this.__repr__();
2778 };
2779 MochiKit.Base.update(MochiKit.Style,{getStyle:function(elem,_31b){
2780 var dom=MochiKit.DOM;
2781 var d=dom._document;
2782 elem=dom.getElement(elem);
2783 _31b=MochiKit.Base.camelize(_31b);
2784 if(!elem||elem==d){
2785 return undefined;
2786 }
2787 if(_31b=="opacity"&&elem.filters){
2788 var _31e=(MochiKit.Style.getStyle(elem,"filter")||"").match(/alpha\(opacity=(.*)\)/);
2789 if(_31e&&_31e[1]){
2790 return parseFloat(_31e[1])/100;
2791 }
2792 return 1;
2793 }
2794 var _31f=elem.style?elem.style[_31b]:null;
2795 if(!_31f){
2796 if(d.defaultView&&d.defaultView.getComputedStyle){
2797 var css=d.defaultView.getComputedStyle(elem,null);
2798 _31b=_31b.replace(/([A-Z])/g,"-$1").toLowerCase();
2799 _31f=css?css.getPropertyValue(_31b):null;
2800 }else{
2801 if(elem.currentStyle){
2802 _31f=elem.currentStyle[_31b];
2803 }
2804 }
2805 }
2806 if(_31b=="opacity"){
2807 _31f=parseFloat(_31f);
2808 }
2809 if(/Opera/.test(navigator.userAgent)&&(MochiKit.Base.find(["left","top","right","bottom"],_31b)!=-1)){
2810 if(MochiKit.Style.getStyle(elem,"position")=="static"){
2811 _31f="auto";
2812 }
2813 }
2814 return _31f=="auto"?null:_31f;
2815 },setStyle:function(elem,_322){
2816 elem=MochiKit.DOM.getElement(elem);
2817 for(var name in _322){
2818 if(name=="opacity"){
2819 MochiKit.Style.setOpacity(elem,_322[name]);
2820 }else{
2821 elem.style[MochiKit.Base.camelize(name)]=_322[name];
2822 }
2823 }
2824 },setOpacity:function(elem,o){
2825 elem=MochiKit.DOM.getElement(elem);
2826 var self=MochiKit.Style;
2827 if(o==1){
2828 var _327=/Gecko/.test(navigator.userAgent)&&!(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
2829 elem.style["opacity"]=_327?0.999999:1;
2830 if(/MSIE/.test(navigator.userAgent)){
2831 elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"");
2832 }
2833 }else{
2834 if(o<0.00001){
2835 o=0;
2836 }
2837 elem.style["opacity"]=o;
2838 if(/MSIE/.test(navigator.userAgent)){
2839 elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o*100+")";
2840 }
2841 }
2842 },getElementPosition:function(elem,_329){
2843 var self=MochiKit.Style;
2844 var dom=MochiKit.DOM;
2845 elem=dom.getElement(elem);
2846 if(!elem||(!(elem.x&&elem.y)&&(!elem.parentNode===null||self.getStyle(elem,"display")=="none"))){
2847 return undefined;
2848 }
2849 var c=new self.Coordinates(0,0);
2850 var box=null;
2851 var _32e=null;
2852 var d=MochiKit.DOM._document;
2853 var de=d.documentElement;
2854 var b=d.body;
2855 if(!elem.parentNode&&elem.x&&elem.y){
2856 c.x+=elem.x||0;
2857 c.y+=elem.y||0;
2858 }else{
2859 if(elem.getBoundingClientRect){
2860 box=elem.getBoundingClientRect();
2861 c.x+=box.left+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
2862 c.y+=box.top+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
2863 }else{
2864 if(elem.offsetParent){
2865 c.x+=elem.offsetLeft;
2866 c.y+=elem.offsetTop;
2867 _32e=elem.offsetParent;
2868 if(_32e!=elem){
2869 while(_32e){
2870 c.x+=_32e.offsetLeft;
2871 c.y+=_32e.offsetTop;
2872 _32e=_32e.offsetParent;
2873 }
2874 }
2875 var ua=navigator.userAgent.toLowerCase();
2876 if((typeof (opera)!="undefined"&&parseFloat(opera.version())<9)||(ua.indexOf("AppleWebKit")!=-1&&self.getStyle(elem,"position")=="absolute")){
2877 c.x-=b.offsetLeft;
2878 c.y-=b.offsetTop;
2879 }
2880 }
2881 }
2882 }
2883 if(typeof (_329)!="undefined"){
2884 _329=arguments.callee(_329);
2885 if(_329){
2886 c.x-=(_329.x||0);
2887 c.y-=(_329.y||0);
2888 }
2889 }
2890 if(elem.parentNode){
2891 _32e=elem.parentNode;
2892 }else{
2893 _32e=null;
2894 }
2895 while(_32e){
2896 var _333=_32e.tagName.toUpperCase();
2897 if(_333==="BODY"||_333==="HTML"){
2898 break;
2899 }
2900 var disp=self.getStyle(_32e,"display");
2901 if(disp!="inline"&&disp!="table-row"){
2902 c.x-=_32e.scrollLeft;
2903 c.y-=_32e.scrollTop;
2904 }
2905 if(_32e.parentNode){
2906 _32e=_32e.parentNode;
2907 }else{
2908 _32e=null;
2909 }
2910 }
2911 return c;
2912 },setElementPosition:function(elem,_336,_337){
2913 elem=MochiKit.DOM.getElement(elem);
2914 if(typeof (_337)=="undefined"){
2915 _337="px";
2916 }
2917 var _338={};
2918 var _339=MochiKit.Base.isUndefinedOrNull;
2919 if(!_339(_336.x)){
2920 _338["left"]=_336.x+_337;
2921 }
2922 if(!_339(_336.y)){
2923 _338["top"]=_336.y+_337;
2924 }
2925 MochiKit.DOM.updateNodeAttributes(elem,{"style":_338});
2926 },getElementDimensions:function(elem){
2927 var self=MochiKit.Style;
2928 var dom=MochiKit.DOM;
2929 if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){
2930 return new self.Dimensions(elem.w||0,elem.h||0);
2931 }
2932 elem=dom.getElement(elem);
2933 if(!elem){
2934 return undefined;
2935 }
2936 var disp=self.getStyle(elem,"display");
2937 if(disp!="none"&&disp!==""&&typeof (disp)!="undefined"){
2938 return new self.Dimensions(elem.offsetWidth||0,elem.offsetHeight||0);
2939 }
2940 var s=elem.style;
2941 var _33f=s.visibility;
2942 var _340=s.position;
2943 s.visibility="hidden";
2944 s.position="absolute";
2945 s.display="";
2946 var _341=elem.offsetWidth;
2947 var _342=elem.offsetHeight;
2948 s.display="none";
2949 s.position=_340;
2950 s.visibility=_33f;
2951 return new self.Dimensions(_341,_342);
2952 },setElementDimensions:function(elem,_344,_345){
2953 elem=MochiKit.DOM.getElement(elem);
2954 if(typeof (_345)=="undefined"){
2955 _345="px";
2956 }
2957 var _346={};
2958 var _347=MochiKit.Base.isUndefinedOrNull;
2959 if(!_347(_344.w)){
2960 _346["width"]=_344.w+_345;
2961 }
2962 if(!_347(_344.h)){
2963 _346["height"]=_344.h+_345;
2964 }
2965 MochiKit.DOM.updateNodeAttributes(elem,{"style":_346});
2966 },setDisplayForElement:function(_348,_349){
2967 var _34a=MochiKit.Base.extend(null,arguments,1);
2968 var _34b=MochiKit.DOM.getElement;
2969 for(var i=0;i<_34a.length;i++){
2970 _349=_34b(_34a[i]);
2971 if(_349){
2972 _349.style.display=_348;
2973 }
2974 }
2975 },getViewportDimensions:function(){
2976 var d=new MochiKit.Style.Dimensions();
2977 var w=MochiKit.DOM._window;
2978 var b=MochiKit.DOM._document.body;
2979 if(w.innerWidth){
2980 d.w=w.innerWidth;
2981 d.h=w.innerHeight;
2982 }else{
2983 if(b.parentElement.clientWidth){
2984 d.w=b.parentElement.clientWidth;
2985 d.h=b.parentElement.clientHeight;
2986 }else{
2987 if(b&&b.clientWidth){
2988 d.w=b.clientWidth;
2989 d.h=b.clientHeight;
2990 }
2991 }
2992 }
2993 return d;
2994 },getViewportPosition:function(){
2995 var c=new MochiKit.Style.Coordinates(0,0);
2996 var d=MochiKit.DOM._document;
2997 var de=d.documentElement;
2998 var db=d.body;
2999 if(de&&(de.scrollTop||de.scrollLeft)){
3000 c.x=de.scrollLeft;
3001 c.y=de.scrollTop;
3002 }else{
3003 if(db){
3004 c.x=db.scrollLeft;
3005 c.y=db.scrollTop;
3006 }
3007 }
3008 return c;
3009 },__new__:function(){
3010 var m=MochiKit.Base;
3011 this.elementPosition=this.getElementPosition;
3012 this.elementDimensions=this.getElementDimensions;
3013 this.hideElement=m.partial(this.setDisplayForElement,"none");
3014 this.showElement=m.partial(this.setDisplayForElement,"block");
3015 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
3016 m.nameFunctions(this);
3017 }});
3018 MochiKit.Style.__new__();
3019 MochiKit.Base._exportSymbols(this,MochiKit.Style);
3020 if(typeof (dojo)!="undefined"){
3021 dojo.provide("MochiKit.Color");
3022 dojo.require("MochiKit.Base");
3023 dojo.require("MochiKit.DOM");
3024 dojo.require("MochiKit.Style");
3025 }
3026 if(typeof (JSAN)!="undefined"){
3027 JSAN.use("MochiKit.Base",[]);
3028 JSAN.use("MochiKit.DOM",[]);
3029 JSAN.use("MochiKit.Style",[]);
3030 }
3031 try{
3032 if(typeof (MochiKit.Base)=="undefined"){
3033 throw "";
3034 }
3035 }
3036 catch(e){
3037 throw "MochiKit.Color depends on MochiKit.Base";
3038 }
3039 try{
3040 if(typeof (MochiKit.DOM)=="undefined"){
3041 throw "";
3042 }
3043 }
3044 catch(e){
3045 throw "MochiKit.Color depends on MochiKit.DOM";
3046 }
3047 try{
3048 if(typeof (MochiKit.Style)=="undefined"){
3049 throw "";
3050 }
3051 }
3052 catch(e){
3053 throw "MochiKit.Color depends on MochiKit.Style";
3054 }
3055 if(typeof (MochiKit.Color)=="undefined"){
3056 MochiKit.Color={};
3057 }
3058 MochiKit.Color.NAME="MochiKit.Color";
3059 MochiKit.Color.VERSION="1.4";
3060 MochiKit.Color.__repr__=function(){
3061 return "["+this.NAME+" "+this.VERSION+"]";
3062 };
3063 MochiKit.Color.toString=function(){
3064 return this.__repr__();
3065 };
3066 MochiKit.Color.Color=function(red,_356,blue,_358){
3067 if(typeof (_358)=="undefined"||_358===null){
3068 _358=1;
3069 }
3070 this.rgb={r:red,g:_356,b:blue,a:_358};
3071 };
3072 MochiKit.Color.Color.prototype={__class__:MochiKit.Color.Color,colorWithAlpha:function(_359){
3073 var rgb=this.rgb;
3074 var m=MochiKit.Color;
3075 return m.Color.fromRGB(rgb.r,rgb.g,rgb.b,_359);
3076 },colorWithHue:function(hue){
3077 var hsl=this.asHSL();
3078 hsl.h=hue;
3079 var m=MochiKit.Color;
3080 return m.Color.fromHSL(hsl);
3081 },colorWithSaturation:function(_35f){
3082 var hsl=this.asHSL();
3083 hsl.s=_35f;
3084 var m=MochiKit.Color;
3085 return m.Color.fromHSL(hsl);
3086 },colorWithLightness:function(_362){
3087 var hsl=this.asHSL();
3088 hsl.l=_362;
3089 var m=MochiKit.Color;
3090 return m.Color.fromHSL(hsl);
3091 },darkerColorWithLevel:function(_365){
3092 var hsl=this.asHSL();
3093 hsl.l=Math.max(hsl.l-_365,0);
3094 var m=MochiKit.Color;
3095 return m.Color.fromHSL(hsl);
3096 },lighterColorWithLevel:function(_368){
3097 var hsl=this.asHSL();
3098 hsl.l=Math.min(hsl.l+_368,1);
3099 var m=MochiKit.Color;
3100 return m.Color.fromHSL(hsl);
3101 },blendedColor:function(_36b,_36c){
3102 if(typeof (_36c)=="undefined"||_36c===null){
3103 _36c=0.5;
3104 }
3105 var sf=1-_36c;
3106 var s=this.rgb;
3107 var d=_36b.rgb;
3108 var df=_36c;
3109 return MochiKit.Color.Color.fromRGB((s.r*sf)+(d.r*df),(s.g*sf)+(d.g*df),(s.b*sf)+(d.b*df),(s.a*sf)+(d.a*df));
3110 },compareRGB:function(_371){
3111 var a=this.asRGB();
3112 var b=_371.asRGB();
3113 return MochiKit.Base.compare([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a]);
3114 },isLight:function(){
3115 return this.asHSL().b>0.5;
3116 },isDark:function(){
3117 return (!this.isLight());
3118 },toHSLString:function(){
3119 var c=this.asHSL();
3120 var ccc=MochiKit.Color.clampColorComponent;
3121 var rval=this._hslString;
3122 if(!rval){
3123 var mid=(ccc(c.h,360).toFixed(0)+","+ccc(c.s,100).toPrecision(4)+"%"+","+ccc(c.l,100).toPrecision(4)+"%");
3124 var a=c.a;
3125 if(a>=1){
3126 a=1;
3127 rval="hsl("+mid+")";
3128 }else{
3129 if(a<=0){
3130 a=0;
3131 }
3132 rval="hsla("+mid+","+a+")";
3133 }
3134 this._hslString=rval;
3135 }
3136 return rval;
3137 },toRGBString:function(){
3138 var c=this.rgb;
3139 var ccc=MochiKit.Color.clampColorComponent;
3140 var rval=this._rgbString;
3141 if(!rval){
3142 var mid=(ccc(c.r,255).toFixed(0)+","+ccc(c.g,255).toFixed(0)+","+ccc(c.b,255).toFixed(0));
3143 if(c.a!=1){
3144 rval="rgba("+mid+","+c.a+")";
3145 }else{
3146 rval="rgb("+mid+")";
3147 }
3148 this._rgbString=rval;
3149 }
3150 return rval;
3151 },asRGB:function(){
3152 return MochiKit.Base.clone(this.rgb);
3153 },toHexString:function(){
3154 var m=MochiKit.Color;
3155 var c=this.rgb;
3156 var ccc=MochiKit.Color.clampColorComponent;
3157 var rval=this._hexString;
3158 if(!rval){
3159 rval=("#"+m.toColorPart(ccc(c.r,255))+m.toColorPart(ccc(c.g,255))+m.toColorPart(ccc(c.b,255)));
3160 this._hexString=rval;
3161 }
3162 return rval;
3163 },asHSV:function(){
3164 var hsv=this.hsv;
3165 var c=this.rgb;
3166 if(typeof (hsv)=="undefined"||hsv===null){
3167 hsv=MochiKit.Color.rgbToHSV(this.rgb);
3168 this.hsv=hsv;
3169 }
3170 return MochiKit.Base.clone(hsv);
3171 },asHSL:function(){
3172 var hsl=this.hsl;
3173 var c=this.rgb;
3174 if(typeof (hsl)=="undefined"||hsl===null){
3175 hsl=MochiKit.Color.rgbToHSL(this.rgb);
3176 this.hsl=hsl;
3177 }
3178 return MochiKit.Base.clone(hsl);
3179 },toString:function(){
3180 return this.toRGBString();
3181 },repr:function(){
3182 var c=this.rgb;
3183 var col=[c.r,c.g,c.b,c.a];
3184 return this.__class__.NAME+"("+col.join(", ")+")";
3185 }};
3186 MochiKit.Base.update(MochiKit.Color.Color,{fromRGB:function(red,_388,blue,_38a){
3187 var _38b=MochiKit.Color.Color;
3188 if(arguments.length==1){
3189 var rgb=red;
3190 red=rgb.r;
3191 _388=rgb.g;
3192 blue=rgb.b;
3193 if(typeof (rgb.a)=="undefined"){
3194 _38a=undefined;
3195 }else{
3196 _38a=rgb.a;
3197 }
3198 }
3199 return new _38b(red,_388,blue,_38a);
3200 },fromHSL:function(hue,_38e,_38f,_390){
3201 var m=MochiKit.Color;
3202 return m.Color.fromRGB(m.hslToRGB.apply(m,arguments));
3203 },fromHSV:function(hue,_393,_394,_395){
3204 var m=MochiKit.Color;
3205 return m.Color.fromRGB(m.hsvToRGB.apply(m,arguments));
3206 },fromName:function(name){
3207 var _398=MochiKit.Color.Color;
3208 if(name.charAt(0)=="\""){
3209 name=name.substr(1,name.length-2);
3210 }
3211 var _399=_398._namedColors[name.toLowerCase()];
3212 if(typeof (_399)=="string"){
3213 return _398.fromHexString(_399);
3214 }else{
3215 if(name=="transparent"){
3216 return _398.transparentColor();
3217 }
3218 }
3219 return null;
3220 },fromString:function(_39a){
3221 var self=MochiKit.Color.Color;
3222 var _39c=_39a.substr(0,3);
3223 if(_39c=="rgb"){
3224 return self.fromRGBString(_39a);
3225 }else{
3226 if(_39c=="hsl"){
3227 return self.fromHSLString(_39a);
3228 }else{
3229 if(_39a.charAt(0)=="#"){
3230 return self.fromHexString(_39a);
3231 }
3232 }
3233 }
3234 return self.fromName(_39a);
3235 },fromHexString:function(_39d){
3236 if(_39d.charAt(0)=="#"){
3237 _39d=_39d.substring(1);
3238 }
3239 var _39e=[];
3240 var i,hex;
3241 if(_39d.length==3){
3242 for(i=0;i<3;i++){
3243 hex=_39d.substr(i,1);
3244 _39e.push(parseInt(hex+hex,16)/255);
3245 }
3246 }else{
3247 for(i=0;i<6;i+=2){
3248 hex=_39d.substr(i,2);
3249 _39e.push(parseInt(hex,16)/255);
3250 }
3251 }
3252 var _3a1=MochiKit.Color.Color;
3253 return _3a1.fromRGB.apply(_3a1,_39e);
3254 },_fromColorString:function(pre,_3a3,_3a4,_3a5){
3255 if(_3a5.indexOf(pre)===0){
3256 _3a5=_3a5.substring(_3a5.indexOf("(",3)+1,_3a5.length-1);
3257 }
3258 var _3a6=_3a5.split(/\s*,\s*/);
3259 var _3a7=[];
3260 for(var i=0;i<_3a6.length;i++){
3261 var c=_3a6[i];
3262 var val;
3263 var _3ab=c.substring(c.length-3);
3264 if(c.charAt(c.length-1)=="%"){
3265 val=0.01*parseFloat(c.substring(0,c.length-1));
3266 }else{
3267 if(_3ab=="deg"){
3268 val=parseFloat(c)/360;
3269 }else{
3270 if(_3ab=="rad"){
3271 val=parseFloat(c)/(Math.PI*2);
3272 }else{
3273 val=_3a4[i]*parseFloat(c);
3274 }
3275 }
3276 }
3277 _3a7.push(val);
3278 }
3279 return this[_3a3].apply(this,_3a7);
3280 },fromComputedStyle:function(elem,_3ad){
3281 var d=MochiKit.DOM;
3282 var cls=MochiKit.Color.Color;
3283 for(elem=d.getElement(elem);elem;elem=elem.parentNode){
3284 var _3b0=MochiKit.Style.getStyle.apply(d,arguments);
3285 if(!_3b0){
3286 continue;
3287 }
3288 var _3b1=cls.fromString(_3b0);
3289 if(!_3b1){
3290 break;
3291 }
3292 if(_3b1.asRGB().a>0){
3293 return _3b1;
3294 }
3295 }
3296 return null;
3297 },fromBackground:function(elem){
3298 var cls=MochiKit.Color.Color;
3299 return cls.fromComputedStyle(elem,"backgroundColor","background-color")||cls.whiteColor();
3300 },fromText:function(elem){
3301 var cls=MochiKit.Color.Color;
3302 return cls.fromComputedStyle(elem,"color","color")||cls.blackColor();
3303 },namedColors:function(){
3304 return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
3305 }});
3306 MochiKit.Base.update(MochiKit.Color,{clampColorComponent:function(v,_3b7){
3307 v*=_3b7;
3308 if(v<0){
3309 return 0;
3310 }else{
3311 if(v>_3b7){
3312 return _3b7;
3313 }else{
3314 return v;
3315 }
3316 }
3317 },_hslValue:function(n1,n2,hue){
3318 if(hue>6){
3319 hue-=6;
3320 }else{
3321 if(hue<0){
3322 hue+=6;
3323 }
3324 }
3325 var val;
3326 if(hue<1){
3327 val=n1+(n2-n1)*hue;
3328 }else{
3329 if(hue<3){
3330 val=n2;
3331 }else{
3332 if(hue<4){
3333 val=n1+(n2-n1)*(4-hue);
3334 }else{
3335 val=n1;
3336 }
3337 }
3338 }
3339 return val;
3340 },hsvToRGB:function(hue,_3bd,_3be,_3bf){
3341 if(arguments.length==1){
3342 var hsv=hue;
3343 hue=hsv.h;
3344 _3bd=hsv.s;
3345 _3be=hsv.v;
3346 _3bf=hsv.a;
3347 }
3348 var red;
3349 var _3c2;
3350 var blue;
3351 if(_3bd===0){
3352 red=_3be;
3353 _3c2=_3be;
3354 blue=_3be;
3355 }else{
3356 var i=Math.floor(hue*6);
3357 var f=(hue*6)-i;
3358 var p=_3be*(1-_3bd);
3359 var q=_3be*(1-(_3bd*f));
3360 var t=_3be*(1-(_3bd*(1-f)));
3361 switch(i){
3362 case 1:
3363 red=q;
3364 _3c2=_3be;
3365 blue=p;
3366 break;
3367 case 2:
3368 red=p;
3369 _3c2=_3be;
3370 blue=t;
3371 break;
3372 case 3:
3373 red=p;
3374 _3c2=q;
3375 blue=_3be;
3376 break;
3377 case 4:
3378 red=t;
3379 _3c2=p;
3380 blue=_3be;
3381 break;
3382 case 5:
3383 red=_3be;
3384 _3c2=p;
3385 blue=q;
3386 break;
3387 case 6:
3388 case 0:
3389 red=_3be;
3390 _3c2=t;
3391 blue=p;
3392 break;
3393 }
3394 }
3395 return {r:red,g:_3c2,b:blue,a:_3bf};
3396 },hslToRGB:function(hue,_3ca,_3cb,_3cc){
3397 if(arguments.length==1){
3398 var hsl=hue;
3399 hue=hsl.h;
3400 _3ca=hsl.s;
3401 _3cb=hsl.l;
3402 _3cc=hsl.a;
3403 }
3404 var red;
3405 var _3cf;
3406 var blue;
3407 if(_3ca===0){
3408 red=_3cb;
3409 _3cf=_3cb;
3410 blue=_3cb;
3411 }else{
3412 var m2;
3413 if(_3cb<=0.5){
3414 m2=_3cb*(1+_3ca);
3415 }else{
3416 m2=_3cb+_3ca-(_3cb*_3ca);
3417 }
3418 var m1=(2*_3cb)-m2;
3419 var f=MochiKit.Color._hslValue;
3420 var h6=hue*6;
3421 red=f(m1,m2,h6+2);
3422 _3cf=f(m1,m2,h6);
3423 blue=f(m1,m2,h6-2);
3424 }
3425 return {r:red,g:_3cf,b:blue,a:_3cc};
3426 },rgbToHSV:function(red,_3d6,blue,_3d8){
3427 if(arguments.length==1){
3428 var rgb=red;
3429 red=rgb.r;
3430 _3d6=rgb.g;
3431 blue=rgb.b;
3432 _3d8=rgb.a;
3433 }
3434 var max=Math.max(Math.max(red,_3d6),blue);
3435 var min=Math.min(Math.min(red,_3d6),blue);
3436 var hue;
3437 var _3dd;
3438 var _3de=max;
3439 if(min==max){
3440 hue=0;
3441 _3dd=0;
3442 }else{
3443 var _3df=(max-min);
3444 _3dd=_3df/max;
3445 if(red==max){
3446 hue=(_3d6-blue)/_3df;
3447 }else{
3448 if(_3d6==max){
3449 hue=2+((blue-red)/_3df);
3450 }else{
3451 hue=4+((red-_3d6)/_3df);
3452 }
3453 }
3454 hue/=6;
3455 if(hue<0){
3456 hue+=1;
3457 }
3458 if(hue>1){
3459 hue-=1;
3460 }
3461 }
3462 return {h:hue,s:_3dd,v:_3de,a:_3d8};
3463 },rgbToHSL:function(red,_3e1,blue,_3e3){
3464 if(arguments.length==1){
3465 var rgb=red;
3466 red=rgb.r;
3467 _3e1=rgb.g;
3468 blue=rgb.b;
3469 _3e3=rgb.a;
3470 }
3471 var max=Math.max(red,Math.max(_3e1,blue));
3472 var min=Math.min(red,Math.min(_3e1,blue));
3473 var hue;
3474 var _3e8;
3475 var _3e9=(max+min)/2;
3476 var _3ea=max-min;
3477 if(_3ea===0){
3478 hue=0;
3479 _3e8=0;
3480 }else{
3481 if(_3e9<=0.5){
3482 _3e8=_3ea/(max+min);
3483 }else{
3484 _3e8=_3ea/(2-max-min);
3485 }
3486 if(red==max){
3487 hue=(_3e1-blue)/_3ea;
3488 }else{
3489 if(_3e1==max){
3490 hue=2+((blue-red)/_3ea);
3491 }else{
3492 hue=4+((red-_3e1)/_3ea);
3493 }
3494 }
3495 hue/=6;
3496 if(hue<0){
3497 hue+=1;
3498 }
3499 if(hue>1){
3500 hue-=1;
3501 }
3502 }
3503 return {h:hue,s:_3e8,l:_3e9,a:_3e3};
3504 },toColorPart:function(num){
3505 num=Math.round(num);
3506 var _3ec=num.toString(16);
3507 if(num<16){
3508 return "0"+_3ec;
3509 }
3510 return _3ec;
3511 },__new__:function(){
3512 var m=MochiKit.Base;
3513 this.Color.fromRGBString=m.bind(this.Color._fromColorString,this.Color,"rgb","fromRGB",[1/255,1/255,1/255,1]);
3514 this.Color.fromHSLString=m.bind(this.Color._fromColorString,this.Color,"hsl","fromHSL",[1/360,0.01,0.01,1]);
3515 var _3ee=1/3;
3516 var _3ef={black:[0,0,0],blue:[0,0,1],brown:[0.6,0.4,0.2],cyan:[0,1,1],darkGray:[_3ee,_3ee,_3ee],gray:[0.5,0.5,0.5],green:[0,1,0],lightGray:[2*_3ee,2*_3ee,2*_3ee],magenta:[1,0,1],orange:[1,0.5,0],purple:[0.5,0,0.5],red:[1,0,0],transparent:[0,0,0,0],white:[1,1,1],yellow:[1,1,0]};
3517 var _3f0=function(name,r,g,b,a){
3518 var rval=this.fromRGB(r,g,b,a);
3519 this[name]=function(){
3520 return rval;
3521 };
3522 return rval;
3523 };
3524 for(var k in _3ef){
3525 var name=k+"Color";
3526 var _3f9=m.concat([_3f0,this.Color,name],_3ef[k]);
3527 this.Color[name]=m.bind.apply(null,_3f9);
3528 }
3529 var _3fa=function(){
3530 for(var i=0;i<arguments.length;i++){
3531 if(!(arguments[i] instanceof Color)){
3532 return false;
3533 }
3534 }
3535 return true;
3536 };
3537 var _3fc=function(a,b){
3538 return a.compareRGB(b);
3539 };
3540 m.nameFunctions(this);
3541 m.registerComparator(this.Color.NAME,_3fa,_3fc);
3542 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
3543 }});
3544 MochiKit.Color.EXPORT=["Color"];
3545 MochiKit.Color.EXPORT_OK=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
3546 MochiKit.Color.__new__();
3547 MochiKit.Base._exportSymbols(this,MochiKit.Color);
3548 MochiKit.Color.Color._namedColors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};
3549 if(typeof (dojo)!="undefined"){
3550 dojo.provide("MochiKit.Signal");
3551 dojo.require("MochiKit.Base");
3552 dojo.require("MochiKit.DOM");
3553 dojo.require("MochiKit.Style");
3554 }
3555 if(typeof (JSAN)!="undefined"){
3556 JSAN.use("MochiKit.Base",[]);
3557 JSAN.use("MochiKit.DOM",[]);
3558 JSAN.use("MochiKit.Style",[]);
3559 }
3560 try{
3561 if(typeof (MochiKit.Base)=="undefined"){
3562 throw "";
3563 }
3564 }
3565 catch(e){
3566 throw "MochiKit.Signal depends on MochiKit.Base!";
3567 }
3568 try{
3569 if(typeof (MochiKit.DOM)=="undefined"){
3570 throw "";
3571 }
3572 }
3573 catch(e){
3574 throw "MochiKit.Signal depends on MochiKit.DOM!";
3575 }
3576 try{
3577 if(typeof (MochiKit.Style)=="undefined"){
3578 throw "";
3579 }
3580 }
3581 catch(e){
3582 throw "MochiKit.Signal depends on MochiKit.Style!";
3583 }
3584 if(typeof (MochiKit.Signal)=="undefined"){
3585 MochiKit.Signal={};
3586 }
3587 MochiKit.Signal.NAME="MochiKit.Signal";
3588 MochiKit.Signal.VERSION="1.4";
3589 MochiKit.Signal._observers=[];
3590 MochiKit.Signal.Event=function(src,e){
3591 this._event=e||window.event;
3592 this._src=src;
3593 };
3594 MochiKit.Base.update(MochiKit.Signal.Event.prototype,{__repr__:function(){
3595 var repr=MochiKit.Base.repr;
3596 var str="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target());
3597 if(this.type()&&this.type().indexOf("key")===0||this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu"){
3598 str+=", modifier(): "+"{alt: "+repr(this.modifier().alt)+", ctrl: "+repr(this.modifier().ctrl)+", meta: "+repr(this.modifier().meta)+", shift: "+repr(this.modifier().shift)+", any: "+repr(this.modifier().any)+"}";
3599 }
3600 if(this.type()&&this.type().indexOf("key")===0){
3601 str+=", key(): {code: "+repr(this.key().code)+", string: "+repr(this.key().string)+"}";
3602 }
3603 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3604 str+=", mouse(): {page: "+repr(this.mouse().page)+", client: "+repr(this.mouse().client);
3605 if(this.type()!="mousemove"){
3606 str+=", button: {left: "+repr(this.mouse().button.left)+", middle: "+repr(this.mouse().button.middle)+", right: "+repr(this.mouse().button.right)+"}}";
3607 }else{
3608 str+="}";
3609 }
3610 }
3611 if(this.type()=="mouseover"||this.type()=="mouseout"){
3612 str+=", relatedTarget(): "+repr(this.relatedTarget());
3613 }
3614 str+="}";
3615 return str;
3616 },toString:function(){
3617 return this.__repr__();
3618 },src:function(){
3619 return this._src;
3620 },event:function(){
3621 return this._event;
3622 },type:function(){
3623 return this._event.type||undefined;
3624 },target:function(){
3625 return this._event.target||this._event.srcElement;
3626 },_relatedTarget:null,relatedTarget:function(){
3627 if(this._relatedTarget!==null){
3628 return this._relatedTarget;
3629 }
3630 var elem=null;
3631 if(this.type()=="mouseover"){
3632 elem=(this._event.relatedTarget||this._event.fromElement);
3633 }else{
3634 if(this.type()=="mouseout"){
3635 elem=(this._event.relatedTarget||this._event.toElement);
3636 }
3637 }
3638 if(elem!==null){
3639 this._relatedTarget=elem;
3640 return elem;
3641 }
3642 return undefined;
3643 },_modifier:null,modifier:function(){
3644 if(this._modifier!==null){
3645 return this._modifier;
3646 }
3647 var m={};
3648 m.alt=this._event.altKey;
3649 m.ctrl=this._event.ctrlKey;
3650 m.meta=this._event.metaKey||false;
3651 m.shift=this._event.shiftKey;
3652 m.any=m.alt||m.ctrl||m.shift||m.meta;
3653 this._modifier=m;
3654 return m;
3655 },_key:null,key:function(){
3656 if(this._key!==null){
3657 return this._key;
3658 }
3659 var k={};
3660 if(this.type()&&this.type().indexOf("key")===0){
3661 if(this.type()=="keydown"||this.type()=="keyup"){
3662 k.code=this._event.keyCode;
3663 k.string=(MochiKit.Signal._specialKeys[k.code]||"KEY_UNKNOWN");
3664 this._key=k;
3665 return k;
3666 }else{
3667 if(this.type()=="keypress"){
3668 k.code=0;
3669 k.string="";
3670 if(typeof (this._event.charCode)!="undefined"&&this._event.charCode!==0&&!MochiKit.Signal._specialMacKeys[this._event.charCode]){
3671 k.code=this._event.charCode;
3672 k.string=String.fromCharCode(k.code);
3673 }else{
3674 if(this._event.keyCode&&typeof (this._event.charCode)=="undefined"){
3675 k.code=this._event.keyCode;
3676 k.string=String.fromCharCode(k.code);
3677 }
3678 }
3679 this._key=k;
3680 return k;
3681 }
3682 }
3683 }
3684 return undefined;
3685 },_mouse:null,mouse:function(){
3686 if(this._mouse!==null){
3687 return this._mouse;
3688 }
3689 var m={};
3690 var e=this._event;
3691 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3692 m.client=new MochiKit.Style.Coordinates(0,0);
3693 if(e.clientX||e.clientY){
3694 m.client.x=(!e.clientX||e.clientX<0)?0:e.clientX;
3695 m.client.y=(!e.clientY||e.clientY<0)?0:e.clientY;
3696 }
3697 m.page=new MochiKit.Style.Coordinates(0,0);
3698 if(e.pageX||e.pageY){
3699 m.page.x=(!e.pageX||e.pageX<0)?0:e.pageX;
3700 m.page.y=(!e.pageY||e.pageY<0)?0:e.pageY;
3701 }else{
3702 var de=MochiKit.DOM._document.documentElement;
3703 var b=MochiKit.DOM._document.body;
3704 m.page.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
3705 m.page.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
3706 }
3707 if(this.type()!="mousemove"){
3708 m.button={};
3709 m.button.left=false;
3710 m.button.right=false;
3711 m.button.middle=false;
3712 if(e.which){
3713 m.button.left=(e.which==1);
3714 m.button.middle=(e.which==2);
3715 m.button.right=(e.which==3);
3716 }else{
3717 m.button.left=!!(e.button&1);
3718 m.button.right=!!(e.button&2);
3719 m.button.middle=!!(e.button&4);
3720 }
3721 }
3722 this._mouse=m;
3723 return m;
3724 }
3725 return undefined;
3726 },stop:function(){
3727 this.stopPropagation();
3728 this.preventDefault();
3729 },stopPropagation:function(){
3730 if(this._event.stopPropagation){
3731 this._event.stopPropagation();
3732 }else{
3733 this._event.cancelBubble=true;
3734 }
3735 },preventDefault:function(){
3736 if(this._event.preventDefault){
3737 this._event.preventDefault();
3738 }else{
3739 if(this._confirmUnload===null){
3740 this._event.returnValue=false;
3741 }
3742 }
3743 },_confirmUnload:null,confirmUnload:function(msg){
3744 if(this.type()=="beforeunload"){
3745 this._confirmUnload=msg;
3746 this._event.returnValue=msg;
3747 }
3748 }});
3749 MochiKit.Signal._specialMacKeys={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
3750 (function(){
3751 var _40b=MochiKit.Signal._specialMacKeys;
3752 for(i=63236;i<=63242;i++){
3753 _40b[i]="KEY_F"+(i-63236+1);
3754 }
3755 })();
3756 MochiKit.Signal._specialKeys={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
3757 (function(){
3758 var _40c=MochiKit.Signal._specialKeys;
3759 for(var i=48;i<=57;i++){
3760 _40c[i]="KEY_"+(i-48);
3761 }
3762 for(i=65;i<=90;i++){
3763 _40c[i]="KEY_"+String.fromCharCode(i);
3764 }
3765 for(i=96;i<=105;i++){
3766 _40c[i]="KEY_NUM_PAD_"+(i-96);
3767 }
3768 for(i=112;i<=123;i++){
3769 _40c[i]="KEY_F"+(i-112+1);
3770 }
3771 })();
3772 MochiKit.Signal.Ident=function(_40e){
3773 this.source=_40e.source;
3774 this.signal=_40e.signal;
3775 this.listener=_40e.listener;
3776 this.isDOM=_40e.isDOM;
3777 this.objOrFunc=_40e.objOrFunc;
3778 this.funcOrStr=_40e.funcOrStr;
3779 this.connected=_40e.connected;
3780 };
3781 MochiKit.Signal.Ident.prototype={};
3782 MochiKit.Base.update(MochiKit.Signal,{__repr__:function(){
3783 return "["+this.NAME+" "+this.VERSION+"]";
3784 },toString:function(){
3785 return this.__repr__();
3786 },_unloadCache:function(){
3787 var self=MochiKit.Signal;
3788 var _410=self._observers;
3789 for(var i=0;i<_410.length;i++){
3790 if(_410[i].signal!=="onload"&&_410[i].signal!=="onunload"){
3791 self._disconnect(_410[i]);
3792 }
3793 }
3794 },_listener:function(src,sig,func,obj,_416){
3795 var self=MochiKit.Signal;
3796 var E=self.Event;
3797 if(!_416){
3798 return MochiKit.Base.bind(func,obj);
3799 }
3800 obj=obj||src;
3801 if(typeof (func)=="string"){
3802 if(sig==="onload"||sig==="onunload"){
3803 return function(_419){
3804 obj[func].apply(obj,[new E(src,_419)]);
3805 var _41a=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:obj,funcOrStr:func});
3806 MochiKit.Signal._disconnect(_41a);
3807 };
3808 }else{
3809 return function(_41b){
3810 obj[func].apply(obj,[new E(src,_41b)]);
3811 };
3812 }
3813 }else{
3814 if(sig==="onload"||sig==="onunload"){
3815 return function(_41c){
3816 func.apply(obj,[new E(src,_41c)]);
3817 MochiKit.Signal.disconnect(src,sig,func);
3818 var _41d=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:func});
3819 MochiKit.Signal._disconnect(_41d);
3820 };
3821 }else{
3822 return function(_41e){
3823 func.apply(obj,[new E(src,_41e)]);
3824 };
3825 }
3826 }
3827 },_browserAlreadyHasMouseEnterAndLeave:function(){
3828 return /MSIE/.test(navigator.userAgent);
3829 },_mouseEnterListener:function(src,sig,func,obj){
3830 var E=MochiKit.Signal.Event;
3831 return function(_424){
3832 var e=new E(src,_424);
3833 try{
3834 e.relatedTarget().nodeName;
3835 }
3836 catch(err){
3837 return;
3838 }
3839 e.stop();
3840 if(MochiKit.DOM.isChildNode(e.relatedTarget(),src)){
3841 return;
3842 }
3843 e.type=function(){
3844 return sig;
3845 };
3846 if(typeof (func)=="string"){
3847 return obj[func].apply(obj,[e]);
3848 }else{
3849 return func.apply(obj,[e]);
3850 }
3851 };
3852 },_getDestPair:function(_426,_427){
3853 var obj=null;
3854 var func=null;
3855 if(typeof (_427)!="undefined"){
3856 obj=_426;
3857 func=_427;
3858 if(typeof (_427)=="string"){
3859 if(typeof (_426[_427])!="function"){
3860 throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
3861 }
3862 }else{
3863 if(typeof (_427)!="function"){
3864 throw new Error("'funcOrStr' must be a function or string");
3865 }
3866 }
3867 }else{
3868 if(typeof (_426)!="function"){
3869 throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
3870 }else{
3871 func=_426;
3872 }
3873 }
3874 return [obj,func];
3875 },connect:function(src,sig,_42c,_42d){
3876 src=MochiKit.DOM.getElement(src);
3877 var self=MochiKit.Signal;
3878 if(typeof (sig)!="string"){
3879 throw new Error("'sig' must be a string");
3880 }
3881 var _42f=self._getDestPair(_42c,_42d);
3882 var obj=_42f[0];
3883 var func=_42f[1];
3884 if(typeof (obj)=="undefined"||obj===null){
3885 obj=src;
3886 }
3887 var _432=!!(src.addEventListener||src.attachEvent);
3888 if(_432&&(sig==="onmouseenter"||sig==="onmouseleave")&&!self._browserAlreadyHasMouseEnterAndLeave()){
3889 var _433=self._mouseEnterListener(src,sig.substr(2),func,obj);
3890 if(sig==="onmouseenter"){
3891 sig="onmouseover";
3892 }else{
3893 sig="onmouseout";
3894 }
3895 }else{
3896 var _433=self._listener(src,sig,func,obj,_432);
3897 }
3898 if(src.addEventListener){
3899 src.addEventListener(sig.substr(2),_433,false);
3900 }else{
3901 if(src.attachEvent){
3902 src.attachEvent(sig,_433);
3903 }
3904 }
3905 var _434=new MochiKit.Signal.Ident({source:src,signal:sig,listener:_433,isDOM:_432,objOrFunc:_42c,funcOrStr:_42d,connected:true});
3906 self._observers.push(_434);
3907 if(!_432&&typeof (src.__connect__)=="function"){
3908 var args=MochiKit.Base.extend([_434],arguments,1);
3909 src.__connect__.apply(src,args);
3910 }
3911 return _434;
3912 },_disconnect:function(_436){
3913 if(!_436.connected){
3914 return;
3915 }
3916 _436.connected=false;
3917 if(!_436.isDOM){
3918 return;
3919 }
3920 var src=_436.source;
3921 var sig=_436.signal;
3922 var _439=_436.listener;
3923 if(src.removeEventListener){
3924 src.removeEventListener(sig.substr(2),_439,false);
3925 }else{
3926 if(src.detachEvent){
3927 src.detachEvent(sig,_439);
3928 }else{
3929 throw new Error("'src' must be a DOM element");
3930 }
3931 }
3932 },disconnect:function(_43a){
3933 var self=MochiKit.Signal;
3934 var _43c=self._observers;
3935 var m=MochiKit.Base;
3936 if(arguments.length>1){
3937 var src=MochiKit.DOM.getElement(arguments[0]);
3938 var sig=arguments[1];
3939 var obj=arguments[2];
3940 var func=arguments[3];
3941 for(var i=_43c.length-1;i>=0;i--){
3942 var o=_43c[i];
3943 if(o.source===src&&o.signal===sig&&o.objOrFunc===obj&&o.funcOrStr===func){
3944 self._disconnect(o);
3945 if(!self._lock){
3946 _43c.splice(i,1);
3947 }else{
3948 self._dirty=true;
3949 }
3950 return true;
3951 }
3952 }
3953 }else{
3954 var idx=m.findIdentical(_43c,_43a);
3955 if(idx>=0){
3956 self._disconnect(_43a);
3957 if(!self._lock){
3958 _43c.splice(idx,1);
3959 }else{
3960 self._dirty=true;
3961 }
3962 return true;
3963 }
3964 }
3965 return false;
3966 },disconnectAllTo:function(_445,_446){
3967 var self=MochiKit.Signal;
3968 var _448=self._observers;
3969 var _449=self._disconnect;
3970 var _44a=self._lock;
3971 var _44b=self._dirty;
3972 if(typeof (_446)==="undefined"){
3973 _446=null;
3974 }
3975 for(var i=_448.length-1;i>=0;i--){
3976 var _44d=_448[i];
3977 if(_44d.objOrFunc===_445&&(_446===null||_44d.funcOrStr===_446)){
3978 _449(_44d);
3979 if(_44a){
3980 _44b=true;
3981 }else{
3982 _448.splice(i,1);
3983 }
3984 }
3985 }
3986 self._dirty=_44b;
3987 },disconnectAll:function(src,sig){
3988 src=MochiKit.DOM.getElement(src);
3989 var m=MochiKit.Base;
3990 var _451=m.flattenArguments(m.extend(null,arguments,1));
3991 var self=MochiKit.Signal;
3992 var _453=self._disconnect;
3993 var _454=self._observers;
3994 var i,_456;
3995 var _457=self._lock;
3996 var _458=self._dirty;
3997 if(_451.length===0){
3998 for(i=_454.length-1;i>=0;i--){
3999 _456=_454[i];
4000 if(_456.source===src){
4001 _453(_456);
4002 if(!_457){
4003 _454.splice(i,1);
4004 }else{
4005 _458=true;
4006 }
4007 }
4008 }
4009 }else{
4010 var sigs={};
4011 for(i=0;i<_451.length;i++){
4012 sigs[_451[i]]=true;
4013 }
4014 for(i=_454.length-1;i>=0;i--){
4015 _456=_454[i];
4016 if(_456.source===src&&_456.signal in sigs){
4017 _453(_456);
4018 if(!_457){
4019 _454.splice(i,1);
4020 }else{
4021 _458=true;
4022 }
4023 }
4024 }
4025 }
4026 self._dirty=_458;
4027 },signal:function(src,sig){
4028 var self=MochiKit.Signal;
4029 var _45d=self._observers;
4030 src=MochiKit.DOM.getElement(src);
4031 var args=MochiKit.Base.extend(null,arguments,2);
4032 var _45f=[];
4033 self._lock=true;
4034 for(var i=0;i<_45d.length;i++){
4035 var _461=_45d[i];
4036 if(_461.source===src&&_461.signal===sig){
4037 try{
4038 _461.listener.apply(src,args);
4039 }
4040 catch(e){
4041 _45f.push(e);
4042 }
4043 }
4044 }
4045 self._lock=false;
4046 if(self._dirty){
4047 self._dirty=false;
4048 for(var i=_45d.length-1;i>=0;i--){
4049 if(!_45d[i].connected){
4050 _45d.splice(i,1);
4051 }
4052 }
4053 }
4054 if(_45f.length==1){
4055 throw _45f[0];
4056 }else{
4057 if(_45f.length>1){
4058 var e=new Error("Multiple errors thrown in handling 'sig', see errors property");
4059 e.errors=_45f;
4060 throw e;
4061 }
4062 }
4063 }});
4064 MochiKit.Signal.EXPORT_OK=[];
4065 MochiKit.Signal.EXPORT=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
4066 MochiKit.Signal.__new__=function(win){
4067 var m=MochiKit.Base;
4068 this._document=document;
4069 this._window=win;
4070 this._lock=false;
4071 this._dirty=false;
4072 try{
4073 this.connect(window,"onunload",this._unloadCache);
4074 }
4075 catch(e){
4076 }
4077 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
4078 m.nameFunctions(this);
4079 };
4080 MochiKit.Signal.__new__(this);
4081 if(MochiKit.__export__){
4082 connect=MochiKit.Signal.connect;
4083 disconnect=MochiKit.Signal.disconnect;
4084 disconnectAll=MochiKit.Signal.disconnectAll;
4085 signal=MochiKit.Signal.signal;
4086 }
4087 MochiKit.Base._exportSymbols(this,MochiKit.Signal);
4088
4089
4090 /***
4091
4092 PlotKit.PlotKit 0.9.1 : PACKED VERSION
4093
4094 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
4095 diff against the source tree, not this file.
4096
4097 For more information, <http://www.liquidx.net/plotkit/>.
4098
4099 Copyright (c) 2006. Alastair Tse.
4100
4101 ***/
4102
4103 try{
4104 if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.DOM)=="undefined"||typeof (MochiKit.Color)=="undefined"||typeof (MochiKit.Format)=="undefined"){
4105 throw "";
4106 }
4107 }
4108 catch(e){
4109 throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}";
4110 }
4111 MochiKit.Base.update(MochiKit.Color.Color.prototype,{asFillColor:function(){
4112 return this.lighterColorWithLevel(0.3);
4113 },asStrokeColor:function(){
4114 return this.darkerColorWithLevel(0.1);
4115 },asPointColor:function(){
4116 return this.lighterColorWithLevel(0.1);
4117 }});
4118 if(typeof (PlotKit)=="undefined"){
4119 PlotKit={};
4120 }
4121 PlotKit.NAME="PlotKit";
4122 PlotKit.VERSION="0.8";
4123 PlotKit.__repr__=function(){
4124 return "["+this.NAME+" "+this.VERSION+"]";
4125 };
4126 PlotKit.toString=function(){
4127 return this.__repr__();
4128 };
4129 if(typeof (PlotKit.Base)=="undefined"){
4130 PlotKit.Base={};
4131 }
4132 PlotKit.Base.NAME="PlotKit.Base";
4133 PlotKit.Base.VERSION=PlotKit.VERSION;
4134 PlotKit.Base.__repr__=function(){
4135 return "["+this.NAME+" "+this.VERSION+"]";
4136 };
4137 PlotKit.Base.toString=function(){
4138 return this.__repr__();
4139 };
4140 PlotKit.Base.usingPrototype=function(){
4141 try{
4142 return (typeof (Object.extend)=="function");
4143 }
4144 catch(e){
4145 return false;
4146 }
4147 };
4148 MochiKit.Base.update(PlotKit.Base,{roundInterval:function(_1,_2,_3){
4149 var _4=MochiKit.Format.roundToFixed;
4150 var _5=_1/_2;
4151 return parseFloat(_4(_5,_3));
4152 },collapse:function(_6){
4153 var m=MochiKit.Base;
4154 var _8=new Array();
4155 for(var i=0;i<_6.length;i++){
4156 _8=m.concat(_8,_6[i]);
4157 }
4158 if(PlotKit.Base.usingPrototype()){
4159 delete _8.extend;
4160 delete _8.from;
4161 delete _8.inspect;
4162 }
4163 return _8;
4164 },uniq:function(_10){
4165 var m=MochiKit.Base;
4166 if(!m.isArrayLike(_10)||(_10.length<1)){
4167 return new Array();
4168 }
4169 var _11=new Array();
4170 var _12=_10[0];
4171 _11.push(_10[0]);
4172 for(var i=1;i<_10.length;i++){
4173 if(m.compare(_10[i],_12)!=0){
4174 _12=_10[i];
4175 _11.push(_10[i]);
4176 }
4177 }
4178 return _11;
4179 },colorScheme:function(){
4180 var mb=MochiKit.Base;
4181 var mc=MochiKit.Color;
4182 var _15=["red","orange","yellow","green","cyan","blue","purple","magenta"];
4183 var _16=function(_17){
4184 return mc.Color[_17+"Color"]();
4185 };
4186 return mb.map(_16,_15);
4187 },baseDarkPrimaryColors:function(){
4188 var _18=MochiKit.Color.Color.fromHexString;
4189 return [_18("#ad3f40"),_18("#ddac2c"),_18("#dfdd0c"),_18("#5276c4"),_18("#739c5a")];
4190 },basePrimaryColors:function(){
4191 var _19=MochiKit.Color.Color.fromHexString;
4192 return [_19("#d24c4d"),_19("#f2b32f"),_19("#ece90e"),_19("#5d83da"),_19("#78a15d")];
4193 },baseBlueColors:function(){
4194 var _20=MochiKit.Color.Color.fromHexString;
4195 return [_20("#4b6b94"),_20("#5d81b4"),_20("#acbad2")];
4196 },palette:function(_21,_22,_23,_24){
4197 var _25=MochiKit.Base.isUndefinedOrNull;
4198 var _26=new Array();
4199 if(_25(_24)){
4200 _24=0.1;
4201 }
4202 if(_25(_23)){
4203 _23=0.4;
4204 }
4205 if(_25(_22)){
4206 _22=-0.2;
4207 }
4208 var _27=_22;
4209 while(_27<=_23){
4210 _26.push(_27);
4211 _27+=_24;
4212 }
4213 var _28=function(_29,_30){
4214 return _29.lighterColorWithLevel(_30);
4215 };
4216 return MochiKit.Base.map(partial(_28,_21),_26);
4217 },excanvasSupported:function(){
4218 if(/MSIE/.test(navigator.userAgent)&&!window.opera){
4219 return true;
4220 }
4221 return false;
4222 },findPosX:function(obj){
4223 var _32=0;
4224 if(obj.offsetParent){
4225 while(obj.offsetParent){
4226 _32+=obj.offsetLeft;
4227 obj=obj.offsetParent;
4228 }
4229 }else{
4230 if(obj.x){
4231 _32+=obj.x;
4232 }
4233 }
4234 return _32;
4235 },findPosY:function(obj){
4236 var _33=0;
4237 if(obj.offsetParent){
4238 while(obj.offsetParent){
4239 _33+=obj.offsetTop;
4240 obj=obj.offsetParent;
4241 }
4242 }else{
4243 if(obj.y){
4244 _33+=obj.y;
4245 }
4246 }
4247 return _33;
4248 },isFuncLike:function(obj){
4249 return (typeof (obj)=="function");
4250 }});
4251 PlotKit.Base.map=function(fn,lst){
4252 if(PlotKit.Base.usingPrototype()){
4253 var _36=[];
4254 for(var x in lst){
4255 if(typeof (lst[x])=="function"){
4256 continue;
4257 }
4258 _36.push(fn(lst[x]));
4259 }
4260 return _36;
4261 }else{
4262 return MochiKit.Base.map(fn,lst);
4263 }
4264 };
4265 PlotKit.Base.items=function(lst){
4266 if(PlotKit.Base.usingPrototype()){
4267 var _38=[];
4268 for(var x in lst){
4269 if(typeof (lst[x])=="function"){
4270 continue;
4271 }
4272 _38.push([x,lst[x]]);
4273 }
4274 return _38;
4275 }else{
4276 return MochiKit.Base.items(lst);
4277 }
4278 };
4279 PlotKit.Base.keys=function(lst){
4280 if(PlotKit.Base.usingPrototype()){
4281 var _39=[];
4282 for(var x in lst){
4283 if(typeof (lst[x])=="function"){
4284 continue;
4285 }
4286 _39.push(x);
4287 }
4288 return _39;
4289 }else{
4290 return MochiKit.Base.keys(lst);
4291 }
4292 };
4293 PlotKit.Base.baseColors=function(){
4294 var _40=MochiKit.Color.Color.fromHexString;
4295 return [_40("#476fb2"),_40("#be2c2b"),_40("#85b730"),_40("#734a99"),_40("#26a1c5"),_40("#fb8707"),_40("#000000")];
4296 };
4297 PlotKit.Base.officeBaseStyle={"axisLineWidth":2,"axisLabelColor":Color.grayColor(),"axisLineColor":Color.whiteColor(),"padding":{top:5,bottom:10,left:30,right:30}};
4298 MochiKit.Base.update(PlotKit.Base,{officeBlue:function(){
4299 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),"backgroundColor":PlotKit.Base.baseColors()[0].lighterColorWithLevel(0.45)};
4300 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4301 return r;
4302 },officeRed:function(){
4303 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),"backgroundColor":PlotKit.Base.baseColors()[1].lighterColorWithLevel(0.5)};
4304 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4305 return r;
4306 },officeGreen:function(){
4307 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[2]),"backgroundColor":PlotKit.Base.baseColors()[2].lighterColorWithLevel(0.5)};
4308 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4309 return r;
4310 },officePurple:function(){
4311 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[3]),"backgroundColor":PlotKit.Base.baseColors()[3].lighterColorWithLevel(0.5)};
4312 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4313 return r;
4314 },officeCyan:function(){
4315 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[4]),"backgroundColor":PlotKit.Base.baseColors()[4].lighterColorWithLevel(0.5)};
4316 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4317 return r;
4318 },officeOrange:function(){
4319 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[5]),"backgroundColor":PlotKit.Base.baseColors()[5].lighterColorWithLevel(0.4)};
4320 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4321 return r;
4322 },officeBlack:function(){
4323 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[6],0,0.6),"backgroundColor":PlotKit.Base.baseColors()[6].lighterColorWithLevel(0.9)};
4324 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
4325 return r;
4326 }});
4327 PlotKit.Base.EXPORT=["baseColors","collapse","colorScheme","findPosX","findPosY","officeBaseStyle","officeBlue","officeRed","officeGreen","officePurple","officeCyan","officeOrange","officeBlack","roundInterval","uniq","isFuncLike","excanvasSupported"];
4328 PlotKit.Base.EXPORT_OK=[];
4329 PlotKit.Base.__new__=function(){
4330 var m=MochiKit.Base;
4331 m.nameFunctions(this);
4332 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
4333 };
4334 PlotKit.Base.__new__();
4335 MochiKit.Base._exportSymbols(this,PlotKit.Base);
4336 try{
4337 if(typeof (PlotKit.Base)=="undefined"){
4338 throw "";
4339 }
4340 }
4341 catch(e){
4342 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base";
4343 }
4344 if(typeof (PlotKit.Layout)=="undefined"){
4345 PlotKit.Layout={};
4346 }
4347 PlotKit.Layout.NAME="PlotKit.Layout";
4348 PlotKit.Layout.VERSION=PlotKit.VERSION;
4349 PlotKit.Layout.__repr__=function(){
4350 return "["+this.NAME+" "+this.VERSION+"]";
4351 };
4352 PlotKit.Layout.toString=function(){
4353 return this.__repr__();
4354 };
4355 PlotKit.Layout.valid_styles=["bar","line","pie","point"];
4356 PlotKit.Layout=function(_42,_43){
4357 this.options={"barWidthFillFraction":0.75,"barOrientation":"vertical","xOriginIsZero":true,"yOriginIsZero":true,"xAxis":null,"yAxis":null,"xTicks":null,"yTicks":null,"xNumberOfTicks":10,"yNumberOfTicks":5,"xTickPrecision":1,"yTickPrecision":1,"pieRadius":0.4};
4358 this.style=_42;
4359 MochiKit.Base.update(this.options,_43?_43:{});
4360 if(!MochiKit.Base.isUndefinedOrNull(this.options.xAxis)){
4361 this.minxval=this.options.xAxis[0];
4362 this.maxxval=this.options.xAxis[1];
4363 this.xscale=this.maxxval-this.minxval;
4364 }else{
4365 this.minxval=0;
4366 this.maxxval=null;
4367 this.xscale=null;
4368 }
4369 if(!MochiKit.Base.isUndefinedOrNull(this.options.yAxis)){
4370 this.minyval=this.options.yAxis[0];
4371 this.maxyval=this.options.yAxis[1];
4372 this.yscale=this.maxyval-this.minyval;
4373 }else{
4374 this.minyval=0;
4375 this.maxyval=null;
4376 this.yscale=null;
4377 }
4378 this.bars=new Array();
4379 this.points=new Array();
4380 this.slices=new Array();
4381 this.xticks=new Array();
4382 this.yticks=new Array();
4383 this.datasets=new Array();
4384 this.minxdelta=0;
4385 this.xrange=1;
4386 this.yrange=1;
4387 this.hitTestCache={x2maxy:null};
4388 };
4389 PlotKit.Layout.prototype.addDataset=function(_44,_45){
4390 this.datasets[_44]=_45;
4391 };
4392 PlotKit.Layout.prototype.removeDataset=function(_46,_47){
4393 delete this.datasets[_46];
4394 };
4395 PlotKit.Layout.prototype.addDatasetFromTable=function(_48,_49,_50,_51,_52){
4396 var _53=MochiKit.Base.isUndefinedOrNull;
4397 var _54=MochiKit.DOM.scrapeText;
4398 var _55=MochiKit.Format.strip;
4399 if(_53(_50)){
4400 _50=0;
4401 }
4402 if(_53(_51)){
4403 _51=1;
4404 }
4405 if(_53(_52)){
4406 _52=-1;
4407 }
4408 var _56=_49.tBodies[0].rows;
4409 var _57=new Array();
4410 var _58=new Array();
4411 if(!_53(_56)){
4412 for(var i=0;i<_56.length;i++){
4413 _57.push([parseFloat(_55(_54(_56[i].cells[_50]))),parseFloat(_55(_54(_56[i].cells[_51])))]);
4414 if(_52>=0){
4415 _58.push({v:parseFloat(_55(_54(_56[i].cells[_50]))),label:_55(_54(_56[i].cells[_52]))});
4416 }
4417 }
4418 this.addDataset(_48,_57);
4419 if(_52>=0){
4420 this.options.xTicks=_58;
4421 }
4422 return true;
4423 }
4424 return false;
4425 };
4426 PlotKit.Layout.prototype.evaluate=function(){
4427 this._evaluateLimits();
4428 this._evaluateScales();
4429 if(this.style=="bar"){
4430 if(this.options.barOrientation=="horizontal"){
4431 this._evaluateHorizBarCharts();
4432 }else{
4433 this._evaluateBarCharts();
4434 }
4435 this._evaluateBarTicks();
4436 }else{
4437 if(this.style=="line"){
4438 this._evaluateLineCharts();
4439 this._evaluateLineTicks();
4440 }else{
4441 if(this.style=="pie"){
4442 this._evaluatePieCharts();
4443 this._evaluatePieTicks();
4444 }
4445 }
4446 }
4447 };
4448 PlotKit.Layout.prototype.hitTest=function(x,y){
4449 var f=MochiKit.Format.twoDigitFloat;
4450 if((this.style=="bar")&&this.bars&&(this.bars.length>0)){
4451 for(var i=0;i<this.bars.length;i++){
4452 var bar=this.bars[i];
4453 if((x>=bar.x)&&(x<=bar.x+bar.w)&&(y>=bar.y)&&(y-bar.y<=bar.h)){
4454 return bar;
4455 }
4456 }
4457 }else{
4458 if(this.style=="line"){
4459 if(this.hitTestCache.x2maxy==null){
4460 this._regenerateHitTestCache();
4461 }
4462 var _62=x/this.xscale;
4463 var _63=this.hitTestCache.xvalues;
4464 var _64=null;
4465 var _65=null;
4466 for(var i=1;i<_63.length;i++){
4467 if(_63[i]>_62){
4468 _64=_63[i-1];
4469 _65=_63[i];
4470 break;
4471 }
4472 }
4473 if((_64!=null)){
4474 var _66=this.hitTestCache.x2maxy[_64];
4475 var _67=this.hitTestCache.x2maxy[_65];
4476 var _68=(1-y)/this.yscale;
4477 var _69=(_67-_66)/(_65-_64);
4478 var _70=_66+_69*(_62-_64);
4479 if(_70>=_68){
4480 var obj={xval:_62,yval:_68,xafter:_65,yafter:_67,xbefore:_64,ybefore:_66,yprojected:_70};
4481 return obj;
4482 }
4483 }
4484 }else{
4485 if(this.style=="pie"){
4486 var _71=Math.sqrt((y-0.5)*(y-0.5)+(x-0.5)*(x-0.5));
4487 if(_71>this.options.pieRadius){
4488 return null;
4489 }
4490 var _72=Math.atan2(y-0.5,x-0.5)-Math.PI/2;
4491 for(var i=0;i<this.slices.length;i++){
4492 var _73=this.slices[i];
4493 if(_73.startAngle<_72&&_73.endAngle>=_72){
4494 return _73;
4495 }
4496 }
4497 }
4498 }
4499 }
4500 return null;
4501 };
4502 PlotKit.Layout.prototype.rectForX=function(x){
4503 return null;
4504 };
4505 PlotKit.Layout.prototype.angleRangeForX=function(x){
4506 return null;
4507 };
4508 PlotKit.Layout.prototype._evaluateLimits=function(){
4509 var map=PlotKit.Base.map;
4510 var _75=PlotKit.Base.items;
4511 var _76=MochiKit.Base.itemgetter;
4512 var _77=PlotKit.Base.collapse;
4513 var _78=MochiKit.Base.listMin;
4514 var _79=MochiKit.Base.listMax;
4515 var _80=MochiKit.Base.isUndefinedOrNull;
4516 var all=_77(map(_76(1),_75(this.datasets)));
4517 if(_80(this.options.xAxis)){
4518 if(this.options.xOriginIsZero){
4519 this.minxval=0;
4520 }else{
4521 this.minxval=_78(map(parseFloat,map(_76(0),all)));
4522 }
4523 this.maxxval=_79(map(parseFloat,map(_76(0),all)));
4524 }else{
4525 this.minxval=this.options.xAxis[0];
4526 this.maxxval=this.options.xAxis[1];
4527 this.xscale=this.maxval-this.minxval;
4528 }
4529 if(_80(this.options.yAxis)){
4530 if(this.options.yOriginIsZero){
4531 this.minyval=0;
4532 }else{
4533 this.minyval=_78(map(parseFloat,map(_76(1),all)));
4534 }
4535 this.maxyval=_79(map(parseFloat,map(_76(1),all)));
4536 }else{
4537 this.minyval=this.options.yAxis[0];
4538 this.maxyval=this.options.yAxis[1];
4539 this.yscale=this.maxyval-this.minyval;
4540 }
4541 };
4542 PlotKit.Layout.prototype._evaluateScales=function(){
4543 var _82=MochiKit.Base.isUndefinedOrNull;
4544 this.xrange=this.maxxval-this.minxval;
4545 if(this.xrange==0){
4546 this.xscale=1;
4547 }else{
4548 this.xscale=1/this.xrange;
4549 }
4550 this.yrange=this.maxyval-this.minyval;
4551 if(this.yrange==0){
4552 this.yscale=1;
4553 }else{
4554 this.yscale=1/this.yrange;
4555 }
4556 };
4557 PlotKit.Layout.prototype._uniqueXValues=function(){
4558 var _83=PlotKit.Base.collapse;
4559 var map=PlotKit.Base.map;
4560 var _84=PlotKit.Base.uniq;
4561 var _85=MochiKit.Base.itemgetter;
4562 var _86=PlotKit.Base.items;
4563 var _87=map(parseFloat,map(_85(0),_83(map(_85(1),_86(this.datasets)))));
4564 _87.sort(MochiKit.Base.compare);
4565 return _84(_87);
4566 };
4567 PlotKit.Layout.prototype._evaluateBarCharts=function(){
4568 var _88=PlotKit.Base.items;
4569 var _89=_88(this.datasets).length;
4570 var _90=10000000;
4571 var _91=this._uniqueXValues();
4572 for(var i=1;i<_91.length;i++){
4573 _90=Math.min(Math.abs(_91[i]-_91[i-1]),_90);
4574 }
4575 var _92=0;
4576 var _93=0;
4577 var _94=0;
4578 if(_91.length==1){
4579 _90=1;
4580 this.xscale=1;
4581 this.minxval=_91[0];
4582 _92=1*this.options.barWidthFillFraction;
4583 _93=_92/_89;
4584 _94=(1-this.options.barWidthFillFraction)/2;
4585 }else{
4586 if(this.xrange==1){
4587 this.xscale=0.5;
4588 }else{
4589 if(this.xrange==2){
4590 this.xscale=1/3;
4591 }else{
4592 this.xscale=(1-_90/this.xrange)/this.xrange;
4593 }
4594 }
4595 _92=_90*this.xscale*this.options.barWidthFillFraction;
4596 _93=_92/_89;
4597 _94=_90*this.xscale*(1-this.options.barWidthFillFraction)/2;
4598 }
4599 this.minxdelta=_90;
4600 this.bars=new Array();
4601 var i=0;
4602 for(var _95 in this.datasets){
4603 var _96=this.datasets[_95];
4604 if(PlotKit.Base.isFuncLike(_96)){
4605 continue;
4606 }
4607 for(var j=0;j<_96.length;j++){
4608 var _98=_96[j];
4609 var _99={x:((parseFloat(_98[0])-this.minxval)*this.xscale)+(i*_93)+_94,y:1-((parseFloat(_98[1])-this.minyval)*this.yscale),w:_93,h:((parseFloat(_98[1])-this.minyval)*this.yscale),xval:parseFloat(_98[0]),yval:parseFloat(_98[1]),name:_95};
4610 if((_99.x>=0)&&(_99.x<=1)&&(_99.y>=0)&&(_99.y<=1)){
4611 this.bars.push(_99);
4612 }
4613 }
4614 i++;
4615 }
4616 };
4617 PlotKit.Layout.prototype._evaluateHorizBarCharts=function(){
4618 var _100=PlotKit.Base.items;
4619 var _101=_100(this.datasets).length;
4620 var _102=10000000;
4621 var _103=this._uniqueXValues();
4622 for(var i=1;i<_103.length;i++){
4623 _102=Math.min(Math.abs(_103[i]-_103[i-1]),_102);
4624 }
4625 var _104=0;
4626 var _105=0;
4627 var _106=0;
4628 if(_103.length==1){
4629 _102=1;
4630 this.xscale=1;
4631 this.minxval=_103[0];
4632 _104=1*this.options.barWidthFillFraction;
4633 _105=_104/_101;
4634 _106=(1-this.options.barWidthFillFraction)/2;
4635 }else{
4636 this.xscale=(1-_102/this.xrange)/this.xrange;
4637 _104=_102*this.xscale*this.options.barWidthFillFraction;
4638 _105=_104/_101;
4639 _106=_102*this.xscale*(1-this.options.barWidthFillFraction)/2;
4640 }
4641 this.minxdelta=_102;
4642 this.bars=new Array();
4643 var i=0;
4644 for(var _107 in this.datasets){
4645 var _108=this.datasets[_107];
4646 if(PlotKit.Base.isFuncLike(_108)){
4647 continue;
4648 }
4649 for(var j=0;j<_108.length;j++){
4650 var item=_108[j];
4651 var rect={y:((parseFloat(item[0])-this.minxval)*this.xscale)+(i*_105)+_106,x:0,h:_105,w:((parseFloat(item[1])-this.minyval)*this.yscale),xval:parseFloat(item[0]),yval:parseFloat(item[1]),name:_107};
4652 if(rect.y<=0){
4653 rect.y=0;
4654 }
4655 if(rect.y>=1){
4656 rect.y=1;
4657 }
4658 if((rect.x>=0)&&(rect.x<=1)){
4659 this.bars.push(rect);
4660 }
4661 }
4662 i++;
4663 }
4664 };
4665 PlotKit.Layout.prototype._evaluateLineCharts=function(){
4666 var _111=PlotKit.Base.items;
4667 var _112=_111(this.datasets).length;
4668 this.points=new Array();
4669 var i=0;
4670 for(var _113 in this.datasets){
4671 var _114=this.datasets[_113];
4672 if(PlotKit.Base.isFuncLike(_114)){
4673 continue;
4674 }
4675 _114.sort(function(a,b){
4676 return compare(parseFloat(a[0]),parseFloat(b[0]));
4677 });
4678 for(var j=0;j<_114.length;j++){
4679 var item=_114[j];
4680 var _117={x:((parseFloat(item[0])-this.minxval)*this.xscale),y:1-((parseFloat(item[1])-this.minyval)*this.yscale),xval:parseFloat(item[0]),yval:parseFloat(item[1]),name:_113};
4681 if(_117.y<=0){
4682 _117.y=0;
4683 }
4684 if(_117.y>=1){
4685 _117.y=1;
4686 }
4687 if((_117.x>=0)&&(_117.x<=1)){
4688 this.points.push(_117);
4689 }
4690 }
4691 i++;
4692 }
4693 };
4694 PlotKit.Layout.prototype._evaluatePieCharts=function(){
4695 var _118=PlotKit.Base.items;
4696 var sum=MochiKit.Iter.sum;
4697 var _120=MochiKit.Base.itemgetter;
4698 var _121=_118(this.datasets).length;
4699 var _122=_118(this.datasets)[0][1];
4700 var _123=sum(map(_120(1),_122));
4701 this.slices=new Array();
4702 var _124=0;
4703 for(var i=0;i<_122.length;i++){
4704 var _125=_122[i][1]/_123;
4705 var _126=_124*Math.PI*2;
4706 var _127=(_124+_125)*Math.PI*2;
4707 var _128={fraction:_125,xval:_122[i][0],yval:_122[i][1],startAngle:_126,endAngle:_127};
4708 if(_122[i][1]!=0){
4709 this.slices.push(_128);
4710 }
4711 _124+=_125;
4712 }
4713 };
4714 PlotKit.Layout.prototype._evaluateLineTicksForXAxis=function(){
4715 var _129=MochiKit.Base.isUndefinedOrNull;
4716 if(this.options.xTicks){
4717 this.xticks=new Array();
4718 var _130=function(tick){
4719 var _132=tick.label;
4720 if(_129(_132)){
4721 _132=tick.v.toString();
4722 }
4723 var pos=this.xscale*(tick.v-this.minxval);
4724 if((pos>=0)&&(pos<=1)){
4725 this.xticks.push([pos,_132]);
4726 }
4727 };
4728 MochiKit.Iter.forEach(this.options.xTicks,bind(_130,this));
4729 }else{
4730 if(this.options.xNumberOfTicks){
4731 var _134=this._uniqueXValues();
4732 var _135=this.xrange/this.options.xNumberOfTicks;
4733 var _136=0;
4734 this.xticks=new Array();
4735 for(var i=0;i<=_134.length;i++){
4736 if((_134[i]-this.minxval)>=(_136*_135)){
4737 var pos=this.xscale*(_134[i]-this.minxval);
4738 if((pos>1)||(pos<0)){
4739 continue;
4740 }
4741 this.xticks.push([pos,_134[i]]);
4742 _136++;
4743 }
4744 if(_136>this.options.xNumberOfTicks){
4745 break;
4746 }
4747 }
4748 }
4749 }
4750 };
4751 PlotKit.Layout.prototype._evaluateLineTicksForYAxis=function(){
4752 var _137=MochiKit.Base.isUndefinedOrNull;
4753 if(this.options.yTicks){
4754 this.yticks=new Array();
4755 var _138=function(tick){
4756 var _139=tick.label;
4757 if(_137(_139)){
4758 _139=tick.v.toString();
4759 }
4760 var pos=1-(this.yscale*(tick.v-this.minyval));
4761 if((pos>=0)&&(pos<=1)){
4762 this.yticks.push([pos,_139]);
4763 }
4764 };
4765 MochiKit.Iter.forEach(this.options.yTicks,bind(_138,this));
4766 }else{
4767 if(this.options.yNumberOfTicks){
4768 this.yticks=new Array();
4769 var _140=PlotKit.Base.roundInterval;
4770 var prec=this.options.yTickPrecision;
4771 var _142=_140(this.yrange,this.options.yNumberOfTicks,prec);
4772 for(var i=0;i<=this.options.yNumberOfTicks;i++){
4773 var yval=this.minyval+(i*_142);
4774 var pos=1-((yval-this.minyval)*this.yscale);
4775 if((pos>1)||(pos<0)){
4776 continue;
4777 }
4778 this.yticks.push([pos,MochiKit.Format.roundToFixed(yval,prec)]);
4779 }
4780 }
4781 }
4782 };
4783 PlotKit.Layout.prototype._evaluateLineTicks=function(){
4784 this._evaluateLineTicksForXAxis();
4785 this._evaluateLineTicksForYAxis();
4786 };
4787 PlotKit.Layout.prototype._evaluateBarTicks=function(){
4788 this._evaluateLineTicks();
4789 var _144=function(tick){
4790 return [tick[0]+(this.minxdelta*this.xscale)/2,tick[1]];
4791 };
4792 this.xticks=MochiKit.Base.map(bind(_144,this),this.xticks);
4793 if(this.options.barOrientation=="horizontal"){
4794 var _145=this.xticks;
4795 this.xticks=this.yticks;
4796 this.yticks=_145;
4797 var _146=function(tick){
4798 return [1-tick[0],tick[1]];
4799 };
4800 this.xticks=MochiKit.Base.map(_146,this.xticks);
4801 }
4802 };
4803 PlotKit.Layout.prototype._evaluatePieTicks=function(){
4804 var _147=MochiKit.Base.isUndefinedOrNull;
4805 var _148=MochiKit.Format.numberFormatter("#%");
4806 this.xticks=new Array();
4807 if(this.options.xTicks){
4808 var _149=new Array();
4809 for(var i=0;i<this.slices.length;i++){
4810 _149[this.slices[i].xval]=this.slices[i];
4811 }
4812 for(var i=0;i<this.options.xTicks.length;i++){
4813 var tick=this.options.xTicks[i];
4814 var _150=_149[tick.v];
4815 var _151=tick.label;
4816 if(_150){
4817 if(_147(_151)){
4818 _151=tick.v.toString();
4819 }
4820 _151+=" ("+_148(_150.fraction)+")";
4821 this.xticks.push([tick.v,_151]);
4822 }
4823 }
4824 }else{
4825 for(var i=0;i<this.slices.length;i++){
4826 var _150=this.slices[i];
4827 var _151=_150.xval+" ("+_148(_150.fraction)+")";
4828 this.xticks.push([_150.xval,_151]);
4829 }
4830 }
4831 };
4832 PlotKit.Layout.prototype._regenerateHitTestCache=function(){
4833 this.hitTestCache.xvalues=this._uniqueXValues();
4834 this.hitTestCache.xlookup=new Array();
4835 this.hitTestCache.x2maxy=new Array();
4836 var _152=MochiKit.Base.listMax;
4837 var _153=MochiKit.Base.itemgetter;
4838 var map=MochiKit.Base.map;
4839 var _154=keys(this.datasets);
4840 for(var i=0;i<_154.length;i++){
4841 var _155=this.datasets[_154[i]];
4842 for(var j=0;j<_155.length;j++){
4843 var xval=_155[j][0];
4844 var yval=_155[j][1];
4845 if(this.hitTestCache.xlookup[xval]){
4846 this.hitTestCache.xlookup[xval].push([yval,_154[i]]);
4847 }else{
4848 this.hitTestCache.xlookup[xval]=[[yval,_154[i]]];
4849 }
4850 }
4851 }
4852 for(var x in this.hitTestCache.xlookup){
4853 var _157=this.hitTestCache.xlookup[x];
4854 this.hitTestCache.x2maxy[x]=_152(map(_153(0),_157));
4855 }
4856 };
4857 PlotKit.LayoutModule={};
4858 PlotKit.LayoutModule.Layout=PlotKit.Layout;
4859 PlotKit.LayoutModule.EXPORT=["Layout"];
4860 PlotKit.LayoutModule.EXPORT_OK=[];
4861 PlotKit.LayoutModule.__new__=function(){
4862 var m=MochiKit.Base;
4863 m.nameFunctions(this);
4864 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
4865 };
4866 PlotKit.LayoutModule.__new__();
4867 MochiKit.Base._exportSymbols(this,PlotKit.LayoutModule);
4868 try{
4869 if((typeof (PlotKit.Base)=="undefined")||(typeof (PlotKit.Layout)=="undefined")){
4870 throw "";
4871 }
4872 }
4873 catch(e){
4874 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}";
4875 }
4876 if(typeof (PlotKit.CanvasRenderer)=="undefined"){
4877 PlotKit.CanvasRenderer={};
4878 }
4879 PlotKit.CanvasRenderer.NAME="PlotKit.CanvasRenderer";
4880 PlotKit.CanvasRenderer.VERSION=PlotKit.VERSION;
4881 PlotKit.CanvasRenderer.__repr__=function(){
4882 return "["+this.NAME+" "+this.VERSION+"]";
4883 };
4884 PlotKit.CanvasRenderer.toString=function(){
4885 return this.__repr__();
4886 };
4887 PlotKit.CanvasRenderer=function(_158,_159,_160){
4888 if(arguments.length>0){
4889 this.__init__(_158,_159,_160);
4890 }
4891 };
4892 PlotKit.CanvasRenderer.prototype.__init__=function(_161,_162,_163){
4893 var _164=MochiKit.Base.isUndefinedOrNull;
4894 var _165=MochiKit.Color.Color;
4895 this.options={"drawBackground":true,"backgroundColor":_165.whiteColor(),"padding":{left:30,right:30,top:5,bottom:10},"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),"strokeColor":_165.whiteColor(),"strokeColorTransform":"asStrokeColor","strokeWidth":0.5,"shouldFill":true,"shouldStroke":true,"drawXAxis":true,"drawYAxis":true,"axisLineColor":_165.blackColor(),"axisLineWidth":0.5,"axisTickSize":3,"axisLabelColor":_165.blackColor(),"axisLabelFont":"Arial","axisLabelFontSize":9,"axisLabelWidth":50,"pieRadius":0.4,"enableEvents":true};
4896 MochiKit.Base.update(this.options,_163?_163:{});
4897 this.layout=_162;
4898 this.element=MochiKit.DOM.getElement(_161);
4899 this.container=this.element.parentNode;
4900 this.isIE=PlotKit.Base.excanvasSupported();
4901 if(this.isIE&&!_164(G_vmlCanvasManager)){
4902 this.IEDelay=0.5;
4903 this.maxTries=5;
4904 this.renderDelay=null;
4905 this.clearDelay=null;
4906 this.element=G_vmlCanvasManager.initElement(this.element);
4907 }
4908 this.height=this.element.height;
4909 this.width=this.element.width;
4910 if(_164(this.element)){
4911 throw "CanvasRenderer() - passed canvas is not found";
4912 }
4913 if(!this.isIE&&!(PlotKit.CanvasRenderer.isSupported(this.element))){
4914 throw "CanvasRenderer() - Canvas is not supported.";
4915 }
4916 if(_164(this.container)||(this.container.nodeName.toLowerCase()!="div")){
4917 throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
4918 }
4919 this.xlabels=new Array();
4920 this.ylabels=new Array();
4921 this.isFirstRender=true;
4922 this.area={x:this.options.padding.left,y:this.options.padding.top,w:this.width-this.options.padding.left-this.options.padding.right,h:this.height-this.options.padding.top-this.options.padding.bottom};
4923 MochiKit.DOM.updateNodeAttributes(this.container,{"style":{"position":"relative","width":this.width+"px"}});
4924 };
4925 PlotKit.CanvasRenderer.prototype.render=function(){
4926 if(this.isIE){
4927 try{
4928 if(this.renderDelay){
4929 this.renderDelay.cancel();
4930 this.renderDelay=null;
4931 }
4932 var _166=this.element.getContext("2d");
4933 }
4934 catch(e){
4935 this.isFirstRender=false;
4936 if(this.maxTries-->0){
4937 this.renderDelay=MochiKit.Async.wait(this.IEDelay);
4938 this.renderDelay.addCallback(bind(this.render,this));
4939 }
4940 return;
4941 }
4942 }
4943 if(this.options.drawBackground){
4944 this._renderBackground();
4945 }
4946 if(this.layout.style=="bar"){
4947 this._renderBarChart();
4948 this._renderBarAxis();
4949 }else{
4950 if(this.layout.style=="pie"){
4951 this._renderPieChart();
4952 this._renderPieAxis();
4953 }else{
4954 if(this.layout.style=="line"){
4955 this._renderLineChart();
4956 this._renderLineAxis();
4957 }
4958 }
4959 }
4960 };
4961 PlotKit.CanvasRenderer.prototype._renderBarChartWrap=function(data,_168){
4962 var _169=this.element.getContext("2d");
4963 var _170=this.options.colorScheme.length;
4964 var _171=this.options.colorScheme;
4965 var _172=MochiKit.Base.keys(this.layout.datasets);
4966 var _173=_172.length;
4967 for(var i=0;i<_173;i++){
4968 var _174=_172[i];
4969 var _175=_171[i%_170];
4970 _169.save();
4971 _169.fillStyle=_175.toRGBString();
4972 if(this.options.strokeColor){
4973 _169.strokeStyle=this.options.strokeColor.toRGBString();
4974 }else{
4975 if(this.options.strokeColorTransform){
4976 _169.strokeStyle=_175[this.options.strokeColorTransform]().toRGBString();
4977 }
4978 }
4979 _169.lineWidth=this.options.strokeWidth;
4980 var _176=function(obj){
4981 if(obj.name==_174){
4982 _168(_169,obj);
4983 }
4984 };
4985 MochiKit.Iter.forEach(data,bind(_176,this));
4986 _169.restore();
4987 }
4988 };
4989 PlotKit.CanvasRenderer.prototype._renderBarChart=function(){
4990 var bind=MochiKit.Base.bind;
4991 var _178=function(_179,bar){
4992 var x=this.area.w*bar.x+this.area.x;
4993 var y=this.area.h*bar.y+this.area.y;
4994 var w=this.area.w*bar.w;
4995 var h=this.area.h*bar.h;
4996 if((w<1)||(h<1)){
4997 return;
4998 }
4999 if(this.options.shouldFill){
5000 _179.fillRect(x,y,w,h);
5001 }
5002 if(this.options.shouldStroke){
5003 _179.strokeRect(x,y,w,h);
5004 }
5005 };
5006 this._renderBarChartWrap(this.layout.bars,bind(_178,this));
5007 };
5008 PlotKit.CanvasRenderer.prototype._renderLineChart=function(){
5009 var _182=this.element.getContext("2d");
5010 var _183=this.options.colorScheme.length;
5011 var _184=this.options.colorScheme;
5012 var _185=MochiKit.Base.keys(this.layout.datasets);
5013 var _186=_185.length;
5014 var bind=MochiKit.Base.bind;
5015 var _187=MochiKit.Base.partial;
5016 for(var i=0;i<_186;i++){
5017 var _188=_185[i];
5018 var _189=_184[i%_183];
5019 var _190=this.options.strokeColorTransform;
5020 _182.save();
5021 _182.fillStyle=_189.toRGBString();
5022 if(this.options.strokeColor){
5023 _182.strokeStyle=this.options.strokeColor.toRGBString();
5024 }else{
5025 if(this.options.strokeColorTransform){
5026 _182.strokeStyle=_189[_190]().toRGBString();
5027 }
5028 }
5029 _182.lineWidth=this.options.strokeWidth;
5030 var _191=function(ctx){
5031 ctx.beginPath();
5032 ctx.moveTo(this.area.x,this.area.y+this.area.h);
5033 var _193=function(ctx_,_195){
5034 if(_195.name==_188){
5035 ctx_.lineTo(this.area.w*_195.x+this.area.x,this.area.h*_195.y+this.area.y);
5036 }
5037 };
5038 MochiKit.Iter.forEach(this.layout.points,_187(_193,ctx),this);
5039 ctx.lineTo(this.area.w+this.area.x,this.area.h+this.area.y);
5040 ctx.lineTo(this.area.x,this.area.y+this.area.h);
5041 ctx.closePath();
5042 };
5043 if(this.options.shouldFill){
5044 bind(_191,this)(_182);
5045 _182.fill();
5046 }
5047 if(this.options.shouldStroke){
5048 bind(_191,this)(_182);
5049 _182.stroke();
5050 }
5051 _182.restore();
5052 }
5053 };
5054 PlotKit.CanvasRenderer.prototype._renderPieChart=function(){
5055 var _196=this.element.getContext("2d");
5056 var _197=this.options.colorScheme.length;
5057 var _198=this.layout.slices;
5058 var _199=this.area.x+this.area.w*0.5;
5059 var _200=this.area.y+this.area.h*0.5;
5060 var _201=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
5061 if(this.isIE){
5062 _199=parseInt(_199);
5063 _200=parseInt(_200);
5064 _201=parseInt(_201);
5065 }
5066 for(var i=0;i<_198.length;i++){
5067 var _202=this.options.colorScheme[i%_197];
5068 _196.save();
5069 _196.fillStyle=_202.toRGBString();
5070 var _203=function(){
5071 _196.beginPath();
5072 _196.moveTo(_199,_200);
5073 _196.arc(_199,_200,_201,_198[i].startAngle-Math.PI/2,_198[i].endAngle-Math.PI/2,false);
5074 _196.lineTo(_199,_200);
5075 _196.closePath();
5076 };
5077 if(Math.abs(_198[i].startAngle-_198[i].endAngle)>0.001){
5078 if(this.options.shouldFill){
5079 _203();
5080 _196.fill();
5081 }
5082 if(this.options.shouldStroke){
5083 _203();
5084 _196.lineWidth=this.options.strokeWidth;
5085 if(this.options.strokeColor){
5086 _196.strokeStyle=this.options.strokeColor.toRGBString();
5087 }else{
5088 if(this.options.strokeColorTransform){
5089 _196.strokeStyle=_202[this.options.strokeColorTransform]().toRGBString();
5090 }
5091 }
5092 _196.stroke();
5093 }
5094 }
5095 _196.restore();
5096 }
5097 };
5098 PlotKit.CanvasRenderer.prototype._renderBarAxis=function(){
5099 this._renderAxis();
5100 };
5101 PlotKit.CanvasRenderer.prototype._renderLineAxis=function(){
5102 this._renderAxis();
5103 };
5104 PlotKit.CanvasRenderer.prototype._renderAxis=function(){
5105 if(!this.options.drawXAxis&&!this.options.drawYAxis){
5106 return;
5107 }
5108 var _204=this.element.getContext("2d");
5109 var _205={"style":{"position":"absolute","fontSize":this.options.axisLabelFontSize+"px","zIndex":10,"color":this.options.axisLabelColor.toRGBString(),"width":this.options.axisLabelWidth+"px","overflow":"hidden"}};
5110 _204.save();
5111 _204.strokeStyle=this.options.axisLineColor.toRGBString();
5112 _204.lineWidth=this.options.axisLineWidth;
5113 if(this.options.drawYAxis){
5114 if(this.layout.yticks){
5115 var _206=function(tick){
5116 if(typeof (tick)=="function"){
5117 return;
5118 }
5119 var x=this.area.x;
5120 var y=this.area.y+tick[0]*this.area.h;
5121 _204.beginPath();
5122 _204.moveTo(x,y);
5123 _204.lineTo(x-this.options.axisTickSize,y);
5124 _204.closePath();
5125 _204.stroke();
5126 var _207=DIV(_205,tick[1]);
5127 _207.style.top=(y-this.options.axisLabelFontSize)+"px";
5128 _207.style.left=(x-this.options.padding.left-this.options.axisTickSize)+"px";
5129 _207.style.textAlign="right";
5130 _207.style.width=(this.options.padding.left-this.options.axisTickSize*2)+"px";
5131 MochiKit.DOM.appendChildNodes(this.container,_207);
5132 this.ylabels.push(_207);
5133 };
5134 MochiKit.Iter.forEach(this.layout.yticks,bind(_206,this));
5135 }
5136 _204.beginPath();
5137 _204.moveTo(this.area.x,this.area.y);
5138 _204.lineTo(this.area.x,this.area.y+this.area.h);
5139 _204.closePath();
5140 _204.stroke();
5141 }
5142 if(this.options.drawXAxis){
5143 if(this.layout.xticks){
5144 var _206=function(tick){
5145 if(typeof (dataset)=="function"){
5146 return;
5147 }
5148 var x=this.area.x+tick[0]*this.area.w;
5149 var y=this.area.y+this.area.h;
5150 _204.beginPath();
5151 _204.moveTo(x,y);
5152 _204.lineTo(x,y+this.options.axisTickSize);
5153 _204.closePath();
5154 _204.stroke();
5155 var _208=DIV(_205,tick[1]);
5156 _208.style.top=(y+this.options.axisTickSize)+"px";
5157 _208.style.left=(x-this.options.axisLabelWidth/2)+"px";
5158 _208.style.textAlign="center";
5159 _208.style.width=this.options.axisLabelWidth+"px";
5160 MochiKit.DOM.appendChildNodes(this.container,_208);
5161 this.xlabels.push(_208);
5162 };
5163 MochiKit.Iter.forEach(this.layout.xticks,bind(_206,this));
5164 }
5165 _204.beginPath();
5166 _204.moveTo(this.area.x,this.area.y+this.area.h);
5167 _204.lineTo(this.area.x+this.area.w,this.area.y+this.area.h);
5168 _204.closePath();
5169 _204.stroke();
5170 }
5171 _204.restore();
5172 };
5173 PlotKit.CanvasRenderer.prototype._renderPieAxis=function(){
5174 if(!this.options.drawXAxis){
5175 return;
5176 }
5177 if(this.layout.xticks){
5178 var _209=new Array();
5179 for(var i=0;i<this.layout.slices.length;i++){
5180 _209[this.layout.slices[i].xval]=this.layout.slices[i];
5181 }
5182 var _210=this.area.x+this.area.w*0.5;
5183 var _211=this.area.y+this.area.h*0.5;
5184 var _212=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
5185 var _213=this.options.axisLabelWidth;
5186 for(var i=0;i<this.layout.xticks.length;i++){
5187 var _214=_209[this.layout.xticks[i][0]];
5188 if(MochiKit.Base.isUndefinedOrNull(_214)){
5189 continue;
5190 }
5191 var _215=(_214.startAngle+_214.endAngle)/2;
5192 var _216=_215;
5193 if(_216>Math.PI*2){
5194 _216=_216-Math.PI*2;
5195 }else{
5196 if(_216<0){
5197 _216=_216+Math.PI*2;
5198 }
5199 }
5200 var _217=_210+Math.sin(_216)*(_212+10);
5201 var _218=_211-Math.cos(_216)*(_212+10);
5202 var _219={"position":"absolute","zIndex":11,"width":_213+"px","fontSize":this.options.axisLabelFontSize+"px","overflow":"hidden","color":this.options.axisLabelColor.toHexString()};
5203 if(_216<=Math.PI*0.5){
5204 _219["textAlign"]="left";
5205 _219["verticalAlign"]="top";
5206 _219["left"]=_217+"px";
5207 _219["top"]=(_218-this.options.axisLabelFontSize)+"px";
5208 }else{
5209 if((_216>Math.PI*0.5)&&(_216<=Math.PI)){
5210 _219["textAlign"]="left";
5211 _219["verticalAlign"]="bottom";
5212 _219["left"]=_217+"px";
5213 _219["top"]=_218+"px";
5214 }else{
5215 if((_216>Math.PI)&&(_216<=Math.PI*1.5)){
5216 _219["textAlign"]="right";
5217 _219["verticalAlign"]="bottom";
5218 _219["left"]=(_217-_213)+"px";
5219 _219["top"]=_218+"px";
5220 }else{
5221 _219["textAlign"]="right";
5222 _219["verticalAlign"]="bottom";
5223 _219["left"]=(_217-_213)+"px";
5224 _219["top"]=(_218-this.options.axisLabelFontSize)+"px";
5225 }
5226 }
5227 }
5228 var _220=DIV({"style":_219},this.layout.xticks[i][1]);
5229 this.xlabels.push(_220);
5230 MochiKit.DOM.appendChildNodes(this.container,_220);
5231 }
5232 }
5233 };
5234 PlotKit.CanvasRenderer.prototype._renderBackground=function(){
5235 var _221=this.element.getContext("2d");
5236 _221.save();
5237 _221.fillStyle=this.options.backgroundColor.toRGBString();
5238 _221.fillRect(0,0,this.width,this.height);
5239 _221.restore();
5240 };
5241 PlotKit.CanvasRenderer.prototype.clear=function(){
5242 if(this.isIE){
5243 try{
5244 if(this.clearDelay){
5245 this.clearDelay.cancel();
5246 this.clearDelay=null;
5247 }
5248 var _222=this.element.getContext("2d");
5249 }
5250 catch(e){
5251 this.isFirstRender=false;
5252 this.clearDelay=MochiKit.Async.wait(this.IEDelay);
5253 this.clearDelay.addCallback(bind(this.clear,this));
5254 return;
5255 }
5256 }
5257 var _222=this.element.getContext("2d");
5258 _222.clearRect(0,0,this.width,this.height);
5259 MochiKit.Iter.forEach(this.xlabels,MochiKit.DOM.removeElement);
5260 MochiKit.Iter.forEach(this.ylabels,MochiKit.DOM.removeElement);
5261 this.xlabels=new Array();
5262 this.ylabels=new Array();
5263 };
5264 PlotKit.CanvasRenderer.prototype._initialiseEvents=function(){
5265 var _223=MochiKit.Signal.connect;
5266 var bind=MochiKit.Base.bind;
5267 _223(this.element,"onclick",bind(this.onclick,this));
5268 };
5269 PlotKit.CanvasRenderer.prototype._resolveObject=function(e){
5270 var x=(e.mouse().page.x-PlotKit.Base.findPosX(this.element)-this.area.x)/this.area.w;
5271 var y=(e.mouse().page.y-PlotKit.Base.findPosY(this.element)-this.area.y)/this.area.h;
5272 var _225=this.layout.hitTest(x,y);
5273 if(_225){
5274 return _225;
5275 }
5276 return null;
5277 };
5278 PlotKit.CanvasRenderer.prototype._createEventObject=function(_226,e){
5279 if(_226==null){
5280 return null;
5281 }
5282 e.chart=_226;
5283 return e;
5284 };
5285 PlotKit.CanvasRenderer.prototype.onclick=function(e){
5286 var _227=this._resolveObject(e);
5287 var _228=this._createEventObject(_227,e);
5288 if(_228!=null){
5289 MochiKit.Signal.signal(this,"onclick",_228);
5290 }
5291 };
5292 PlotKit.CanvasRenderer.prototype.onmouseover=function(e){
5293 var _229=this._resolveObject(e);
5294 var _230=this._createEventObject(_229,e);
5295 if(_230!=null){
5296 signal(this,"onmouseover",_230);
5297 }
5298 };
5299 PlotKit.CanvasRenderer.prototype.onmouseout=function(e){
5300 var _231=this._resolveObject(e);
5301 var _232=this._createEventObject(_231,e);
5302 if(_232==null){
5303 signal(this,"onmouseout",e);
5304 }else{
5305 signal(this,"onmouseout",_232);
5306 }
5307 };
5308 PlotKit.CanvasRenderer.prototype.onmousemove=function(e){
5309 var _233=this._resolveObject(e);
5310 var _234=this._createEventObject(_233,e);
5311 if((_233==null)&&(this.event_isinside==null)){
5312 return;
5313 }
5314 if((_233!=null)&&(this.event_isinside==null)){
5315 signal(this,"onmouseover",_234);
5316 }
5317 if((_233==null)&&(this.event_isinside!=null)){
5318 signal(this,"onmouseout",_234);
5319 }
5320 if((_233!=null)&&(this.event_isinside!=null)){
5321 signal(this,"onmousemove",_234);
5322 }
5323 this.event_isinside=_233;
5324 };
5325 PlotKit.CanvasRenderer.isSupported=function(_235){
5326 var _236=null;
5327 try{
5328 if(MochiKit.Base.isUndefinedOrNull(_235)){
5329 _236=MochiKit.DOM.CANVAS({});
5330 }else{
5331 _236=MochiKit.DOM.getElement(_235);
5332 }
5333 var _237=_236.getContext("2d");
5334 }
5335 catch(e){
5336 var ie=navigator.appVersion.match(/MSIE (\d\.\d)/);
5337 var _239=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);
5338 if((!ie)||(ie[1]<6)||(_239)){
5339 return false;
5340 }
5341 return true;
5342 }
5343 return true;
5344 };
5345 PlotKit.Canvas={};
5346 PlotKit.Canvas.CanvasRenderer=PlotKit.CanvasRenderer;
5347 PlotKit.Canvas.EXPORT=["CanvasRenderer"];
5348 PlotKit.Canvas.EXPORT_OK=["CanvasRenderer"];
5349 PlotKit.Canvas.__new__=function(){
5350 var m=MochiKit.Base;
5351 m.nameFunctions(this);
5352 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
5353 };
5354 PlotKit.Canvas.__new__();
5355 MochiKit.Base._exportSymbols(this,PlotKit.Canvas);
5356
5357
5358 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
5359 // All Rights Reserved.
5360
5361 /**
5362 * @fileoverview Subclasses various parts of PlotKit to meet the additional
5363 * needs of DateGraph: grid overlays and error bars
5364 */
5365
5366 // Subclass PlotKit.Layout to add:
5367 // 1. Sigma/errorBars properties
5368 // 2. Copy error terms for PlotKit.CanvasRenderer._renderLineChart
5369
5370 /**
5371 * Creates a new DateGraphLayout object. Options are the same as those allowed
5372 * by the PlotKit.Layout constructor.
5373 * @param {Object} options Options for PlotKit.Layout
5374 * @return {Object} The DateGraphLayout object
5375 */
5376 DateGraphLayout = function(options) {
5377 PlotKit.Layout.call(this, "line", options);
5378 };
5379 DateGraphLayout.prototype = new PlotKit.Layout();
5380
5381 /**
5382 * Behaves the same way as PlotKit.Layout, but also copies the errors
5383 * @private
5384 */
5385 DateGraphLayout.prototype.evaluateWithError = function() {
5386 this.evaluate();
5387 if (!this.options.errorBars) return;
5388
5389 // Copy over the error terms
5390 var i = 0; // index in this.points
5391 for (var setName in this.datasets) {
5392 var j = 0;
5393 var dataset = this.datasets[setName];
5394 if (PlotKit.Base.isFuncLike(dataset)) continue;
5395 for (var j = 0; j < dataset.length; j++, i++) {
5396 var item = dataset[j];
5397 var xv = parseFloat(item[0]);
5398 var yv = parseFloat(item[1]);
5399
5400 if (xv == this.points[i].xval &&
5401 yv == this.points[i].yval) {
5402 this.points[i].errorMinus = parseFloat(item[2]);
5403 this.points[i].errorPlus = parseFloat(item[3]);
5404 }
5405 }
5406 }
5407 };
5408
5409 /**
5410 * Convenience function to remove all the data sets from a graph
5411 */
5412 DateGraphLayout.prototype.removeAllDatasets = function() {
5413 delete this.datasets;
5414 this.datasets = new Array();
5415 };
5416
5417 /**
5418 * Change the values of various layout options
5419 * @param {Object} new_options an associative array of new properties
5420 */
5421 DateGraphLayout.prototype.updateOptions = function(new_options) {
5422 MochiKit.Base.update(this.options, new_options ? new_options : {});
5423 };
5424
5425 // Subclass PlotKit.CanvasRenderer to add:
5426 // 1. X/Y grid overlay
5427 // 2. Ability to draw error bars (if required)
5428
5429 /**
5430 * Sets some PlotKit.CanvasRenderer options
5431 * @param {Object} element The canvas to attach to
5432 * @param {Layout} layout The DateGraphLayout object for this graph.
5433 * @param {Object} options Options to pass on to CanvasRenderer
5434 */
5435 DateGraphCanvasRenderer = function(element, layout, options) {
5436 PlotKit.CanvasRenderer.call(this, element, layout, options);
5437 this.options.shouldFill = false;
5438 this.options.shouldStroke = true;
5439 this.options.drawYGrid = true;
5440 this.options.drawXGrid = true;
5441 this.options.gridLineColor = MochiKit.Color.Color.grayColor();
5442 MochiKit.Base.update(this.options, options);
5443
5444 // TODO(danvk) This shouldn't be necessary: effects should be overlaid
5445 this.options.drawBackground = false;
5446 };
5447 DateGraphCanvasRenderer.prototype = new PlotKit.CanvasRenderer();
5448
5449 /**
5450 * Draw an X/Y grid on top of the existing plot
5451 */
5452 DateGraphCanvasRenderer.prototype.render = function() {
5453 // Do the ordinary rendering, as before
5454 // TODO(danvk) Call super.render()
5455 this._renderLineChart();
5456 this._renderLineAxis();
5457
5458 // Draw the new X/Y grid
5459 var ctx = this.element.getContext("2d");
5460 if (this.options.drawYGrid) {
5461 var ticks = this.layout.yticks;
5462 ctx.save();
5463 ctx.strokeStyle = this.options.gridLineColor.toRGBString();
5464 ctx.lineWidth = this.options.axisLineWidth;
5465 for (var i = 0; i < ticks.length; i++) {
5466 var x = this.area.x;
5467 var y = this.area.y + ticks[i][0] * this.area.h;
5468 ctx.beginPath();
5469 ctx.moveTo(x, y);
5470 ctx.lineTo(x + this.area.w, y);
5471 ctx.closePath();
5472 ctx.stroke();
5473 }
5474 }
5475
5476 if (this.options.drawXGrid) {
5477 var ticks = this.layout.xticks;
5478 ctx.save();
5479 ctx.strokeStyle = this.options.gridLineColor.toRGBString();
5480 ctx.lineWidth = this.options.axisLineWidth;
5481 for (var i=0; i<ticks.length; i++) {
5482 var x = this.area.x + ticks[i][0] * this.area.w;
5483 var y = this.area.y + this.area.h;
5484 ctx.beginPath();
5485 ctx.moveTo(x, y);
5486 ctx.lineTo(x, this.area.y);
5487 ctx.closePath();
5488 ctx.stroke();
5489 }
5490 }
5491 };
5492
5493 /**
5494 * Overrides the CanvasRenderer method to draw error bars
5495 */
5496 DateGraphCanvasRenderer.prototype._renderLineChart = function() {
5497 var context = this.element.getContext("2d");
5498 var colorCount = this.options.colorScheme.length;
5499 var colorScheme = this.options.colorScheme;
5500 var setNames = MochiKit.Base.keys(this.layout.datasets);
5501 var errorBars = this.layout.options.errorBars;
5502 var setCount = setNames.length;
5503 var bind = MochiKit.Base.bind;
5504 var partial = MochiKit.Base.partial;
5505
5506 //Update Points
5507 var updatePoint = function(point) {
5508 point.canvasx = this.area.w * point.x + this.area.x;
5509 point.canvasy = this.area.h * point.y + this.area.y;
5510 }
5511 MochiKit.Iter.forEach(this.layout.points, updatePoint, this);
5512
5513 // create paths
5514 var makePath = function(ctx) {
5515 for (var i = 0; i < setCount; i++) {
5516 var setName = setNames[i];
5517 var color = colorScheme[i%colorCount];
5518 var strokeX = this.options.strokeColorTransform;
5519
5520 // setup graphics context
5521 context.save();
5522 context.strokeStyle = color.toRGBString();
5523 context.lineWidth = this.options.strokeWidth;
5524 ctx.beginPath();
5525 var point = this.layout.points[0];
5526 var first_point = true;
5527 var addPoint = function(ctx_, point) {
5528 if (point.name == setName) {
5529 if (first_point)
5530 ctx_.moveTo(point.canvasx, point.canvasy);
5531 else
5532 ctx_.lineTo(point.canvasx, point.canvasy);
5533 first_point = false;
5534 }
5535 };
5536 MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this);
5537 ctx.stroke();
5538 }
5539 };
5540
5541 var makeErrorBars = function(ctx) {
5542 for (var i = 0; i < setCount; i++) {
5543 var setName = setNames[i];
5544 var color = colorScheme[i % colorCount];
5545 var strokeX = this.options.strokeColorTransform;
5546
5547 // setup graphics context
5548 context.save();
5549 context.strokeStyle = color.toRGBString();
5550 context.lineWidth = this.options.strokeWidth;
5551 var prevX = -1;
5552 var prevYs = [-1, -1];
5553 var count = 0;
5554 var yscale = this.layout.yscale;
5555 var errorTrapezoid = function(ctx_,point) {
5556 count++;
5557 if (point.name == setName) {
5558 var newYs = [ point.y - point.errorPlus * yscale,
5559 point.y + point.errorMinus * yscale ];
5560 newYs[0] = this.area.h * newYs[0] + this.area.y;
5561 newYs[1] = this.area.h * newYs[1] + this.area.y;
5562 if (prevX >= 0) {
5563 ctx_.moveTo(prevX, prevYs[0]);
5564 ctx_.lineTo(point.canvasx, newYs[0]);
5565 ctx_.lineTo(point.canvasx, newYs[1]);
5566 ctx_.lineTo(prevX, prevYs[1]);
5567 ctx_.closePath();
5568 }
5569 prevYs[0] = newYs[0];
5570 prevYs[1] = newYs[1];
5571 prevX = point.canvasx;
5572 }
5573 };
5574 // should be same color as the lines
5575 var err_color = color.colorWithAlpha(0.15);
5576 ctx.fillStyle = err_color.toRGBString();
5577 ctx.beginPath();
5578 MochiKit.Iter.forEach(this.layout.points, partial(errorTrapezoid, ctx), this);
5579 ctx.fill();
5580 }
5581 };
5582
5583 if (errorBars)
5584 bind(makeErrorBars, this)(context);
5585 bind(makePath, this)(context);
5586 context.restore();
5587 };
5588 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
5589 // All Rights Reserved.
5590
5591 /**
5592 * @fileoverview Creates an interactive, zoomable graph based on a CSV file or
5593 * string. DateGraph can handle multiple series with or without error bars. The
5594 * date/value ranges will be automatically set. DateGraph uses the
5595 * &lt;canvas&gt; tag, so it only works in FF1.5+.
5596 * @author danvdk@gmail.com (Dan Vanderkam)
5597
5598 Usage:
5599 <div id="graphdiv" style="width:800px; height:500px;"></div>
5600 <script type="text/javascript">
5601 new DateGraph(document.getElementById("graphdiv"),
5602 "datafile.csv",
5603 ["Series 1", "Series 2"],
5604 { }); // options
5605 </script>
5606
5607 The CSV file is of the form
5608
5609 YYYYMMDD,A1,B1,C1
5610 YYYYMMDD,A2,B2,C2
5611
5612 If null is passed as the third parameter (series names), then the first line
5613 of the CSV file is assumed to contain names for each series.
5614
5615 If the 'errorBars' option is set in the constructor, the input should be of
5616 the form
5617
5618 YYYYMMDD,A1,sigmaA1,B1,sigmaB1,...
5619 YYYYMMDD,A2,sigmaA2,B2,sigmaB2,...
5620
5621 If the 'fractions' option is set, the input should be of the form:
5622
5623 YYYYMMDD,A1/B1,A2/B2,...
5624 YYYYMMDD,A1/B1,A2/B2,...
5625
5626 And error bars will be calculated automatically using a binomial distribution.
5627
5628 For further documentation and examples, see http://www/~danvk/dg/
5629
5630 */
5631
5632 /**
5633 * An interactive, zoomable graph
5634 * @param {String | Function} file A file containing CSV data or a function that
5635 * returns this data. The expected format for each line is
5636 * YYYYMMDD,val1,val2,... or, if attrs.errorBars is set,
5637 * YYYYMMDD,val1,stddev1,val2,stddev2,...
5638 * @param {Array.<String>} labels Labels for the data series
5639 * @param {Object} attrs Various other attributes, e.g. errorBars determines
5640 * whether the input data contains error ranges.
5641 */
5642 DateGraph = function(div, file, labels, attrs) {
5643 if (arguments.length > 0)
5644 this.__init__(div, file, labels, attrs);
5645 };
5646
5647 DateGraph.NAME = "DateGraph";
5648 DateGraph.VERSION = "1.1";
5649 DateGraph.__repr__ = function() {
5650 return "[" + this.NAME + " " + this.VERSION + "]";
5651 };
5652 DateGraph.toString = function() {
5653 return this.__repr__();
5654 };
5655
5656 // Various default values
5657 DateGraph.DEFAULT_ROLL_PERIOD = 1;
5658 DateGraph.DEFAULT_WIDTH = 480;
5659 DateGraph.DEFAULT_HEIGHT = 320;
5660 DateGraph.DEFAULT_STROKE_WIDTH = 1.0;
5661 DateGraph.AXIS_LINE_WIDTH = 0.3;
5662
5663 /**
5664 * Initializes the DateGraph. This creates a new DIV and constructs the PlotKit
5665 * and interaction &lt;canvas&gt; inside of it. See the constructor for details
5666 * on the parameters.
5667 * @param {String | Function} file Source data
5668 * @param {Array.<String>} labels Names of the data series
5669 * @param {Object} attrs Miscellaneous other options
5670 * @private
5671 */
5672 DateGraph.prototype.__init__ = function(div, file, labels, attrs) {
5673 // Copy the important bits into the object
5674 this.maindiv_ = div;
5675 this.labels_ = labels;
5676 this.file_ = file;
5677 this.rollPeriod_ = attrs.rollPeriod || DateGraph.DEFAULT_ROLL_PERIOD;
5678 this.previousVerticalX_ = -1;
5679 this.width_ = parseInt(div.style.width, 10);
5680 this.height_ = parseInt(div.style.height, 10);
5681 this.errorBars_ = attrs.errorBars || false;
5682 this.fractions_ = attrs.fractions || false;
5683 this.strokeWidth_ = attrs.strokeWidth || DateGraph.DEFAULT_STROKE_WIDTH;
5684 this.dateWindow_ = attrs.dateWindow || null;
5685 this.valueRange_ = attrs.valueRange || null;
5686 this.labelsSeparateLines = attrs.labelsSeparateLines || false;
5687 this.labelsDiv_ = attrs.labelsDiv || null;
5688 this.labelsKMB_ = attrs.labelsKMB || false;
5689 this.minTickSize_ = attrs.minTickSize || 0;
5690 this.xValueParser_ = attrs.xValueParser || DateGraph.prototype.dateParser;
5691 this.xValueFormatter_ = attrs.xValueFormatter ||
5692 DateGraph.prototype.dateString_;
5693 this.xTicker_ = attrs.xTicker || DateGraph.prototype.dateTicker;
5694 this.sigma_ = attrs.sigma || 2.0;
5695 this.wilsonInterval_ = attrs.wilsonInterval || true;
5696 this.customBars_ = attrs.customBars || false;
5697 this.attrs_ = attrs;
5698
5699 // Make a note of whether labels will be pulled from the CSV file.
5700 this.labelsFromCSV_ = (this.labels_ == null);
5701 if (this.labels_ == null)
5702 this.labels_ = [];
5703
5704 // Prototype of the callback is "void clickCallback(event, date)"
5705 this.clickCallback_ = attrs.clickCallback || null;
5706
5707 // Prototype of zoom callback is "void dragCallback(minDate, maxDate)"
5708 this.zoomCallback_ = attrs.zoomCallback || null;
5709
5710 // Create the containing DIV and other interactive elements
5711 this.createInterface_();
5712
5713 // Create the PlotKit grapher
5714 this.layoutOptions_ = { 'errorBars': (this.errorBars_ || this.customBars_),
5715 'xOriginIsZero': false };
5716 MochiKit.Base.update(this.layoutOptions_, attrs);
5717 this.setColors_(attrs);
5718
5719 this.layout_ = new DateGraphLayout(this.layoutOptions_);
5720
5721 this.renderOptions_ = { colorScheme: this.colors_,
5722 strokeColor: null,
5723 strokeWidth: this.strokeWidth_,
5724 axisLabelFontSize: 14,
5725 axisLineWidth: DateGraph.AXIS_LINE_WIDTH };
5726 MochiKit.Base.update(this.renderOptions_, attrs);
5727 this.plotter_ = new DateGraphCanvasRenderer(this.hidden_, this.layout_,
5728 this.renderOptions_);
5729
5730 this.createStatusMessage_();
5731 this.createRollInterface_();
5732 this.createDragInterface_();
5733
5734 connect(window, 'onload', this, function(e) { this.start_(); });
5735 };
5736
5737 /**
5738 * Returns the current rolling period, as set by the user or an option.
5739 * @return {Number} The number of days in the rolling window
5740 */
5741 DateGraph.prototype.rollPeriod = function() {
5742 return this.rollPeriod_;
5743 }
5744
5745 /**
5746 * Generates interface elements for the DateGraph: a containing div, a div to
5747 * display the current point, and a textbox to adjust the rolling average
5748 * period.
5749 * @private
5750 */
5751 DateGraph.prototype.createInterface_ = function() {
5752 // Create the all-enclosing graph div
5753 var enclosing = this.maindiv_;
5754
5755 this.graphDiv = MochiKit.DOM.DIV( { style: { 'width': this.width_ + "px",
5756 'height': this.height_ + "px"
5757 }});
5758 appendChildNodes(enclosing, this.graphDiv);
5759
5760 // Create the canvas to store
5761 var canvas = MochiKit.DOM.CANVAS;
5762 this.canvas_ = canvas( { style: { 'position': 'absolute' },
5763 width: this.width_,
5764 height: this.height_});
5765 appendChildNodes(this.graphDiv, this.canvas_);
5766
5767 this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
5768 connect(this.hidden_, 'onmousemove', this, function(e) { this.mouseMove_(e) });
5769 connect(this.hidden_, 'onmouseout', this, function(e) { this.mouseOut_(e) });
5770 }
5771
5772 /**
5773 * Creates the canvas containing the PlotKit graph. Only plotkit ever draws on
5774 * this particular canvas. All DateGraph work is done on this.canvas_.
5775 * @param {Object} canvas The DateGraph canvas to over which to overlay the plot
5776 * @return {Object} The newly-created canvas
5777 * @private
5778 */
5779 DateGraph.prototype.createPlotKitCanvas_ = function(canvas) {
5780 var h = document.createElement("canvas");
5781 h.style.position = "absolute";
5782 h.style.top = canvas.style.top;
5783 h.style.left = canvas.style.left;
5784 h.width = this.width_;
5785 h.height = this.height_;
5786 MochiKit.DOM.appendChildNodes(this.graphDiv, h);
5787 return h;
5788 };
5789
5790 /**
5791 * Generate a set of distinct colors for the data series. This is done with a
5792 * color wheel. Saturation/Value are customizable, and the hue is
5793 * equally-spaced around the color wheel. If a custom set of colors is
5794 * specified, that is used instead.
5795 * @param {Object} attrs Various attributes, e.g. saturation and value
5796 * @private
5797 */
5798 DateGraph.prototype.setColors_ = function(attrs) {
5799 var num = this.labels_.length;
5800 this.colors_ = [];
5801 if (!attrs.colors) {
5802 var sat = attrs.colorSaturation || 1.0;
5803 var val = attrs.colorValue || 0.5;
5804 for (var i = 1; i <= num; i++) {
5805 var hue = (1.0*i/(1+num));
5806 this.colors_.push( MochiKit.Color.Color.fromHSV(hue, sat, val) );
5807 }
5808 } else {
5809 for (var i = 0; i < num; i++) {
5810 var colorStr = attrs.colors[i % attrs.colors.length];
5811 this.colors_.push( MochiKit.Color.Color.fromString(colorStr) );
5812 }
5813 }
5814 }
5815
5816 /**
5817 * Create the div that contains information on the selected point(s)
5818 * This goes in the top right of the canvas, unless an external div has already
5819 * been specified.
5820 * @private
5821 */
5822 DateGraph.prototype.createStatusMessage_ = function(){
5823 if (!this.labelsDiv_) {
5824 var divWidth = 250;
5825 var messagestyle = { "style": {
5826 "position": "absolute",
5827 "fontSize": "14px",
5828 "zIndex": 10,
5829 "width": divWidth + "px",
5830 "top": "0px",
5831 "left": this.width_ - divWidth + "px",
5832 "background": "white",
5833 "textAlign": "left",
5834 "overflow": "hidden"}};
5835 this.labelsDiv_ = MochiKit.DOM.DIV(messagestyle);
5836 MochiKit.DOM.appendChildNodes(this.graphDiv, this.labelsDiv_);
5837 }
5838 };
5839
5840 /**
5841 * Create the text box to adjust the averaging period
5842 * @return {Object} The newly-created text box
5843 * @private
5844 */
5845 DateGraph.prototype.createRollInterface_ = function() {
5846 var padding = this.plotter_.options.padding;
5847 var textAttr = { "type": "text",
5848 "size": "2",
5849 "value": this.rollPeriod_,
5850 "style": { "position": "absolute",
5851 "zIndex": 10,
5852 "top": (this.height_ - 25 - padding.bottom) + "px",
5853 "left": (padding.left+1) + "px" }
5854 };
5855 var roller = MochiKit.DOM.INPUT(textAttr);
5856 var pa = this.graphDiv;
5857 MochiKit.DOM.appendChildNodes(pa, roller);
5858 connect(roller, 'onchange', this,
5859 function() { this.adjustRoll(roller.value); });
5860 return roller;
5861 }
5862
5863 /**
5864 * Set up all the mouse handlers needed to capture dragging behavior for zoom
5865 * events. Uses MochiKit.Signal to attach all the event handlers.
5866 * @private
5867 */
5868 DateGraph.prototype.createDragInterface_ = function() {
5869 var self = this;
5870
5871 // Tracks whether the mouse is down right now
5872 var mouseDown = false;
5873 var dragStartX = null;
5874 var dragStartY = null;
5875 var dragEndX = null;
5876 var dragEndY = null;
5877 var prevEndX = null;
5878
5879 // Utility function to convert page-wide coordinates to canvas coords
5880 var px = PlotKit.Base.findPosX(this.canvas_);
5881 var py = PlotKit.Base.findPosY(this.canvas_);
5882 var getX = function(e) { return e.mouse().page.x - px };
5883 var getY = function(e) { return e.mouse().page.y - py };
5884
5885 // Draw zoom rectangles when the mouse is down and the user moves around
5886 connect(this.hidden_, 'onmousemove', function(event) {
5887 if (mouseDown) {
5888 dragEndX = getX(event);
5889 dragEndY = getY(event);
5890
5891 self.drawZoomRect_(dragStartX, dragEndX, prevEndX);
5892 prevEndX = dragEndX;
5893 }
5894 });
5895
5896 // Track the beginning of drag events
5897 connect(this.hidden_, 'onmousedown', function(event) {
5898 mouseDown = true;
5899 dragStartX = getX(event);
5900 dragStartY = getY(event);
5901 });
5902
5903 // If the user releases the mouse button during a drag, but not over the
5904 // canvas, then it doesn't count as a zooming action.
5905 connect(document, 'onmouseup', this, function(event) {
5906 if (mouseDown) {
5907 mouseDown = false;
5908 dragStartX = null;
5909 dragStartY = null;
5910 }
5911 });
5912
5913 // Temporarily cancel the dragging event when the mouse leaves the graph
5914 connect(this.hidden_, 'onmouseout', this, function(event) {
5915 if (mouseDown) {
5916 dragEndX = null;
5917 dragEndY = null;
5918 }
5919 });
5920
5921 // If the mouse is released on the canvas during a drag event, then it's a
5922 // zoom. Only do the zoom if it's over a large enough area (>= 10 pixels)
5923 connect(this.hidden_, 'onmouseup', this, function(event) {
5924 if (mouseDown) {
5925 mouseDown = false;
5926 dragEndX = getX(event);
5927 dragEndY = getY(event);
5928 var regionWidth = Math.abs(dragEndX - dragStartX);
5929 var regionHeight = Math.abs(dragEndY - dragStartY);
5930
5931 if (regionWidth < 2 && regionHeight < 2 &&
5932 self.clickCallback_ != null &&
5933 self.lastx_ != undefined) {
5934 self.clickCallback_(event, new Date(self.lastx_));
5935 }
5936
5937 if (regionWidth >= 10) {
5938 self.doZoom_(Math.min(dragStartX, dragEndX),
5939 Math.max(dragStartX, dragEndX));
5940 } else {
5941 self.canvas_.getContext("2d").clearRect(0, 0,
5942 self.canvas_.width,
5943 self.canvas_.height);
5944 }
5945
5946 dragStartX = null;
5947 dragStartY = null;
5948 }
5949 });
5950
5951 // Double-clicking zooms back out
5952 connect(this.hidden_, 'ondblclick', this, function(event) {
5953 self.dateWindow_ = null;
5954 self.drawGraph_(self.rawData_);
5955 var minDate = self.rawData_[0][0];
5956 var maxDate = self.rawData_[self.rawData_.length - 1][0];
5957 self.zoomCallback_(minDate, maxDate);
5958 });
5959 };
5960
5961 /**
5962 * Draw a gray zoom rectangle over the desired area of the canvas. Also clears
5963 * up any previous zoom rectangles that were drawn. This could be optimized to
5964 * avoid extra redrawing, but it's tricky to avoid interactions with the status
5965 * dots.
5966 * @param {Number} startX The X position where the drag started, in canvas
5967 * coordinates.
5968 * @param {Number} endX The current X position of the drag, in canvas coords.
5969 * @param {Number} prevEndX The value of endX on the previous call to this
5970 * function. Used to avoid excess redrawing
5971 * @private
5972 */
5973 DateGraph.prototype.drawZoomRect_ = function(startX, endX, prevEndX) {
5974 var ctx = this.canvas_.getContext("2d");
5975
5976 // Clean up from the previous rect if necessary
5977 if (prevEndX) {
5978 ctx.clearRect(Math.min(startX, prevEndX), 0,
5979 Math.abs(startX - prevEndX), this.height_);
5980 }
5981
5982 // Draw a light-grey rectangle to show the new viewing area
5983 if (endX && startX) {
5984 ctx.fillStyle = "rgba(128,128,128,0.33)";
5985 ctx.fillRect(Math.min(startX, endX), 0,
5986 Math.abs(endX - startX), this.height_);
5987 }
5988 };
5989
5990 /**
5991 * Zoom to something containing [lowX, highX]. These are pixel coordinates
5992 * in the canvas. The exact zoom window may be slightly larger if there are no
5993 * data points near lowX or highX. This function redraws the graph.
5994 * @param {Number} lowX The leftmost pixel value that should be visible.
5995 * @param {Number} highX The rightmost pixel value that should be visible.
5996 * @private
5997 */
5998 DateGraph.prototype.doZoom_ = function(lowX, highX) {
5999 // Find the earliest and latest dates contained in this canvasx range.
6000 var points = this.layout_.points;
6001 var minDate = null;
6002 var maxDate = null;
6003 // Find the nearest [minDate, maxDate] that contains [lowX, highX]
6004 for (var i = 0; i < points.length; i++) {
6005 var cx = points[i].canvasx;
6006 var x = points[i].xval;
6007 if (cx < lowX && (minDate == null || x > minDate)) minDate = x;
6008 if (cx > highX && (maxDate == null || x < maxDate)) maxDate = x;
6009 }
6010 // Use the extremes if either is missing
6011 if (minDate == null) minDate = points[0].xval;
6012 if (maxDate == null) maxDate = points[points.length-1].xval;
6013
6014 this.dateWindow_ = [minDate, maxDate];
6015 this.drawGraph_(this.rawData_);
6016 this.zoomCallback_(minDate, maxDate);
6017 };
6018
6019 /**
6020 * When the mouse moves in the canvas, display information about a nearby data
6021 * point and draw dots over those points in the data series. This function
6022 * takes care of cleanup of previously-drawn dots.
6023 * @param {Object} event The mousemove event from the browser.
6024 * @private
6025 */
6026 DateGraph.prototype.mouseMove_ = function(event) {
6027 var canvasx = event.mouse().page.x - PlotKit.Base.findPosX(this.hidden_);
6028 var points = this.layout_.points;
6029
6030 var lastx = -1;
6031 var lasty = -1;
6032
6033 // Loop through all the points and find the date nearest to our current
6034 // location.
6035 var minDist = 1e+100;
6036 var idx = -1;
6037 for (var i = 0; i < points.length; i++) {
6038 var dist = Math.abs(points[i].canvasx - canvasx);
6039 if (dist > minDist) break;
6040 minDist = dist;
6041 idx = i;
6042 }
6043 if (idx >= 0) lastx = points[idx].xval;
6044 // Check that you can really highlight the last day's data
6045 if (canvasx > points[points.length-1].canvasx)
6046 lastx = points[points.length-1].xval;
6047
6048 // Extract the points we've selected
6049 var selPoints = [];
6050 for (var i = 0; i < points.length; i++) {
6051 if (points[i].xval == lastx) {
6052 selPoints.push(points[i]);
6053 }
6054 }
6055
6056 // Clear the previously drawn vertical, if there is one
6057 var circleSize = 3;
6058 var ctx = this.canvas_.getContext("2d");
6059 if (this.previousVerticalX_ >= 0) {
6060 var px = this.previousVerticalX_;
6061 ctx.clearRect(px - circleSize - 1, 0, 2 * circleSize + 2, this.height_);
6062 }
6063
6064 if (selPoints.length > 0) {
6065 var canvasx = selPoints[0].canvasx;
6066
6067 // Set the status message to indicate the selected point(s)
6068 var replace = this.xValueFormatter_(lastx) + ":";
6069 var clen = this.colors_.length;
6070 for (var i = 0; i < selPoints.length; i++) {
6071 if (this.labelsSeparateLines) {
6072 replace += "<br/>";
6073 }
6074 var point = selPoints[i];
6075 replace += " <b><font color='" + this.colors_[i%clen].toHexString() + "'>"
6076 + point.name + "</font></b>:"
6077 + this.round_(point.yval, 2);
6078 }
6079 this.labelsDiv_.innerHTML = replace;
6080
6081 // Save last x position for callbacks.
6082 this.lastx_ = lastx;
6083
6084 // Draw colored circles over the center of each selected point
6085 ctx.save()
6086 for (var i = 0; i < selPoints.length; i++) {
6087 ctx.beginPath();
6088 ctx.fillStyle = this.colors_[i%clen].toRGBString();
6089 ctx.arc(canvasx, selPoints[i%clen].canvasy, circleSize, 0, 360, false);
6090 ctx.fill();
6091 }
6092 ctx.restore();
6093
6094 this.previousVerticalX_ = canvasx;
6095 }
6096 };
6097
6098 /**
6099 * The mouse has left the canvas. Clear out whatever artifacts remain
6100 * @param {Object} event the mouseout event from the browser.
6101 * @private
6102 */
6103 DateGraph.prototype.mouseOut_ = function(event) {
6104 // Get rid of the overlay data
6105 var ctx = this.canvas_.getContext("2d");
6106 ctx.clearRect(0, 0, this.width_, this.height_);
6107 this.labelsDiv_.innerHTML = "";
6108 };
6109
6110 /**
6111 * Convert a JS date (millis since epoch) to YYYY/MM/DD
6112 * @param {Number} date The JavaScript date (ms since epoch)
6113 * @return {String} A date of the form "YYYY/MM/DD"
6114 * @private
6115 */
6116 DateGraph.prototype.dateString_ = function(date) {
6117 var d = new Date(date);
6118
6119 // Get the year:
6120 var year = "" + d.getFullYear();
6121 // Get a 0 padded month string
6122 var month = "" + (d.getMonth() + 1); //months are 0-offset, sigh
6123 if (month.length < 2) month = "0" + month;
6124 // Get a 0 padded day string
6125 var day = "" + d.getDate();
6126 if (day.length < 2) day = "0" + day;
6127
6128 return year + "/" + month + "/" + day;
6129 };
6130
6131 /**
6132 * Round a number to the specified number of digits past the decimal point.
6133 * @param {Number} num The number to round
6134 * @param {Number} places The number of decimals to which to round
6135 * @return {Number} The rounded number
6136 * @private
6137 */
6138 DateGraph.prototype.round_ = function(num, places) {
6139 var shift = Math.pow(10, places);
6140 return Math.round(num * shift)/shift;
6141 };
6142
6143 /**
6144 * Fires when there's data available to be graphed.
6145 * @param {String} data Raw CSV data to be plotted
6146 * @private
6147 */
6148 DateGraph.prototype.loadedEvent_ = function(data) {
6149 this.rawData_ = this.parseCSV_(data);
6150 this.drawGraph_(this.rawData_);
6151 };
6152
6153 DateGraph.prototype.months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
6154 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
6155 DateGraph.prototype.quarters = ["Jan", "Apr", "Jul", "Oct"];
6156
6157 /**
6158 * Add ticks on the x-axis representing years, months, quarters, weeks, or days
6159 * @private
6160 */
6161 DateGraph.prototype.addXTicks_ = function() {
6162 // Determine the correct ticks scale on the x-axis: quarterly, monthly, ...
6163 var startDate, endDate;
6164 if (this.dateWindow_) {
6165 startDate = this.dateWindow_[0];
6166 endDate = this.dateWindow_[1];
6167 } else {
6168 startDate = this.rawData_[0][0];
6169 endDate = this.rawData_[this.rawData_.length - 1][0];
6170 }
6171
6172 var xTicks = this.xTicker_(startDate, endDate);
6173 this.layout_.updateOptions({xTicks: xTicks});
6174 }
6175
6176 /**
6177 * Add ticks to the x-axis based on a date range.
6178 * @param {Number} startDate Start of the date window (millis since epoch)
6179 * @param {Number} endDate End of the date window (millis since epoch)
6180 * @return {Array.<Object>} Array of {label, value} tuples.
6181 * @public
6182 */
6183 DateGraph.prototype.dateTicker = function(startDate, endDate) {
6184 var ONE_DAY = 24*60*60*1000;
6185 startDate = startDate / ONE_DAY;
6186 endDate = endDate / ONE_DAY;
6187 var dateSpan = endDate - startDate;
6188
6189 var scale = [];
6190 var isMonthly = false;
6191 var yearMod = 1;
6192 if (dateSpan > 30 * 366) { // decadal
6193 isMonthly = true;
6194 scale = ["Jan"];
6195 yearMod = 10;
6196 } else if (dateSpan > 4*366) { // annual
6197 scale = ["Jan"];
6198 isMonthly = true;
6199 } else if (dateSpan > 366) { // quarterly
6200 scale = this.quarters;
6201 isMonthly = true;
6202 } else if (dateSpan > 40) { // monthly
6203 scale = this.months;
6204 isMonthly = true;
6205 } else if (dateSpan > 10) { // weekly
6206 for (var week = startDate - 14; week < endDate + 14; week += 7) {
6207 scale.push(week * ONE_DAY);
6208 }
6209 } else { // daily
6210 for (var day = startDate - 14; day < endDate + 14; day += 1) {
6211 scale.push(day * ONE_DAY);
6212 }
6213 }
6214
6215 var xTicks = [];
6216
6217 if (isMonthly) {
6218 var startYear = 1900 + (new Date(startDate* ONE_DAY)).getYear();
6219 var endYear = 1900 + (new Date(endDate * ONE_DAY)).getYear();
6220 for (var i = startYear; i <= endYear; i++) {
6221 if (i % yearMod != 0) continue;
6222 for (var j = 0; j < scale.length; j++ ) {
6223 var date = Date.parse(scale[j] + " 1, " + i);
6224 xTicks.push( {label: scale[j] + "'" + ("" + i).substr(2,2), v: date } );
6225 }
6226 }
6227 } else {
6228 for (var i = 0; i < scale.length; i++) {
6229 var date = new Date(scale[i]);
6230 var year = date.getFullYear().toString();
6231 var label = this.months[date.getMonth()] + date.getDate();
6232 label += "'" + year.substr(year.length - 2, 2);
6233 xTicks.push( {label: label, v: date} );
6234 }
6235 }
6236 return xTicks;
6237 };
6238
6239 /**
6240 * Add ticks when the x axis has numbers on it (instead of dates)
6241 * @param {Number} startDate Start of the date window (millis since epoch)
6242 * @param {Number} endDate End of the date window (millis since epoch)
6243 * @return {Array.<Object>} Array of {label, value} tuples.
6244 * @public
6245 */
6246 DateGraph.prototype.numericTicks = function(minV, maxV) {
6247 var scale;
6248 if (maxV <= 0.0) {
6249 scale = 1.0;
6250 } else {
6251 scale = Math.pow( 10, Math.floor(Math.log(maxV)/Math.log(10.0)) );
6252 }
6253
6254 // Add a smallish number of ticks at human-friendly points
6255 var nTicks = (maxV - minV) / scale;
6256 while (2 * nTicks < 20) {
6257 nTicks *= 2;
6258 }
6259 if ((maxV - minV) / nTicks < this.minTickSize_) {
6260 nTicks = this.round_((maxV - minV) / this.minTickSize_, 1);
6261 }
6262
6263 // Construct labels for the ticks
6264 var ticks = [];
6265 for (var i = 0; i <= nTicks; i++) {
6266 var tickV = minV + i * (maxV - minV) / nTicks;
6267 var label = this.round_(tickV, 2);
6268 if (this.labelsKMB_) {
6269 var k = 1000;
6270 if (tickV >= k*k*k) {
6271 label = this.round_(tickV/(k*k*k), 1) + "B";
6272 } else if (tickV >= k*k) {
6273 label = this.round_(tickV/(k*k), 1) + "M";
6274 } else if (tickV >= k) {
6275 label = this.round_(tickV/k, 1) + "K";
6276 }
6277 }
6278 ticks.push( {label: label, v: tickV} );
6279 }
6280 return ticks;
6281 };
6282
6283 /**
6284 * Adds appropriate ticks on the y-axis
6285 * @param {Number} minY The minimum Y value in the data set
6286 * @param {Number} maxY The maximum Y value in the data set
6287 * @private
6288 */
6289 DateGraph.prototype.addYTicks_ = function(minY, maxY) {
6290 // Set the number of ticks so that the labels are human-friendly.
6291 var ticks = this.numericTicks(minY, maxY);
6292 this.layout_.updateOptions( { yAxis: [minY, maxY],
6293 yTicks: ticks } );
6294 };
6295
6296 /**
6297 * Update the graph with new data. Data is in the format
6298 * [ [date1, val1, val2, ...], [date2, val1, val2, ...] if errorBars=false
6299 * or, if errorBars=true,
6300 * [ [date1, [val1,stddev1], [val2,stddev2], ...], [date2, ...], ...]
6301 * @param {Array.<Object>} data The data (see above)
6302 * @private
6303 */
6304 DateGraph.prototype.drawGraph_ = function(data) {
6305 var maxY = null;
6306 this.layout_.removeAllDatasets();
6307 // Loop over all fields in the dataset
6308 for (var i = 1; i < data[0].length; i++) {
6309 var series = [];
6310 for (var j = 0; j < data.length; j++) {
6311 var date = data[j][0];
6312 series[j] = [date, data[j][i]];
6313 }
6314 series = this.rollingAverage(series, this.rollPeriod_);
6315
6316 // Prune down to the desired range, if necessary (for zooming)
6317 var bars = this.errorBars_ || this.customBars_;
6318 if (this.dateWindow_) {
6319 var low = this.dateWindow_[0];
6320 var high= this.dateWindow_[1];
6321 var pruned = [];
6322 for (var k = 0; k < series.length; k++) {
6323 if (series[k][0] >= low && series[k][0] <= high) {
6324 pruned.push(series[k]);
6325 var y = bars ? series[k][1][0] : series[k][1];
6326 if (maxY == null || y > maxY) maxY = y;
6327 }
6328 }
6329 series = pruned;
6330 } else {
6331 for (var j = 0; j < series.length; j++) {
6332 var y = bars ? series[j][1][0] : series[j][1];
6333 if (maxY == null || y > maxY) {
6334 maxY = bars ? y + series[j][1][1] : y;
6335 }
6336 }
6337 }
6338
6339 if (bars) {
6340 var vals = [];
6341 for (var j=0; j<series.length; j++)
6342 vals[j] = [series[j][0],
6343 series[j][1][0], series[j][1][1], series[j][1][2]];
6344 this.layout_.addDataset(this.labels_[i - 1], vals);
6345 } else {
6346 this.layout_.addDataset(this.labels_[i - 1], series);
6347 }
6348 }
6349
6350 // Use some heuristics to come up with a good maxY value, unless it's been
6351 // set explicitly by the user.
6352 if (this.valueRange_ != null) {
6353 this.addYTicks_(this.valueRange_[0], this.valueRange_[1]);
6354 } else {
6355 // Add some padding and round up to an integer to be human-friendly.
6356 maxY *= 1.1;
6357 if (maxY <= 0.0) maxY = 1.0;
6358 else {
6359 var scale = Math.pow(10, Math.floor(Math.log(maxY) / Math.log(10.0)));
6360 maxY = scale * Math.ceil(maxY / scale);
6361 }
6362 this.addYTicks_(0, maxY);
6363 }
6364
6365 this.addXTicks_();
6366
6367 // Tell PlotKit to use this new data and render itself
6368 this.layout_.evaluateWithError();
6369 this.plotter_.clear();
6370 this.plotter_.render();
6371 this.canvas_.getContext('2d').clearRect(0, 0,
6372 this.canvas_.width, this.canvas_.height);
6373 };
6374
6375 /**
6376 * Calculates the rolling average of a data set.
6377 * If originalData is [label, val], rolls the average of those.
6378 * If originalData is [label, [, it's interpreted as [value, stddev]
6379 * and the roll is returned in the same form, with appropriately reduced
6380 * stddev for each value.
6381 * Note that this is where fractional input (i.e. '5/10') is converted into
6382 * decimal values.
6383 * @param {Array} originalData The data in the appropriate format (see above)
6384 * @param {Number} rollPeriod The number of days over which to average the data
6385 */
6386 DateGraph.prototype.rollingAverage = function(originalData, rollPeriod) {
6387 if (originalData.length < 2)
6388 return originalData;
6389 var rollPeriod = Math.min(rollPeriod, originalData.length - 1);
6390 var rollingData = [];
6391 var sigma = this.sigma_;
6392
6393 if (this.fractions_) {
6394 var num = 0;
6395 var den = 0; // numerator/denominator
6396 var mult = 100.0;
6397 for (var i = 0; i < originalData.length; i++) {
6398 num += originalData[i][1][0];
6399 den += originalData[i][1][1];
6400 if (i - rollPeriod >= 0) {
6401 num -= originalData[i - rollPeriod][1][0];
6402 den -= originalData[i - rollPeriod][1][1];
6403 }
6404
6405 var date = originalData[i][0];
6406 var value = den ? num / den : 0.0;
6407 if (this.errorBars_) {
6408 if (this.wilsonInterval_) {
6409 // For more details on this confidence interval, see:
6410 // http://en.wikipedia.org/wiki/Binomial_confidence_interval
6411 if (den) {
6412 var p = value < 0 ? 0 : value, n = den;
6413 var pm = sigma * Math.sqrt(p*(1-p)/n + sigma*sigma/(4*n*n));
6414 var denom = 1 + sigma * sigma / den;
6415 var low = (p + sigma * sigma / (2 * den) - pm) / denom;
6416 var high = (p + sigma * sigma / (2 * den) + pm) / denom;
6417 rollingData[i] = [date,
6418 [p * mult, (p - low) * mult, (high - p) * mult]];
6419 } else {
6420 rollingData[i] = [date, [0, 0, 0]];
6421 }
6422 } else {
6423 var stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0;
6424 rollingData[i] = [date, [mult * value, mult * stddev, mult * stddev]];
6425 }
6426 } else {
6427 rollingData[i] = [date, mult * value];
6428 }
6429 }
6430 } else if (this.customBars_) {
6431 // just ignore the rolling for now.
6432 // TODO(danvk): do something reasonable.
6433 for (var i = 0; i < originalData.length; i++) {
6434 var data = originalData[i][1];
6435 var y = data[1];
6436 rollingData[i] = [originalData[i][0], [y, y - data[0], data[2] - y]];
6437 }
6438 } else {
6439 // Calculate the rolling average for the first rollPeriod - 1 points where
6440 // there is not enough data to roll over the full number of days
6441 var num_init_points = Math.min(rollPeriod - 1, originalData.length - 2);
6442 if (!this.errorBars_){
6443 for (var i = 0; i < num_init_points; i++) {
6444 var sum = 0;
6445 for (var j = 0; j < i + 1; j++)
6446 sum += originalData[j][1];
6447 rollingData[i] = [originalData[i][0], sum / (i + 1)];
6448 }
6449 // Calculate the rolling average for the remaining points
6450 for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
6451 i < originalData.length;
6452 i++) {
6453 var sum = 0;
6454 for (var j = i - rollPeriod + 1; j < i + 1; j++)
6455 sum += originalData[j][1];
6456 rollingData[i] = [originalData[i][0], sum / rollPeriod];
6457 }
6458 } else {
6459 for (var i = 0; i < num_init_points; i++) {
6460 var sum = 0;
6461 var variance = 0;
6462 for (var j = 0; j < i + 1; j++) {
6463 sum += originalData[j][1][0];
6464 variance += Math.pow(originalData[j][1][1], 2);
6465 }
6466 var stddev = Math.sqrt(variance)/(i+1);
6467 rollingData[i] = [originalData[i][0],
6468 [sum/(i+1), sigma * stddev, sigma * stddev]];
6469 }
6470 // Calculate the rolling average for the remaining points
6471 for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
6472 i < originalData.length;
6473 i++) {
6474 var sum = 0;
6475 var variance = 0;
6476 for (var j = i - rollPeriod + 1; j < i + 1; j++) {
6477 sum += originalData[j][1][0];
6478 variance += Math.pow(originalData[j][1][1], 2);
6479 }
6480 var stddev = Math.sqrt(variance) / rollPeriod;
6481 rollingData[i] = [originalData[i][0],
6482 [sum / rollPeriod, sigma * stddev, sigma * stddev]];
6483 }
6484 }
6485 }
6486
6487 return rollingData;
6488 };
6489
6490 /**
6491 * Parses a date, returning the number of milliseconds since epoch. This can be
6492 * passed in as an xValueParser in the DateGraph constructor.
6493 * @param {String} A date in YYYYMMDD format.
6494 * @return {Number} Milliseconds since epoch.
6495 * @public
6496 */
6497 DateGraph.prototype.dateParser = function(dateStr) {
6498 var dateStrSlashed;
6499 if (dateStr.search("-") != -1) {
6500 dateStrSlashed = dateStr.replace("-", "/", "g");
6501 } else if (dateStr.search("/") != -1) {
6502 return Date.parse(dateStr);
6503 } else {
6504 dateStrSlashed = dateStr.substr(0,4) + "/" + dateStr.substr(4,2)
6505 + "/" + dateStr.substr(6,2);
6506 }
6507 return Date.parse(dateStrSlashed);
6508 };
6509
6510 /**
6511 * Parses a string in a special csv format. We expect a csv file where each
6512 * line is a date point, and the first field in each line is the date string.
6513 * We also expect that all remaining fields represent series.
6514 * if this.errorBars_ is set, then interpret the fields as:
6515 * date, series1, stddev1, series2, stddev2, ...
6516 * @param {Array.<Object>} data See above.
6517 * @private
6518 */
6519 DateGraph.prototype.parseCSV_ = function(data) {
6520 var ret = [];
6521 var lines = data.split("\n");
6522 var start = this.labelsFromCSV_ ? 1 : 0;
6523 if (this.labelsFromCSV_) {
6524 var labels = lines[0].split(",");
6525 labels.shift(); // a "date" parameter is assumed.
6526 this.labels_ = labels;
6527 // regenerate automatic colors.
6528 this.setColors_(this.attrs_);
6529 this.renderOptions_.colorScheme = this.colors_;
6530 MochiKit.Base.update(this.plotter_.options, this.renderOptions_);
6531 MochiKit.Base.update(this.layoutOptions_, this.attrs_);
6532 }
6533
6534 for (var i = start; i < lines.length; i++) {
6535 var line = lines[i];
6536 if (line.length == 0) continue; // skip blank lines
6537 var inFields = line.split(',');
6538 if (inFields.length < 2)
6539 continue;
6540
6541 var fields = [];
6542 fields[0] = this.xValueParser_(inFields[0]);
6543
6544 // If fractions are expected, parse the numbers as "A/B"
6545 if (this.fractions_) {
6546 for (var j = 1; j < inFields.length; j++) {
6547 // TODO(danvk): figure out an appropriate way to flag parse errors.
6548 var vals = inFields[j].split("/");
6549 fields[j] = [parseFloat(vals[0]), parseFloat(vals[1])];
6550 }
6551 } else if (this.errorBars_) {
6552 // If there are error bars, values are (value, stddev) pairs
6553 for (var j = 1; j < inFields.length; j += 2)
6554 fields[(j + 1) / 2] = [parseFloat(inFields[j]),
6555 parseFloat(inFields[j + 1])];
6556 } else if (this.customBars_) {
6557 // Bars are a low;center;high tuple
6558 for (var j = 1; j < inFields.length; j++) {
6559 var vals = inFields[j].split(";");
6560 fields[j] = [ parseFloat(vals[0]),
6561 parseFloat(vals[1]),
6562 parseFloat(vals[2]) ];
6563 }
6564 } else {
6565 // Values are just numbers
6566 for (var j = 1; j < inFields.length; j++)
6567 fields[j] = parseFloat(inFields[j]);
6568 }
6569 ret.push(fields);
6570 }
6571 return ret;
6572 };
6573
6574 /**
6575 * Get the CSV data. If it's in a function, call that function. If it's in a
6576 * file, do an XMLHttpRequest to get it.
6577 * @private
6578 */
6579 DateGraph.prototype.start_ = function() {
6580 if (typeof this.file_ == 'function') {
6581 // Stubbed out to allow this to run off a filesystem
6582 this.loadedEvent_(this.file_());
6583 } else {
6584 var req = new XMLHttpRequest();
6585 var caller = this;
6586 req.onreadystatechange = function () {
6587 if (req.readyState == 4) {
6588 if (req.status == 200) {
6589 caller.loadedEvent_(req.responseText);
6590 }
6591 }
6592 };
6593
6594 req.open("GET", this.file_, true);
6595 req.send(null);
6596 }
6597 };
6598
6599 /**
6600 * Changes various properties of the graph. These can include:
6601 * <ul>
6602 * <li>file: changes the source data for the graph</li>
6603 * <li>errorBars: changes whether the data contains stddev</li>
6604 * </ul>
6605 * @param {Object} attrs The new properties and values
6606 */
6607 DateGraph.prototype.updateOptions = function(attrs) {
6608 if (attrs.errorBars) {
6609 this.errorBars_ = attrs.errorBars;
6610 }
6611 if (attrs.customBars) {
6612 this.customBars_ = attrs.customBars;
6613 }
6614 if (attrs.strokeWidth) {
6615 this.strokeWidth_ = attrs.strokeWidth;
6616 }
6617 if (attrs.rollPeriod) {
6618 this.rollPeriod_ = attrs.rollPeriod;
6619 }
6620 if (attrs.dateWindow) {
6621 this.dateWindow_ = attrs.dateWindow;
6622 }
6623 if (attrs.valueRange) {
6624 this.valueRange_ = attrs.valueRange;
6625 }
6626 if (attrs.minTickSize) {
6627 this.minTickSize_ = attrs.minTickSize;
6628 }
6629 if (typeof(attrs.labels) != 'undefined') {
6630 this.labels_ = attrs.labels;
6631 this.labelsFromCSV_ = (attrs.labels == null);
6632 }
6633 this.layout_.updateOptions({ 'errorBars': this.errorBars_ });
6634 if (attrs['file'] && attrs['file'] != this.file_) {
6635 this.file_ = attrs['file'];
6636 this.start_();
6637 } else {
6638 this.drawGraph_(this.rawData_);
6639 }
6640 };
6641
6642 /**
6643 * Adjusts the number of days in the rolling average. Updates the graph to
6644 * reflect the new averaging period.
6645 * @param {Number} length Number of days over which to average the data.
6646 */
6647 DateGraph.prototype.adjustRoll = function(length) {
6648 this.rollPeriod_ = length;
6649 this.drawGraph_(this.rawData_);
6650 };