Only pack a subset of MochiKit. This saves another 90k.
[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.Format");
1006 }
1007 if(typeof (MochiKit)=="undefined"){
1008 MochiKit={};
1009 }
1010 if(typeof (MochiKit.Format)=="undefined"){
1011 MochiKit.Format={};
1012 }
1013 MochiKit.Format.NAME="MochiKit.Format";
1014 MochiKit.Format.VERSION="1.4";
1015 MochiKit.Format.__repr__=function(){
1016 return "["+this.NAME+" "+this.VERSION+"]";
1017 };
1018 MochiKit.Format.toString=function(){
1019 return this.__repr__();
1020 };
1021 MochiKit.Format._numberFormatter=function(_14d,_14e,_14f,_150,_151,_152,_153,_154,_155){
1022 return function(num){
1023 num=parseFloat(num);
1024 if(typeof (num)=="undefined"||num===null||isNaN(num)){
1025 return _14d;
1026 }
1027 var _157=_14e;
1028 var _158=_14f;
1029 if(num<0){
1030 num=-num;
1031 }else{
1032 _157=_157.replace(/-/,"");
1033 }
1034 var me=arguments.callee;
1035 var fmt=MochiKit.Format.formatLocale(_150);
1036 if(_151){
1037 num=num*100;
1038 _158=fmt.percent+_158;
1039 }
1040 num=MochiKit.Format.roundToFixed(num,_152);
1041 var _15b=num.split(/\./);
1042 var _15c=_15b[0];
1043 var frac=(_15b.length==1)?"":_15b[1];
1044 var res="";
1045 while(_15c.length<_153){
1046 _15c="0"+_15c;
1047 }
1048 if(_154){
1049 while(_15c.length>_154){
1050 var i=_15c.length-_154;
1051 res=fmt.separator+_15c.substring(i,_15c.length)+res;
1052 _15c=_15c.substring(0,i);
1053 }
1054 }
1055 res=_15c+res;
1056 if(_152>0){
1057 while(frac.length<_155){
1058 frac=frac+"0";
1059 }
1060 res=res+fmt.decimal+frac;
1061 }
1062 return _157+res+_158;
1063 };
1064 };
1065 MochiKit.Format.numberFormatter=function(_160,_161,_162){
1066 if(typeof (_161)=="undefined"){
1067 _161="";
1068 }
1069 var _163=_160.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
1070 if(!_163){
1071 throw TypeError("Invalid pattern");
1072 }
1073 var _164=_160.substr(0,_163.index);
1074 var _165=_160.substr(_163.index+_163[0].length);
1075 if(_164.search(/-/)==-1){
1076 _164=_164+"-";
1077 }
1078 var _166=_163[1];
1079 var frac=(typeof (_163[2])=="string"&&_163[2]!="")?_163[2]:"";
1080 var _168=(typeof (_163[3])=="string"&&_163[3]!="");
1081 var tmp=_166.split(/,/);
1082 var _16a;
1083 if(typeof (_162)=="undefined"){
1084 _162="default";
1085 }
1086 if(tmp.length==1){
1087 _16a=null;
1088 }else{
1089 _16a=tmp[1].length;
1090 }
1091 var _16b=_166.length-_166.replace(/0/g,"").length;
1092 var _16c=frac.length-frac.replace(/0/g,"").length;
1093 var _16d=frac.length;
1094 var rval=MochiKit.Format._numberFormatter(_161,_164,_165,_162,_168,_16d,_16b,_16a,_16c);
1095 var m=MochiKit.Base;
1096 if(m){
1097 var fn=arguments.callee;
1098 var args=m.concat(arguments);
1099 rval.repr=function(){
1100 return [self.NAME,"(",map(m.repr,args).join(", "),")"].join("");
1101 };
1102 }
1103 return rval;
1104 };
1105 MochiKit.Format.formatLocale=function(_172){
1106 if(typeof (_172)=="undefined"||_172===null){
1107 _172="default";
1108 }
1109 if(typeof (_172)=="string"){
1110 var rval=MochiKit.Format.LOCALE[_172];
1111 if(typeof (rval)=="string"){
1112 rval=arguments.callee(rval);
1113 MochiKit.Format.LOCALE[_172]=rval;
1114 }
1115 return rval;
1116 }else{
1117 return _172;
1118 }
1119 };
1120 MochiKit.Format.twoDigitAverage=function(_174,_175){
1121 if(_175){
1122 var res=_174/_175;
1123 if(!isNaN(res)){
1124 return MochiKit.Format.twoDigitFloat(_174/_175);
1125 }
1126 }
1127 return "0";
1128 };
1129 MochiKit.Format.twoDigitFloat=function(_177){
1130 var sign=(_177<0?"-":"");
1131 var s=Math.floor(Math.abs(_177)*100).toString();
1132 if(s=="0"){
1133 return s;
1134 }
1135 if(s.length<3){
1136 while(s.charAt(s.length-1)=="0"){
1137 s=s.substring(0,s.length-1);
1138 }
1139 return sign+"0."+s;
1140 }
1141 var head=sign+s.substring(0,s.length-2);
1142 var tail=s.substring(s.length-2,s.length);
1143 if(tail=="00"){
1144 return head;
1145 }else{
1146 if(tail.charAt(1)=="0"){
1147 return head+"."+tail.charAt(0);
1148 }else{
1149 return head+"."+tail;
1150 }
1151 }
1152 };
1153 MochiKit.Format.lstrip=function(str,_17d){
1154 str=str+"";
1155 if(typeof (str)!="string"){
1156 return null;
1157 }
1158 if(!_17d){
1159 return str.replace(/^\s+/,"");
1160 }else{
1161 return str.replace(new RegExp("^["+_17d+"]+"),"");
1162 }
1163 };
1164 MochiKit.Format.rstrip=function(str,_17f){
1165 str=str+"";
1166 if(typeof (str)!="string"){
1167 return null;
1168 }
1169 if(!_17f){
1170 return str.replace(/\s+$/,"");
1171 }else{
1172 return str.replace(new RegExp("["+_17f+"]+$"),"");
1173 }
1174 };
1175 MochiKit.Format.strip=function(str,_181){
1176 var self=MochiKit.Format;
1177 return self.rstrip(self.lstrip(str,_181),_181);
1178 };
1179 MochiKit.Format.truncToFixed=function(_183,_184){
1180 _183=Math.floor(_183*Math.pow(10,_184));
1181 var res=(_183*Math.pow(10,-_184)).toFixed(_184);
1182 if(res.charAt(0)=="."){
1183 res="0"+res;
1184 }
1185 return res;
1186 };
1187 MochiKit.Format.roundToFixed=function(_186,_187){
1188 return MochiKit.Format.truncToFixed(_186+0.5*Math.pow(10,-_187),_187);
1189 };
1190 MochiKit.Format.percentFormat=function(_188){
1191 return MochiKit.Format.twoDigitFloat(100*_188)+"%";
1192 };
1193 MochiKit.Format.EXPORT=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
1194 MochiKit.Format.LOCALE={en_US:{separator:",",decimal:".",percent:"%"},de_DE:{separator:".",decimal:",",percent:"%"},fr_FR:{separator:" ",decimal:",",percent:"%"},"default":"en_US"};
1195 MochiKit.Format.EXPORT_OK=[];
1196 MochiKit.Format.EXPORT_TAGS={":all":MochiKit.Format.EXPORT,":common":MochiKit.Format.EXPORT};
1197 MochiKit.Format.__new__=function(){
1198 var base=this.NAME+".";
1199 var k,v,o;
1200 for(k in this.LOCALE){
1201 o=this.LOCALE[k];
1202 if(typeof (o)=="object"){
1203 o.repr=function(){
1204 return this.NAME;
1205 };
1206 o.NAME=base+"LOCALE."+k;
1207 }
1208 }
1209 for(k in this){
1210 o=this[k];
1211 if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
1212 try{
1213 o.NAME=base+k;
1214 }
1215 catch(e){
1216 }
1217 }
1218 }
1219 };
1220 MochiKit.Format.__new__();
1221 if(typeof (MochiKit.Base)!="undefined"){
1222 MochiKit.Base._exportSymbols(this,MochiKit.Format);
1223 }else{
1224 (function(_18d,_18e){
1225 if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(MochiKit.__export__===false)){
1226 var all=_18e.EXPORT_TAGS[":all"];
1227 for(var i=0;i<all.length;i++){
1228 _18d[all[i]]=_18e[all[i]];
1229 }
1230 }
1231 })(this,MochiKit.Format);
1232 }
1233 if(typeof (dojo)!="undefined"){
1234 dojo.provide("MochiKit.DOM");
1235 dojo.require("MochiKit.Base");
1236 }
1237 if(typeof (JSAN)!="undefined"){
1238 JSAN.use("MochiKit.Base",[]);
1239 }
1240 try{
1241 if(typeof (MochiKit.Base)=="undefined"){
1242 throw "";
1243 }
1244 }
1245 catch(e){
1246 throw "MochiKit.DOM depends on MochiKit.Base!";
1247 }
1248 if(typeof (MochiKit.DOM)=="undefined"){
1249 MochiKit.DOM={};
1250 }
1251 MochiKit.DOM.NAME="MochiKit.DOM";
1252 MochiKit.DOM.VERSION="1.4";
1253 MochiKit.DOM.__repr__=function(){
1254 return "["+this.NAME+" "+this.VERSION+"]";
1255 };
1256 MochiKit.DOM.toString=function(){
1257 return this.__repr__();
1258 };
1259 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"];
1260 MochiKit.DOM.EXPORT_OK=["domConverters"];
1261 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"]];
1262 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);");
1263 MochiKit.Base.update(MochiKit.DOM,{currentWindow:function(){
1264 return MochiKit.DOM._window;
1265 },currentDocument:function(){
1266 return MochiKit.DOM._document;
1267 },withWindow:function(win,func){
1268 var self=MochiKit.DOM;
1269 var _194=self._document;
1270 var _195=self._window;
1271 var rval;
1272 try{
1273 self._window=win;
1274 self._document=win.document;
1275 rval=func();
1276 }
1277 catch(e){
1278 self._window=_195;
1279 self._document=_194;
1280 throw e;
1281 }
1282 self._window=_195;
1283 self._document=_194;
1284 return rval;
1285 },formContents:function(elem){
1286 var _198=[];
1287 var _199=[];
1288 var m=MochiKit.Base;
1289 var self=MochiKit.DOM;
1290 if(typeof (elem)=="undefined"||elem===null){
1291 elem=self._document.body;
1292 }else{
1293 elem=self.getElement(elem);
1294 }
1295 m.nodeWalk(elem,function(elem){
1296 var name=elem.name;
1297 if(m.isNotEmpty(name)){
1298 var _19e=elem.tagName.toUpperCase();
1299 if(_19e==="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){
1300 return null;
1301 }
1302 if(_19e==="SELECT"){
1303 if(elem.type=="select-one"){
1304 if(elem.selectedIndex>=0){
1305 var opt=elem.options[elem.selectedIndex];
1306 var v=opt.value;
1307 if(!v){
1308 var h=opt.outerHTML;
1309 if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
1310 v=opt.text;
1311 }
1312 }
1313 _198.push(name);
1314 _199.push(v);
1315 return null;
1316 }
1317 _198.push(name);
1318 _199.push("");
1319 return null;
1320 }else{
1321 var opts=elem.options;
1322 if(!opts.length){
1323 _198.push(name);
1324 _199.push("");
1325 return null;
1326 }
1327 for(var i=0;i<opts.length;i++){
1328 var opt=opts[i];
1329 if(!opt.selected){
1330 continue;
1331 }
1332 var v=opt.value;
1333 if(!v){
1334 var h=opt.outerHTML;
1335 if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
1336 v=opt.text;
1337 }
1338 }
1339 _198.push(name);
1340 _199.push(v);
1341 }
1342 return null;
1343 }
1344 }
1345 if(_19e==="FORM"||_19e==="P"||_19e==="SPAN"||_19e==="DIV"){
1346 return elem.childNodes;
1347 }
1348 _198.push(name);
1349 _199.push(elem.value||"");
1350 return null;
1351 }
1352 return elem.childNodes;
1353 });
1354 return [_198,_199];
1355 },withDocument:function(doc,func){
1356 var self=MochiKit.DOM;
1357 var _1a7=self._document;
1358 var rval;
1359 try{
1360 self._document=doc;
1361 rval=func();
1362 }
1363 catch(e){
1364 self._document=_1a7;
1365 throw e;
1366 }
1367 self._document=_1a7;
1368 return rval;
1369 },registerDOMConverter:function(name,_1aa,wrap,_1ac){
1370 MochiKit.DOM.domConverters.register(name,_1aa,wrap,_1ac);
1371 },coerceToDOM:function(node,ctx){
1372 var m=MochiKit.Base;
1373 var im=MochiKit.Iter;
1374 var self=MochiKit.DOM;
1375 if(im){
1376 var iter=im.iter;
1377 var _1b3=im.repeat;
1378 var map=m.map;
1379 }
1380 var _1b5=self.domConverters;
1381 var _1b6=arguments.callee;
1382 var _1b7=m.NotFound;
1383 while(true){
1384 if(typeof (node)=="undefined"||node===null){
1385 return null;
1386 }
1387 if(typeof (node)=="function"&&typeof (node.length)=="number"&&!(node instanceof Function)){
1388 node=im.list(node);
1389 }
1390 if(typeof (node.nodeType)!="undefined"&&node.nodeType>0){
1391 return node;
1392 }
1393 if(typeof (node)=="number"||typeof (node)=="boolean"){
1394 node=node.toString();
1395 }
1396 if(typeof (node)=="string"){
1397 return self._document.createTextNode(node);
1398 }
1399 if(typeof (node.__dom__)=="function"){
1400 node=node.__dom__(ctx);
1401 continue;
1402 }
1403 if(typeof (node.dom)=="function"){
1404 node=node.dom(ctx);
1405 continue;
1406 }
1407 if(typeof (node)=="function"){
1408 node=node.apply(ctx,[ctx]);
1409 continue;
1410 }
1411 if(im){
1412 var _1b8=null;
1413 try{
1414 _1b8=iter(node);
1415 }
1416 catch(e){
1417 }
1418 if(_1b8){
1419 return map(_1b6,_1b8,_1b3(ctx));
1420 }
1421 }
1422 try{
1423 node=_1b5.match(node,ctx);
1424 continue;
1425 }
1426 catch(e){
1427 if(e!=_1b7){
1428 throw e;
1429 }
1430 }
1431 return self._document.createTextNode(node.toString());
1432 }
1433 return undefined;
1434 },isChildNode:function(node,_1ba){
1435 var self=MochiKit.DOM;
1436 if(typeof (node)=="string"){
1437 node=self.getElement(node);
1438 }
1439 if(typeof (_1ba)=="string"){
1440 _1ba=self.getElement(_1ba);
1441 }
1442 if(node===_1ba){
1443 return true;
1444 }
1445 while(node&&node.tagName.toUpperCase()!="BODY"){
1446 node=node.parentNode;
1447 if(node===_1ba){
1448 return true;
1449 }
1450 }
1451 return false;
1452 },setNodeAttribute:function(node,attr,_1be){
1453 var o={};
1454 o[attr]=_1be;
1455 try{
1456 return MochiKit.DOM.updateNodeAttributes(node,o);
1457 }
1458 catch(e){
1459 }
1460 return null;
1461 },getNodeAttribute:function(node,attr){
1462 var self=MochiKit.DOM;
1463 var _1c3=self.attributeArray.renames[attr];
1464 node=self.getElement(node);
1465 try{
1466 if(_1c3){
1467 return node[_1c3];
1468 }
1469 return node.getAttribute(attr);
1470 }
1471 catch(e){
1472 }
1473 return null;
1474 },removeNodeAttribute:function(node,attr){
1475 var self=MochiKit.DOM;
1476 var _1c7=self.attributeArray.renames[attr];
1477 node=self.getElement(node);
1478 try{
1479 if(_1c7){
1480 return node[_1c7];
1481 }
1482 return node.removeAttribute(attr);
1483 }
1484 catch(e){
1485 }
1486 return null;
1487 },updateNodeAttributes:function(node,_1c9){
1488 var elem=node;
1489 var self=MochiKit.DOM;
1490 if(typeof (node)=="string"){
1491 elem=self.getElement(node);
1492 }
1493 if(_1c9){
1494 var _1cc=MochiKit.Base.updatetree;
1495 if(self.attributeArray.compliant){
1496 for(var k in _1c9){
1497 var v=_1c9[k];
1498 if(typeof (v)=="object"&&typeof (elem[k])=="object"){
1499 if(k=="style"&&MochiKit.Style){
1500 MochiKit.Style.setStyle(elem,v);
1501 }else{
1502 _1cc(elem[k],v);
1503 }
1504 }else{
1505 if(k.substring(0,2)=="on"){
1506 if(typeof (v)=="string"){
1507 v=new Function(v);
1508 }
1509 elem[k]=v;
1510 }else{
1511 elem.setAttribute(k,v);
1512 }
1513 }
1514 }
1515 }else{
1516 var _1cf=self.attributeArray.renames;
1517 for(var k in _1c9){
1518 v=_1c9[k];
1519 var _1d0=_1cf[k];
1520 if(k=="style"&&typeof (v)=="string"){
1521 elem.style.cssText=v;
1522 }else{
1523 if(typeof (_1d0)=="string"){
1524 elem[_1d0]=v;
1525 }else{
1526 if(typeof (elem[k])=="object"&&typeof (v)=="object"){
1527 if(k=="style"&&MochiKit.Style){
1528 MochiKit.Style.setStyle(elem,v);
1529 }else{
1530 _1cc(elem[k],v);
1531 }
1532 }else{
1533 if(k.substring(0,2)=="on"){
1534 if(typeof (v)=="string"){
1535 v=new Function(v);
1536 }
1537 elem[k]=v;
1538 }else{
1539 elem.setAttribute(k,v);
1540 }
1541 }
1542 }
1543 }
1544 }
1545 }
1546 }
1547 return elem;
1548 },appendChildNodes:function(node){
1549 var elem=node;
1550 var self=MochiKit.DOM;
1551 if(typeof (node)=="string"){
1552 elem=self.getElement(node);
1553 }
1554 var _1d4=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
1555 var _1d5=MochiKit.Base.concat;
1556 while(_1d4.length){
1557 var n=_1d4.shift();
1558 if(typeof (n)=="undefined"||n===null){
1559 }else{
1560 if(typeof (n.nodeType)=="number"){
1561 elem.appendChild(n);
1562 }else{
1563 _1d4=_1d5(n,_1d4);
1564 }
1565 }
1566 }
1567 return elem;
1568 },insertSiblingNodesBefore:function(node){
1569 var elem=node;
1570 var self=MochiKit.DOM;
1571 if(typeof (node)=="string"){
1572 elem=self.getElement(node);
1573 }
1574 var _1da=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
1575 var _1db=elem.parentNode;
1576 var _1dc=MochiKit.Base.concat;
1577 while(_1da.length){
1578 var n=_1da.shift();
1579 if(typeof (n)=="undefined"||n===null){
1580 }else{
1581 if(typeof (n.nodeType)=="number"){
1582 _1db.insertBefore(n,elem);
1583 }else{
1584 _1da=_1dc(n,_1da);
1585 }
1586 }
1587 }
1588 return _1db;
1589 },insertSiblingNodesAfter:function(node){
1590 var elem=node;
1591 var self=MochiKit.DOM;
1592 if(typeof (node)=="string"){
1593 elem=self.getElement(node);
1594 }
1595 var _1e1=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
1596 if(elem.nextSibling){
1597 return self.insertSiblingNodesBefore(elem.nextSibling,_1e1);
1598 }else{
1599 return self.appendChildNodes(elem.parentNode,_1e1);
1600 }
1601 },replaceChildNodes:function(node){
1602 var elem=node;
1603 var self=MochiKit.DOM;
1604 if(typeof (node)=="string"){
1605 elem=self.getElement(node);
1606 arguments[0]=elem;
1607 }
1608 var _1e5;
1609 while((_1e5=elem.firstChild)){
1610 elem.removeChild(_1e5);
1611 }
1612 if(arguments.length<2){
1613 return elem;
1614 }else{
1615 return self.appendChildNodes.apply(this,arguments);
1616 }
1617 },createDOM:function(name,_1e7){
1618 var elem;
1619 var self=MochiKit.DOM;
1620 var m=MochiKit.Base;
1621 if(typeof (_1e7)=="string"||typeof (_1e7)=="number"){
1622 var args=m.extend([name,null],arguments,1);
1623 return arguments.callee.apply(this,args);
1624 }
1625 if(typeof (name)=="string"){
1626 var _1ec=self._xhtml;
1627 if(_1e7&&!self.attributeArray.compliant){
1628 var _1ed="";
1629 if("name" in _1e7){
1630 _1ed+=" name=\""+self.escapeHTML(_1e7.name)+"\"";
1631 }
1632 if(name=="input"&&"type" in _1e7){
1633 _1ed+=" type=\""+self.escapeHTML(_1e7.type)+"\"";
1634 }
1635 if(_1ed){
1636 name="<"+name+_1ed+">";
1637 _1ec=false;
1638 }
1639 }
1640 var d=self._document;
1641 if(_1ec&&d===document){
1642 elem=d.createElementNS("http://www.w3.org/1999/xhtml",name);
1643 }else{
1644 elem=d.createElement(name);
1645 }
1646 }else{
1647 elem=name;
1648 }
1649 if(_1e7){
1650 self.updateNodeAttributes(elem,_1e7);
1651 }
1652 if(arguments.length<=2){
1653 return elem;
1654 }else{
1655 var args=m.extend([elem],arguments,2);
1656 return self.appendChildNodes.apply(this,args);
1657 }
1658 },createDOMFunc:function(){
1659 var m=MochiKit.Base;
1660 return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments));
1661 },removeElement:function(elem){
1662 var e=MochiKit.DOM.getElement(elem);
1663 e.parentNode.removeChild(e);
1664 return e;
1665 },swapDOM:function(dest,src){
1666 var self=MochiKit.DOM;
1667 dest=self.getElement(dest);
1668 var _1f5=dest.parentNode;
1669 if(src){
1670 src=self.getElement(src);
1671 _1f5.replaceChild(src,dest);
1672 }else{
1673 _1f5.removeChild(dest);
1674 }
1675 return src;
1676 },getElement:function(id){
1677 var self=MochiKit.DOM;
1678 if(arguments.length==1){
1679 return ((typeof (id)=="string")?self._document.getElementById(id):id);
1680 }else{
1681 return MochiKit.Base.map(self.getElement,arguments);
1682 }
1683 },getElementsByTagAndClassName:function(_1f8,_1f9,_1fa){
1684 var self=MochiKit.DOM;
1685 if(typeof (_1f8)=="undefined"||_1f8===null){
1686 _1f8="*";
1687 }
1688 if(typeof (_1fa)=="undefined"||_1fa===null){
1689 _1fa=self._document;
1690 }
1691 _1fa=self.getElement(_1fa);
1692 var _1fc=(_1fa.getElementsByTagName(_1f8)||self._document.all);
1693 if(typeof (_1f9)=="undefined"||_1f9===null){
1694 return MochiKit.Base.extend(null,_1fc);
1695 }
1696 var _1fd=[];
1697 for(var i=0;i<_1fc.length;i++){
1698 var _1ff=_1fc[i];
1699 var cls=_1ff.className;
1700 if(!cls){
1701 continue;
1702 }
1703 var _201=cls.split(" ");
1704 for(var j=0;j<_201.length;j++){
1705 if(_201[j]==_1f9){
1706 _1fd.push(_1ff);
1707 break;
1708 }
1709 }
1710 }
1711 return _1fd;
1712 },_newCallStack:function(path,once){
1713 var rval=function(){
1714 var _206=arguments.callee.callStack;
1715 for(var i=0;i<_206.length;i++){
1716 if(_206[i].apply(this,arguments)===false){
1717 break;
1718 }
1719 }
1720 if(once){
1721 try{
1722 this[path]=null;
1723 }
1724 catch(e){
1725 }
1726 }
1727 };
1728 rval.callStack=[];
1729 return rval;
1730 },addToCallStack:function(_208,path,func,once){
1731 var self=MochiKit.DOM;
1732 var _20d=_208[path];
1733 var _20e=_20d;
1734 if(!(typeof (_20d)=="function"&&typeof (_20d.callStack)=="object"&&_20d.callStack!==null)){
1735 _20e=self._newCallStack(path,once);
1736 if(typeof (_20d)=="function"){
1737 _20e.callStack.push(_20d);
1738 }
1739 _208[path]=_20e;
1740 }
1741 _20e.callStack.push(func);
1742 },addLoadEvent:function(func){
1743 var self=MochiKit.DOM;
1744 self.addToCallStack(self._window,"onload",func,true);
1745 },focusOnLoad:function(_211){
1746 var self=MochiKit.DOM;
1747 self.addLoadEvent(function(){
1748 _211=self.getElement(_211);
1749 if(_211){
1750 _211.focus();
1751 }
1752 });
1753 },setElementClass:function(_213,_214){
1754 var self=MochiKit.DOM;
1755 var obj=self.getElement(_213);
1756 if(self.attributeArray.compliant){
1757 obj.setAttribute("class",_214);
1758 }else{
1759 obj.setAttribute("className",_214);
1760 }
1761 },toggleElementClass:function(_217){
1762 var self=MochiKit.DOM;
1763 for(var i=1;i<arguments.length;i++){
1764 var obj=self.getElement(arguments[i]);
1765 if(!self.addElementClass(obj,_217)){
1766 self.removeElementClass(obj,_217);
1767 }
1768 }
1769 },addElementClass:function(_21b,_21c){
1770 var self=MochiKit.DOM;
1771 var obj=self.getElement(_21b);
1772 var cls=obj.className;
1773 if(cls==undefined||cls.length===0){
1774 self.setElementClass(obj,_21c);
1775 return true;
1776 }
1777 if(cls==_21c){
1778 return false;
1779 }
1780 var _220=cls.split(" ");
1781 for(var i=0;i<_220.length;i++){
1782 if(_220[i]==_21c){
1783 return false;
1784 }
1785 }
1786 self.setElementClass(obj,cls+" "+_21c);
1787 return true;
1788 },removeElementClass:function(_222,_223){
1789 var self=MochiKit.DOM;
1790 var obj=self.getElement(_222);
1791 var cls=obj.className;
1792 if(cls==undefined||cls.length===0){
1793 return false;
1794 }
1795 if(cls==_223){
1796 self.setElementClass(obj,"");
1797 return true;
1798 }
1799 var _227=cls.split(" ");
1800 for(var i=0;i<_227.length;i++){
1801 if(_227[i]==_223){
1802 _227.splice(i,1);
1803 self.setElementClass(obj,_227.join(" "));
1804 return true;
1805 }
1806 }
1807 return false;
1808 },swapElementClass:function(_229,_22a,_22b){
1809 var obj=MochiKit.DOM.getElement(_229);
1810 var res=MochiKit.DOM.removeElementClass(obj,_22a);
1811 if(res){
1812 MochiKit.DOM.addElementClass(obj,_22b);
1813 }
1814 return res;
1815 },hasElementClass:function(_22e,_22f){
1816 var obj=MochiKit.DOM.getElement(_22e);
1817 var cls=obj.className;
1818 if(!cls){
1819 return false;
1820 }
1821 var _232=cls.split(" ");
1822 for(var i=1;i<arguments.length;i++){
1823 var good=false;
1824 for(var j=0;j<_232.length;j++){
1825 if(_232[j]==arguments[i]){
1826 good=true;
1827 break;
1828 }
1829 }
1830 if(!good){
1831 return false;
1832 }
1833 }
1834 return true;
1835 },escapeHTML:function(s){
1836 return s.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
1837 },toHTML:function(dom){
1838 return MochiKit.DOM.emitHTML(dom).join("");
1839 },emitHTML:function(dom,lst){
1840 if(typeof (lst)=="undefined"||lst===null){
1841 lst=[];
1842 }
1843 var _23a=[dom];
1844 var self=MochiKit.DOM;
1845 var _23c=self.escapeHTML;
1846 var _23d=self.attributeArray;
1847 while(_23a.length){
1848 dom=_23a.pop();
1849 if(typeof (dom)=="string"){
1850 lst.push(dom);
1851 }else{
1852 if(dom.nodeType==1){
1853 lst.push("<"+dom.tagName.toLowerCase());
1854 var _23e=[];
1855 var _23f=_23d(dom);
1856 for(var i=0;i<_23f.length;i++){
1857 var a=_23f[i];
1858 _23e.push([" ",a.name,"=\"",_23c(a.value),"\""]);
1859 }
1860 _23e.sort();
1861 for(i=0;i<_23e.length;i++){
1862 var _242=_23e[i];
1863 for(var j=0;j<_242.length;j++){
1864 lst.push(_242[j]);
1865 }
1866 }
1867 if(dom.hasChildNodes()){
1868 lst.push(">");
1869 _23a.push("</"+dom.tagName.toLowerCase()+">");
1870 var _244=dom.childNodes;
1871 for(i=_244.length-1;i>=0;i--){
1872 _23a.push(_244[i]);
1873 }
1874 }else{
1875 lst.push("/>");
1876 }
1877 }else{
1878 if(dom.nodeType==3){
1879 lst.push(_23c(dom.nodeValue));
1880 }
1881 }
1882 }
1883 }
1884 return lst;
1885 },scrapeText:function(node,_246){
1886 var rval=[];
1887 (function(node){
1888 var cn=node.childNodes;
1889 if(cn){
1890 for(var i=0;i<cn.length;i++){
1891 arguments.callee.call(this,cn[i]);
1892 }
1893 }
1894 var _24b=node.nodeValue;
1895 if(typeof (_24b)=="string"){
1896 rval.push(_24b);
1897 }
1898 })(MochiKit.DOM.getElement(node));
1899 if(_246){
1900 return rval;
1901 }else{
1902 return rval.join("");
1903 }
1904 },removeEmptyTextNodes:function(_24c){
1905 _24c=MochiKit.DOM.getElement(_24c);
1906 for(var i=0;i<_24c.childNodes.length;i++){
1907 var node=_24c.childNodes[i];
1908 if(node.nodeType==3&&!/\S/.test(node.nodeValue)){
1909 node.parentNode.removeChild(node);
1910 }
1911 }
1912 },makeClipping:function(_24f){
1913 _24f=MochiKit.DOM.getElement(_24f);
1914 var _250=_24f.style.overflow;
1915 if((MochiKit.Style.getStyle(_24f,"overflow")||"visible")!="hidden"){
1916 _24f.style.overflow="hidden";
1917 }
1918 return _250;
1919 },undoClipping:function(_251,_252){
1920 _251=MochiKit.DOM.getElement(_251);
1921 if(!_252){
1922 return;
1923 }
1924 _251.style.overflow=_252;
1925 },makePositioned:function(_253){
1926 _253=MochiKit.DOM.getElement(_253);
1927 var pos=MochiKit.Style.getStyle(_253,"position");
1928 if(pos=="static"||!pos){
1929 _253.style.position="relative";
1930 if(/Opera/.test(navigator.userAgent)){
1931 _253.style.top=0;
1932 _253.style.left=0;
1933 }
1934 }
1935 },undoPositioned:function(_255){
1936 _255=MochiKit.DOM.getElement(_255);
1937 if(_255.style.position=="relative"){
1938 _255.style.position=_255.style.top=_255.style.left=_255.style.bottom=_255.style.right="";
1939 }
1940 },getFirstElementByTagAndClassName:function(_256,_257,_258){
1941 var self=MochiKit.DOM;
1942 if(typeof (_256)=="undefined"||_256===null){
1943 _256="*";
1944 }
1945 if(typeof (_258)=="undefined"||_258===null){
1946 _258=self._document;
1947 }
1948 _258=self.getElement(_258);
1949 var _25a=(_258.getElementsByTagName(_256)||self._document.all);
1950 if(typeof (_257)=="undefined"||_257===null){
1951 return _25a[0];
1952 }
1953 for(var i=0;i<_25a.length;i++){
1954 var _25c=_25a[i];
1955 var _25d=_25c.className.split(" ");
1956 for(var j=0;j<_25d.length;j++){
1957 if(_25d[j]==_257){
1958 return _25c;
1959 }
1960 }
1961 }
1962 },getFirstParentByTagAndClassName:function(elem,_260,_261){
1963 var self=MochiKit.DOM;
1964 elem=self.getElement(elem);
1965 if(typeof (_260)=="undefined"||_260===null){
1966 _260="*";
1967 }else{
1968 _260=_260.toUpperCase();
1969 }
1970 if(typeof (_261)=="undefined"||_261===null){
1971 _261=null;
1972 }
1973 var _263="";
1974 var _264="";
1975 while(elem&&elem.tagName){
1976 elem=elem.parentNode;
1977 if(_260=="*"&&_261===null){
1978 return elem;
1979 }
1980 _263=elem.className.split(" ");
1981 _264=elem.tagName.toUpperCase();
1982 if(_261===null&&_260==_264){
1983 return elem;
1984 }else{
1985 if(_261!==null){
1986 for(var i=0;i<_263.length;i++){
1987 if(_260=="*"&&_263[i]==_261){
1988 return elem;
1989 }else{
1990 if(_260==_264&&_263[i]==_261){
1991 return elem;
1992 }
1993 }
1994 }
1995 }
1996 }
1997 }
1998 return elem;
1999 },isParent:function(_266,_267){
2000 if(!_266.parentNode||_266==_267){
2001 return false;
2002 }
2003 if(_266.parentNode==_267){
2004 return true;
2005 }
2006 return MochiKit.DOM.isParent(_266.parentNode,_267);
2007 },__new__:function(win){
2008 var m=MochiKit.Base;
2009 if(typeof (document)!="undefined"){
2010 this._document=document;
2011 var _26a="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
2012 this._xhtml=(document.documentElement&&document.createElementNS&&document.documentElement.namespaceURI===_26a);
2013 }else{
2014 if(MochiKit.MockDOM){
2015 this._document=MochiKit.MockDOM.document;
2016 }
2017 }
2018 this._window=win;
2019 this.domConverters=new m.AdapterRegistry();
2020 var _26b=this._document.createElement("span");
2021 var _26c;
2022 if(_26b&&_26b.attributes&&_26b.attributes.length>0){
2023 var _26d=m.filter;
2024 _26c=function(node){
2025 return _26d(_26c.ignoreAttrFilter,node.attributes);
2026 };
2027 _26c.ignoreAttr={};
2028 var _26f=_26b.attributes;
2029 var _270=_26c.ignoreAttr;
2030 for(var i=0;i<_26f.length;i++){
2031 var a=_26f[i];
2032 _270[a.name]=a.value;
2033 }
2034 _26c.ignoreAttrFilter=function(a){
2035 return (_26c.ignoreAttr[a.name]!=a.value);
2036 };
2037 _26c.compliant=false;
2038 _26c.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor","cellspacing":"cellSpacing","cellpadding":"cellPadding"};
2039 }else{
2040 _26c=function(node){
2041 return node.attributes;
2042 };
2043 _26c.compliant=true;
2044 _26c.renames={};
2045 }
2046 this.attributeArray=_26c;
2047 var _275=function(_276,arr){
2048 var _278=arr[1].split(".");
2049 var str="";
2050 var obj={};
2051 str+="if (!MochiKit."+_278[1]+") { throw new Error(\"";
2052 str+="This function has been deprecated and depends on MochiKit.";
2053 str+=_278[1]+".\");}";
2054 str+="return MochiKit."+_278[1]+"."+arr[0];
2055 str+=".apply(this, arguments);";
2056 obj[_278[2]]=new Function(str);
2057 MochiKit.Base.update(MochiKit[_276],obj);
2058 };
2059 for(var i;i<MochiKit.DOM.DEPRECATED.length;i++){
2060 _275("DOM",MochiKit.DOM.DEPRECATED[i]);
2061 }
2062 var _27b=this.createDOMFunc;
2063 this.UL=_27b("ul");
2064 this.OL=_27b("ol");
2065 this.LI=_27b("li");
2066 this.TD=_27b("td");
2067 this.TR=_27b("tr");
2068 this.TBODY=_27b("tbody");
2069 this.THEAD=_27b("thead");
2070 this.TFOOT=_27b("tfoot");
2071 this.TABLE=_27b("table");
2072 this.TH=_27b("th");
2073 this.INPUT=_27b("input");
2074 this.SPAN=_27b("span");
2075 this.A=_27b("a");
2076 this.DIV=_27b("div");
2077 this.IMG=_27b("img");
2078 this.BUTTON=_27b("button");
2079 this.TT=_27b("tt");
2080 this.PRE=_27b("pre");
2081 this.H1=_27b("h1");
2082 this.H2=_27b("h2");
2083 this.H3=_27b("h3");
2084 this.BR=_27b("br");
2085 this.HR=_27b("hr");
2086 this.LABEL=_27b("label");
2087 this.TEXTAREA=_27b("textarea");
2088 this.FORM=_27b("form");
2089 this.P=_27b("p");
2090 this.SELECT=_27b("select");
2091 this.OPTION=_27b("option");
2092 this.OPTGROUP=_27b("optgroup");
2093 this.LEGEND=_27b("legend");
2094 this.FIELDSET=_27b("fieldset");
2095 this.STRONG=_27b("strong");
2096 this.CANVAS=_27b("canvas");
2097 this.$=this.getElement;
2098 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
2099 m.nameFunctions(this);
2100 }});
2101 MochiKit.DOM.__new__(((typeof (window)=="undefined")?this:window));
2102 if(MochiKit.__export__){
2103 withWindow=MochiKit.DOM.withWindow;
2104 withDocument=MochiKit.DOM.withDocument;
2105 }
2106 MochiKit.Base._exportSymbols(this,MochiKit.DOM);
2107 if(typeof (dojo)!="undefined"){
2108 dojo.provide("MochiKit.Style");
2109 dojo.require("MochiKit.Base");
2110 dojo.require("MochiKit.DOM");
2111 }
2112 if(typeof (JSAN)!="undefined"){
2113 JSAN.use("MochiKit.Base",[]);
2114 JSAN.use("MochiKit.DOM",[]);
2115 }
2116 try{
2117 if(typeof (MochiKit.Base)=="undefined"){
2118 throw "";
2119 }
2120 }
2121 catch(e){
2122 throw "MochiKit.Style depends on MochiKit.Base!";
2123 }
2124 try{
2125 if(typeof (MochiKit.DOM)=="undefined"){
2126 throw "";
2127 }
2128 }
2129 catch(e){
2130 throw "MochiKit.Style depends on MochiKit.DOM!";
2131 }
2132 if(typeof (MochiKit.Style)=="undefined"){
2133 MochiKit.Style={};
2134 }
2135 MochiKit.Style.NAME="MochiKit.Style";
2136 MochiKit.Style.VERSION="1.4";
2137 MochiKit.Style.__repr__=function(){
2138 return "["+this.NAME+" "+this.VERSION+"]";
2139 };
2140 MochiKit.Style.toString=function(){
2141 return this.__repr__();
2142 };
2143 MochiKit.Style.EXPORT_OK=[];
2144 MochiKit.Style.EXPORT=["setStyle","setOpacity","getStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
2145 MochiKit.Style.Dimensions=function(w,h){
2146 this.w=w;
2147 this.h=h;
2148 };
2149 MochiKit.Style.Dimensions.prototype.__repr__=function(){
2150 var repr=MochiKit.Base.repr;
2151 return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}";
2152 };
2153 MochiKit.Style.Dimensions.prototype.toString=function(){
2154 return this.__repr__();
2155 };
2156 MochiKit.Style.Coordinates=function(x,y){
2157 this.x=x;
2158 this.y=y;
2159 };
2160 MochiKit.Style.Coordinates.prototype.__repr__=function(){
2161 var repr=MochiKit.Base.repr;
2162 return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}";
2163 };
2164 MochiKit.Style.Coordinates.prototype.toString=function(){
2165 return this.__repr__();
2166 };
2167 MochiKit.Base.update(MochiKit.Style,{getStyle:function(elem,_283){
2168 var dom=MochiKit.DOM;
2169 var d=dom._document;
2170 elem=dom.getElement(elem);
2171 _283=MochiKit.Base.camelize(_283);
2172 if(!elem||elem==d){
2173 return undefined;
2174 }
2175 if(_283=="opacity"&&elem.filters){
2176 var _286=(MochiKit.Style.getStyle(elem,"filter")||"").match(/alpha\(opacity=(.*)\)/);
2177 if(_286&&_286[1]){
2178 return parseFloat(_286[1])/100;
2179 }
2180 return 1;
2181 }
2182 var _287=elem.style?elem.style[_283]:null;
2183 if(!_287){
2184 if(d.defaultView&&d.defaultView.getComputedStyle){
2185 var css=d.defaultView.getComputedStyle(elem,null);
2186 _283=_283.replace(/([A-Z])/g,"-$1").toLowerCase();
2187 _287=css?css.getPropertyValue(_283):null;
2188 }else{
2189 if(elem.currentStyle){
2190 _287=elem.currentStyle[_283];
2191 }
2192 }
2193 }
2194 if(_283=="opacity"){
2195 _287=parseFloat(_287);
2196 }
2197 if(/Opera/.test(navigator.userAgent)&&(MochiKit.Base.find(["left","top","right","bottom"],_283)!=-1)){
2198 if(MochiKit.Style.getStyle(elem,"position")=="static"){
2199 _287="auto";
2200 }
2201 }
2202 return _287=="auto"?null:_287;
2203 },setStyle:function(elem,_28a){
2204 elem=MochiKit.DOM.getElement(elem);
2205 for(var name in _28a){
2206 if(name=="opacity"){
2207 MochiKit.Style.setOpacity(elem,_28a[name]);
2208 }else{
2209 elem.style[MochiKit.Base.camelize(name)]=_28a[name];
2210 }
2211 }
2212 },setOpacity:function(elem,o){
2213 elem=MochiKit.DOM.getElement(elem);
2214 var self=MochiKit.Style;
2215 if(o==1){
2216 var _28f=/Gecko/.test(navigator.userAgent)&&!(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
2217 elem.style["opacity"]=_28f?0.999999:1;
2218 if(/MSIE/.test(navigator.userAgent)){
2219 elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"");
2220 }
2221 }else{
2222 if(o<0.00001){
2223 o=0;
2224 }
2225 elem.style["opacity"]=o;
2226 if(/MSIE/.test(navigator.userAgent)){
2227 elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o*100+")";
2228 }
2229 }
2230 },getElementPosition:function(elem,_291){
2231 var self=MochiKit.Style;
2232 var dom=MochiKit.DOM;
2233 elem=dom.getElement(elem);
2234 if(!elem||(!(elem.x&&elem.y)&&(!elem.parentNode===null||self.getStyle(elem,"display")=="none"))){
2235 return undefined;
2236 }
2237 var c=new self.Coordinates(0,0);
2238 var box=null;
2239 var _296=null;
2240 var d=MochiKit.DOM._document;
2241 var de=d.documentElement;
2242 var b=d.body;
2243 if(!elem.parentNode&&elem.x&&elem.y){
2244 c.x+=elem.x||0;
2245 c.y+=elem.y||0;
2246 }else{
2247 if(elem.getBoundingClientRect){
2248 box=elem.getBoundingClientRect();
2249 c.x+=box.left+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
2250 c.y+=box.top+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
2251 }else{
2252 if(elem.offsetParent){
2253 c.x+=elem.offsetLeft;
2254 c.y+=elem.offsetTop;
2255 _296=elem.offsetParent;
2256 if(_296!=elem){
2257 while(_296){
2258 c.x+=_296.offsetLeft;
2259 c.y+=_296.offsetTop;
2260 _296=_296.offsetParent;
2261 }
2262 }
2263 var ua=navigator.userAgent.toLowerCase();
2264 if((typeof (opera)!="undefined"&&parseFloat(opera.version())<9)||(ua.indexOf("AppleWebKit")!=-1&&self.getStyle(elem,"position")=="absolute")){
2265 c.x-=b.offsetLeft;
2266 c.y-=b.offsetTop;
2267 }
2268 }
2269 }
2270 }
2271 if(typeof (_291)!="undefined"){
2272 _291=arguments.callee(_291);
2273 if(_291){
2274 c.x-=(_291.x||0);
2275 c.y-=(_291.y||0);
2276 }
2277 }
2278 if(elem.parentNode){
2279 _296=elem.parentNode;
2280 }else{
2281 _296=null;
2282 }
2283 while(_296){
2284 var _29b=_296.tagName.toUpperCase();
2285 if(_29b==="BODY"||_29b==="HTML"){
2286 break;
2287 }
2288 var disp=self.getStyle(_296,"display");
2289 if(disp!="inline"&&disp!="table-row"){
2290 c.x-=_296.scrollLeft;
2291 c.y-=_296.scrollTop;
2292 }
2293 if(_296.parentNode){
2294 _296=_296.parentNode;
2295 }else{
2296 _296=null;
2297 }
2298 }
2299 return c;
2300 },setElementPosition:function(elem,_29e,_29f){
2301 elem=MochiKit.DOM.getElement(elem);
2302 if(typeof (_29f)=="undefined"){
2303 _29f="px";
2304 }
2305 var _2a0={};
2306 var _2a1=MochiKit.Base.isUndefinedOrNull;
2307 if(!_2a1(_29e.x)){
2308 _2a0["left"]=_29e.x+_29f;
2309 }
2310 if(!_2a1(_29e.y)){
2311 _2a0["top"]=_29e.y+_29f;
2312 }
2313 MochiKit.DOM.updateNodeAttributes(elem,{"style":_2a0});
2314 },getElementDimensions:function(elem){
2315 var self=MochiKit.Style;
2316 var dom=MochiKit.DOM;
2317 if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){
2318 return new self.Dimensions(elem.w||0,elem.h||0);
2319 }
2320 elem=dom.getElement(elem);
2321 if(!elem){
2322 return undefined;
2323 }
2324 var disp=self.getStyle(elem,"display");
2325 if(disp!="none"&&disp!==""&&typeof (disp)!="undefined"){
2326 return new self.Dimensions(elem.offsetWidth||0,elem.offsetHeight||0);
2327 }
2328 var s=elem.style;
2329 var _2a7=s.visibility;
2330 var _2a8=s.position;
2331 s.visibility="hidden";
2332 s.position="absolute";
2333 s.display="";
2334 var _2a9=elem.offsetWidth;
2335 var _2aa=elem.offsetHeight;
2336 s.display="none";
2337 s.position=_2a8;
2338 s.visibility=_2a7;
2339 return new self.Dimensions(_2a9,_2aa);
2340 },setElementDimensions:function(elem,_2ac,_2ad){
2341 elem=MochiKit.DOM.getElement(elem);
2342 if(typeof (_2ad)=="undefined"){
2343 _2ad="px";
2344 }
2345 var _2ae={};
2346 var _2af=MochiKit.Base.isUndefinedOrNull;
2347 if(!_2af(_2ac.w)){
2348 _2ae["width"]=_2ac.w+_2ad;
2349 }
2350 if(!_2af(_2ac.h)){
2351 _2ae["height"]=_2ac.h+_2ad;
2352 }
2353 MochiKit.DOM.updateNodeAttributes(elem,{"style":_2ae});
2354 },setDisplayForElement:function(_2b0,_2b1){
2355 var _2b2=MochiKit.Base.extend(null,arguments,1);
2356 var _2b3=MochiKit.DOM.getElement;
2357 for(var i=0;i<_2b2.length;i++){
2358 _2b1=_2b3(_2b2[i]);
2359 if(_2b1){
2360 _2b1.style.display=_2b0;
2361 }
2362 }
2363 },getViewportDimensions:function(){
2364 var d=new MochiKit.Style.Dimensions();
2365 var w=MochiKit.DOM._window;
2366 var b=MochiKit.DOM._document.body;
2367 if(w.innerWidth){
2368 d.w=w.innerWidth;
2369 d.h=w.innerHeight;
2370 }else{
2371 if(b.parentElement.clientWidth){
2372 d.w=b.parentElement.clientWidth;
2373 d.h=b.parentElement.clientHeight;
2374 }else{
2375 if(b&&b.clientWidth){
2376 d.w=b.clientWidth;
2377 d.h=b.clientHeight;
2378 }
2379 }
2380 }
2381 return d;
2382 },getViewportPosition:function(){
2383 var c=new MochiKit.Style.Coordinates(0,0);
2384 var d=MochiKit.DOM._document;
2385 var de=d.documentElement;
2386 var db=d.body;
2387 if(de&&(de.scrollTop||de.scrollLeft)){
2388 c.x=de.scrollLeft;
2389 c.y=de.scrollTop;
2390 }else{
2391 if(db){
2392 c.x=db.scrollLeft;
2393 c.y=db.scrollTop;
2394 }
2395 }
2396 return c;
2397 },__new__:function(){
2398 var m=MochiKit.Base;
2399 this.elementPosition=this.getElementPosition;
2400 this.elementDimensions=this.getElementDimensions;
2401 this.hideElement=m.partial(this.setDisplayForElement,"none");
2402 this.showElement=m.partial(this.setDisplayForElement,"block");
2403 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
2404 m.nameFunctions(this);
2405 }});
2406 MochiKit.Style.__new__();
2407 MochiKit.Base._exportSymbols(this,MochiKit.Style);
2408 if(typeof (dojo)!="undefined"){
2409 dojo.provide("MochiKit.Color");
2410 dojo.require("MochiKit.Base");
2411 dojo.require("MochiKit.DOM");
2412 dojo.require("MochiKit.Style");
2413 }
2414 if(typeof (JSAN)!="undefined"){
2415 JSAN.use("MochiKit.Base",[]);
2416 JSAN.use("MochiKit.DOM",[]);
2417 JSAN.use("MochiKit.Style",[]);
2418 }
2419 try{
2420 if(typeof (MochiKit.Base)=="undefined"){
2421 throw "";
2422 }
2423 }
2424 catch(e){
2425 throw "MochiKit.Color depends on MochiKit.Base";
2426 }
2427 try{
2428 if(typeof (MochiKit.DOM)=="undefined"){
2429 throw "";
2430 }
2431 }
2432 catch(e){
2433 throw "MochiKit.Color depends on MochiKit.DOM";
2434 }
2435 try{
2436 if(typeof (MochiKit.Style)=="undefined"){
2437 throw "";
2438 }
2439 }
2440 catch(e){
2441 throw "MochiKit.Color depends on MochiKit.Style";
2442 }
2443 if(typeof (MochiKit.Color)=="undefined"){
2444 MochiKit.Color={};
2445 }
2446 MochiKit.Color.NAME="MochiKit.Color";
2447 MochiKit.Color.VERSION="1.4";
2448 MochiKit.Color.__repr__=function(){
2449 return "["+this.NAME+" "+this.VERSION+"]";
2450 };
2451 MochiKit.Color.toString=function(){
2452 return this.__repr__();
2453 };
2454 MochiKit.Color.Color=function(red,_2be,blue,_2c0){
2455 if(typeof (_2c0)=="undefined"||_2c0===null){
2456 _2c0=1;
2457 }
2458 this.rgb={r:red,g:_2be,b:blue,a:_2c0};
2459 };
2460 MochiKit.Color.Color.prototype={__class__:MochiKit.Color.Color,colorWithAlpha:function(_2c1){
2461 var rgb=this.rgb;
2462 var m=MochiKit.Color;
2463 return m.Color.fromRGB(rgb.r,rgb.g,rgb.b,_2c1);
2464 },colorWithHue:function(hue){
2465 var hsl=this.asHSL();
2466 hsl.h=hue;
2467 var m=MochiKit.Color;
2468 return m.Color.fromHSL(hsl);
2469 },colorWithSaturation:function(_2c7){
2470 var hsl=this.asHSL();
2471 hsl.s=_2c7;
2472 var m=MochiKit.Color;
2473 return m.Color.fromHSL(hsl);
2474 },colorWithLightness:function(_2ca){
2475 var hsl=this.asHSL();
2476 hsl.l=_2ca;
2477 var m=MochiKit.Color;
2478 return m.Color.fromHSL(hsl);
2479 },darkerColorWithLevel:function(_2cd){
2480 var hsl=this.asHSL();
2481 hsl.l=Math.max(hsl.l-_2cd,0);
2482 var m=MochiKit.Color;
2483 return m.Color.fromHSL(hsl);
2484 },lighterColorWithLevel:function(_2d0){
2485 var hsl=this.asHSL();
2486 hsl.l=Math.min(hsl.l+_2d0,1);
2487 var m=MochiKit.Color;
2488 return m.Color.fromHSL(hsl);
2489 },blendedColor:function(_2d3,_2d4){
2490 if(typeof (_2d4)=="undefined"||_2d4===null){
2491 _2d4=0.5;
2492 }
2493 var sf=1-_2d4;
2494 var s=this.rgb;
2495 var d=_2d3.rgb;
2496 var df=_2d4;
2497 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));
2498 },compareRGB:function(_2d9){
2499 var a=this.asRGB();
2500 var b=_2d9.asRGB();
2501 return MochiKit.Base.compare([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a]);
2502 },isLight:function(){
2503 return this.asHSL().b>0.5;
2504 },isDark:function(){
2505 return (!this.isLight());
2506 },toHSLString:function(){
2507 var c=this.asHSL();
2508 var ccc=MochiKit.Color.clampColorComponent;
2509 var rval=this._hslString;
2510 if(!rval){
2511 var mid=(ccc(c.h,360).toFixed(0)+","+ccc(c.s,100).toPrecision(4)+"%"+","+ccc(c.l,100).toPrecision(4)+"%");
2512 var a=c.a;
2513 if(a>=1){
2514 a=1;
2515 rval="hsl("+mid+")";
2516 }else{
2517 if(a<=0){
2518 a=0;
2519 }
2520 rval="hsla("+mid+","+a+")";
2521 }
2522 this._hslString=rval;
2523 }
2524 return rval;
2525 },toRGBString:function(){
2526 var c=this.rgb;
2527 var ccc=MochiKit.Color.clampColorComponent;
2528 var rval=this._rgbString;
2529 if(!rval){
2530 var mid=(ccc(c.r,255).toFixed(0)+","+ccc(c.g,255).toFixed(0)+","+ccc(c.b,255).toFixed(0));
2531 if(c.a!=1){
2532 rval="rgba("+mid+","+c.a+")";
2533 }else{
2534 rval="rgb("+mid+")";
2535 }
2536 this._rgbString=rval;
2537 }
2538 return rval;
2539 },asRGB:function(){
2540 return MochiKit.Base.clone(this.rgb);
2541 },toHexString:function(){
2542 var m=MochiKit.Color;
2543 var c=this.rgb;
2544 var ccc=MochiKit.Color.clampColorComponent;
2545 var rval=this._hexString;
2546 if(!rval){
2547 rval=("#"+m.toColorPart(ccc(c.r,255))+m.toColorPart(ccc(c.g,255))+m.toColorPart(ccc(c.b,255)));
2548 this._hexString=rval;
2549 }
2550 return rval;
2551 },asHSV:function(){
2552 var hsv=this.hsv;
2553 var c=this.rgb;
2554 if(typeof (hsv)=="undefined"||hsv===null){
2555 hsv=MochiKit.Color.rgbToHSV(this.rgb);
2556 this.hsv=hsv;
2557 }
2558 return MochiKit.Base.clone(hsv);
2559 },asHSL:function(){
2560 var hsl=this.hsl;
2561 var c=this.rgb;
2562 if(typeof (hsl)=="undefined"||hsl===null){
2563 hsl=MochiKit.Color.rgbToHSL(this.rgb);
2564 this.hsl=hsl;
2565 }
2566 return MochiKit.Base.clone(hsl);
2567 },toString:function(){
2568 return this.toRGBString();
2569 },repr:function(){
2570 var c=this.rgb;
2571 var col=[c.r,c.g,c.b,c.a];
2572 return this.__class__.NAME+"("+col.join(", ")+")";
2573 }};
2574 MochiKit.Base.update(MochiKit.Color.Color,{fromRGB:function(red,_2f0,blue,_2f2){
2575 var _2f3=MochiKit.Color.Color;
2576 if(arguments.length==1){
2577 var rgb=red;
2578 red=rgb.r;
2579 _2f0=rgb.g;
2580 blue=rgb.b;
2581 if(typeof (rgb.a)=="undefined"){
2582 _2f2=undefined;
2583 }else{
2584 _2f2=rgb.a;
2585 }
2586 }
2587 return new _2f3(red,_2f0,blue,_2f2);
2588 },fromHSL:function(hue,_2f6,_2f7,_2f8){
2589 var m=MochiKit.Color;
2590 return m.Color.fromRGB(m.hslToRGB.apply(m,arguments));
2591 },fromHSV:function(hue,_2fb,_2fc,_2fd){
2592 var m=MochiKit.Color;
2593 return m.Color.fromRGB(m.hsvToRGB.apply(m,arguments));
2594 },fromName:function(name){
2595 var _300=MochiKit.Color.Color;
2596 if(name.charAt(0)=="\""){
2597 name=name.substr(1,name.length-2);
2598 }
2599 var _301=_300._namedColors[name.toLowerCase()];
2600 if(typeof (_301)=="string"){
2601 return _300.fromHexString(_301);
2602 }else{
2603 if(name=="transparent"){
2604 return _300.transparentColor();
2605 }
2606 }
2607 return null;
2608 },fromString:function(_302){
2609 var self=MochiKit.Color.Color;
2610 var _304=_302.substr(0,3);
2611 if(_304=="rgb"){
2612 return self.fromRGBString(_302);
2613 }else{
2614 if(_304=="hsl"){
2615 return self.fromHSLString(_302);
2616 }else{
2617 if(_302.charAt(0)=="#"){
2618 return self.fromHexString(_302);
2619 }
2620 }
2621 }
2622 return self.fromName(_302);
2623 },fromHexString:function(_305){
2624 if(_305.charAt(0)=="#"){
2625 _305=_305.substring(1);
2626 }
2627 var _306=[];
2628 var i,hex;
2629 if(_305.length==3){
2630 for(i=0;i<3;i++){
2631 hex=_305.substr(i,1);
2632 _306.push(parseInt(hex+hex,16)/255);
2633 }
2634 }else{
2635 for(i=0;i<6;i+=2){
2636 hex=_305.substr(i,2);
2637 _306.push(parseInt(hex,16)/255);
2638 }
2639 }
2640 var _309=MochiKit.Color.Color;
2641 return _309.fromRGB.apply(_309,_306);
2642 },_fromColorString:function(pre,_30b,_30c,_30d){
2643 if(_30d.indexOf(pre)===0){
2644 _30d=_30d.substring(_30d.indexOf("(",3)+1,_30d.length-1);
2645 }
2646 var _30e=_30d.split(/\s*,\s*/);
2647 var _30f=[];
2648 for(var i=0;i<_30e.length;i++){
2649 var c=_30e[i];
2650 var val;
2651 var _313=c.substring(c.length-3);
2652 if(c.charAt(c.length-1)=="%"){
2653 val=0.01*parseFloat(c.substring(0,c.length-1));
2654 }else{
2655 if(_313=="deg"){
2656 val=parseFloat(c)/360;
2657 }else{
2658 if(_313=="rad"){
2659 val=parseFloat(c)/(Math.PI*2);
2660 }else{
2661 val=_30c[i]*parseFloat(c);
2662 }
2663 }
2664 }
2665 _30f.push(val);
2666 }
2667 return this[_30b].apply(this,_30f);
2668 },fromComputedStyle:function(elem,_315){
2669 var d=MochiKit.DOM;
2670 var cls=MochiKit.Color.Color;
2671 for(elem=d.getElement(elem);elem;elem=elem.parentNode){
2672 var _318=MochiKit.Style.getStyle.apply(d,arguments);
2673 if(!_318){
2674 continue;
2675 }
2676 var _319=cls.fromString(_318);
2677 if(!_319){
2678 break;
2679 }
2680 if(_319.asRGB().a>0){
2681 return _319;
2682 }
2683 }
2684 return null;
2685 },fromBackground:function(elem){
2686 var cls=MochiKit.Color.Color;
2687 return cls.fromComputedStyle(elem,"backgroundColor","background-color")||cls.whiteColor();
2688 },fromText:function(elem){
2689 var cls=MochiKit.Color.Color;
2690 return cls.fromComputedStyle(elem,"color","color")||cls.blackColor();
2691 },namedColors:function(){
2692 return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
2693 }});
2694 MochiKit.Base.update(MochiKit.Color,{clampColorComponent:function(v,_31f){
2695 v*=_31f;
2696 if(v<0){
2697 return 0;
2698 }else{
2699 if(v>_31f){
2700 return _31f;
2701 }else{
2702 return v;
2703 }
2704 }
2705 },_hslValue:function(n1,n2,hue){
2706 if(hue>6){
2707 hue-=6;
2708 }else{
2709 if(hue<0){
2710 hue+=6;
2711 }
2712 }
2713 var val;
2714 if(hue<1){
2715 val=n1+(n2-n1)*hue;
2716 }else{
2717 if(hue<3){
2718 val=n2;
2719 }else{
2720 if(hue<4){
2721 val=n1+(n2-n1)*(4-hue);
2722 }else{
2723 val=n1;
2724 }
2725 }
2726 }
2727 return val;
2728 },hsvToRGB:function(hue,_325,_326,_327){
2729 if(arguments.length==1){
2730 var hsv=hue;
2731 hue=hsv.h;
2732 _325=hsv.s;
2733 _326=hsv.v;
2734 _327=hsv.a;
2735 }
2736 var red;
2737 var _32a;
2738 var blue;
2739 if(_325===0){
2740 red=_326;
2741 _32a=_326;
2742 blue=_326;
2743 }else{
2744 var i=Math.floor(hue*6);
2745 var f=(hue*6)-i;
2746 var p=_326*(1-_325);
2747 var q=_326*(1-(_325*f));
2748 var t=_326*(1-(_325*(1-f)));
2749 switch(i){
2750 case 1:
2751 red=q;
2752 _32a=_326;
2753 blue=p;
2754 break;
2755 case 2:
2756 red=p;
2757 _32a=_326;
2758 blue=t;
2759 break;
2760 case 3:
2761 red=p;
2762 _32a=q;
2763 blue=_326;
2764 break;
2765 case 4:
2766 red=t;
2767 _32a=p;
2768 blue=_326;
2769 break;
2770 case 5:
2771 red=_326;
2772 _32a=p;
2773 blue=q;
2774 break;
2775 case 6:
2776 case 0:
2777 red=_326;
2778 _32a=t;
2779 blue=p;
2780 break;
2781 }
2782 }
2783 return {r:red,g:_32a,b:blue,a:_327};
2784 },hslToRGB:function(hue,_332,_333,_334){
2785 if(arguments.length==1){
2786 var hsl=hue;
2787 hue=hsl.h;
2788 _332=hsl.s;
2789 _333=hsl.l;
2790 _334=hsl.a;
2791 }
2792 var red;
2793 var _337;
2794 var blue;
2795 if(_332===0){
2796 red=_333;
2797 _337=_333;
2798 blue=_333;
2799 }else{
2800 var m2;
2801 if(_333<=0.5){
2802 m2=_333*(1+_332);
2803 }else{
2804 m2=_333+_332-(_333*_332);
2805 }
2806 var m1=(2*_333)-m2;
2807 var f=MochiKit.Color._hslValue;
2808 var h6=hue*6;
2809 red=f(m1,m2,h6+2);
2810 _337=f(m1,m2,h6);
2811 blue=f(m1,m2,h6-2);
2812 }
2813 return {r:red,g:_337,b:blue,a:_334};
2814 },rgbToHSV:function(red,_33e,blue,_340){
2815 if(arguments.length==1){
2816 var rgb=red;
2817 red=rgb.r;
2818 _33e=rgb.g;
2819 blue=rgb.b;
2820 _340=rgb.a;
2821 }
2822 var max=Math.max(Math.max(red,_33e),blue);
2823 var min=Math.min(Math.min(red,_33e),blue);
2824 var hue;
2825 var _345;
2826 var _346=max;
2827 if(min==max){
2828 hue=0;
2829 _345=0;
2830 }else{
2831 var _347=(max-min);
2832 _345=_347/max;
2833 if(red==max){
2834 hue=(_33e-blue)/_347;
2835 }else{
2836 if(_33e==max){
2837 hue=2+((blue-red)/_347);
2838 }else{
2839 hue=4+((red-_33e)/_347);
2840 }
2841 }
2842 hue/=6;
2843 if(hue<0){
2844 hue+=1;
2845 }
2846 if(hue>1){
2847 hue-=1;
2848 }
2849 }
2850 return {h:hue,s:_345,v:_346,a:_340};
2851 },rgbToHSL:function(red,_349,blue,_34b){
2852 if(arguments.length==1){
2853 var rgb=red;
2854 red=rgb.r;
2855 _349=rgb.g;
2856 blue=rgb.b;
2857 _34b=rgb.a;
2858 }
2859 var max=Math.max(red,Math.max(_349,blue));
2860 var min=Math.min(red,Math.min(_349,blue));
2861 var hue;
2862 var _350;
2863 var _351=(max+min)/2;
2864 var _352=max-min;
2865 if(_352===0){
2866 hue=0;
2867 _350=0;
2868 }else{
2869 if(_351<=0.5){
2870 _350=_352/(max+min);
2871 }else{
2872 _350=_352/(2-max-min);
2873 }
2874 if(red==max){
2875 hue=(_349-blue)/_352;
2876 }else{
2877 if(_349==max){
2878 hue=2+((blue-red)/_352);
2879 }else{
2880 hue=4+((red-_349)/_352);
2881 }
2882 }
2883 hue/=6;
2884 if(hue<0){
2885 hue+=1;
2886 }
2887 if(hue>1){
2888 hue-=1;
2889 }
2890 }
2891 return {h:hue,s:_350,l:_351,a:_34b};
2892 },toColorPart:function(num){
2893 num=Math.round(num);
2894 var _354=num.toString(16);
2895 if(num<16){
2896 return "0"+_354;
2897 }
2898 return _354;
2899 },__new__:function(){
2900 var m=MochiKit.Base;
2901 this.Color.fromRGBString=m.bind(this.Color._fromColorString,this.Color,"rgb","fromRGB",[1/255,1/255,1/255,1]);
2902 this.Color.fromHSLString=m.bind(this.Color._fromColorString,this.Color,"hsl","fromHSL",[1/360,0.01,0.01,1]);
2903 var _356=1/3;
2904 var _357={black:[0,0,0],blue:[0,0,1],brown:[0.6,0.4,0.2],cyan:[0,1,1],darkGray:[_356,_356,_356],gray:[0.5,0.5,0.5],green:[0,1,0],lightGray:[2*_356,2*_356,2*_356],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]};
2905 var _358=function(name,r,g,b,a){
2906 var rval=this.fromRGB(r,g,b,a);
2907 this[name]=function(){
2908 return rval;
2909 };
2910 return rval;
2911 };
2912 for(var k in _357){
2913 var name=k+"Color";
2914 var _361=m.concat([_358,this.Color,name],_357[k]);
2915 this.Color[name]=m.bind.apply(null,_361);
2916 }
2917 var _362=function(){
2918 for(var i=0;i<arguments.length;i++){
2919 if(!(arguments[i] instanceof Color)){
2920 return false;
2921 }
2922 }
2923 return true;
2924 };
2925 var _364=function(a,b){
2926 return a.compareRGB(b);
2927 };
2928 m.nameFunctions(this);
2929 m.registerComparator(this.Color.NAME,_362,_364);
2930 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
2931 }});
2932 MochiKit.Color.EXPORT=["Color"];
2933 MochiKit.Color.EXPORT_OK=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
2934 MochiKit.Color.__new__();
2935 MochiKit.Base._exportSymbols(this,MochiKit.Color);
2936 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"};
2937 if(typeof (dojo)!="undefined"){
2938 dojo.provide("MochiKit.Signal");
2939 dojo.require("MochiKit.Base");
2940 dojo.require("MochiKit.DOM");
2941 dojo.require("MochiKit.Style");
2942 }
2943 if(typeof (JSAN)!="undefined"){
2944 JSAN.use("MochiKit.Base",[]);
2945 JSAN.use("MochiKit.DOM",[]);
2946 JSAN.use("MochiKit.Style",[]);
2947 }
2948 try{
2949 if(typeof (MochiKit.Base)=="undefined"){
2950 throw "";
2951 }
2952 }
2953 catch(e){
2954 throw "MochiKit.Signal depends on MochiKit.Base!";
2955 }
2956 try{
2957 if(typeof (MochiKit.DOM)=="undefined"){
2958 throw "";
2959 }
2960 }
2961 catch(e){
2962 throw "MochiKit.Signal depends on MochiKit.DOM!";
2963 }
2964 try{
2965 if(typeof (MochiKit.Style)=="undefined"){
2966 throw "";
2967 }
2968 }
2969 catch(e){
2970 throw "MochiKit.Signal depends on MochiKit.Style!";
2971 }
2972 if(typeof (MochiKit.Signal)=="undefined"){
2973 MochiKit.Signal={};
2974 }
2975 MochiKit.Signal.NAME="MochiKit.Signal";
2976 MochiKit.Signal.VERSION="1.4";
2977 MochiKit.Signal._observers=[];
2978 MochiKit.Signal.Event=function(src,e){
2979 this._event=e||window.event;
2980 this._src=src;
2981 };
2982 MochiKit.Base.update(MochiKit.Signal.Event.prototype,{__repr__:function(){
2983 var repr=MochiKit.Base.repr;
2984 var str="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target());
2985 if(this.type()&&this.type().indexOf("key")===0||this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu"){
2986 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)+"}";
2987 }
2988 if(this.type()&&this.type().indexOf("key")===0){
2989 str+=", key(): {code: "+repr(this.key().code)+", string: "+repr(this.key().string)+"}";
2990 }
2991 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
2992 str+=", mouse(): {page: "+repr(this.mouse().page)+", client: "+repr(this.mouse().client);
2993 if(this.type()!="mousemove"){
2994 str+=", button: {left: "+repr(this.mouse().button.left)+", middle: "+repr(this.mouse().button.middle)+", right: "+repr(this.mouse().button.right)+"}}";
2995 }else{
2996 str+="}";
2997 }
2998 }
2999 if(this.type()=="mouseover"||this.type()=="mouseout"){
3000 str+=", relatedTarget(): "+repr(this.relatedTarget());
3001 }
3002 str+="}";
3003 return str;
3004 },toString:function(){
3005 return this.__repr__();
3006 },src:function(){
3007 return this._src;
3008 },event:function(){
3009 return this._event;
3010 },type:function(){
3011 return this._event.type||undefined;
3012 },target:function(){
3013 return this._event.target||this._event.srcElement;
3014 },_relatedTarget:null,relatedTarget:function(){
3015 if(this._relatedTarget!==null){
3016 return this._relatedTarget;
3017 }
3018 var elem=null;
3019 if(this.type()=="mouseover"){
3020 elem=(this._event.relatedTarget||this._event.fromElement);
3021 }else{
3022 if(this.type()=="mouseout"){
3023 elem=(this._event.relatedTarget||this._event.toElement);
3024 }
3025 }
3026 if(elem!==null){
3027 this._relatedTarget=elem;
3028 return elem;
3029 }
3030 return undefined;
3031 },_modifier:null,modifier:function(){
3032 if(this._modifier!==null){
3033 return this._modifier;
3034 }
3035 var m={};
3036 m.alt=this._event.altKey;
3037 m.ctrl=this._event.ctrlKey;
3038 m.meta=this._event.metaKey||false;
3039 m.shift=this._event.shiftKey;
3040 m.any=m.alt||m.ctrl||m.shift||m.meta;
3041 this._modifier=m;
3042 return m;
3043 },_key:null,key:function(){
3044 if(this._key!==null){
3045 return this._key;
3046 }
3047 var k={};
3048 if(this.type()&&this.type().indexOf("key")===0){
3049 if(this.type()=="keydown"||this.type()=="keyup"){
3050 k.code=this._event.keyCode;
3051 k.string=(MochiKit.Signal._specialKeys[k.code]||"KEY_UNKNOWN");
3052 this._key=k;
3053 return k;
3054 }else{
3055 if(this.type()=="keypress"){
3056 k.code=0;
3057 k.string="";
3058 if(typeof (this._event.charCode)!="undefined"&&this._event.charCode!==0&&!MochiKit.Signal._specialMacKeys[this._event.charCode]){
3059 k.code=this._event.charCode;
3060 k.string=String.fromCharCode(k.code);
3061 }else{
3062 if(this._event.keyCode&&typeof (this._event.charCode)=="undefined"){
3063 k.code=this._event.keyCode;
3064 k.string=String.fromCharCode(k.code);
3065 }
3066 }
3067 this._key=k;
3068 return k;
3069 }
3070 }
3071 }
3072 return undefined;
3073 },_mouse:null,mouse:function(){
3074 if(this._mouse!==null){
3075 return this._mouse;
3076 }
3077 var m={};
3078 var e=this._event;
3079 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3080 m.client=new MochiKit.Style.Coordinates(0,0);
3081 if(e.clientX||e.clientY){
3082 m.client.x=(!e.clientX||e.clientX<0)?0:e.clientX;
3083 m.client.y=(!e.clientY||e.clientY<0)?0:e.clientY;
3084 }
3085 m.page=new MochiKit.Style.Coordinates(0,0);
3086 if(e.pageX||e.pageY){
3087 m.page.x=(!e.pageX||e.pageX<0)?0:e.pageX;
3088 m.page.y=(!e.pageY||e.pageY<0)?0:e.pageY;
3089 }else{
3090 var de=MochiKit.DOM._document.documentElement;
3091 var b=MochiKit.DOM._document.body;
3092 m.page.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
3093 m.page.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
3094 }
3095 if(this.type()!="mousemove"){
3096 m.button={};
3097 m.button.left=false;
3098 m.button.right=false;
3099 m.button.middle=false;
3100 if(e.which){
3101 m.button.left=(e.which==1);
3102 m.button.middle=(e.which==2);
3103 m.button.right=(e.which==3);
3104 }else{
3105 m.button.left=!!(e.button&1);
3106 m.button.right=!!(e.button&2);
3107 m.button.middle=!!(e.button&4);
3108 }
3109 }
3110 this._mouse=m;
3111 return m;
3112 }
3113 return undefined;
3114 },stop:function(){
3115 this.stopPropagation();
3116 this.preventDefault();
3117 },stopPropagation:function(){
3118 if(this._event.stopPropagation){
3119 this._event.stopPropagation();
3120 }else{
3121 this._event.cancelBubble=true;
3122 }
3123 },preventDefault:function(){
3124 if(this._event.preventDefault){
3125 this._event.preventDefault();
3126 }else{
3127 if(this._confirmUnload===null){
3128 this._event.returnValue=false;
3129 }
3130 }
3131 },_confirmUnload:null,confirmUnload:function(msg){
3132 if(this.type()=="beforeunload"){
3133 this._confirmUnload=msg;
3134 this._event.returnValue=msg;
3135 }
3136 }});
3137 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"};
3138 (function(){
3139 var _373=MochiKit.Signal._specialMacKeys;
3140 for(i=63236;i<=63242;i++){
3141 _373[i]="KEY_F"+(i-63236+1);
3142 }
3143 })();
3144 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"};
3145 (function(){
3146 var _374=MochiKit.Signal._specialKeys;
3147 for(var i=48;i<=57;i++){
3148 _374[i]="KEY_"+(i-48);
3149 }
3150 for(i=65;i<=90;i++){
3151 _374[i]="KEY_"+String.fromCharCode(i);
3152 }
3153 for(i=96;i<=105;i++){
3154 _374[i]="KEY_NUM_PAD_"+(i-96);
3155 }
3156 for(i=112;i<=123;i++){
3157 _374[i]="KEY_F"+(i-112+1);
3158 }
3159 })();
3160 MochiKit.Signal.Ident=function(_376){
3161 this.source=_376.source;
3162 this.signal=_376.signal;
3163 this.listener=_376.listener;
3164 this.isDOM=_376.isDOM;
3165 this.objOrFunc=_376.objOrFunc;
3166 this.funcOrStr=_376.funcOrStr;
3167 this.connected=_376.connected;
3168 };
3169 MochiKit.Signal.Ident.prototype={};
3170 MochiKit.Base.update(MochiKit.Signal,{__repr__:function(){
3171 return "["+this.NAME+" "+this.VERSION+"]";
3172 },toString:function(){
3173 return this.__repr__();
3174 },_unloadCache:function(){
3175 var self=MochiKit.Signal;
3176 var _378=self._observers;
3177 for(var i=0;i<_378.length;i++){
3178 if(_378[i].signal!=="onload"&&_378[i].signal!=="onunload"){
3179 self._disconnect(_378[i]);
3180 }
3181 }
3182 },_listener:function(src,sig,func,obj,_37e){
3183 var self=MochiKit.Signal;
3184 var E=self.Event;
3185 if(!_37e){
3186 return MochiKit.Base.bind(func,obj);
3187 }
3188 obj=obj||src;
3189 if(typeof (func)=="string"){
3190 if(sig==="onload"||sig==="onunload"){
3191 return function(_381){
3192 obj[func].apply(obj,[new E(src,_381)]);
3193 var _382=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:obj,funcOrStr:func});
3194 MochiKit.Signal._disconnect(_382);
3195 };
3196 }else{
3197 return function(_383){
3198 obj[func].apply(obj,[new E(src,_383)]);
3199 };
3200 }
3201 }else{
3202 if(sig==="onload"||sig==="onunload"){
3203 return function(_384){
3204 func.apply(obj,[new E(src,_384)]);
3205 MochiKit.Signal.disconnect(src,sig,func);
3206 var _385=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:func});
3207 MochiKit.Signal._disconnect(_385);
3208 };
3209 }else{
3210 return function(_386){
3211 func.apply(obj,[new E(src,_386)]);
3212 };
3213 }
3214 }
3215 },_browserAlreadyHasMouseEnterAndLeave:function(){
3216 return /MSIE/.test(navigator.userAgent);
3217 },_mouseEnterListener:function(src,sig,func,obj){
3218 var E=MochiKit.Signal.Event;
3219 return function(_38c){
3220 var e=new E(src,_38c);
3221 try{
3222 e.relatedTarget().nodeName;
3223 }
3224 catch(err){
3225 return;
3226 }
3227 e.stop();
3228 if(MochiKit.DOM.isChildNode(e.relatedTarget(),src)){
3229 return;
3230 }
3231 e.type=function(){
3232 return sig;
3233 };
3234 if(typeof (func)=="string"){
3235 return obj[func].apply(obj,[e]);
3236 }else{
3237 return func.apply(obj,[e]);
3238 }
3239 };
3240 },_getDestPair:function(_38e,_38f){
3241 var obj=null;
3242 var func=null;
3243 if(typeof (_38f)!="undefined"){
3244 obj=_38e;
3245 func=_38f;
3246 if(typeof (_38f)=="string"){
3247 if(typeof (_38e[_38f])!="function"){
3248 throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
3249 }
3250 }else{
3251 if(typeof (_38f)!="function"){
3252 throw new Error("'funcOrStr' must be a function or string");
3253 }
3254 }
3255 }else{
3256 if(typeof (_38e)!="function"){
3257 throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
3258 }else{
3259 func=_38e;
3260 }
3261 }
3262 return [obj,func];
3263 },connect:function(src,sig,_394,_395){
3264 src=MochiKit.DOM.getElement(src);
3265 var self=MochiKit.Signal;
3266 if(typeof (sig)!="string"){
3267 throw new Error("'sig' must be a string");
3268 }
3269 var _397=self._getDestPair(_394,_395);
3270 var obj=_397[0];
3271 var func=_397[1];
3272 if(typeof (obj)=="undefined"||obj===null){
3273 obj=src;
3274 }
3275 var _39a=!!(src.addEventListener||src.attachEvent);
3276 if(_39a&&(sig==="onmouseenter"||sig==="onmouseleave")&&!self._browserAlreadyHasMouseEnterAndLeave()){
3277 var _39b=self._mouseEnterListener(src,sig.substr(2),func,obj);
3278 if(sig==="onmouseenter"){
3279 sig="onmouseover";
3280 }else{
3281 sig="onmouseout";
3282 }
3283 }else{
3284 var _39b=self._listener(src,sig,func,obj,_39a);
3285 }
3286 if(src.addEventListener){
3287 src.addEventListener(sig.substr(2),_39b,false);
3288 }else{
3289 if(src.attachEvent){
3290 src.attachEvent(sig,_39b);
3291 }
3292 }
3293 var _39c=new MochiKit.Signal.Ident({source:src,signal:sig,listener:_39b,isDOM:_39a,objOrFunc:_394,funcOrStr:_395,connected:true});
3294 self._observers.push(_39c);
3295 if(!_39a&&typeof (src.__connect__)=="function"){
3296 var args=MochiKit.Base.extend([_39c],arguments,1);
3297 src.__connect__.apply(src,args);
3298 }
3299 return _39c;
3300 },_disconnect:function(_39e){
3301 if(!_39e.connected){
3302 return;
3303 }
3304 _39e.connected=false;
3305 if(!_39e.isDOM){
3306 return;
3307 }
3308 var src=_39e.source;
3309 var sig=_39e.signal;
3310 var _3a1=_39e.listener;
3311 if(src.removeEventListener){
3312 src.removeEventListener(sig.substr(2),_3a1,false);
3313 }else{
3314 if(src.detachEvent){
3315 src.detachEvent(sig,_3a1);
3316 }else{
3317 throw new Error("'src' must be a DOM element");
3318 }
3319 }
3320 },disconnect:function(_3a2){
3321 var self=MochiKit.Signal;
3322 var _3a4=self._observers;
3323 var m=MochiKit.Base;
3324 if(arguments.length>1){
3325 var src=MochiKit.DOM.getElement(arguments[0]);
3326 var sig=arguments[1];
3327 var obj=arguments[2];
3328 var func=arguments[3];
3329 for(var i=_3a4.length-1;i>=0;i--){
3330 var o=_3a4[i];
3331 if(o.source===src&&o.signal===sig&&o.objOrFunc===obj&&o.funcOrStr===func){
3332 self._disconnect(o);
3333 if(!self._lock){
3334 _3a4.splice(i,1);
3335 }else{
3336 self._dirty=true;
3337 }
3338 return true;
3339 }
3340 }
3341 }else{
3342 var idx=m.findIdentical(_3a4,_3a2);
3343 if(idx>=0){
3344 self._disconnect(_3a2);
3345 if(!self._lock){
3346 _3a4.splice(idx,1);
3347 }else{
3348 self._dirty=true;
3349 }
3350 return true;
3351 }
3352 }
3353 return false;
3354 },disconnectAllTo:function(_3ad,_3ae){
3355 var self=MochiKit.Signal;
3356 var _3b0=self._observers;
3357 var _3b1=self._disconnect;
3358 var _3b2=self._lock;
3359 var _3b3=self._dirty;
3360 if(typeof (_3ae)==="undefined"){
3361 _3ae=null;
3362 }
3363 for(var i=_3b0.length-1;i>=0;i--){
3364 var _3b5=_3b0[i];
3365 if(_3b5.objOrFunc===_3ad&&(_3ae===null||_3b5.funcOrStr===_3ae)){
3366 _3b1(_3b5);
3367 if(_3b2){
3368 _3b3=true;
3369 }else{
3370 _3b0.splice(i,1);
3371 }
3372 }
3373 }
3374 self._dirty=_3b3;
3375 },disconnectAll:function(src,sig){
3376 src=MochiKit.DOM.getElement(src);
3377 var m=MochiKit.Base;
3378 var _3b9=m.flattenArguments(m.extend(null,arguments,1));
3379 var self=MochiKit.Signal;
3380 var _3bb=self._disconnect;
3381 var _3bc=self._observers;
3382 var i,_3be;
3383 var _3bf=self._lock;
3384 var _3c0=self._dirty;
3385 if(_3b9.length===0){
3386 for(i=_3bc.length-1;i>=0;i--){
3387 _3be=_3bc[i];
3388 if(_3be.source===src){
3389 _3bb(_3be);
3390 if(!_3bf){
3391 _3bc.splice(i,1);
3392 }else{
3393 _3c0=true;
3394 }
3395 }
3396 }
3397 }else{
3398 var sigs={};
3399 for(i=0;i<_3b9.length;i++){
3400 sigs[_3b9[i]]=true;
3401 }
3402 for(i=_3bc.length-1;i>=0;i--){
3403 _3be=_3bc[i];
3404 if(_3be.source===src&&_3be.signal in sigs){
3405 _3bb(_3be);
3406 if(!_3bf){
3407 _3bc.splice(i,1);
3408 }else{
3409 _3c0=true;
3410 }
3411 }
3412 }
3413 }
3414 self._dirty=_3c0;
3415 },signal:function(src,sig){
3416 var self=MochiKit.Signal;
3417 var _3c5=self._observers;
3418 src=MochiKit.DOM.getElement(src);
3419 var args=MochiKit.Base.extend(null,arguments,2);
3420 var _3c7=[];
3421 self._lock=true;
3422 for(var i=0;i<_3c5.length;i++){
3423 var _3c9=_3c5[i];
3424 if(_3c9.source===src&&_3c9.signal===sig){
3425 try{
3426 _3c9.listener.apply(src,args);
3427 }
3428 catch(e){
3429 _3c7.push(e);
3430 }
3431 }
3432 }
3433 self._lock=false;
3434 if(self._dirty){
3435 self._dirty=false;
3436 for(var i=_3c5.length-1;i>=0;i--){
3437 if(!_3c5[i].connected){
3438 _3c5.splice(i,1);
3439 }
3440 }
3441 }
3442 if(_3c7.length==1){
3443 throw _3c7[0];
3444 }else{
3445 if(_3c7.length>1){
3446 var e=new Error("Multiple errors thrown in handling 'sig', see errors property");
3447 e.errors=_3c7;
3448 throw e;
3449 }
3450 }
3451 }});
3452 MochiKit.Signal.EXPORT_OK=[];
3453 MochiKit.Signal.EXPORT=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
3454 MochiKit.Signal.__new__=function(win){
3455 var m=MochiKit.Base;
3456 this._document=document;
3457 this._window=win;
3458 this._lock=false;
3459 this._dirty=false;
3460 try{
3461 this.connect(window,"onunload",this._unloadCache);
3462 }
3463 catch(e){
3464 }
3465 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
3466 m.nameFunctions(this);
3467 };
3468 MochiKit.Signal.__new__(this);
3469 if(MochiKit.__export__){
3470 connect=MochiKit.Signal.connect;
3471 disconnect=MochiKit.Signal.disconnect;
3472 disconnectAll=MochiKit.Signal.disconnectAll;
3473 signal=MochiKit.Signal.signal;
3474 }
3475 MochiKit.Base._exportSymbols(this,MochiKit.Signal);
3476
3477
3478 /***
3479
3480 PlotKit.PlotKit 0.9.1 : PACKED VERSION
3481
3482 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
3483 diff against the source tree, not this file.
3484
3485 For more information, <http://www.liquidx.net/plotkit/>.
3486
3487 Copyright (c) 2006. Alastair Tse.
3488
3489 ***/
3490
3491 try{
3492 if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.DOM)=="undefined"||typeof (MochiKit.Color)=="undefined"||typeof (MochiKit.Format)=="undefined"){
3493 throw "";
3494 }
3495 }
3496 catch(e){
3497 throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}";
3498 }
3499 MochiKit.Base.update(MochiKit.Color.Color.prototype,{asFillColor:function(){
3500 return this.lighterColorWithLevel(0.3);
3501 },asStrokeColor:function(){
3502 return this.darkerColorWithLevel(0.1);
3503 },asPointColor:function(){
3504 return this.lighterColorWithLevel(0.1);
3505 }});
3506 if(typeof (PlotKit)=="undefined"){
3507 PlotKit={};
3508 }
3509 PlotKit.NAME="PlotKit";
3510 PlotKit.VERSION="0.8";
3511 PlotKit.__repr__=function(){
3512 return "["+this.NAME+" "+this.VERSION+"]";
3513 };
3514 PlotKit.toString=function(){
3515 return this.__repr__();
3516 };
3517 if(typeof (PlotKit.Base)=="undefined"){
3518 PlotKit.Base={};
3519 }
3520 PlotKit.Base.NAME="PlotKit.Base";
3521 PlotKit.Base.VERSION=PlotKit.VERSION;
3522 PlotKit.Base.__repr__=function(){
3523 return "["+this.NAME+" "+this.VERSION+"]";
3524 };
3525 PlotKit.Base.toString=function(){
3526 return this.__repr__();
3527 };
3528 PlotKit.Base.usingPrototype=function(){
3529 try{
3530 return (typeof (Object.extend)=="function");
3531 }
3532 catch(e){
3533 return false;
3534 }
3535 };
3536 MochiKit.Base.update(PlotKit.Base,{roundInterval:function(_1,_2,_3){
3537 var _4=MochiKit.Format.roundToFixed;
3538 var _5=_1/_2;
3539 return parseFloat(_4(_5,_3));
3540 },collapse:function(_6){
3541 var m=MochiKit.Base;
3542 var _8=new Array();
3543 for(var i=0;i<_6.length;i++){
3544 _8=m.concat(_8,_6[i]);
3545 }
3546 if(PlotKit.Base.usingPrototype()){
3547 delete _8.extend;
3548 delete _8.from;
3549 delete _8.inspect;
3550 }
3551 return _8;
3552 },uniq:function(_10){
3553 var m=MochiKit.Base;
3554 if(!m.isArrayLike(_10)||(_10.length<1)){
3555 return new Array();
3556 }
3557 var _11=new Array();
3558 var _12=_10[0];
3559 _11.push(_10[0]);
3560 for(var i=1;i<_10.length;i++){
3561 if(m.compare(_10[i],_12)!=0){
3562 _12=_10[i];
3563 _11.push(_10[i]);
3564 }
3565 }
3566 return _11;
3567 },colorScheme:function(){
3568 var mb=MochiKit.Base;
3569 var mc=MochiKit.Color;
3570 var _15=["red","orange","yellow","green","cyan","blue","purple","magenta"];
3571 var _16=function(_17){
3572 return mc.Color[_17+"Color"]();
3573 };
3574 return mb.map(_16,_15);
3575 },baseDarkPrimaryColors:function(){
3576 var _18=MochiKit.Color.Color.fromHexString;
3577 return [_18("#ad3f40"),_18("#ddac2c"),_18("#dfdd0c"),_18("#5276c4"),_18("#739c5a")];
3578 },basePrimaryColors:function(){
3579 var _19=MochiKit.Color.Color.fromHexString;
3580 return [_19("#d24c4d"),_19("#f2b32f"),_19("#ece90e"),_19("#5d83da"),_19("#78a15d")];
3581 },baseBlueColors:function(){
3582 var _20=MochiKit.Color.Color.fromHexString;
3583 return [_20("#4b6b94"),_20("#5d81b4"),_20("#acbad2")];
3584 },palette:function(_21,_22,_23,_24){
3585 var _25=MochiKit.Base.isUndefinedOrNull;
3586 var _26=new Array();
3587 if(_25(_24)){
3588 _24=0.1;
3589 }
3590 if(_25(_23)){
3591 _23=0.4;
3592 }
3593 if(_25(_22)){
3594 _22=-0.2;
3595 }
3596 var _27=_22;
3597 while(_27<=_23){
3598 _26.push(_27);
3599 _27+=_24;
3600 }
3601 var _28=function(_29,_30){
3602 return _29.lighterColorWithLevel(_30);
3603 };
3604 return MochiKit.Base.map(partial(_28,_21),_26);
3605 },excanvasSupported:function(){
3606 if(/MSIE/.test(navigator.userAgent)&&!window.opera){
3607 return true;
3608 }
3609 return false;
3610 },findPosX:function(obj){
3611 var _32=0;
3612 if(obj.offsetParent){
3613 while(obj.offsetParent){
3614 _32+=obj.offsetLeft;
3615 obj=obj.offsetParent;
3616 }
3617 }else{
3618 if(obj.x){
3619 _32+=obj.x;
3620 }
3621 }
3622 return _32;
3623 },findPosY:function(obj){
3624 var _33=0;
3625 if(obj.offsetParent){
3626 while(obj.offsetParent){
3627 _33+=obj.offsetTop;
3628 obj=obj.offsetParent;
3629 }
3630 }else{
3631 if(obj.y){
3632 _33+=obj.y;
3633 }
3634 }
3635 return _33;
3636 },isFuncLike:function(obj){
3637 return (typeof (obj)=="function");
3638 }});
3639 PlotKit.Base.map=function(fn,lst){
3640 if(PlotKit.Base.usingPrototype()){
3641 var _36=[];
3642 for(var x in lst){
3643 if(typeof (lst[x])=="function"){
3644 continue;
3645 }
3646 _36.push(fn(lst[x]));
3647 }
3648 return _36;
3649 }else{
3650 return MochiKit.Base.map(fn,lst);
3651 }
3652 };
3653 PlotKit.Base.items=function(lst){
3654 if(PlotKit.Base.usingPrototype()){
3655 var _38=[];
3656 for(var x in lst){
3657 if(typeof (lst[x])=="function"){
3658 continue;
3659 }
3660 _38.push([x,lst[x]]);
3661 }
3662 return _38;
3663 }else{
3664 return MochiKit.Base.items(lst);
3665 }
3666 };
3667 PlotKit.Base.keys=function(lst){
3668 if(PlotKit.Base.usingPrototype()){
3669 var _39=[];
3670 for(var x in lst){
3671 if(typeof (lst[x])=="function"){
3672 continue;
3673 }
3674 _39.push(x);
3675 }
3676 return _39;
3677 }else{
3678 return MochiKit.Base.keys(lst);
3679 }
3680 };
3681 PlotKit.Base.baseColors=function(){
3682 var _40=MochiKit.Color.Color.fromHexString;
3683 return [_40("#476fb2"),_40("#be2c2b"),_40("#85b730"),_40("#734a99"),_40("#26a1c5"),_40("#fb8707"),_40("#000000")];
3684 };
3685 PlotKit.Base.officeBaseStyle={"axisLineWidth":2,"axisLabelColor":Color.grayColor(),"axisLineColor":Color.whiteColor(),"padding":{top:5,bottom:10,left:30,right:30}};
3686 MochiKit.Base.update(PlotKit.Base,{officeBlue:function(){
3687 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),"backgroundColor":PlotKit.Base.baseColors()[0].lighterColorWithLevel(0.45)};
3688 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3689 return r;
3690 },officeRed:function(){
3691 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),"backgroundColor":PlotKit.Base.baseColors()[1].lighterColorWithLevel(0.5)};
3692 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3693 return r;
3694 },officeGreen:function(){
3695 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[2]),"backgroundColor":PlotKit.Base.baseColors()[2].lighterColorWithLevel(0.5)};
3696 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3697 return r;
3698 },officePurple:function(){
3699 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[3]),"backgroundColor":PlotKit.Base.baseColors()[3].lighterColorWithLevel(0.5)};
3700 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3701 return r;
3702 },officeCyan:function(){
3703 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[4]),"backgroundColor":PlotKit.Base.baseColors()[4].lighterColorWithLevel(0.5)};
3704 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3705 return r;
3706 },officeOrange:function(){
3707 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[5]),"backgroundColor":PlotKit.Base.baseColors()[5].lighterColorWithLevel(0.4)};
3708 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3709 return r;
3710 },officeBlack:function(){
3711 var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[6],0,0.6),"backgroundColor":PlotKit.Base.baseColors()[6].lighterColorWithLevel(0.9)};
3712 MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
3713 return r;
3714 }});
3715 PlotKit.Base.EXPORT=["baseColors","collapse","colorScheme","findPosX","findPosY","officeBaseStyle","officeBlue","officeRed","officeGreen","officePurple","officeCyan","officeOrange","officeBlack","roundInterval","uniq","isFuncLike","excanvasSupported"];
3716 PlotKit.Base.EXPORT_OK=[];
3717 PlotKit.Base.__new__=function(){
3718 var m=MochiKit.Base;
3719 m.nameFunctions(this);
3720 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
3721 };
3722 PlotKit.Base.__new__();
3723 MochiKit.Base._exportSymbols(this,PlotKit.Base);
3724 try{
3725 if(typeof (PlotKit.Base)=="undefined"){
3726 throw "";
3727 }
3728 }
3729 catch(e){
3730 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base";
3731 }
3732 if(typeof (PlotKit.Layout)=="undefined"){
3733 PlotKit.Layout={};
3734 }
3735 PlotKit.Layout.NAME="PlotKit.Layout";
3736 PlotKit.Layout.VERSION=PlotKit.VERSION;
3737 PlotKit.Layout.__repr__=function(){
3738 return "["+this.NAME+" "+this.VERSION+"]";
3739 };
3740 PlotKit.Layout.toString=function(){
3741 return this.__repr__();
3742 };
3743 PlotKit.Layout.valid_styles=["bar","line","pie","point"];
3744 PlotKit.Layout=function(_42,_43){
3745 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};
3746 this.style=_42;
3747 MochiKit.Base.update(this.options,_43?_43:{});
3748 if(!MochiKit.Base.isUndefinedOrNull(this.options.xAxis)){
3749 this.minxval=this.options.xAxis[0];
3750 this.maxxval=this.options.xAxis[1];
3751 this.xscale=this.maxxval-this.minxval;
3752 }else{
3753 this.minxval=0;
3754 this.maxxval=null;
3755 this.xscale=null;
3756 }
3757 if(!MochiKit.Base.isUndefinedOrNull(this.options.yAxis)){
3758 this.minyval=this.options.yAxis[0];
3759 this.maxyval=this.options.yAxis[1];
3760 this.yscale=this.maxyval-this.minyval;
3761 }else{
3762 this.minyval=0;
3763 this.maxyval=null;
3764 this.yscale=null;
3765 }
3766 this.bars=new Array();
3767 this.points=new Array();
3768 this.slices=new Array();
3769 this.xticks=new Array();
3770 this.yticks=new Array();
3771 this.datasets=new Array();
3772 this.minxdelta=0;
3773 this.xrange=1;
3774 this.yrange=1;
3775 this.hitTestCache={x2maxy:null};
3776 };
3777 PlotKit.Layout.prototype.addDataset=function(_44,_45){
3778 this.datasets[_44]=_45;
3779 };
3780 PlotKit.Layout.prototype.removeDataset=function(_46,_47){
3781 delete this.datasets[_46];
3782 };
3783 PlotKit.Layout.prototype.addDatasetFromTable=function(_48,_49,_50,_51,_52){
3784 var _53=MochiKit.Base.isUndefinedOrNull;
3785 var _54=MochiKit.DOM.scrapeText;
3786 var _55=MochiKit.Format.strip;
3787 if(_53(_50)){
3788 _50=0;
3789 }
3790 if(_53(_51)){
3791 _51=1;
3792 }
3793 if(_53(_52)){
3794 _52=-1;
3795 }
3796 var _56=_49.tBodies[0].rows;
3797 var _57=new Array();
3798 var _58=new Array();
3799 if(!_53(_56)){
3800 for(var i=0;i<_56.length;i++){
3801 _57.push([parseFloat(_55(_54(_56[i].cells[_50]))),parseFloat(_55(_54(_56[i].cells[_51])))]);
3802 if(_52>=0){
3803 _58.push({v:parseFloat(_55(_54(_56[i].cells[_50]))),label:_55(_54(_56[i].cells[_52]))});
3804 }
3805 }
3806 this.addDataset(_48,_57);
3807 if(_52>=0){
3808 this.options.xTicks=_58;
3809 }
3810 return true;
3811 }
3812 return false;
3813 };
3814 PlotKit.Layout.prototype.evaluate=function(){
3815 this._evaluateLimits();
3816 this._evaluateScales();
3817 if(this.style=="bar"){
3818 if(this.options.barOrientation=="horizontal"){
3819 this._evaluateHorizBarCharts();
3820 }else{
3821 this._evaluateBarCharts();
3822 }
3823 this._evaluateBarTicks();
3824 }else{
3825 if(this.style=="line"){
3826 this._evaluateLineCharts();
3827 this._evaluateLineTicks();
3828 }else{
3829 if(this.style=="pie"){
3830 this._evaluatePieCharts();
3831 this._evaluatePieTicks();
3832 }
3833 }
3834 }
3835 };
3836 PlotKit.Layout.prototype.hitTest=function(x,y){
3837 var f=MochiKit.Format.twoDigitFloat;
3838 if((this.style=="bar")&&this.bars&&(this.bars.length>0)){
3839 for(var i=0;i<this.bars.length;i++){
3840 var bar=this.bars[i];
3841 if((x>=bar.x)&&(x<=bar.x+bar.w)&&(y>=bar.y)&&(y-bar.y<=bar.h)){
3842 return bar;
3843 }
3844 }
3845 }else{
3846 if(this.style=="line"){
3847 if(this.hitTestCache.x2maxy==null){
3848 this._regenerateHitTestCache();
3849 }
3850 var _62=x/this.xscale;
3851 var _63=this.hitTestCache.xvalues;
3852 var _64=null;
3853 var _65=null;
3854 for(var i=1;i<_63.length;i++){
3855 if(_63[i]>_62){
3856 _64=_63[i-1];
3857 _65=_63[i];
3858 break;
3859 }
3860 }
3861 if((_64!=null)){
3862 var _66=this.hitTestCache.x2maxy[_64];
3863 var _67=this.hitTestCache.x2maxy[_65];
3864 var _68=(1-y)/this.yscale;
3865 var _69=(_67-_66)/(_65-_64);
3866 var _70=_66+_69*(_62-_64);
3867 if(_70>=_68){
3868 var obj={xval:_62,yval:_68,xafter:_65,yafter:_67,xbefore:_64,ybefore:_66,yprojected:_70};
3869 return obj;
3870 }
3871 }
3872 }else{
3873 if(this.style=="pie"){
3874 var _71=Math.sqrt((y-0.5)*(y-0.5)+(x-0.5)*(x-0.5));
3875 if(_71>this.options.pieRadius){
3876 return null;
3877 }
3878 var _72=Math.atan2(y-0.5,x-0.5)-Math.PI/2;
3879 for(var i=0;i<this.slices.length;i++){
3880 var _73=this.slices[i];
3881 if(_73.startAngle<_72&&_73.endAngle>=_72){
3882 return _73;
3883 }
3884 }
3885 }
3886 }
3887 }
3888 return null;
3889 };
3890 PlotKit.Layout.prototype.rectForX=function(x){
3891 return null;
3892 };
3893 PlotKit.Layout.prototype.angleRangeForX=function(x){
3894 return null;
3895 };
3896 PlotKit.Layout.prototype._evaluateLimits=function(){
3897 var map=PlotKit.Base.map;
3898 var _75=PlotKit.Base.items;
3899 var _76=MochiKit.Base.itemgetter;
3900 var _77=PlotKit.Base.collapse;
3901 var _78=MochiKit.Base.listMin;
3902 var _79=MochiKit.Base.listMax;
3903 var _80=MochiKit.Base.isUndefinedOrNull;
3904 var all=_77(map(_76(1),_75(this.datasets)));
3905 if(_80(this.options.xAxis)){
3906 if(this.options.xOriginIsZero){
3907 this.minxval=0;
3908 }else{
3909 this.minxval=_78(map(parseFloat,map(_76(0),all)));
3910 }
3911 this.maxxval=_79(map(parseFloat,map(_76(0),all)));
3912 }else{
3913 this.minxval=this.options.xAxis[0];
3914 this.maxxval=this.options.xAxis[1];
3915 this.xscale=this.maxval-this.minxval;
3916 }
3917 if(_80(this.options.yAxis)){
3918 if(this.options.yOriginIsZero){
3919 this.minyval=0;
3920 }else{
3921 this.minyval=_78(map(parseFloat,map(_76(1),all)));
3922 }
3923 this.maxyval=_79(map(parseFloat,map(_76(1),all)));
3924 }else{
3925 this.minyval=this.options.yAxis[0];
3926 this.maxyval=this.options.yAxis[1];
3927 this.yscale=this.maxyval-this.minyval;
3928 }
3929 };
3930 PlotKit.Layout.prototype._evaluateScales=function(){
3931 var _82=MochiKit.Base.isUndefinedOrNull;
3932 this.xrange=this.maxxval-this.minxval;
3933 if(this.xrange==0){
3934 this.xscale=1;
3935 }else{
3936 this.xscale=1/this.xrange;
3937 }
3938 this.yrange=this.maxyval-this.minyval;
3939 if(this.yrange==0){
3940 this.yscale=1;
3941 }else{
3942 this.yscale=1/this.yrange;
3943 }
3944 };
3945 PlotKit.Layout.prototype._uniqueXValues=function(){
3946 var _83=PlotKit.Base.collapse;
3947 var map=PlotKit.Base.map;
3948 var _84=PlotKit.Base.uniq;
3949 var _85=MochiKit.Base.itemgetter;
3950 var _86=PlotKit.Base.items;
3951 var _87=map(parseFloat,map(_85(0),_83(map(_85(1),_86(this.datasets)))));
3952 _87.sort(MochiKit.Base.compare);
3953 return _84(_87);
3954 };
3955 PlotKit.Layout.prototype._evaluateBarCharts=function(){
3956 var _88=PlotKit.Base.items;
3957 var _89=_88(this.datasets).length;
3958 var _90=10000000;
3959 var _91=this._uniqueXValues();
3960 for(var i=1;i<_91.length;i++){
3961 _90=Math.min(Math.abs(_91[i]-_91[i-1]),_90);
3962 }
3963 var _92=0;
3964 var _93=0;
3965 var _94=0;
3966 if(_91.length==1){
3967 _90=1;
3968 this.xscale=1;
3969 this.minxval=_91[0];
3970 _92=1*this.options.barWidthFillFraction;
3971 _93=_92/_89;
3972 _94=(1-this.options.barWidthFillFraction)/2;
3973 }else{
3974 if(this.xrange==1){
3975 this.xscale=0.5;
3976 }else{
3977 if(this.xrange==2){
3978 this.xscale=1/3;
3979 }else{
3980 this.xscale=(1-_90/this.xrange)/this.xrange;
3981 }
3982 }
3983 _92=_90*this.xscale*this.options.barWidthFillFraction;
3984 _93=_92/_89;
3985 _94=_90*this.xscale*(1-this.options.barWidthFillFraction)/2;
3986 }
3987 this.minxdelta=_90;
3988 this.bars=new Array();
3989 var i=0;
3990 for(var _95 in this.datasets){
3991 var _96=this.datasets[_95];
3992 if(PlotKit.Base.isFuncLike(_96)){
3993 continue;
3994 }
3995 for(var j=0;j<_96.length;j++){
3996 var _98=_96[j];
3997 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};
3998 if((_99.x>=0)&&(_99.x<=1)&&(_99.y>=0)&&(_99.y<=1)){
3999 this.bars.push(_99);
4000 }
4001 }
4002 i++;
4003 }
4004 };
4005 PlotKit.Layout.prototype._evaluateHorizBarCharts=function(){
4006 var _100=PlotKit.Base.items;
4007 var _101=_100(this.datasets).length;
4008 var _102=10000000;
4009 var _103=this._uniqueXValues();
4010 for(var i=1;i<_103.length;i++){
4011 _102=Math.min(Math.abs(_103[i]-_103[i-1]),_102);
4012 }
4013 var _104=0;
4014 var _105=0;
4015 var _106=0;
4016 if(_103.length==1){
4017 _102=1;
4018 this.xscale=1;
4019 this.minxval=_103[0];
4020 _104=1*this.options.barWidthFillFraction;
4021 _105=_104/_101;
4022 _106=(1-this.options.barWidthFillFraction)/2;
4023 }else{
4024 this.xscale=(1-_102/this.xrange)/this.xrange;
4025 _104=_102*this.xscale*this.options.barWidthFillFraction;
4026 _105=_104/_101;
4027 _106=_102*this.xscale*(1-this.options.barWidthFillFraction)/2;
4028 }
4029 this.minxdelta=_102;
4030 this.bars=new Array();
4031 var i=0;
4032 for(var _107 in this.datasets){
4033 var _108=this.datasets[_107];
4034 if(PlotKit.Base.isFuncLike(_108)){
4035 continue;
4036 }
4037 for(var j=0;j<_108.length;j++){
4038 var item=_108[j];
4039 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};
4040 if(rect.y<=0){
4041 rect.y=0;
4042 }
4043 if(rect.y>=1){
4044 rect.y=1;
4045 }
4046 if((rect.x>=0)&&(rect.x<=1)){
4047 this.bars.push(rect);
4048 }
4049 }
4050 i++;
4051 }
4052 };
4053 PlotKit.Layout.prototype._evaluateLineCharts=function(){
4054 var _111=PlotKit.Base.items;
4055 var _112=_111(this.datasets).length;
4056 this.points=new Array();
4057 var i=0;
4058 for(var _113 in this.datasets){
4059 var _114=this.datasets[_113];
4060 if(PlotKit.Base.isFuncLike(_114)){
4061 continue;
4062 }
4063 _114.sort(function(a,b){
4064 return compare(parseFloat(a[0]),parseFloat(b[0]));
4065 });
4066 for(var j=0;j<_114.length;j++){
4067 var item=_114[j];
4068 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};
4069 if(_117.y<=0){
4070 _117.y=0;
4071 }
4072 if(_117.y>=1){
4073 _117.y=1;
4074 }
4075 if((_117.x>=0)&&(_117.x<=1)){
4076 this.points.push(_117);
4077 }
4078 }
4079 i++;
4080 }
4081 };
4082 PlotKit.Layout.prototype._evaluatePieCharts=function(){
4083 var _118=PlotKit.Base.items;
4084 var sum=MochiKit.Iter.sum;
4085 var _120=MochiKit.Base.itemgetter;
4086 var _121=_118(this.datasets).length;
4087 var _122=_118(this.datasets)[0][1];
4088 var _123=sum(map(_120(1),_122));
4089 this.slices=new Array();
4090 var _124=0;
4091 for(var i=0;i<_122.length;i++){
4092 var _125=_122[i][1]/_123;
4093 var _126=_124*Math.PI*2;
4094 var _127=(_124+_125)*Math.PI*2;
4095 var _128={fraction:_125,xval:_122[i][0],yval:_122[i][1],startAngle:_126,endAngle:_127};
4096 if(_122[i][1]!=0){
4097 this.slices.push(_128);
4098 }
4099 _124+=_125;
4100 }
4101 };
4102 PlotKit.Layout.prototype._evaluateLineTicksForXAxis=function(){
4103 var _129=MochiKit.Base.isUndefinedOrNull;
4104 if(this.options.xTicks){
4105 this.xticks=new Array();
4106 var _130=function(tick){
4107 var _132=tick.label;
4108 if(_129(_132)){
4109 _132=tick.v.toString();
4110 }
4111 var pos=this.xscale*(tick.v-this.minxval);
4112 if((pos>=0)&&(pos<=1)){
4113 this.xticks.push([pos,_132]);
4114 }
4115 };
4116 MochiKit.Iter.forEach(this.options.xTicks,bind(_130,this));
4117 }else{
4118 if(this.options.xNumberOfTicks){
4119 var _134=this._uniqueXValues();
4120 var _135=this.xrange/this.options.xNumberOfTicks;
4121 var _136=0;
4122 this.xticks=new Array();
4123 for(var i=0;i<=_134.length;i++){
4124 if((_134[i]-this.minxval)>=(_136*_135)){
4125 var pos=this.xscale*(_134[i]-this.minxval);
4126 if((pos>1)||(pos<0)){
4127 continue;
4128 }
4129 this.xticks.push([pos,_134[i]]);
4130 _136++;
4131 }
4132 if(_136>this.options.xNumberOfTicks){
4133 break;
4134 }
4135 }
4136 }
4137 }
4138 };
4139 PlotKit.Layout.prototype._evaluateLineTicksForYAxis=function(){
4140 var _137=MochiKit.Base.isUndefinedOrNull;
4141 if(this.options.yTicks){
4142 this.yticks=new Array();
4143 var _138=function(tick){
4144 var _139=tick.label;
4145 if(_137(_139)){
4146 _139=tick.v.toString();
4147 }
4148 var pos=1-(this.yscale*(tick.v-this.minyval));
4149 if((pos>=0)&&(pos<=1)){
4150 this.yticks.push([pos,_139]);
4151 }
4152 };
4153 MochiKit.Iter.forEach(this.options.yTicks,bind(_138,this));
4154 }else{
4155 if(this.options.yNumberOfTicks){
4156 this.yticks=new Array();
4157 var _140=PlotKit.Base.roundInterval;
4158 var prec=this.options.yTickPrecision;
4159 var _142=_140(this.yrange,this.options.yNumberOfTicks,prec);
4160 for(var i=0;i<=this.options.yNumberOfTicks;i++){
4161 var yval=this.minyval+(i*_142);
4162 var pos=1-((yval-this.minyval)*this.yscale);
4163 if((pos>1)||(pos<0)){
4164 continue;
4165 }
4166 this.yticks.push([pos,MochiKit.Format.roundToFixed(yval,prec)]);
4167 }
4168 }
4169 }
4170 };
4171 PlotKit.Layout.prototype._evaluateLineTicks=function(){
4172 this._evaluateLineTicksForXAxis();
4173 this._evaluateLineTicksForYAxis();
4174 };
4175 PlotKit.Layout.prototype._evaluateBarTicks=function(){
4176 this._evaluateLineTicks();
4177 var _144=function(tick){
4178 return [tick[0]+(this.minxdelta*this.xscale)/2,tick[1]];
4179 };
4180 this.xticks=MochiKit.Base.map(bind(_144,this),this.xticks);
4181 if(this.options.barOrientation=="horizontal"){
4182 var _145=this.xticks;
4183 this.xticks=this.yticks;
4184 this.yticks=_145;
4185 var _146=function(tick){
4186 return [1-tick[0],tick[1]];
4187 };
4188 this.xticks=MochiKit.Base.map(_146,this.xticks);
4189 }
4190 };
4191 PlotKit.Layout.prototype._evaluatePieTicks=function(){
4192 var _147=MochiKit.Base.isUndefinedOrNull;
4193 var _148=MochiKit.Format.numberFormatter("#%");
4194 this.xticks=new Array();
4195 if(this.options.xTicks){
4196 var _149=new Array();
4197 for(var i=0;i<this.slices.length;i++){
4198 _149[this.slices[i].xval]=this.slices[i];
4199 }
4200 for(var i=0;i<this.options.xTicks.length;i++){
4201 var tick=this.options.xTicks[i];
4202 var _150=_149[tick.v];
4203 var _151=tick.label;
4204 if(_150){
4205 if(_147(_151)){
4206 _151=tick.v.toString();
4207 }
4208 _151+=" ("+_148(_150.fraction)+")";
4209 this.xticks.push([tick.v,_151]);
4210 }
4211 }
4212 }else{
4213 for(var i=0;i<this.slices.length;i++){
4214 var _150=this.slices[i];
4215 var _151=_150.xval+" ("+_148(_150.fraction)+")";
4216 this.xticks.push([_150.xval,_151]);
4217 }
4218 }
4219 };
4220 PlotKit.Layout.prototype._regenerateHitTestCache=function(){
4221 this.hitTestCache.xvalues=this._uniqueXValues();
4222 this.hitTestCache.xlookup=new Array();
4223 this.hitTestCache.x2maxy=new Array();
4224 var _152=MochiKit.Base.listMax;
4225 var _153=MochiKit.Base.itemgetter;
4226 var map=MochiKit.Base.map;
4227 var _154=keys(this.datasets);
4228 for(var i=0;i<_154.length;i++){
4229 var _155=this.datasets[_154[i]];
4230 for(var j=0;j<_155.length;j++){
4231 var xval=_155[j][0];
4232 var yval=_155[j][1];
4233 if(this.hitTestCache.xlookup[xval]){
4234 this.hitTestCache.xlookup[xval].push([yval,_154[i]]);
4235 }else{
4236 this.hitTestCache.xlookup[xval]=[[yval,_154[i]]];
4237 }
4238 }
4239 }
4240 for(var x in this.hitTestCache.xlookup){
4241 var _157=this.hitTestCache.xlookup[x];
4242 this.hitTestCache.x2maxy[x]=_152(map(_153(0),_157));
4243 }
4244 };
4245 PlotKit.LayoutModule={};
4246 PlotKit.LayoutModule.Layout=PlotKit.Layout;
4247 PlotKit.LayoutModule.EXPORT=["Layout"];
4248 PlotKit.LayoutModule.EXPORT_OK=[];
4249 PlotKit.LayoutModule.__new__=function(){
4250 var m=MochiKit.Base;
4251 m.nameFunctions(this);
4252 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
4253 };
4254 PlotKit.LayoutModule.__new__();
4255 MochiKit.Base._exportSymbols(this,PlotKit.LayoutModule);
4256 try{
4257 if((typeof (PlotKit.Base)=="undefined")||(typeof (PlotKit.Layout)=="undefined")){
4258 throw "";
4259 }
4260 }
4261 catch(e){
4262 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}";
4263 }
4264 if(typeof (PlotKit.CanvasRenderer)=="undefined"){
4265 PlotKit.CanvasRenderer={};
4266 }
4267 PlotKit.CanvasRenderer.NAME="PlotKit.CanvasRenderer";
4268 PlotKit.CanvasRenderer.VERSION=PlotKit.VERSION;
4269 PlotKit.CanvasRenderer.__repr__=function(){
4270 return "["+this.NAME+" "+this.VERSION+"]";
4271 };
4272 PlotKit.CanvasRenderer.toString=function(){
4273 return this.__repr__();
4274 };
4275 PlotKit.CanvasRenderer=function(_158,_159,_160){
4276 if(arguments.length>0){
4277 this.__init__(_158,_159,_160);
4278 }
4279 };
4280 PlotKit.CanvasRenderer.prototype.__init__=function(_161,_162,_163){
4281 var _164=MochiKit.Base.isUndefinedOrNull;
4282 var _165=MochiKit.Color.Color;
4283 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};
4284 MochiKit.Base.update(this.options,_163?_163:{});
4285 this.layout=_162;
4286 this.element=MochiKit.DOM.getElement(_161);
4287 this.container=this.element.parentNode;
4288 this.isIE=PlotKit.Base.excanvasSupported();
4289 if(this.isIE&&!_164(G_vmlCanvasManager)){
4290 this.IEDelay=0.5;
4291 this.maxTries=5;
4292 this.renderDelay=null;
4293 this.clearDelay=null;
4294 this.element=G_vmlCanvasManager.initElement(this.element);
4295 }
4296 this.height=this.element.height;
4297 this.width=this.element.width;
4298 if(_164(this.element)){
4299 throw "CanvasRenderer() - passed canvas is not found";
4300 }
4301 if(!this.isIE&&!(PlotKit.CanvasRenderer.isSupported(this.element))){
4302 throw "CanvasRenderer() - Canvas is not supported.";
4303 }
4304 if(_164(this.container)||(this.container.nodeName.toLowerCase()!="div")){
4305 throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
4306 }
4307 this.xlabels=new Array();
4308 this.ylabels=new Array();
4309 this.isFirstRender=true;
4310 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};
4311 MochiKit.DOM.updateNodeAttributes(this.container,{"style":{"position":"relative","width":this.width+"px"}});
4312 };
4313 PlotKit.CanvasRenderer.prototype.render=function(){
4314 if(this.isIE){
4315 try{
4316 if(this.renderDelay){
4317 this.renderDelay.cancel();
4318 this.renderDelay=null;
4319 }
4320 var _166=this.element.getContext("2d");
4321 }
4322 catch(e){
4323 this.isFirstRender=false;
4324 if(this.maxTries-->0){
4325 this.renderDelay=MochiKit.Async.wait(this.IEDelay);
4326 this.renderDelay.addCallback(bind(this.render,this));
4327 }
4328 return;
4329 }
4330 }
4331 if(this.options.drawBackground){
4332 this._renderBackground();
4333 }
4334 if(this.layout.style=="bar"){
4335 this._renderBarChart();
4336 this._renderBarAxis();
4337 }else{
4338 if(this.layout.style=="pie"){
4339 this._renderPieChart();
4340 this._renderPieAxis();
4341 }else{
4342 if(this.layout.style=="line"){
4343 this._renderLineChart();
4344 this._renderLineAxis();
4345 }
4346 }
4347 }
4348 };
4349 PlotKit.CanvasRenderer.prototype._renderBarChartWrap=function(data,_168){
4350 var _169=this.element.getContext("2d");
4351 var _170=this.options.colorScheme.length;
4352 var _171=this.options.colorScheme;
4353 var _172=MochiKit.Base.keys(this.layout.datasets);
4354 var _173=_172.length;
4355 for(var i=0;i<_173;i++){
4356 var _174=_172[i];
4357 var _175=_171[i%_170];
4358 _169.save();
4359 _169.fillStyle=_175.toRGBString();
4360 if(this.options.strokeColor){
4361 _169.strokeStyle=this.options.strokeColor.toRGBString();
4362 }else{
4363 if(this.options.strokeColorTransform){
4364 _169.strokeStyle=_175[this.options.strokeColorTransform]().toRGBString();
4365 }
4366 }
4367 _169.lineWidth=this.options.strokeWidth;
4368 var _176=function(obj){
4369 if(obj.name==_174){
4370 _168(_169,obj);
4371 }
4372 };
4373 MochiKit.Iter.forEach(data,bind(_176,this));
4374 _169.restore();
4375 }
4376 };
4377 PlotKit.CanvasRenderer.prototype._renderBarChart=function(){
4378 var bind=MochiKit.Base.bind;
4379 var _178=function(_179,bar){
4380 var x=this.area.w*bar.x+this.area.x;
4381 var y=this.area.h*bar.y+this.area.y;
4382 var w=this.area.w*bar.w;
4383 var h=this.area.h*bar.h;
4384 if((w<1)||(h<1)){
4385 return;
4386 }
4387 if(this.options.shouldFill){
4388 _179.fillRect(x,y,w,h);
4389 }
4390 if(this.options.shouldStroke){
4391 _179.strokeRect(x,y,w,h);
4392 }
4393 };
4394 this._renderBarChartWrap(this.layout.bars,bind(_178,this));
4395 };
4396 PlotKit.CanvasRenderer.prototype._renderLineChart=function(){
4397 var _182=this.element.getContext("2d");
4398 var _183=this.options.colorScheme.length;
4399 var _184=this.options.colorScheme;
4400 var _185=MochiKit.Base.keys(this.layout.datasets);
4401 var _186=_185.length;
4402 var bind=MochiKit.Base.bind;
4403 var _187=MochiKit.Base.partial;
4404 for(var i=0;i<_186;i++){
4405 var _188=_185[i];
4406 var _189=_184[i%_183];
4407 var _190=this.options.strokeColorTransform;
4408 _182.save();
4409 _182.fillStyle=_189.toRGBString();
4410 if(this.options.strokeColor){
4411 _182.strokeStyle=this.options.strokeColor.toRGBString();
4412 }else{
4413 if(this.options.strokeColorTransform){
4414 _182.strokeStyle=_189[_190]().toRGBString();
4415 }
4416 }
4417 _182.lineWidth=this.options.strokeWidth;
4418 var _191=function(ctx){
4419 ctx.beginPath();
4420 ctx.moveTo(this.area.x,this.area.y+this.area.h);
4421 var _193=function(ctx_,_195){
4422 if(_195.name==_188){
4423 ctx_.lineTo(this.area.w*_195.x+this.area.x,this.area.h*_195.y+this.area.y);
4424 }
4425 };
4426 MochiKit.Iter.forEach(this.layout.points,_187(_193,ctx),this);
4427 ctx.lineTo(this.area.w+this.area.x,this.area.h+this.area.y);
4428 ctx.lineTo(this.area.x,this.area.y+this.area.h);
4429 ctx.closePath();
4430 };
4431 if(this.options.shouldFill){
4432 bind(_191,this)(_182);
4433 _182.fill();
4434 }
4435 if(this.options.shouldStroke){
4436 bind(_191,this)(_182);
4437 _182.stroke();
4438 }
4439 _182.restore();
4440 }
4441 };
4442 PlotKit.CanvasRenderer.prototype._renderPieChart=function(){
4443 var _196=this.element.getContext("2d");
4444 var _197=this.options.colorScheme.length;
4445 var _198=this.layout.slices;
4446 var _199=this.area.x+this.area.w*0.5;
4447 var _200=this.area.y+this.area.h*0.5;
4448 var _201=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
4449 if(this.isIE){
4450 _199=parseInt(_199);
4451 _200=parseInt(_200);
4452 _201=parseInt(_201);
4453 }
4454 for(var i=0;i<_198.length;i++){
4455 var _202=this.options.colorScheme[i%_197];
4456 _196.save();
4457 _196.fillStyle=_202.toRGBString();
4458 var _203=function(){
4459 _196.beginPath();
4460 _196.moveTo(_199,_200);
4461 _196.arc(_199,_200,_201,_198[i].startAngle-Math.PI/2,_198[i].endAngle-Math.PI/2,false);
4462 _196.lineTo(_199,_200);
4463 _196.closePath();
4464 };
4465 if(Math.abs(_198[i].startAngle-_198[i].endAngle)>0.001){
4466 if(this.options.shouldFill){
4467 _203();
4468 _196.fill();
4469 }
4470 if(this.options.shouldStroke){
4471 _203();
4472 _196.lineWidth=this.options.strokeWidth;
4473 if(this.options.strokeColor){
4474 _196.strokeStyle=this.options.strokeColor.toRGBString();
4475 }else{
4476 if(this.options.strokeColorTransform){
4477 _196.strokeStyle=_202[this.options.strokeColorTransform]().toRGBString();
4478 }
4479 }
4480 _196.stroke();
4481 }
4482 }
4483 _196.restore();
4484 }
4485 };
4486 PlotKit.CanvasRenderer.prototype._renderBarAxis=function(){
4487 this._renderAxis();
4488 };
4489 PlotKit.CanvasRenderer.prototype._renderLineAxis=function(){
4490 this._renderAxis();
4491 };
4492 PlotKit.CanvasRenderer.prototype._renderAxis=function(){
4493 if(!this.options.drawXAxis&&!this.options.drawYAxis){
4494 return;
4495 }
4496 var _204=this.element.getContext("2d");
4497 var _205={"style":{"position":"absolute","fontSize":this.options.axisLabelFontSize+"px","zIndex":10,"color":this.options.axisLabelColor.toRGBString(),"width":this.options.axisLabelWidth+"px","overflow":"hidden"}};
4498 _204.save();
4499 _204.strokeStyle=this.options.axisLineColor.toRGBString();
4500 _204.lineWidth=this.options.axisLineWidth;
4501 if(this.options.drawYAxis){
4502 if(this.layout.yticks){
4503 var _206=function(tick){
4504 if(typeof (tick)=="function"){
4505 return;
4506 }
4507 var x=this.area.x;
4508 var y=this.area.y+tick[0]*this.area.h;
4509 _204.beginPath();
4510 _204.moveTo(x,y);
4511 _204.lineTo(x-this.options.axisTickSize,y);
4512 _204.closePath();
4513 _204.stroke();
4514 var _207=DIV(_205,tick[1]);
4515 _207.style.top=(y-this.options.axisLabelFontSize)+"px";
4516 _207.style.left=(x-this.options.padding.left-this.options.axisTickSize)+"px";
4517 _207.style.textAlign="right";
4518 _207.style.width=(this.options.padding.left-this.options.axisTickSize*2)+"px";
4519 MochiKit.DOM.appendChildNodes(this.container,_207);
4520 this.ylabels.push(_207);
4521 };
4522 MochiKit.Iter.forEach(this.layout.yticks,bind(_206,this));
4523 }
4524 _204.beginPath();
4525 _204.moveTo(this.area.x,this.area.y);
4526 _204.lineTo(this.area.x,this.area.y+this.area.h);
4527 _204.closePath();
4528 _204.stroke();
4529 }
4530 if(this.options.drawXAxis){
4531 if(this.layout.xticks){
4532 var _206=function(tick){
4533 if(typeof (dataset)=="function"){
4534 return;
4535 }
4536 var x=this.area.x+tick[0]*this.area.w;
4537 var y=this.area.y+this.area.h;
4538 _204.beginPath();
4539 _204.moveTo(x,y);
4540 _204.lineTo(x,y+this.options.axisTickSize);
4541 _204.closePath();
4542 _204.stroke();
4543 var _208=DIV(_205,tick[1]);
4544 _208.style.top=(y+this.options.axisTickSize)+"px";
4545 _208.style.left=(x-this.options.axisLabelWidth/2)+"px";
4546 _208.style.textAlign="center";
4547 _208.style.width=this.options.axisLabelWidth+"px";
4548 MochiKit.DOM.appendChildNodes(this.container,_208);
4549 this.xlabels.push(_208);
4550 };
4551 MochiKit.Iter.forEach(this.layout.xticks,bind(_206,this));
4552 }
4553 _204.beginPath();
4554 _204.moveTo(this.area.x,this.area.y+this.area.h);
4555 _204.lineTo(this.area.x+this.area.w,this.area.y+this.area.h);
4556 _204.closePath();
4557 _204.stroke();
4558 }
4559 _204.restore();
4560 };
4561 PlotKit.CanvasRenderer.prototype._renderPieAxis=function(){
4562 if(!this.options.drawXAxis){
4563 return;
4564 }
4565 if(this.layout.xticks){
4566 var _209=new Array();
4567 for(var i=0;i<this.layout.slices.length;i++){
4568 _209[this.layout.slices[i].xval]=this.layout.slices[i];
4569 }
4570 var _210=this.area.x+this.area.w*0.5;
4571 var _211=this.area.y+this.area.h*0.5;
4572 var _212=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
4573 var _213=this.options.axisLabelWidth;
4574 for(var i=0;i<this.layout.xticks.length;i++){
4575 var _214=_209[this.layout.xticks[i][0]];
4576 if(MochiKit.Base.isUndefinedOrNull(_214)){
4577 continue;
4578 }
4579 var _215=(_214.startAngle+_214.endAngle)/2;
4580 var _216=_215;
4581 if(_216>Math.PI*2){
4582 _216=_216-Math.PI*2;
4583 }else{
4584 if(_216<0){
4585 _216=_216+Math.PI*2;
4586 }
4587 }
4588 var _217=_210+Math.sin(_216)*(_212+10);
4589 var _218=_211-Math.cos(_216)*(_212+10);
4590 var _219={"position":"absolute","zIndex":11,"width":_213+"px","fontSize":this.options.axisLabelFontSize+"px","overflow":"hidden","color":this.options.axisLabelColor.toHexString()};
4591 if(_216<=Math.PI*0.5){
4592 _219["textAlign"]="left";
4593 _219["verticalAlign"]="top";
4594 _219["left"]=_217+"px";
4595 _219["top"]=(_218-this.options.axisLabelFontSize)+"px";
4596 }else{
4597 if((_216>Math.PI*0.5)&&(_216<=Math.PI)){
4598 _219["textAlign"]="left";
4599 _219["verticalAlign"]="bottom";
4600 _219["left"]=_217+"px";
4601 _219["top"]=_218+"px";
4602 }else{
4603 if((_216>Math.PI)&&(_216<=Math.PI*1.5)){
4604 _219["textAlign"]="right";
4605 _219["verticalAlign"]="bottom";
4606 _219["left"]=(_217-_213)+"px";
4607 _219["top"]=_218+"px";
4608 }else{
4609 _219["textAlign"]="right";
4610 _219["verticalAlign"]="bottom";
4611 _219["left"]=(_217-_213)+"px";
4612 _219["top"]=(_218-this.options.axisLabelFontSize)+"px";
4613 }
4614 }
4615 }
4616 var _220=DIV({"style":_219},this.layout.xticks[i][1]);
4617 this.xlabels.push(_220);
4618 MochiKit.DOM.appendChildNodes(this.container,_220);
4619 }
4620 }
4621 };
4622 PlotKit.CanvasRenderer.prototype._renderBackground=function(){
4623 var _221=this.element.getContext("2d");
4624 _221.save();
4625 _221.fillStyle=this.options.backgroundColor.toRGBString();
4626 _221.fillRect(0,0,this.width,this.height);
4627 _221.restore();
4628 };
4629 PlotKit.CanvasRenderer.prototype.clear=function(){
4630 if(this.isIE){
4631 try{
4632 if(this.clearDelay){
4633 this.clearDelay.cancel();
4634 this.clearDelay=null;
4635 }
4636 var _222=this.element.getContext("2d");
4637 }
4638 catch(e){
4639 this.isFirstRender=false;
4640 this.clearDelay=MochiKit.Async.wait(this.IEDelay);
4641 this.clearDelay.addCallback(bind(this.clear,this));
4642 return;
4643 }
4644 }
4645 var _222=this.element.getContext("2d");
4646 _222.clearRect(0,0,this.width,this.height);
4647 MochiKit.Iter.forEach(this.xlabels,MochiKit.DOM.removeElement);
4648 MochiKit.Iter.forEach(this.ylabels,MochiKit.DOM.removeElement);
4649 this.xlabels=new Array();
4650 this.ylabels=new Array();
4651 };
4652 PlotKit.CanvasRenderer.prototype._initialiseEvents=function(){
4653 var _223=MochiKit.Signal.connect;
4654 var bind=MochiKit.Base.bind;
4655 _223(this.element,"onclick",bind(this.onclick,this));
4656 };
4657 PlotKit.CanvasRenderer.prototype._resolveObject=function(e){
4658 var x=(e.mouse().page.x-PlotKit.Base.findPosX(this.element)-this.area.x)/this.area.w;
4659 var y=(e.mouse().page.y-PlotKit.Base.findPosY(this.element)-this.area.y)/this.area.h;
4660 var _225=this.layout.hitTest(x,y);
4661 if(_225){
4662 return _225;
4663 }
4664 return null;
4665 };
4666 PlotKit.CanvasRenderer.prototype._createEventObject=function(_226,e){
4667 if(_226==null){
4668 return null;
4669 }
4670 e.chart=_226;
4671 return e;
4672 };
4673 PlotKit.CanvasRenderer.prototype.onclick=function(e){
4674 var _227=this._resolveObject(e);
4675 var _228=this._createEventObject(_227,e);
4676 if(_228!=null){
4677 MochiKit.Signal.signal(this,"onclick",_228);
4678 }
4679 };
4680 PlotKit.CanvasRenderer.prototype.onmouseover=function(e){
4681 var _229=this._resolveObject(e);
4682 var _230=this._createEventObject(_229,e);
4683 if(_230!=null){
4684 signal(this,"onmouseover",_230);
4685 }
4686 };
4687 PlotKit.CanvasRenderer.prototype.onmouseout=function(e){
4688 var _231=this._resolveObject(e);
4689 var _232=this._createEventObject(_231,e);
4690 if(_232==null){
4691 signal(this,"onmouseout",e);
4692 }else{
4693 signal(this,"onmouseout",_232);
4694 }
4695 };
4696 PlotKit.CanvasRenderer.prototype.onmousemove=function(e){
4697 var _233=this._resolveObject(e);
4698 var _234=this._createEventObject(_233,e);
4699 if((_233==null)&&(this.event_isinside==null)){
4700 return;
4701 }
4702 if((_233!=null)&&(this.event_isinside==null)){
4703 signal(this,"onmouseover",_234);
4704 }
4705 if((_233==null)&&(this.event_isinside!=null)){
4706 signal(this,"onmouseout",_234);
4707 }
4708 if((_233!=null)&&(this.event_isinside!=null)){
4709 signal(this,"onmousemove",_234);
4710 }
4711 this.event_isinside=_233;
4712 };
4713 PlotKit.CanvasRenderer.isSupported=function(_235){
4714 var _236=null;
4715 try{
4716 if(MochiKit.Base.isUndefinedOrNull(_235)){
4717 _236=MochiKit.DOM.CANVAS({});
4718 }else{
4719 _236=MochiKit.DOM.getElement(_235);
4720 }
4721 var _237=_236.getContext("2d");
4722 }
4723 catch(e){
4724 var ie=navigator.appVersion.match(/MSIE (\d\.\d)/);
4725 var _239=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);
4726 if((!ie)||(ie[1]<6)||(_239)){
4727 return false;
4728 }
4729 return true;
4730 }
4731 return true;
4732 };
4733 PlotKit.Canvas={};
4734 PlotKit.Canvas.CanvasRenderer=PlotKit.CanvasRenderer;
4735 PlotKit.Canvas.EXPORT=["CanvasRenderer"];
4736 PlotKit.Canvas.EXPORT_OK=["CanvasRenderer"];
4737 PlotKit.Canvas.__new__=function(){
4738 var m=MochiKit.Base;
4739 m.nameFunctions(this);
4740 this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
4741 };
4742 PlotKit.Canvas.__new__();
4743 MochiKit.Base._exportSymbols(this,PlotKit.Canvas);
4744
4745
4746 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
4747 // All Rights Reserved.
4748
4749 /**
4750 * @fileoverview Subclasses various parts of PlotKit to meet the additional
4751 * needs of DateGraph: grid overlays and error bars
4752 */
4753
4754 // Subclass PlotKit.Layout to add:
4755 // 1. Sigma/errorBars properties
4756 // 2. Copy error terms for PlotKit.CanvasRenderer._renderLineChart
4757
4758 /**
4759 * Creates a new DateGraphLayout object. Options are the same as those allowed
4760 * by the PlotKit.Layout constructor.
4761 * @param {Object} options Options for PlotKit.Layout
4762 * @return {Object} The DateGraphLayout object
4763 */
4764 DateGraphLayout = function(options) {
4765 PlotKit.Layout.call(this, "line", options);
4766 };
4767 DateGraphLayout.prototype = new PlotKit.Layout();
4768
4769 /**
4770 * Behaves the same way as PlotKit.Layout, but also copies the errors
4771 * @private
4772 */
4773 DateGraphLayout.prototype.evaluateWithError = function() {
4774 this.evaluate();
4775 if (!this.options.errorBars) return;
4776
4777 // Copy over the error terms
4778 var i = 0; // index in this.points
4779 for (var setName in this.datasets) {
4780 var j = 0;
4781 var dataset = this.datasets[setName];
4782 if (PlotKit.Base.isFuncLike(dataset)) continue;
4783 for (var j = 0; j < dataset.length; j++, i++) {
4784 var item = dataset[j];
4785 var xv = parseFloat(item[0]);
4786 var yv = parseFloat(item[1]);
4787
4788 if (xv == this.points[i].xval &&
4789 yv == this.points[i].yval) {
4790 this.points[i].errorMinus = parseFloat(item[2]);
4791 this.points[i].errorPlus = parseFloat(item[3]);
4792 }
4793 }
4794 }
4795 };
4796
4797 /**
4798 * Convenience function to remove all the data sets from a graph
4799 */
4800 DateGraphLayout.prototype.removeAllDatasets = function() {
4801 delete this.datasets;
4802 this.datasets = new Array();
4803 };
4804
4805 /**
4806 * Change the values of various layout options
4807 * @param {Object} new_options an associative array of new properties
4808 */
4809 DateGraphLayout.prototype.updateOptions = function(new_options) {
4810 MochiKit.Base.update(this.options, new_options ? new_options : {});
4811 };
4812
4813 // Subclass PlotKit.CanvasRenderer to add:
4814 // 1. X/Y grid overlay
4815 // 2. Ability to draw error bars (if required)
4816
4817 /**
4818 * Sets some PlotKit.CanvasRenderer options
4819 * @param {Object} element The canvas to attach to
4820 * @param {Layout} layout The DateGraphLayout object for this graph.
4821 * @param {Object} options Options to pass on to CanvasRenderer
4822 */
4823 DateGraphCanvasRenderer = function(element, layout, options) {
4824 PlotKit.CanvasRenderer.call(this, element, layout, options);
4825 this.options.shouldFill = false;
4826 this.options.shouldStroke = true;
4827 this.options.drawYGrid = true;
4828 this.options.drawXGrid = true;
4829 this.options.gridLineColor = MochiKit.Color.Color.grayColor();
4830 MochiKit.Base.update(this.options, options);
4831
4832 // TODO(danvk) This shouldn't be necessary: effects should be overlaid
4833 this.options.drawBackground = false;
4834 };
4835 DateGraphCanvasRenderer.prototype = new PlotKit.CanvasRenderer();
4836
4837 /**
4838 * Draw an X/Y grid on top of the existing plot
4839 */
4840 DateGraphCanvasRenderer.prototype.render = function() {
4841 // Do the ordinary rendering, as before
4842 // TODO(danvk) Call super.render()
4843 this._renderLineChart();
4844 this._renderLineAxis();
4845
4846 // Draw the new X/Y grid
4847 var ctx = this.element.getContext("2d");
4848 if (this.options.drawYGrid) {
4849 var ticks = this.layout.yticks;
4850 ctx.save();
4851 ctx.strokeStyle = this.options.gridLineColor.toRGBString();
4852 ctx.lineWidth = this.options.axisLineWidth;
4853 for (var i = 0; i < ticks.length; i++) {
4854 var x = this.area.x;
4855 var y = this.area.y + ticks[i][0] * this.area.h;
4856 ctx.beginPath();
4857 ctx.moveTo(x, y);
4858 ctx.lineTo(x + this.area.w, y);
4859 ctx.closePath();
4860 ctx.stroke();
4861 }
4862 }
4863
4864 if (this.options.drawXGrid) {
4865 var ticks = this.layout.xticks;
4866 ctx.save();
4867 ctx.strokeStyle = this.options.gridLineColor.toRGBString();
4868 ctx.lineWidth = this.options.axisLineWidth;
4869 for (var i=0; i<ticks.length; i++) {
4870 var x = this.area.x + ticks[i][0] * this.area.w;
4871 var y = this.area.y + this.area.h;
4872 ctx.beginPath();
4873 ctx.moveTo(x, y);
4874 ctx.lineTo(x, this.area.y);
4875 ctx.closePath();
4876 ctx.stroke();
4877 }
4878 }
4879 };
4880
4881 /**
4882 * Overrides the CanvasRenderer method to draw error bars
4883 */
4884 DateGraphCanvasRenderer.prototype._renderLineChart = function() {
4885 var context = this.element.getContext("2d");
4886 var colorCount = this.options.colorScheme.length;
4887 var colorScheme = this.options.colorScheme;
4888 var setNames = MochiKit.Base.keys(this.layout.datasets);
4889 var errorBars = this.layout.options.errorBars;
4890 var setCount = setNames.length;
4891 var bind = MochiKit.Base.bind;
4892 var partial = MochiKit.Base.partial;
4893
4894 //Update Points
4895 var updatePoint = function(point) {
4896 point.canvasx = this.area.w * point.x + this.area.x;
4897 point.canvasy = this.area.h * point.y + this.area.y;
4898 }
4899 MochiKit.Iter.forEach(this.layout.points, updatePoint, this);
4900
4901 // create paths
4902 var makePath = function(ctx) {
4903 for (var i = 0; i < setCount; i++) {
4904 var setName = setNames[i];
4905 var color = colorScheme[i%colorCount];
4906 var strokeX = this.options.strokeColorTransform;
4907
4908 // setup graphics context
4909 context.save();
4910 context.strokeStyle = color.toRGBString();
4911 context.lineWidth = this.options.strokeWidth;
4912 ctx.beginPath();
4913 var point = this.layout.points[0];
4914 var first_point = true;
4915 var addPoint = function(ctx_, point) {
4916 if (point.name == setName) {
4917 if (first_point)
4918 ctx_.moveTo(point.canvasx, point.canvasy);
4919 else
4920 ctx_.lineTo(point.canvasx, point.canvasy);
4921 first_point = false;
4922 }
4923 };
4924 MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this);
4925 ctx.stroke();
4926 }
4927 };
4928
4929 var makeErrorBars = function(ctx) {
4930 for (var i = 0; i < setCount; i++) {
4931 var setName = setNames[i];
4932 var color = colorScheme[i % colorCount];
4933 var strokeX = this.options.strokeColorTransform;
4934
4935 // setup graphics context
4936 context.save();
4937 context.strokeStyle = color.toRGBString();
4938 context.lineWidth = this.options.strokeWidth;
4939 var prevX = -1;
4940 var prevYs = [-1, -1];
4941 var count = 0;
4942 var yscale = this.layout.yscale;
4943 var errorTrapezoid = function(ctx_,point) {
4944 count++;
4945 if (point.name == setName) {
4946 var newYs = [ point.y - point.errorPlus * yscale,
4947 point.y + point.errorMinus * yscale ];
4948 newYs[0] = this.area.h * newYs[0] + this.area.y;
4949 newYs[1] = this.area.h * newYs[1] + this.area.y;
4950 if (prevX >= 0) {
4951 ctx_.moveTo(prevX, prevYs[0]);
4952 ctx_.lineTo(point.canvasx, newYs[0]);
4953 ctx_.lineTo(point.canvasx, newYs[1]);
4954 ctx_.lineTo(prevX, prevYs[1]);
4955 ctx_.closePath();
4956 }
4957 prevYs[0] = newYs[0];
4958 prevYs[1] = newYs[1];
4959 prevX = point.canvasx;
4960 }
4961 };
4962 // should be same color as the lines
4963 var err_color = color.colorWithAlpha(0.15);
4964 ctx.fillStyle = err_color.toRGBString();
4965 ctx.beginPath();
4966 MochiKit.Iter.forEach(this.layout.points, partial(errorTrapezoid, ctx), this);
4967 ctx.fill();
4968 }
4969 };
4970
4971 if (errorBars)
4972 bind(makeErrorBars, this)(context);
4973 bind(makePath, this)(context);
4974 context.restore();
4975 };
4976 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
4977 // All Rights Reserved.
4978
4979 /**
4980 * @fileoverview Creates an interactive, zoomable graph based on a CSV file or
4981 * string. DateGraph can handle multiple series with or without error bars. The
4982 * date/value ranges will be automatically set. DateGraph uses the
4983 * &lt;canvas&gt; tag, so it only works in FF1.5+.
4984 * @author danvdk@gmail.com (Dan Vanderkam)
4985
4986 Usage:
4987 <div id="graphdiv" style="width:800px; height:500px;"></div>
4988 <script type="text/javascript">
4989 new DateGraph(document.getElementById("graphdiv"),
4990 "datafile.csv",
4991 ["Series 1", "Series 2"],
4992 { }); // options
4993 </script>
4994
4995 The CSV file is of the form
4996
4997 YYYYMMDD,A1,B1,C1
4998 YYYYMMDD,A2,B2,C2
4999
5000 If null is passed as the third parameter (series names), then the first line
5001 of the CSV file is assumed to contain names for each series.
5002
5003 If the 'errorBars' option is set in the constructor, the input should be of
5004 the form
5005
5006 YYYYMMDD,A1,sigmaA1,B1,sigmaB1,...
5007 YYYYMMDD,A2,sigmaA2,B2,sigmaB2,...
5008
5009 If the 'fractions' option is set, the input should be of the form:
5010
5011 YYYYMMDD,A1/B1,A2/B2,...
5012 YYYYMMDD,A1/B1,A2/B2,...
5013
5014 And error bars will be calculated automatically using a binomial distribution.
5015
5016 For further documentation and examples, see http://www/~danvk/dg/
5017
5018 */
5019
5020 /**
5021 * An interactive, zoomable graph
5022 * @param {String | Function} file A file containing CSV data or a function that
5023 * returns this data. The expected format for each line is
5024 * YYYYMMDD,val1,val2,... or, if attrs.errorBars is set,
5025 * YYYYMMDD,val1,stddev1,val2,stddev2,...
5026 * @param {Array.<String>} labels Labels for the data series
5027 * @param {Object} attrs Various other attributes, e.g. errorBars determines
5028 * whether the input data contains error ranges.
5029 */
5030 DateGraph = function(div, file, labels, attrs) {
5031 if (arguments.length > 0)
5032 this.__init__(div, file, labels, attrs);
5033 };
5034
5035 DateGraph.NAME = "DateGraph";
5036 DateGraph.VERSION = "1.1";
5037 DateGraph.__repr__ = function() {
5038 return "[" + this.NAME + " " + this.VERSION + "]";
5039 };
5040 DateGraph.toString = function() {
5041 return this.__repr__();
5042 };
5043
5044 // Various default values
5045 DateGraph.DEFAULT_ROLL_PERIOD = 1;
5046 DateGraph.DEFAULT_WIDTH = 480;
5047 DateGraph.DEFAULT_HEIGHT = 320;
5048 DateGraph.DEFAULT_STROKE_WIDTH = 1.0;
5049 DateGraph.AXIS_LINE_WIDTH = 0.3;
5050
5051 /**
5052 * Initializes the DateGraph. This creates a new DIV and constructs the PlotKit
5053 * and interaction &lt;canvas&gt; inside of it. See the constructor for details
5054 * on the parameters.
5055 * @param {String | Function} file Source data
5056 * @param {Array.<String>} labels Names of the data series
5057 * @param {Object} attrs Miscellaneous other options
5058 * @private
5059 */
5060 DateGraph.prototype.__init__ = function(div, file, labels, attrs) {
5061 // Copy the important bits into the object
5062 this.maindiv_ = div;
5063 this.labels_ = labels;
5064 this.file_ = file;
5065 this.rollPeriod_ = attrs.rollPeriod || DateGraph.DEFAULT_ROLL_PERIOD;
5066 this.previousVerticalX_ = -1;
5067 this.width_ = parseInt(div.style.width, 10);
5068 this.height_ = parseInt(div.style.height, 10);
5069 this.errorBars_ = attrs.errorBars || false;
5070 this.fractions_ = attrs.fractions || false;
5071 this.strokeWidth_ = attrs.strokeWidth || DateGraph.DEFAULT_STROKE_WIDTH;
5072 this.dateWindow_ = attrs.dateWindow || null;
5073 this.valueRange_ = attrs.valueRange || null;
5074 this.labelsSeparateLines = attrs.labelsSeparateLines || false;
5075 this.labelsDiv_ = attrs.labelsDiv || null;
5076 this.labelsKMB_ = attrs.labelsKMB || false;
5077 this.minTickSize_ = attrs.minTickSize || 0;
5078 this.xValueParser_ = attrs.xValueParser || DateGraph.prototype.dateParser;
5079 this.xValueFormatter_ = attrs.xValueFormatter ||
5080 DateGraph.prototype.dateString_;
5081 this.xTicker_ = attrs.xTicker || DateGraph.prototype.dateTicker;
5082 this.sigma_ = attrs.sigma || 2.0;
5083 this.wilsonInterval_ = attrs.wilsonInterval || true;
5084 this.customBars_ = attrs.customBars || false;
5085 this.attrs_ = attrs;
5086
5087 // Make a note of whether labels will be pulled from the CSV file.
5088 this.labelsFromCSV_ = (this.labels_ == null);
5089 if (this.labels_ == null)
5090 this.labels_ = [];
5091
5092 // Prototype of the callback is "void clickCallback(event, date)"
5093 this.clickCallback_ = attrs.clickCallback || null;
5094
5095 // Prototype of zoom callback is "void dragCallback(minDate, maxDate)"
5096 this.zoomCallback_ = attrs.zoomCallback || null;
5097
5098 // Create the containing DIV and other interactive elements
5099 this.createInterface_();
5100
5101 // Create the PlotKit grapher
5102 this.layoutOptions_ = { 'errorBars': (this.errorBars_ || this.customBars_),
5103 'xOriginIsZero': false };
5104 MochiKit.Base.update(this.layoutOptions_, attrs);
5105 this.setColors_(attrs);
5106
5107 this.layout_ = new DateGraphLayout(this.layoutOptions_);
5108
5109 this.renderOptions_ = { colorScheme: this.colors_,
5110 strokeColor: null,
5111 strokeWidth: this.strokeWidth_,
5112 axisLabelFontSize: 14,
5113 axisLineWidth: DateGraph.AXIS_LINE_WIDTH };
5114 MochiKit.Base.update(this.renderOptions_, attrs);
5115 this.plotter_ = new DateGraphCanvasRenderer(this.hidden_, this.layout_,
5116 this.renderOptions_);
5117
5118 this.createStatusMessage_();
5119 this.createRollInterface_();
5120 this.createDragInterface_();
5121
5122 connect(window, 'onload', this, function(e) { this.start_(); });
5123 };
5124
5125 /**
5126 * Returns the current rolling period, as set by the user or an option.
5127 * @return {Number} The number of days in the rolling window
5128 */
5129 DateGraph.prototype.rollPeriod = function() {
5130 return this.rollPeriod_;
5131 }
5132
5133 /**
5134 * Generates interface elements for the DateGraph: a containing div, a div to
5135 * display the current point, and a textbox to adjust the rolling average
5136 * period.
5137 * @private
5138 */
5139 DateGraph.prototype.createInterface_ = function() {
5140 // Create the all-enclosing graph div
5141 var enclosing = this.maindiv_;
5142
5143 this.graphDiv = MochiKit.DOM.DIV( { style: { 'width': this.width_ + "px",
5144 'height': this.height_ + "px"
5145 }});
5146 appendChildNodes(enclosing, this.graphDiv);
5147
5148 // Create the canvas to store
5149 var canvas = MochiKit.DOM.CANVAS;
5150 this.canvas_ = canvas( { style: { 'position': 'absolute' },
5151 width: this.width_,
5152 height: this.height_});
5153 appendChildNodes(this.graphDiv, this.canvas_);
5154
5155 this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
5156 connect(this.hidden_, 'onmousemove', this, function(e) { this.mouseMove_(e) });
5157 connect(this.hidden_, 'onmouseout', this, function(e) { this.mouseOut_(e) });
5158 }
5159
5160 /**
5161 * Creates the canvas containing the PlotKit graph. Only plotkit ever draws on
5162 * this particular canvas. All DateGraph work is done on this.canvas_.
5163 * @param {Object} canvas The DateGraph canvas to over which to overlay the plot
5164 * @return {Object} The newly-created canvas
5165 * @private
5166 */
5167 DateGraph.prototype.createPlotKitCanvas_ = function(canvas) {
5168 var h = document.createElement("canvas");
5169 h.style.position = "absolute";
5170 h.style.top = canvas.style.top;
5171 h.style.left = canvas.style.left;
5172 h.width = this.width_;
5173 h.height = this.height_;
5174 MochiKit.DOM.appendChildNodes(this.graphDiv, h);
5175 return h;
5176 };
5177
5178 /**
5179 * Generate a set of distinct colors for the data series. This is done with a
5180 * color wheel. Saturation/Value are customizable, and the hue is
5181 * equally-spaced around the color wheel. If a custom set of colors is
5182 * specified, that is used instead.
5183 * @param {Object} attrs Various attributes, e.g. saturation and value
5184 * @private
5185 */
5186 DateGraph.prototype.setColors_ = function(attrs) {
5187 var num = this.labels_.length;
5188 this.colors_ = [];
5189 if (!attrs.colors) {
5190 var sat = attrs.colorSaturation || 1.0;
5191 var val = attrs.colorValue || 0.5;
5192 for (var i = 1; i <= num; i++) {
5193 var hue = (1.0*i/(1+num));
5194 this.colors_.push( MochiKit.Color.Color.fromHSV(hue, sat, val) );
5195 }
5196 } else {
5197 for (var i = 0; i < num; i++) {
5198 var colorStr = attrs.colors[i % attrs.colors.length];
5199 this.colors_.push( MochiKit.Color.Color.fromString(colorStr) );
5200 }
5201 }
5202 }
5203
5204 /**
5205 * Create the div that contains information on the selected point(s)
5206 * This goes in the top right of the canvas, unless an external div has already
5207 * been specified.
5208 * @private
5209 */
5210 DateGraph.prototype.createStatusMessage_ = function(){
5211 if (!this.labelsDiv_) {
5212 var divWidth = 250;
5213 var messagestyle = { "style": {
5214 "position": "absolute",
5215 "fontSize": "14px",
5216 "zIndex": 10,
5217 "width": divWidth + "px",
5218 "top": "0px",
5219 "left": this.width_ - divWidth + "px",
5220 "background": "white",
5221 "textAlign": "left",
5222 "overflow": "hidden"}};
5223 this.labelsDiv_ = MochiKit.DOM.DIV(messagestyle);
5224 MochiKit.DOM.appendChildNodes(this.graphDiv, this.labelsDiv_);
5225 }
5226 };
5227
5228 /**
5229 * Create the text box to adjust the averaging period
5230 * @return {Object} The newly-created text box
5231 * @private
5232 */
5233 DateGraph.prototype.createRollInterface_ = function() {
5234 var padding = this.plotter_.options.padding;
5235 var textAttr = { "type": "text",
5236 "size": "2",
5237 "value": this.rollPeriod_,
5238 "style": { "position": "absolute",
5239 "zIndex": 10,
5240 "top": (this.height_ - 25 - padding.bottom) + "px",
5241 "left": (padding.left+1) + "px" }
5242 };
5243 var roller = MochiKit.DOM.INPUT(textAttr);
5244 var pa = this.graphDiv;
5245 MochiKit.DOM.appendChildNodes(pa, roller);
5246 connect(roller, 'onchange', this,
5247 function() { this.adjustRoll(roller.value); });
5248 return roller;
5249 }
5250
5251 /**
5252 * Set up all the mouse handlers needed to capture dragging behavior for zoom
5253 * events. Uses MochiKit.Signal to attach all the event handlers.
5254 * @private
5255 */
5256 DateGraph.prototype.createDragInterface_ = function() {
5257 var self = this;
5258
5259 // Tracks whether the mouse is down right now
5260 var mouseDown = false;
5261 var dragStartX = null;
5262 var dragStartY = null;
5263 var dragEndX = null;
5264 var dragEndY = null;
5265 var prevEndX = null;
5266
5267 // Utility function to convert page-wide coordinates to canvas coords
5268 var px = PlotKit.Base.findPosX(this.canvas_);
5269 var py = PlotKit.Base.findPosY(this.canvas_);
5270 var getX = function(e) { return e.mouse().page.x - px };
5271 var getY = function(e) { return e.mouse().page.y - py };
5272
5273 // Draw zoom rectangles when the mouse is down and the user moves around
5274 connect(this.hidden_, 'onmousemove', function(event) {
5275 if (mouseDown) {
5276 dragEndX = getX(event);
5277 dragEndY = getY(event);
5278
5279 self.drawZoomRect_(dragStartX, dragEndX, prevEndX);
5280 prevEndX = dragEndX;
5281 }
5282 });
5283
5284 // Track the beginning of drag events
5285 connect(this.hidden_, 'onmousedown', function(event) {
5286 mouseDown = true;
5287 dragStartX = getX(event);
5288 dragStartY = getY(event);
5289 });
5290
5291 // If the user releases the mouse button during a drag, but not over the
5292 // canvas, then it doesn't count as a zooming action.
5293 connect(document, 'onmouseup', this, function(event) {
5294 if (mouseDown) {
5295 mouseDown = false;
5296 dragStartX = null;
5297 dragStartY = null;
5298 }
5299 });
5300
5301 // Temporarily cancel the dragging event when the mouse leaves the graph
5302 connect(this.hidden_, 'onmouseout', this, function(event) {
5303 if (mouseDown) {
5304 dragEndX = null;
5305 dragEndY = null;
5306 }
5307 });
5308
5309 // If the mouse is released on the canvas during a drag event, then it's a
5310 // zoom. Only do the zoom if it's over a large enough area (>= 10 pixels)
5311 connect(this.hidden_, 'onmouseup', this, function(event) {
5312 if (mouseDown) {
5313 mouseDown = false;
5314 dragEndX = getX(event);
5315 dragEndY = getY(event);
5316 var regionWidth = Math.abs(dragEndX - dragStartX);
5317 var regionHeight = Math.abs(dragEndY - dragStartY);
5318
5319 if (regionWidth < 2 && regionHeight < 2 &&
5320 self.clickCallback_ != null &&
5321 self.lastx_ != undefined) {
5322 self.clickCallback_(event, new Date(self.lastx_));
5323 }
5324
5325 if (regionWidth >= 10) {
5326 self.doZoom_(Math.min(dragStartX, dragEndX),
5327 Math.max(dragStartX, dragEndX));
5328 } else {
5329 self.canvas_.getContext("2d").clearRect(0, 0,
5330 self.canvas_.width,
5331 self.canvas_.height);
5332 }
5333
5334 dragStartX = null;
5335 dragStartY = null;
5336 }
5337 });
5338
5339 // Double-clicking zooms back out
5340 connect(this.hidden_, 'ondblclick', this, function(event) {
5341 self.dateWindow_ = null;
5342 self.drawGraph_(self.rawData_);
5343 var minDate = self.rawData_[0][0];
5344 var maxDate = self.rawData_[self.rawData_.length - 1][0];
5345 self.zoomCallback_(minDate, maxDate);
5346 });
5347 };
5348
5349 /**
5350 * Draw a gray zoom rectangle over the desired area of the canvas. Also clears
5351 * up any previous zoom rectangles that were drawn. This could be optimized to
5352 * avoid extra redrawing, but it's tricky to avoid interactions with the status
5353 * dots.
5354 * @param {Number} startX The X position where the drag started, in canvas
5355 * coordinates.
5356 * @param {Number} endX The current X position of the drag, in canvas coords.
5357 * @param {Number} prevEndX The value of endX on the previous call to this
5358 * function. Used to avoid excess redrawing
5359 * @private
5360 */
5361 DateGraph.prototype.drawZoomRect_ = function(startX, endX, prevEndX) {
5362 var ctx = this.canvas_.getContext("2d");
5363
5364 // Clean up from the previous rect if necessary
5365 if (prevEndX) {
5366 ctx.clearRect(Math.min(startX, prevEndX), 0,
5367 Math.abs(startX - prevEndX), this.height_);
5368 }
5369
5370 // Draw a light-grey rectangle to show the new viewing area
5371 if (endX && startX) {
5372 ctx.fillStyle = "rgba(128,128,128,0.33)";
5373 ctx.fillRect(Math.min(startX, endX), 0,
5374 Math.abs(endX - startX), this.height_);
5375 }
5376 };
5377
5378 /**
5379 * Zoom to something containing [lowX, highX]. These are pixel coordinates
5380 * in the canvas. The exact zoom window may be slightly larger if there are no
5381 * data points near lowX or highX. This function redraws the graph.
5382 * @param {Number} lowX The leftmost pixel value that should be visible.
5383 * @param {Number} highX The rightmost pixel value that should be visible.
5384 * @private
5385 */
5386 DateGraph.prototype.doZoom_ = function(lowX, highX) {
5387 // Find the earliest and latest dates contained in this canvasx range.
5388 var points = this.layout_.points;
5389 var minDate = null;
5390 var maxDate = null;
5391 // Find the nearest [minDate, maxDate] that contains [lowX, highX]
5392 for (var i = 0; i < points.length; i++) {
5393 var cx = points[i].canvasx;
5394 var x = points[i].xval;
5395 if (cx < lowX && (minDate == null || x > minDate)) minDate = x;
5396 if (cx > highX && (maxDate == null || x < maxDate)) maxDate = x;
5397 }
5398 // Use the extremes if either is missing
5399 if (minDate == null) minDate = points[0].xval;
5400 if (maxDate == null) maxDate = points[points.length-1].xval;
5401
5402 this.dateWindow_ = [minDate, maxDate];
5403 this.drawGraph_(this.rawData_);
5404 this.zoomCallback_(minDate, maxDate);
5405 };
5406
5407 /**
5408 * When the mouse moves in the canvas, display information about a nearby data
5409 * point and draw dots over those points in the data series. This function
5410 * takes care of cleanup of previously-drawn dots.
5411 * @param {Object} event The mousemove event from the browser.
5412 * @private
5413 */
5414 DateGraph.prototype.mouseMove_ = function(event) {
5415 var canvasx = event.mouse().page.x - PlotKit.Base.findPosX(this.hidden_);
5416 var points = this.layout_.points;
5417
5418 var lastx = -1;
5419 var lasty = -1;
5420
5421 // Loop through all the points and find the date nearest to our current
5422 // location.
5423 var minDist = 1e+100;
5424 var idx = -1;
5425 for (var i = 0; i < points.length; i++) {
5426 var dist = Math.abs(points[i].canvasx - canvasx);
5427 if (dist > minDist) break;
5428 minDist = dist;
5429 idx = i;
5430 }
5431 if (idx >= 0) lastx = points[idx].xval;
5432 // Check that you can really highlight the last day's data
5433 if (canvasx > points[points.length-1].canvasx)
5434 lastx = points[points.length-1].xval;
5435
5436 // Extract the points we've selected
5437 var selPoints = [];
5438 for (var i = 0; i < points.length; i++) {
5439 if (points[i].xval == lastx) {
5440 selPoints.push(points[i]);
5441 }
5442 }
5443
5444 // Clear the previously drawn vertical, if there is one
5445 var circleSize = 3;
5446 var ctx = this.canvas_.getContext("2d");
5447 if (this.previousVerticalX_ >= 0) {
5448 var px = this.previousVerticalX_;
5449 ctx.clearRect(px - circleSize - 1, 0, 2 * circleSize + 2, this.height_);
5450 }
5451
5452 if (selPoints.length > 0) {
5453 var canvasx = selPoints[0].canvasx;
5454
5455 // Set the status message to indicate the selected point(s)
5456 var replace = this.xValueFormatter_(lastx) + ":";
5457 var clen = this.colors_.length;
5458 for (var i = 0; i < selPoints.length; i++) {
5459 if (this.labelsSeparateLines) {
5460 replace += "<br/>";
5461 }
5462 var point = selPoints[i];
5463 replace += " <b><font color='" + this.colors_[i%clen].toHexString() + "'>"
5464 + point.name + "</font></b>:"
5465 + this.round_(point.yval, 2);
5466 }
5467 this.labelsDiv_.innerHTML = replace;
5468
5469 // Save last x position for callbacks.
5470 this.lastx_ = lastx;
5471
5472 // Draw colored circles over the center of each selected point
5473 ctx.save()
5474 for (var i = 0; i < selPoints.length; i++) {
5475 ctx.beginPath();
5476 ctx.fillStyle = this.colors_[i%clen].toRGBString();
5477 ctx.arc(canvasx, selPoints[i%clen].canvasy, circleSize, 0, 360, false);
5478 ctx.fill();
5479 }
5480 ctx.restore();
5481
5482 this.previousVerticalX_ = canvasx;
5483 }
5484 };
5485
5486 /**
5487 * The mouse has left the canvas. Clear out whatever artifacts remain
5488 * @param {Object} event the mouseout event from the browser.
5489 * @private
5490 */
5491 DateGraph.prototype.mouseOut_ = function(event) {
5492 // Get rid of the overlay data
5493 var ctx = this.canvas_.getContext("2d");
5494 ctx.clearRect(0, 0, this.width_, this.height_);
5495 this.labelsDiv_.innerHTML = "";
5496 };
5497
5498 /**
5499 * Convert a JS date (millis since epoch) to YYYY/MM/DD
5500 * @param {Number} date The JavaScript date (ms since epoch)
5501 * @return {String} A date of the form "YYYY/MM/DD"
5502 * @private
5503 */
5504 DateGraph.prototype.dateString_ = function(date) {
5505 var d = new Date(date);
5506
5507 // Get the year:
5508 var year = "" + d.getFullYear();
5509 // Get a 0 padded month string
5510 var month = "" + (d.getMonth() + 1); //months are 0-offset, sigh
5511 if (month.length < 2) month = "0" + month;
5512 // Get a 0 padded day string
5513 var day = "" + d.getDate();
5514 if (day.length < 2) day = "0" + day;
5515
5516 return year + "/" + month + "/" + day;
5517 };
5518
5519 /**
5520 * Round a number to the specified number of digits past the decimal point.
5521 * @param {Number} num The number to round
5522 * @param {Number} places The number of decimals to which to round
5523 * @return {Number} The rounded number
5524 * @private
5525 */
5526 DateGraph.prototype.round_ = function(num, places) {
5527 var shift = Math.pow(10, places);
5528 return Math.round(num * shift)/shift;
5529 };
5530
5531 /**
5532 * Fires when there's data available to be graphed.
5533 * @param {String} data Raw CSV data to be plotted
5534 * @private
5535 */
5536 DateGraph.prototype.loadedEvent_ = function(data) {
5537 this.rawData_ = this.parseCSV_(data);
5538 this.drawGraph_(this.rawData_);
5539 };
5540
5541 DateGraph.prototype.months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
5542 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
5543 DateGraph.prototype.quarters = ["Jan", "Apr", "Jul", "Oct"];
5544
5545 /**
5546 * Add ticks on the x-axis representing years, months, quarters, weeks, or days
5547 * @private
5548 */
5549 DateGraph.prototype.addXTicks_ = function() {
5550 // Determine the correct ticks scale on the x-axis: quarterly, monthly, ...
5551 var startDate, endDate;
5552 if (this.dateWindow_) {
5553 startDate = this.dateWindow_[0];
5554 endDate = this.dateWindow_[1];
5555 } else {
5556 startDate = this.rawData_[0][0];
5557 endDate = this.rawData_[this.rawData_.length - 1][0];
5558 }
5559
5560 var xTicks = this.xTicker_(startDate, endDate);
5561 this.layout_.updateOptions({xTicks: xTicks});
5562 }
5563
5564 /**
5565 * Add ticks to the x-axis based on a date range.
5566 * @param {Number} startDate Start of the date window (millis since epoch)
5567 * @param {Number} endDate End of the date window (millis since epoch)
5568 * @return {Array.<Object>} Array of {label, value} tuples.
5569 * @public
5570 */
5571 DateGraph.prototype.dateTicker = function(startDate, endDate) {
5572 var ONE_DAY = 24*60*60*1000;
5573 startDate = startDate / ONE_DAY;
5574 endDate = endDate / ONE_DAY;
5575 var dateSpan = endDate - startDate;
5576
5577 var scale = [];
5578 var isMonthly = false;
5579 var yearMod = 1;
5580 if (dateSpan > 30 * 366) { // decadal
5581 isMonthly = true;
5582 scale = ["Jan"];
5583 yearMod = 10;
5584 } else if (dateSpan > 4*366) { // annual
5585 scale = ["Jan"];
5586 isMonthly = true;
5587 } else if (dateSpan > 366) { // quarterly
5588 scale = this.quarters;
5589 isMonthly = true;
5590 } else if (dateSpan > 40) { // monthly
5591 scale = this.months;
5592 isMonthly = true;
5593 } else if (dateSpan > 10) { // weekly
5594 for (var week = startDate - 14; week < endDate + 14; week += 7) {
5595 scale.push(week * ONE_DAY);
5596 }
5597 } else { // daily
5598 for (var day = startDate - 14; day < endDate + 14; day += 1) {
5599 scale.push(day * ONE_DAY);
5600 }
5601 }
5602
5603 var xTicks = [];
5604
5605 if (isMonthly) {
5606 var startYear = 1900 + (new Date(startDate* ONE_DAY)).getYear();
5607 var endYear = 1900 + (new Date(endDate * ONE_DAY)).getYear();
5608 for (var i = startYear; i <= endYear; i++) {
5609 if (i % yearMod != 0) continue;
5610 for (var j = 0; j < scale.length; j++ ) {
5611 var date = Date.parse(scale[j] + " 1, " + i);
5612 xTicks.push( {label: scale[j] + "'" + ("" + i).substr(2,2), v: date } );
5613 }
5614 }
5615 } else {
5616 for (var i = 0; i < scale.length; i++) {
5617 var date = new Date(scale[i]);
5618 var year = date.getFullYear().toString();
5619 var label = this.months[date.getMonth()] + date.getDate();
5620 label += "'" + year.substr(year.length - 2, 2);
5621 xTicks.push( {label: label, v: date} );
5622 }
5623 }
5624 return xTicks;
5625 };
5626
5627 /**
5628 * Add ticks when the x axis has numbers on it (instead of dates)
5629 * @param {Number} startDate Start of the date window (millis since epoch)
5630 * @param {Number} endDate End of the date window (millis since epoch)
5631 * @return {Array.<Object>} Array of {label, value} tuples.
5632 * @public
5633 */
5634 DateGraph.prototype.numericTicks = function(minV, maxV) {
5635 var scale;
5636 if (maxV <= 0.0) {
5637 scale = 1.0;
5638 } else {
5639 scale = Math.pow( 10, Math.floor(Math.log(maxV)/Math.log(10.0)) );
5640 }
5641
5642 // Add a smallish number of ticks at human-friendly points
5643 var nTicks = (maxV - minV) / scale;
5644 while (2 * nTicks < 20) {
5645 nTicks *= 2;
5646 }
5647 if ((maxV - minV) / nTicks < this.minTickSize_) {
5648 nTicks = this.round_((maxV - minV) / this.minTickSize_, 1);
5649 }
5650
5651 // Construct labels for the ticks
5652 var ticks = [];
5653 for (var i = 0; i <= nTicks; i++) {
5654 var tickV = minV + i * (maxV - minV) / nTicks;
5655 var label = this.round_(tickV, 2);
5656 if (this.labelsKMB_) {
5657 var k = 1000;
5658 if (tickV >= k*k*k) {
5659 label = this.round_(tickV/(k*k*k), 1) + "B";
5660 } else if (tickV >= k*k) {
5661 label = this.round_(tickV/(k*k), 1) + "M";
5662 } else if (tickV >= k) {
5663 label = this.round_(tickV/k, 1) + "K";
5664 }
5665 }
5666 ticks.push( {label: label, v: tickV} );
5667 }
5668 return ticks;
5669 };
5670
5671 /**
5672 * Adds appropriate ticks on the y-axis
5673 * @param {Number} minY The minimum Y value in the data set
5674 * @param {Number} maxY The maximum Y value in the data set
5675 * @private
5676 */
5677 DateGraph.prototype.addYTicks_ = function(minY, maxY) {
5678 // Set the number of ticks so that the labels are human-friendly.
5679 var ticks = this.numericTicks(minY, maxY);
5680 this.layout_.updateOptions( { yAxis: [minY, maxY],
5681 yTicks: ticks } );
5682 };
5683
5684 /**
5685 * Update the graph with new data. Data is in the format
5686 * [ [date1, val1, val2, ...], [date2, val1, val2, ...] if errorBars=false
5687 * or, if errorBars=true,
5688 * [ [date1, [val1,stddev1], [val2,stddev2], ...], [date2, ...], ...]
5689 * @param {Array.<Object>} data The data (see above)
5690 * @private
5691 */
5692 DateGraph.prototype.drawGraph_ = function(data) {
5693 var maxY = null;
5694 this.layout_.removeAllDatasets();
5695 // Loop over all fields in the dataset
5696 for (var i = 1; i < data[0].length; i++) {
5697 var series = [];
5698 for (var j = 0; j < data.length; j++) {
5699 var date = data[j][0];
5700 series[j] = [date, data[j][i]];
5701 }
5702 series = this.rollingAverage(series, this.rollPeriod_);
5703
5704 // Prune down to the desired range, if necessary (for zooming)
5705 var bars = this.errorBars_ || this.customBars_;
5706 if (this.dateWindow_) {
5707 var low = this.dateWindow_[0];
5708 var high= this.dateWindow_[1];
5709 var pruned = [];
5710 for (var k = 0; k < series.length; k++) {
5711 if (series[k][0] >= low && series[k][0] <= high) {
5712 pruned.push(series[k]);
5713 var y = bars ? series[k][1][0] : series[k][1];
5714 if (maxY == null || y > maxY) maxY = y;
5715 }
5716 }
5717 series = pruned;
5718 } else {
5719 for (var j = 0; j < series.length; j++) {
5720 var y = bars ? series[j][1][0] : series[j][1];
5721 if (maxY == null || y > maxY) {
5722 maxY = bars ? y + series[j][1][1] : y;
5723 }
5724 }
5725 }
5726
5727 if (bars) {
5728 var vals = [];
5729 for (var j=0; j<series.length; j++)
5730 vals[j] = [series[j][0],
5731 series[j][1][0], series[j][1][1], series[j][1][2]];
5732 this.layout_.addDataset(this.labels_[i - 1], vals);
5733 } else {
5734 this.layout_.addDataset(this.labels_[i - 1], series);
5735 }
5736 }
5737
5738 // Use some heuristics to come up with a good maxY value, unless it's been
5739 // set explicitly by the user.
5740 if (this.valueRange_ != null) {
5741 this.addYTicks_(this.valueRange_[0], this.valueRange_[1]);
5742 } else {
5743 // Add some padding and round up to an integer to be human-friendly.
5744 maxY *= 1.1;
5745 if (maxY <= 0.0) maxY = 1.0;
5746 else {
5747 var scale = Math.pow(10, Math.floor(Math.log(maxY) / Math.log(10.0)));
5748 maxY = scale * Math.ceil(maxY / scale);
5749 }
5750 this.addYTicks_(0, maxY);
5751 }
5752
5753 this.addXTicks_();
5754
5755 // Tell PlotKit to use this new data and render itself
5756 this.layout_.evaluateWithError();
5757 this.plotter_.clear();
5758 this.plotter_.render();
5759 this.canvas_.getContext('2d').clearRect(0, 0,
5760 this.canvas_.width, this.canvas_.height);
5761 };
5762
5763 /**
5764 * Calculates the rolling average of a data set.
5765 * If originalData is [label, val], rolls the average of those.
5766 * If originalData is [label, [, it's interpreted as [value, stddev]
5767 * and the roll is returned in the same form, with appropriately reduced
5768 * stddev for each value.
5769 * Note that this is where fractional input (i.e. '5/10') is converted into
5770 * decimal values.
5771 * @param {Array} originalData The data in the appropriate format (see above)
5772 * @param {Number} rollPeriod The number of days over which to average the data
5773 */
5774 DateGraph.prototype.rollingAverage = function(originalData, rollPeriod) {
5775 if (originalData.length < 2)
5776 return originalData;
5777 var rollPeriod = Math.min(rollPeriod, originalData.length - 1);
5778 var rollingData = [];
5779 var sigma = this.sigma_;
5780
5781 if (this.fractions_) {
5782 var num = 0;
5783 var den = 0; // numerator/denominator
5784 var mult = 100.0;
5785 for (var i = 0; i < originalData.length; i++) {
5786 num += originalData[i][1][0];
5787 den += originalData[i][1][1];
5788 if (i - rollPeriod >= 0) {
5789 num -= originalData[i - rollPeriod][1][0];
5790 den -= originalData[i - rollPeriod][1][1];
5791 }
5792
5793 var date = originalData[i][0];
5794 var value = den ? num / den : 0.0;
5795 if (this.errorBars_) {
5796 if (this.wilsonInterval_) {
5797 // For more details on this confidence interval, see:
5798 // http://en.wikipedia.org/wiki/Binomial_confidence_interval
5799 if (den) {
5800 var p = value < 0 ? 0 : value, n = den;
5801 var pm = sigma * Math.sqrt(p*(1-p)/n + sigma*sigma/(4*n*n));
5802 var denom = 1 + sigma * sigma / den;
5803 var low = (p + sigma * sigma / (2 * den) - pm) / denom;
5804 var high = (p + sigma * sigma / (2 * den) + pm) / denom;
5805 rollingData[i] = [date,
5806 [p * mult, (p - low) * mult, (high - p) * mult]];
5807 } else {
5808 rollingData[i] = [date, [0, 0, 0]];
5809 }
5810 } else {
5811 var stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0;
5812 rollingData[i] = [date, [mult * value, mult * stddev, mult * stddev]];
5813 }
5814 } else {
5815 rollingData[i] = [date, mult * value];
5816 }
5817 }
5818 } else if (this.customBars_) {
5819 // just ignore the rolling for now.
5820 // TODO(danvk): do something reasonable.
5821 for (var i = 0; i < originalData.length; i++) {
5822 var data = originalData[i][1];
5823 var y = data[1];
5824 rollingData[i] = [originalData[i][0], [y, y - data[0], data[2] - y]];
5825 }
5826 } else {
5827 // Calculate the rolling average for the first rollPeriod - 1 points where
5828 // there is not enough data to roll over the full number of days
5829 var num_init_points = Math.min(rollPeriod - 1, originalData.length - 2);
5830 if (!this.errorBars_){
5831 for (var i = 0; i < num_init_points; i++) {
5832 var sum = 0;
5833 for (var j = 0; j < i + 1; j++)
5834 sum += originalData[j][1];
5835 rollingData[i] = [originalData[i][0], sum / (i + 1)];
5836 }
5837 // Calculate the rolling average for the remaining points
5838 for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
5839 i < originalData.length;
5840 i++) {
5841 var sum = 0;
5842 for (var j = i - rollPeriod + 1; j < i + 1; j++)
5843 sum += originalData[j][1];
5844 rollingData[i] = [originalData[i][0], sum / rollPeriod];
5845 }
5846 } else {
5847 for (var i = 0; i < num_init_points; i++) {
5848 var sum = 0;
5849 var variance = 0;
5850 for (var j = 0; j < i + 1; j++) {
5851 sum += originalData[j][1][0];
5852 variance += Math.pow(originalData[j][1][1], 2);
5853 }
5854 var stddev = Math.sqrt(variance)/(i+1);
5855 rollingData[i] = [originalData[i][0],
5856 [sum/(i+1), sigma * stddev, sigma * stddev]];
5857 }
5858 // Calculate the rolling average for the remaining points
5859 for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
5860 i < originalData.length;
5861 i++) {
5862 var sum = 0;
5863 var variance = 0;
5864 for (var j = i - rollPeriod + 1; j < i + 1; j++) {
5865 sum += originalData[j][1][0];
5866 variance += Math.pow(originalData[j][1][1], 2);
5867 }
5868 var stddev = Math.sqrt(variance) / rollPeriod;
5869 rollingData[i] = [originalData[i][0],
5870 [sum / rollPeriod, sigma * stddev, sigma * stddev]];
5871 }
5872 }
5873 }
5874
5875 return rollingData;
5876 };
5877
5878 /**
5879 * Parses a date, returning the number of milliseconds since epoch. This can be
5880 * passed in as an xValueParser in the DateGraph constructor.
5881 * @param {String} A date in YYYYMMDD format.
5882 * @return {Number} Milliseconds since epoch.
5883 * @public
5884 */
5885 DateGraph.prototype.dateParser = function(dateStr) {
5886 var dateStrSlashed;
5887 if (dateStr.search("-") != -1) {
5888 dateStrSlashed = dateStr.replace("-", "/", "g");
5889 } else if (dateStr.search("/") != -1) {
5890 return Date.parse(dateStr);
5891 } else {
5892 dateStrSlashed = dateStr.substr(0,4) + "/" + dateStr.substr(4,2)
5893 + "/" + dateStr.substr(6,2);
5894 }
5895 return Date.parse(dateStrSlashed);
5896 };
5897
5898 /**
5899 * Parses a string in a special csv format. We expect a csv file where each
5900 * line is a date point, and the first field in each line is the date string.
5901 * We also expect that all remaining fields represent series.
5902 * if this.errorBars_ is set, then interpret the fields as:
5903 * date, series1, stddev1, series2, stddev2, ...
5904 * @param {Array.<Object>} data See above.
5905 * @private
5906 */
5907 DateGraph.prototype.parseCSV_ = function(data) {
5908 var ret = [];
5909 var lines = data.split("\n");
5910 var start = this.labelsFromCSV_ ? 1 : 0;
5911 if (this.labelsFromCSV_) {
5912 var labels = lines[0].split(",");
5913 labels.shift(); // a "date" parameter is assumed.
5914 this.labels_ = labels;
5915 // regenerate automatic colors.
5916 this.setColors_(this.attrs_);
5917 this.renderOptions_.colorScheme = this.colors_;
5918 MochiKit.Base.update(this.plotter_.options, this.renderOptions_);
5919 MochiKit.Base.update(this.layoutOptions_, this.attrs_);
5920 }
5921
5922 for (var i = start; i < lines.length; i++) {
5923 var line = lines[i];
5924 if (line.length == 0) continue; // skip blank lines
5925 var inFields = line.split(',');
5926 if (inFields.length < 2)
5927 continue;
5928
5929 var fields = [];
5930 fields[0] = this.xValueParser_(inFields[0]);
5931
5932 // If fractions are expected, parse the numbers as "A/B"
5933 if (this.fractions_) {
5934 for (var j = 1; j < inFields.length; j++) {
5935 // TODO(danvk): figure out an appropriate way to flag parse errors.
5936 var vals = inFields[j].split("/");
5937 fields[j] = [parseFloat(vals[0]), parseFloat(vals[1])];
5938 }
5939 } else if (this.errorBars_) {
5940 // If there are error bars, values are (value, stddev) pairs
5941 for (var j = 1; j < inFields.length; j += 2)
5942 fields[(j + 1) / 2] = [parseFloat(inFields[j]),
5943 parseFloat(inFields[j + 1])];
5944 } else if (this.customBars_) {
5945 // Bars are a low;center;high tuple
5946 for (var j = 1; j < inFields.length; j++) {
5947 var vals = inFields[j].split(";");
5948 fields[j] = [ parseFloat(vals[0]),
5949 parseFloat(vals[1]),
5950 parseFloat(vals[2]) ];
5951 }
5952 } else {
5953 // Values are just numbers
5954 for (var j = 1; j < inFields.length; j++)
5955 fields[j] = parseFloat(inFields[j]);
5956 }
5957 ret.push(fields);
5958 }
5959 return ret;
5960 };
5961
5962 /**
5963 * Get the CSV data. If it's in a function, call that function. If it's in a
5964 * file, do an XMLHttpRequest to get it.
5965 * @private
5966 */
5967 DateGraph.prototype.start_ = function() {
5968 if (typeof this.file_ == 'function') {
5969 // Stubbed out to allow this to run off a filesystem
5970 this.loadedEvent_(this.file_());
5971 } else {
5972 var req = new XMLHttpRequest();
5973 var caller = this;
5974 req.onreadystatechange = function () {
5975 if (req.readyState == 4) {
5976 if (req.status == 200) {
5977 caller.loadedEvent_(req.responseText);
5978 }
5979 }
5980 };
5981
5982 req.open("GET", this.file_, true);
5983 req.send(null);
5984 }
5985 };
5986
5987 /**
5988 * Changes various properties of the graph. These can include:
5989 * <ul>
5990 * <li>file: changes the source data for the graph</li>
5991 * <li>errorBars: changes whether the data contains stddev</li>
5992 * </ul>
5993 * @param {Object} attrs The new properties and values
5994 */
5995 DateGraph.prototype.updateOptions = function(attrs) {
5996 if (attrs.errorBars) {
5997 this.errorBars_ = attrs.errorBars;
5998 }
5999 if (attrs.customBars) {
6000 this.customBars_ = attrs.customBars;
6001 }
6002 if (attrs.strokeWidth) {
6003 this.strokeWidth_ = attrs.strokeWidth;
6004 }
6005 if (attrs.rollPeriod) {
6006 this.rollPeriod_ = attrs.rollPeriod;
6007 }
6008 if (attrs.dateWindow) {
6009 this.dateWindow_ = attrs.dateWindow;
6010 }
6011 if (attrs.valueRange) {
6012 this.valueRange_ = attrs.valueRange;
6013 }
6014 if (attrs.minTickSize) {
6015 this.minTickSize_ = attrs.minTickSize;
6016 }
6017 if (typeof(attrs.labels) != 'undefined') {
6018 this.labels_ = attrs.labels;
6019 this.labelsFromCSV_ = (attrs.labels == null);
6020 }
6021 this.layout_.updateOptions({ 'errorBars': this.errorBars_ });
6022 if (attrs['file'] && attrs['file'] != this.file_) {
6023 this.file_ = attrs['file'];
6024 this.start_();
6025 } else {
6026 this.drawGraph_(this.rawData_);
6027 }
6028 };
6029
6030 /**
6031 * Adjusts the number of days in the rolling average. Updates the graph to
6032 * reflect the new averaging period.
6033 * @param {Number} length Number of days over which to average the data.
6034 */
6035 DateGraph.prototype.adjustRoll = function(length) {
6036 this.rollPeriod_ = length;
6037 this.drawGraph_(this.rawData_);
6038 };