3 MochiKit.MochiKit 1.4 : PACKED VERSION
5 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
6 diff against the source tree, not this file.
8 See <http://mochikit.com/> for documentation, downloads, license, etc.
10 (c) 2005 Bob Ippolito. All rights Reserved.
14 if(typeof (dojo
)!="undefined"){
15 dojo
.provide("MochiKit.Base");
17 if(typeof (MochiKit
)=="undefined"){
20 if(typeof (MochiKit
.Base
)=="undefined"){
23 if(typeof (MochiKit
.__export__
)=="undefined"){
24 MochiKit
.__export__
=(MochiKit
.__compat__
||(typeof (JSAN
)=="undefined"&&typeof (dojo
)=="undefined"));
26 MochiKit
.Base
.VERSION
="1.4";
27 MochiKit
.Base
.NAME
="MochiKit.Base";
28 MochiKit
.Base
.update
=function(_1
,_2
){
32 for(var i
=1;i
<arguments
.length
;i
++){
34 if(typeof (o
)!="undefined"&&o
!==null){
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
){
49 for(var i
=1;i
<_7
.length
;i
++){
50 cc
+=_7
[i
].charAt(0).toUpperCase()+_7
[i
].substring(1);
53 },counter
:function(n
){
54 if(arguments
.length
===0){
61 var me
=arguments
.callee
;
62 if(arguments
.length
==1){
66 },_flattenArray
:function(_d
,_e
){
67 for(var i
=0;i
<_e
.length
;i
++){
69 if(o
instanceof Array
){
70 arguments
.callee(_d
,o
);
76 },flattenArray
:function(lst
){
77 return MochiKit
.Base
._flattenArray([],lst
);
78 },flattenArguments
:function(lst
){
81 var _15
=m
.extend(null,arguments
);
84 if(o
&&typeof (o
)=="object"&&typeof (o
.length
)=="number"){
85 for(var i
=o
.length
-1;i
>=0;i
--){
93 },extend
:function(_18
,obj
,_1a
){
99 if(typeof (l
)!="number"){
100 if(typeof (MochiKit
.Iter
)!="undefined"){
101 obj
=MochiKit
.Iter
.list(obj
);
104 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
110 for(var i
=_1a
;i
<l
;i
++){
115 },updatetree
:function(_1d
,obj
){
119 for(var i
=1;i
<arguments
.length
;i
++){
121 if(typeof (o
)!="undefined"&&o
!==null){
124 if(typeof (_1d
[k
])=="object"&&typeof (v
)=="object"){
125 arguments
.callee(_1d
[k
],v
);
133 },setdefault
:function(_23
,obj
){
137 for(var i
=1;i
<arguments
.length
;i
++){
146 },keys
:function(obj
){
152 },values
:function(obj
){
158 },items
:function(obj
){
172 },_newNamedError
:function(_33
,_34
,_35
){
173 _35
.prototype=new MochiKit
.Base
.NamedError(_33
.NAME
+"."+_34
);
175 },operator
:{truth
:function(a
){
177 },lognot
:function(a
){
179 },identity
:function(a
){
201 },lshift
:function(a
,b
){
203 },rshift
:function(a
,b
){
205 },zrshift
:function(a
,b
){
224 return MochiKit
.Base
.compare(a
,b
)===0;
226 return MochiKit
.Base
.compare(a
,b
)!==0;
228 return MochiKit
.Base
.compare(a
,b
)==1;
230 return MochiKit
.Base
.compare(a
,b
)!=-1;
232 return MochiKit
.Base
.compare(a
,b
)==-1;
234 return MochiKit
.Base
.compare(a
,b
)!=1;
235 },logand
:function(a
,b
){
237 },logor
:function(a
,b
){
239 },contains
:function(a
,b
){
241 }},forwardCall
:function(_73
){
243 return this[_73
].apply(this,arguments
);
245 },itemgetter
:function(_74
){
246 return function(arg
){
249 },typeMatcher
:function(){
251 for(var i
=0;i
<arguments
.length
;i
++){
252 var typ
=arguments
[i
];
256 for(var i
=0;i
<arguments
.length
;i
++){
257 if(!(typeof (arguments
[i
]) in _76
)){
264 for(var i
=0;i
<arguments
.length
;i
++){
265 if(arguments
[i
]!==null){
270 },isUndefinedOrNull
:function(){
271 for(var i
=0;i
<arguments
.length
;i
++){
273 if(!(typeof (o
)=="undefined"||o
===null)){
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
++){
288 },isArrayLike
:function(){
289 for(var i
=0;i
<arguments
.length
;i
++){
292 if((typ
!="object"&&!(typ
=="function"&&typeof (o
.item
)=="function"))||o
===null||typeof (o
.length
)!="number"||o
.nodeType
===3){
297 },isDateLike
:function(){
298 for(var i
=0;i
<arguments
.length
;i
++){
300 if(typeof (o
)!="object"||o
===null||typeof (o
.getTime
)!="function"){
307 return MochiKit
.Base
.extend(null,arguments
,1);
310 for(var i
=1;i
<arguments
.length
;i
++){
311 _87
.push(fn(arguments
[i
]));
314 },map
:function(fn
,lst
){
316 var itr
=MochiKit
.Iter
;
317 var _8d
=m
.isArrayLike
;
318 if(arguments
.length
<=2){
326 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
330 return m
.extend(null,lst
);
333 for(var i
=0;i
<lst
.length
;i
++){
334 _8e
.push(fn(lst
[i
]));
342 for(i
=1;i
<arguments
.length
;i
++){
343 if(!_8d(arguments
[i
])){
345 return itr
.list(itr
.imap
.apply(null,arguments
));
347 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
350 var l
=arguments
[i
].length
;
351 if(_90
===null||_90
>l
){
358 for(var j
=1;j
<arguments
.length
;j
++){
359 _92
.push(arguments
[j
][i
]);
361 _8e
.push(fn
.apply(this,_92
));
365 },xfilter
:function(fn
){
368 fn
=MochiKit
.Base
.operator
.truth
;
370 for(var i
=1;i
<arguments
.length
;i
++){
377 },filter
:function(fn
,lst
,_9a
){
380 if(!m
.isArrayLike(lst
)){
382 lst
=MochiKit
.Iter
.list(lst
);
384 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
390 if(typeof (Array
.prototype.filter
)=="function"){
391 return Array
.prototype.filter
.call(lst
,fn
,_9a
);
393 if(typeof (_9a
)=="undefined"||_9a
===null){
394 for(var i
=0;i
<lst
.length
;i
++){
401 for(i
=0;i
<lst
.length
;i
++){
410 },_wrapDumbFunction
:function(_9f
){
412 switch(arguments
.length
){
416 return _9f(arguments
[0]);
418 return _9f(arguments
[0],arguments
[1]);
420 return _9f(arguments
[0],arguments
[1],arguments
[2]);
423 for(var i
=0;i
<arguments
.length
;i
++){
424 _a0
.push("arguments["+i
+"]");
426 return eval("(func("+_a0
.join(",")+"))");
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
);
435 return function(obj
){
436 return obj
[_a2
].apply(obj
,_a3
);
439 },method
:function(_a6
,_a7
){
441 return m
.bind
.apply(this,m
.extend([_a7
,_a6
],arguments
,2));
442 },compose
:function(f1
,f2
){
445 if(arguments
.length
===0){
446 throw new TypeError("compose() requires at least one argument");
448 for(var i
=0;i
<arguments
.length
;i
++){
450 if(typeof (fn
)!="function"){
451 throw new TypeError(m
.repr(fn
)+" is not a function");
457 for(var i
=_ab
.length
-1;i
>=0;i
--){
458 _af
=[_ab
[i
].apply(this,_af
)];
462 },bind
:function(_b1
,_b2
){
463 if(typeof (_b1
)=="string"){
467 var _b4
=_b1
.im_preargs
;
470 if(typeof (_b1
)=="function"&&typeof (_b1
.apply
)=="undefined"){
471 _b1
=m
._wrapDumbFunction(_b1
);
473 if(typeof (_b3
)!="function"){
476 if(typeof (_b2
)!="undefined"){
479 if(typeof (_b4
)=="undefined"){
484 m
.extend(_b4
,arguments
,2);
487 var me
=arguments
.callee
;
488 if(me
.im_preargs
.length
>0){
489 _b8
=m
.concat(me
.im_preargs
,_b8
);
495 return me
.im_func
.apply(_ba
,_b8
);
501 },bindMethods
:function(_bb
){
502 var _bc
=MochiKit
.Base
.bind
;
505 if(typeof (_be
)=="function"){
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
){
515 var _c5
=(typeof (a
)=="undefined"||a
===null);
516 var _c6
=(typeof (b
)=="undefined"||b
===null);
529 var _c8
=m
._primitives
;
530 if(!(typeof (a
) in _c8
&&typeof (b
) in _c8
)){
532 return m
.comparatorRegistry
.match(a
,b
);
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
;
563 for(var i
=0;i
<_cf
;i
++){
564 var cmp
=_ce(a
[i
],b
[i
]);
570 },registerRepr
:function(_d3
,_d4
,_d5
,_d6
){
571 MochiKit
.Base
.reprRegistry
.register(_d3
,_d4
,_d5
,_d6
);
573 if(typeof (o
)=="undefined"){
581 if(typeof (o
.__repr__
)=="function"){
584 if(typeof (o
.repr
)=="function"&&o
.repr
!=arguments
.callee
){
588 return MochiKit
.Base
.reprRegistry
.match(o
);
591 if(typeof (o
.NAME
)=="string"&&(o
.toString
==Function
.prototype.toString
||o
.toString
==Object
.prototype.toString
)){
599 return "["+typeof (o
)+"]";
601 if(typeof (o
)=="function"){
602 o
=_d8
.replace(/^\s+/,"");
603 var idx
=o
.indexOf("{");
605 o
=o
.substr(0,idx
)+"{...}";
609 },reprArrayLike
:function(o
){
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
){
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
){
622 if(_e3
=="number"||_e3
=="boolean"){
630 var _e5
=m
.reprString
;
634 var me
=arguments
.callee
;
636 if(typeof (o
.__json__
)=="function"){
642 if(typeof (o
.json
)=="function"){
648 if(_e3
!="function"&&typeof (o
.length
)=="number"){
650 for(var i
=0;i
<o
.length
;i
++){
652 if(typeof (val
)!="string"){
657 return "["+res
.join(", ")+"]";
660 _e7
=m
.jsonRegistry
.match(o
);
670 if(_e3
=="undefined"){
671 throw new TypeError("undefined can not be serialized as JSON");
679 if(typeof (k
)=="number"){
682 if(typeof (k
)=="string"){
689 if(typeof (val
)!="string"){
692 res
.push(_ec
+":"+val
);
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
){
701 return (MochiKit
.Base
.compare(_ef
,arr
)===0);
704 var _f2
=MochiKit
.Base
.extend
;
705 for(var i
=0;i
<arguments
.length
;i
++){
706 _f2(_f1
,arguments
[i
]);
709 },keyComparator
:function(key
){
712 if(arguments
.length
==1){
713 return function(a
,b
){
714 return _f6(a
[key
],b
[key
]);
717 var _f9
=m
.extend(null,arguments
);
718 return function(a
,b
){
720 for(var i
=0;(_fc
===0)&&(i
<_f9
.length
);i
++){
722 _fc
=_f6(a
[key
],b
[key
]);
726 },reverseKeyComparator
:function(key
){
727 var _100
=MochiKit
.Base
.keyComparator
.apply(this,arguments
);
728 return function(a
,b
){
731 },partial
:function(func
){
733 return m
.bind
.apply(this,m
.extend([func
,undefined
],arguments
,1));
734 },listMinMax
:function(_105
,lst
){
739 var _108
=MochiKit
.Base
.compare
;
740 for(var i
=1;i
<lst
.length
;i
++){
742 if(_108(o
,cur
)==_105
){
748 return MochiKit
.Base
.listMinMax(1,arguments
);
750 return MochiKit
.Base
.listMinMax(-1,arguments
);
751 },findIdentical
:function(lst
,_10c
,_10d
,end
){
752 if(typeof (end
)=="undefined"||end
===null){
755 if(typeof (_10d
)=="undefined"||_10d
===null){
758 for(var i
=_10d
;i
<end
;i
++){
767 var args
=m
.extend(null,arguments
);
768 var _113
=args
.length
;
771 if(o
&&typeof (o
)=="object"&&typeof (o
.length
)=="number"){
773 for(var i
=o
.length
-1;i
>=0;i
--){
781 throw new TypeError("mean() requires at least one argument");
785 var data
=MochiKit
.Base
.flattenArguments(arguments
);
787 throw new TypeError("median() requires at least one argument");
790 if(data
.length
%2==0){
791 var _117
=data
.length
/2;
792 return (data
[_117
]+data
[_117
-1])/2;
794 return data
[(data
.length
-1)/2];
796 },findValue
:function(lst
,_119
,_11a
,end
){
797 if(typeof (end
)=="undefined"||end
===null){
800 if(typeof (_11a
)=="undefined"||_11a
===null){
803 var cmp
=MochiKit
.Base
.compare
;
804 for(var i
=_11a
;i
<end
;i
++){
805 if(cmp(lst
[i
],_119
)===0){
810 },nodeWalk
:function(node
,_11f
){
812 var _121
=MochiKit
.Base
.extend
;
814 var res
=_11f(_120
.shift());
819 },nameFunctions
:function(_123
){
821 if(typeof (base
)=="undefined"){
826 for(var name
in _123
){
828 if(typeof (o
)=="function"&&typeof (o
.NAME
)=="undefined"){
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
);
842 if(arguments
.length
==1){
843 if(typeof (_127
.length
)=="number"&&_127
.length
==2){
844 return arguments
.callee(_127
[0],_127
[1]);
851 if(typeof (v
)=="function"){
854 if(typeof (v
)!="string"&&typeof (v
.length
)=="number"){
855 for(var i
=0;i
<v
.length
;i
++){
868 var len
=Math
.min(_127
.length
,_128
.length
);
869 var _130
=MochiKit
.Base
.urlEncode
;
870 for(var i
=0;i
<len
;i
++){
872 if(typeof (v
)!="undefined"&&v
!==null){
873 rval
.push(_130(_127
[i
])+"="+_130(v
));
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(/(\&\;|\&\#38\;|\&|\&)/);
882 if(typeof (decodeURIComponent
)!="undefined"){
883 _136
=decodeURIComponent
;
888 for(var i
=0;i
<_134
.length
;i
++){
889 var pair
=_134
[i
].split("=");
890 var name
=_136(pair
.shift());
895 if(!(arr
instanceof Array
)){
899 arr
.push(_136(pair
.join("=")));
902 for(i
=0;i
<_134
.length
;i
++){
903 pair
=_134
[i
].split("=");
904 var name
=pair
.shift();
908 o
[_136(name
)]=_136(pair
.join("="));
913 MochiKit
.Base
.AdapterRegistry
=function(){
916 MochiKit
.Base
.AdapterRegistry
.prototype={register
:function(name
,_13c
,wrap
,_13e
){
918 this.pairs
.unshift([name
,_13c
,wrap
]);
920 this.pairs
.push([name
,_13c
,wrap
]);
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
);
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
];
934 this.pairs
.splice(i
,1);
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__
){
946 var all
=_145
.EXPORT_TAGS
[":all"];
947 for(var i
=0;i
<all
.length
;i
++){
948 _144
[all
[i
]]=_145
[all
[i
]];
951 MochiKit
.Base
.__new__
=function(){
953 m
.noop
=m
.operator
.identity
;
954 m
.forward
=m
.forwardCall
;
956 if(typeof (encodeURIComponent
)!="undefined"){
957 m
.urlEncode
=function(_149
){
958 return encodeURIComponent(_149
).replace(/\'/g,"%27");
961 m
.urlEncode
=function(_14a
){
962 return escape(_14a
).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval
.replace(/\'/g,"%27");
965 m
.NamedError
=function(name
){
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
)+")";
974 return this.name
+"()";
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);
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);
997 MochiKit
.Base
.__new__();
998 if(MochiKit
.__export__
){
999 compare
=MochiKit
.Base
.compare
;
1000 compose
=MochiKit
.Base
.compose
;
1001 serializeJSON
=MochiKit
.Base
.serializeJSON
;
1003 MochiKit
.Base
._exportSymbols(this,MochiKit
.Base
);
1004 if(typeof (dojo
)!="undefined"){
1005 dojo
.provide("MochiKit.Iter");
1006 dojo
.require("MochiKit.Base");
1008 if(typeof (JSAN
)!="undefined"){
1009 JSAN
.use("MochiKit.Base",[]);
1012 if(typeof (MochiKit
.Base
)=="undefined"){
1017 throw "MochiKit.Iter depends on MochiKit.Base!";
1019 if(typeof (MochiKit
.Iter
)=="undefined"){
1022 MochiKit
.Iter
.NAME
="MochiKit.Iter";
1023 MochiKit
.Iter
.VERSION
="1.4";
1024 MochiKit
.Base
.update(MochiKit
.Iter
,{__repr__
:function(){
1025 return "["+this.NAME
+" "+this.VERSION
+"]";
1026 },toString
:function(){
1027 return this.__repr__();
1028 },registerIteratorFactory
:function(name
,_14e
,_14f
,_150
){
1029 MochiKit
.Iter
.iteratorRegistry
.register(name
,_14e
,_14f
,_150
);
1030 },iter
:function(_151
,_152
){
1031 var self
=MochiKit
.Iter
;
1032 if(arguments
.length
==2){
1033 return self
.takewhile(function(a
){
1037 if(typeof (_151
.next
)=="function"){
1040 if(typeof (_151
.iter
)=="function"){
1045 return self
.iteratorRegistry
.match(_151
);
1048 var m
=MochiKit
.Base
;
1050 e
=new TypeError(typeof (_151
)+": "+m
.repr(_151
)+" is not iterable");
1054 },count
:function(n
){
1058 var m
=MochiKit
.Base
;
1059 return {repr
:function(){
1060 return "count("+n
+")";
1061 },toString
:m
.forwardCall("repr"),next
:m
.counter(n
)};
1062 },cycle
:function(p
){
1063 var self
=MochiKit
.Iter
;
1064 var m
=MochiKit
.Base
;
1066 var _15c
=self
.iter(p
);
1067 return {repr
:function(){
1068 return "cycle(...)";
1069 },toString
:m
.forwardCall("repr"),next
:function(){
1071 var rval
=_15c
.next();
1076 if(e
!=self
.StopIteration
){
1080 this.next
=function(){
1081 throw self
.StopIteration
;
1085 this.next
=function(){
1093 },repeat
:function(elem
,n
){
1094 var m
=MochiKit
.Base
;
1095 if(typeof (n
)=="undefined"){
1096 return {repr
:function(){
1097 return "repeat("+m
.repr(elem
)+")";
1098 },toString
:m
.forwardCall("repr"),next
:function(){
1102 return {repr
:function(){
1103 return "repeat("+m
.repr(elem
)+", "+n
+")";
1104 },toString
:m
.forwardCall("repr"),next
:function(){
1106 throw MochiKit
.Iter
.StopIteration
;
1111 },next
:function(_162
){
1113 },izip
:function(p
,q
){
1114 var m
=MochiKit
.Base
;
1115 var self
=MochiKit
.Iter
;
1117 var _168
=m
.map(self
.iter
,arguments
);
1118 return {repr
:function(){
1120 },toString
:m
.forwardCall("repr"),next
:function(){
1121 return m
.map(next
,_168
);
1123 },ifilter
:function(pred
,seq
){
1124 var m
=MochiKit
.Base
;
1125 seq
=MochiKit
.Iter
.iter(seq
);
1127 pred
=m
.operator
.truth
;
1129 return {repr
:function(){
1130 return "ifilter(...)";
1131 },toString
:m
.forwardCall("repr"),next
:function(){
1133 var rval
=seq
.next();
1140 },ifilterfalse
:function(pred
,seq
){
1141 var m
=MochiKit
.Base
;
1142 seq
=MochiKit
.Iter
.iter(seq
);
1144 pred
=m
.operator
.truth
;
1146 return {repr
:function(){
1147 return "ifilterfalse(...)";
1148 },toString
:m
.forwardCall("repr"),next
:function(){
1150 var rval
=seq
.next();
1157 },islice
:function(seq
){
1158 var self
=MochiKit
.Iter
;
1159 var m
=MochiKit
.Base
;
1165 if(arguments
.length
==2){
1168 if(arguments
.length
==3){
1177 return {repr
:function(){
1178 return "islice("+["...",_174
,stop
,step
].join(", ")+")";
1179 },toString
:m
.forwardCall("repr"),next
:function(){
1186 throw self
.StopIteration
;
1191 },imap
:function(fun
,p
,q
){
1192 var m
=MochiKit
.Base
;
1193 var self
=MochiKit
.Iter
;
1194 var _17e
=m
.map(self
.iter
,m
.extend(null,arguments
,1));
1197 return {repr
:function(){
1199 },toString
:m
.forwardCall("repr"),next
:function(){
1200 return fun
.apply(this,map(next
,_17e
));
1202 },applymap
:function(fun
,seq
,self
){
1203 seq
=MochiKit
.Iter
.iter(seq
);
1204 var m
=MochiKit
.Base
;
1205 return {repr
:function(){
1206 return "applymap(...)";
1207 },toString
:m
.forwardCall("repr"),next
:function(){
1208 return fun
.apply(self
,seq
.next());
1210 },chain
:function(p
,q
){
1211 var self
=MochiKit
.Iter
;
1212 var m
=MochiKit
.Base
;
1213 if(arguments
.length
==1){
1214 return self
.iter(arguments
[0]);
1216 var _189
=m
.map(self
.iter
,arguments
);
1217 return {repr
:function(){
1218 return "chain(...)";
1219 },toString
:m
.forwardCall("repr"),next
:function(){
1220 while(_189
.length
>1){
1222 return _189
[0].next();
1225 if(e
!=self
.StopIteration
){
1232 var arg
=_189
.shift();
1233 this.next
=m
.bind("next",arg
);
1236 throw self
.StopIteration
;
1238 },takewhile
:function(pred
,seq
){
1239 var self
=MochiKit
.Iter
;
1241 return {repr
:function(){
1242 return "takewhile(...)";
1243 },toString
:MochiKit
.Base
.forwardCall("repr"),next
:function(){
1244 var rval
=seq
.next();
1246 this.next
=function(){
1247 throw self
.StopIteration
;
1253 },dropwhile
:function(pred
,seq
){
1254 seq
=MochiKit
.Iter
.iter(seq
);
1255 var m
=MochiKit
.Base
;
1257 return {"repr":function(){
1258 return "dropwhile(...)";
1259 },"toString":m
.forwardCall("repr"),"next":function(){
1261 var rval
=seq
.next();
1266 this.next
=bind("next",seq
);
1269 },_tee
:function(_194
,sync
,_196
){
1271 var m
=MochiKit
.Base
;
1273 return {repr
:function(){
1274 return "tee("+_194
+", ...)";
1275 },toString
:m
.forwardCall("repr"),next
:function(){
1277 var i
=sync
.pos
[_194
];
1280 sync
.deque
.push(rval
);
1284 rval
=sync
.deque
[i
-sync
.min
];
1286 if(i
==sync
.min
&&_198(sync
.pos
)!=sync
.min
){
1293 },tee
:function(_19b
,n
){
1295 var sync
={"pos":[],"deque":[],"max":-1,"min":-1};
1296 if(arguments
.length
==1||typeof (n
)=="undefined"||n
===null){
1299 var self
=MochiKit
.Iter
;
1300 _19b
=self
.iter(_19b
);
1302 for(var i
=0;i
<n
;i
++){
1303 rval
.push(_tee(i
,sync
,_19b
));
1306 },list
:function(_1a2
){
1308 if(_1a2
instanceof Array
){
1309 return _1a2
.slice();
1311 if(typeof (_1a2
)=="function"&&!(_1a2
instanceof Function
)&&typeof (_1a2
.length
)=="number"){
1313 for(var i
=0;i
<_1a2
.length
;i
++){
1318 var self
=MochiKit
.Iter
;
1319 _1a2
=self
.iter(_1a2
);
1323 rval
.push(_1a2
.next());
1327 if(e
!=self
.StopIteration
){
1333 },reduce
:function(fn
,_1a7
,_1a8
){
1336 var self
=MochiKit
.Iter
;
1337 _1a7
=self
.iter(_1a7
);
1338 if(arguments
.length
<3){
1343 if(e
==self
.StopIteration
){
1344 e
=new TypeError("reduce() of empty sequence with no initial value");
1352 x
=fn(x
,_1a7
.next());
1356 if(e
!=self
.StopIteration
){
1365 if(arguments
.length
==1){
1368 if(arguments
.length
==2){
1372 if(arguments
.length
==3){
1377 throw new TypeError("range() takes 1, 2, or 3 arguments!");
1382 throw new TypeError("range() step must not be 0");
1384 return {next
:function(){
1385 if((step
>0&&_1ac
>=stop
)||(step
<0&&_1ac
<=stop
)){
1386 throw MochiKit
.Iter
.StopIteration
;
1392 return "range("+[_1ac
,stop
,step
].join(", ")+")";
1393 },toString
:MochiKit
.Base
.forwardCall("repr")};
1394 },sum
:function(_1b0
,_1b1
){
1395 if(typeof (_1b1
)=="undefined"||_1b1
===null){
1399 var self
=MochiKit
.Iter
;
1400 _1b0
=self
.iter(_1b0
);
1407 if(e
!=self
.StopIteration
){
1412 },exhaust
:function(_1b4
){
1413 var self
=MochiKit
.Iter
;
1414 _1b4
=self
.iter(_1b4
);
1421 if(e
!=self
.StopIteration
){
1425 },forEach
:function(_1b6
,func
,self
){
1426 var m
=MochiKit
.Base
;
1427 if(arguments
.length
>2){
1428 func
=m
.bind(func
,self
);
1430 if(m
.isArrayLike(_1b6
)){
1432 for(var i
=0;i
<_1b6
.length
;i
++){
1437 if(e
!=MochiKit
.Iter
.StopIteration
){
1443 self
.exhaust(self
.imap(func
,_1b6
));
1445 },every
:function(_1bb
,func
){
1446 var self
=MochiKit
.Iter
;
1448 self
.ifilterfalse(func
,_1bb
).next();
1452 if(e
!=self
.StopIteration
){
1457 },sorted
:function(_1be
,cmp
){
1458 var rval
=MochiKit
.Iter
.list(_1be
);
1459 if(arguments
.length
==1){
1460 cmp
=MochiKit
.Base
.compare
;
1464 },reversed
:function(_1c1
){
1465 var rval
=MochiKit
.Iter
.list(_1c1
);
1468 },some
:function(_1c3
,func
){
1469 var self
=MochiKit
.Iter
;
1471 self
.ifilter(func
,_1c3
).next();
1475 if(e
!=self
.StopIteration
){
1480 },iextend
:function(lst
,_1c7
){
1481 if(MochiKit
.Base
.isArrayLike(_1c7
)){
1482 for(var i
=0;i
<_1c7
.length
;i
++){
1486 var self
=MochiKit
.Iter
;
1487 _1c7
=self
.iter(_1c7
);
1490 lst
.push(_1c7
.next());
1494 if(e
!=self
.StopIteration
){
1500 },groupby
:function(_1ca
,_1cb
){
1501 var m
=MochiKit
.Base
;
1502 var self
=MochiKit
.Iter
;
1503 if(arguments
.length
<2){
1504 _1cb
=m
.operator
.identity
;
1506 _1ca
=self
.iter(_1ca
);
1521 return {repr
:function(){
1522 return "groupby(...)";
1524 while(_1d3(k
,pk
)===0){
1532 return [k
,{next
:function(){
1537 throw self
.StopIteration
;
1542 },groupby_as_array
:function(_1d4
,_1d5
){
1543 var m
=MochiKit
.Base
;
1544 var self
=MochiKit
.Iter
;
1545 if(arguments
.length
<2){
1546 _1d5
=m
.operator
.identity
;
1548 _1d4
=self
.iter(_1d4
);
1555 var _1dc
=_1d4
.next();
1559 if(e
==self
.StopIteration
){
1564 if(_1d9
||_1db(key
,_1da
)!==0){
1566 _1d8
.push([key
,_1de
]);
1573 },arrayLikeIter
:function(_1df
){
1575 return {repr
:function(){
1576 return "arrayLikeIter(...)";
1577 },toString
:MochiKit
.Base
.forwardCall("repr"),next
:function(){
1579 throw MochiKit
.Iter
.StopIteration
;
1583 },hasIterateNext
:function(_1e1
){
1584 return (_1e1
&&typeof (_1e1
.iterateNext
)=="function");
1585 },iterateNextIter
:function(_1e2
){
1586 return {repr
:function(){
1587 return "iterateNextIter(...)";
1588 },toString
:MochiKit
.Base
.forwardCall("repr"),next
:function(){
1589 var rval
=_1e2
.iterateNext();
1590 if(rval
===null||rval
===undefined
){
1591 throw MochiKit
.Iter
.StopIteration
;
1596 MochiKit
.Iter
.EXPORT_OK
=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",];
1597 MochiKit
.Iter
.EXPORT
=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"];
1598 MochiKit
.Iter
.__new__
=function(){
1599 var m
=MochiKit
.Base
;
1600 if(typeof (StopIteration
)!="undefined"){
1601 this.StopIteration
=StopIteration
;
1603 this.StopIteration
=new m
.NamedError("StopIteration");
1605 this.iteratorRegistry
=new m
.AdapterRegistry();
1606 this.registerIteratorFactory("arrayLike",m
.isArrayLike
,this.arrayLikeIter
);
1607 this.registerIteratorFactory("iterateNext",this.hasIterateNext
,this.iterateNextIter
);
1608 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
1609 m
.nameFunctions(this);
1611 MochiKit
.Iter
.__new__();
1612 if(MochiKit
.__export__
){
1613 reduce
=MochiKit
.Iter
.reduce
;
1615 MochiKit
.Base
._exportSymbols(this,MochiKit
.Iter
);
1616 if(typeof (dojo
)!="undefined"){
1617 dojo
.provide("MochiKit.Format");
1619 if(typeof (MochiKit
)=="undefined"){
1622 if(typeof (MochiKit
.Format
)=="undefined"){
1625 MochiKit
.Format
.NAME
="MochiKit.Format";
1626 MochiKit
.Format
.VERSION
="1.4";
1627 MochiKit
.Format
.__repr__
=function(){
1628 return "["+this.NAME
+" "+this.VERSION
+"]";
1630 MochiKit
.Format
.toString
=function(){
1631 return this.__repr__();
1633 MochiKit
.Format
._numberFormatter
=function(_1e5
,_1e6
,_1e7
,_1e8
,_1e9
,_1ea
,_1eb
,_1ec
,_1ed
){
1634 return function(num
){
1635 num
=parseFloat(num
);
1636 if(typeof (num
)=="undefined"||num
===null||isNaN(num
)){
1644 _1ef
=_1ef
.replace(/-/,"");
1646 var me
=arguments
.callee
;
1647 var fmt
=MochiKit
.Format
.formatLocale(_1e8
);
1650 _1f0
=fmt
.percent
+_1f0
;
1652 num
=MochiKit
.Format
.roundToFixed(num
,_1ea
);
1653 var _1f3
=num
.split(/\./);
1655 var frac
=(_1f3
.length
==1)?"":_1f3
[1];
1657 while(_1f4
.length
<_1eb
){
1661 while(_1f4
.length
>_1ec
){
1662 var i
=_1f4
.length
-_1ec
;
1663 res
=fmt
.separator
+_1f4
.substring(i
,_1f4
.length
)+res
;
1664 _1f4
=_1f4
.substring(0,i
);
1669 while(frac
.length
<_1ed
){
1672 res
=res
+fmt
.decimal+frac
;
1674 return _1ef
+res
+_1f0
;
1677 MochiKit
.Format
.numberFormatter
=function(_1f8
,_1f9
,_1fa
){
1678 if(typeof (_1f9
)=="undefined"){
1681 var _1fb
=_1f8
.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
1683 throw TypeError("Invalid pattern");
1685 var _1fc
=_1f8
.substr(0,_1fb
.index
);
1686 var _1fd
=_1f8
.substr(_1fb
.index
+_1fb
[0].length
);
1687 if(_1fc
.search(/-/)==-1){
1691 var frac
=(typeof (_1fb
[2])=="string"&&_1fb
[2]!="")?_1fb
[2]:"";
1692 var _200
=(typeof (_1fb
[3])=="string"&&_1fb
[3]!="");
1693 var tmp
=_1fe
.split(/,/);
1695 if(typeof (_1fa
)=="undefined"){
1703 var _203
=_1fe
.length
-_1fe
.replace(/0/g,"").length
;
1704 var _204
=frac
.length
-frac
.replace(/0/g,"").length
;
1705 var _205
=frac
.length
;
1706 var rval
=MochiKit
.Format
._numberFormatter(_1f9
,_1fc
,_1fd
,_1fa
,_200
,_205
,_203
,_202
,_204
);
1707 var m
=MochiKit
.Base
;
1709 var fn
=arguments
.callee
;
1710 var args
=m
.concat(arguments
);
1711 rval
.repr
=function(){
1712 return [self
.NAME
,"(",map(m
.repr
,args
).join(", "),")"].join("");
1717 MochiKit
.Format
.formatLocale
=function(_20a
){
1718 if(typeof (_20a
)=="undefined"||_20a
===null){
1721 if(typeof (_20a
)=="string"){
1722 var rval
=MochiKit
.Format
.LOCALE
[_20a
];
1723 if(typeof (rval
)=="string"){
1724 rval
=arguments
.callee(rval
);
1725 MochiKit
.Format
.LOCALE
[_20a
]=rval
;
1732 MochiKit
.Format
.twoDigitAverage
=function(_20c
,_20d
){
1736 return MochiKit
.Format
.twoDigitFloat(_20c
/_20d
);
1741 MochiKit
.Format
.twoDigitFloat
=function(_20f
){
1742 var sign
=(_20f
<0?"-":"");
1743 var s
=Math
.floor(Math
.abs(_20f
)*100).toString();
1748 while(s
.charAt(s
.length
-1)=="0"){
1749 s
=s
.substring(0,s
.length
-1);
1753 var head
=sign
+s
.substring(0,s
.length
-2);
1754 var tail
=s
.substring(s
.length
-2,s
.length
);
1758 if(tail
.charAt(1)=="0"){
1759 return head
+"."+tail
.charAt(0);
1761 return head
+"."+tail
;
1765 MochiKit
.Format
.lstrip
=function(str
,_215
){
1767 if(typeof (str
)!="string"){
1771 return str
.replace(/^\s+/,"");
1773 return str
.replace(new RegExp("^["+_215
+"]+"),"");
1776 MochiKit
.Format
.rstrip
=function(str
,_217
){
1778 if(typeof (str
)!="string"){
1782 return str
.replace(/\s+$/,"");
1784 return str
.replace(new RegExp("["+_217
+"]+$"),"");
1787 MochiKit
.Format
.strip
=function(str
,_219
){
1788 var self
=MochiKit
.Format
;
1789 return self
.rstrip(self
.lstrip(str
,_219
),_219
);
1791 MochiKit
.Format
.truncToFixed
=function(_21b
,_21c
){
1792 _21b
=Math
.floor(_21b
*Math
.pow(10,_21c
));
1793 var res
=(_21b
*Math
.pow(10,-_21c
)).toFixed(_21c
);
1794 if(res
.charAt(0)=="."){
1799 MochiKit
.Format
.roundToFixed
=function(_21e
,_21f
){
1800 return MochiKit
.Format
.truncToFixed(_21e
+0.5*Math
.pow(10,-_21f
),_21f
);
1802 MochiKit
.Format
.percentFormat
=function(_220
){
1803 return MochiKit
.Format
.twoDigitFloat(100*_220
)+"%";
1805 MochiKit
.Format
.EXPORT
=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
1806 MochiKit
.Format
.LOCALE
={en_US
:{separator
:",",decimal:".",percent
:"%"},de_DE
:{separator
:".",decimal:",",percent
:"%"},fr_FR
:{separator
:" ",decimal:",",percent
:"%"},"default":"en_US"};
1807 MochiKit
.Format
.EXPORT_OK
=[];
1808 MochiKit
.Format
.EXPORT_TAGS
={":all":MochiKit
.Format
.EXPORT
,":common":MochiKit
.Format
.EXPORT
};
1809 MochiKit
.Format
.__new__
=function(){
1810 var base
=this.NAME
+".";
1812 for(k
in this.LOCALE
){
1814 if(typeof (o
)=="object"){
1818 o
.NAME
=base
+"LOCALE."+k
;
1823 if(typeof (o
)=="function"&&typeof (o
.NAME
)=="undefined"){
1832 MochiKit
.Format
.__new__();
1833 if(typeof (MochiKit
.Base
)!="undefined"){
1834 MochiKit
.Base
._exportSymbols(this,MochiKit
.Format
);
1836 (function(_225
,_226
){
1837 if((typeof (JSAN
)=="undefined"&&typeof (dojo
)=="undefined")||(MochiKit
.__export__
===false)){
1838 var all
=_226
.EXPORT_TAGS
[":all"];
1839 for(var i
=0;i
<all
.length
;i
++){
1840 _225
[all
[i
]]=_226
[all
[i
]];
1843 })(this,MochiKit
.Format
);
1845 if(typeof (dojo
)!="undefined"){
1846 dojo
.provide("MochiKit.DOM");
1847 dojo
.require("MochiKit.Base");
1849 if(typeof (JSAN
)!="undefined"){
1850 JSAN
.use("MochiKit.Base",[]);
1853 if(typeof (MochiKit
.Base
)=="undefined"){
1858 throw "MochiKit.DOM depends on MochiKit.Base!";
1860 if(typeof (MochiKit
.DOM
)=="undefined"){
1863 MochiKit
.DOM
.NAME
="MochiKit.DOM";
1864 MochiKit
.DOM
.VERSION
="1.4";
1865 MochiKit
.DOM
.__repr__
=function(){
1866 return "["+this.NAME
+" "+this.VERSION
+"]";
1868 MochiKit
.DOM
.toString
=function(){
1869 return this.__repr__();
1871 MochiKit
.DOM
.EXPORT
=["removeEmptyTextNodes","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","isChildNode","getNodeAttribute","removeNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","insertSiblingNodesAfter","insertSiblingNodesBefore","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","scrapeText","isParent","getFirstParentByTagAndClassName","makeClipping","undoClipping","makePositioned","undoPositioned","getFirstElementByTagAndClassName"];
1872 MochiKit
.DOM
.EXPORT_OK
=["domConverters"];
1873 MochiKit
.DOM
.DEPRECATED
=[["computedStyle","MochiKit.Style.getStyle","1.4"],["elementDimensions","MochiKit.Style.getElementDimensions","1.4"],["elementPosition","MochiKit.Style.getElementPosition","1.4"],["hideElement","MochiKit.Style.hideElement","1.4"],["setElementDimensions","MochiKit.Style.setElementDimensions","1.4"],["setElementPosition","MochiKit.Style.setElementPosition","1.4"],["setDisplayForElement","MochiKit.Style.setDisplayForElement","1.4"],["setOpacity","MochiKit.Style.setOpacity","1.4"],["showElement","MochiKit.Style.showElement","1.4"],["Coordinates","MochiKit.Style.Coordinates","1.4"],["Dimensions","MochiKit.Style.Dimensions","1.4"]];
1874 MochiKit
.DOM
.getViewportDimensions
=new Function(""+"if (!MochiKit[\"Style\"]) {"+" throw new Error(\"This function has been deprecated and depends on MochiKit.Style.\");"+"}"+"return MochiKit.Style.getViewportDimensions.apply(this, arguments);");
1875 MochiKit
.Base
.update(MochiKit
.DOM
,{currentWindow
:function(){
1876 return MochiKit
.DOM
._window
;
1877 },currentDocument
:function(){
1878 return MochiKit
.DOM
._document
;
1879 },withWindow
:function(win
,func
){
1880 var self
=MochiKit
.DOM
;
1881 var _22c
=self
._document
;
1882 var _22d
=self
._window
;
1886 self
._document
=win
.document
;
1891 self
._document
=_22c
;
1895 self
._document
=_22c
;
1897 },formContents
:function(elem
){
1900 var m
=MochiKit
.Base
;
1901 var self
=MochiKit
.DOM
;
1902 if(typeof (elem
)=="undefined"||elem
===null){
1903 elem
=self
._document
.body
;
1905 elem
=self
.getElement(elem
);
1907 m
.nodeWalk(elem
,function(elem
){
1909 if(m
.isNotEmpty(name
)){
1910 var _236
=elem
.tagName
.toUpperCase();
1911 if(_236
==="INPUT"&&(elem
.type
=="radio"||elem
.type
=="checkbox")&&!elem
.checked
){
1914 if(_236
==="SELECT"){
1915 if(elem
.type
=="select-one"){
1916 if(elem
.selectedIndex
>=0){
1917 var opt
=elem
.options
[elem
.selectedIndex
];
1920 var h
=opt
.outerHTML
;
1921 if(h
&&!h
.match(/^[^>]+\svalue\s*=/i)){
1933 var opts
=elem
.options
;
1939 for(var i
=0;i
<opts
.length
;i
++){
1946 var h
=opt
.outerHTML
;
1947 if(h
&&!h
.match(/^[^>]+\svalue\s*=/i)){
1957 if(_236
==="FORM"||_236
==="P"||_236
==="SPAN"||_236
==="DIV"){
1958 return elem
.childNodes
;
1961 _231
.push(elem
.value
||"");
1964 return elem
.childNodes
;
1967 },withDocument
:function(doc
,func
){
1968 var self
=MochiKit
.DOM
;
1969 var _23f
=self
._document
;
1976 self
._document
=_23f
;
1979 self
._document
=_23f
;
1981 },registerDOMConverter
:function(name
,_242
,wrap
,_244
){
1982 MochiKit
.DOM
.domConverters
.register(name
,_242
,wrap
,_244
);
1983 },coerceToDOM
:function(node
,ctx
){
1984 var m
=MochiKit
.Base
;
1985 var im
=MochiKit
.Iter
;
1986 var self
=MochiKit
.DOM
;
1992 var _24d
=self
.domConverters
;
1993 var _24e
=arguments
.callee
;
1994 var _24f
=m
.NotFound
;
1996 if(typeof (node
)=="undefined"||node
===null){
1999 if(typeof (node
)=="function"&&typeof (node
.length
)=="number"&&!(node
instanceof Function
)){
2002 if(typeof (node
.nodeType
)!="undefined"&&node
.nodeType
>0){
2005 if(typeof (node
)=="number"||typeof (node
)=="boolean"){
2006 node
=node
.toString();
2008 if(typeof (node
)=="string"){
2009 return self
._document
.createTextNode(node
);
2011 if(typeof (node
.__dom__
)=="function"){
2012 node
=node
.__dom__(ctx
);
2015 if(typeof (node
.dom
)=="function"){
2019 if(typeof (node
)=="function"){
2020 node
=node
.apply(ctx
,[ctx
]);
2031 return map(_24e
,_250
,_24b(ctx
));
2035 node
=_24d
.match(node
,ctx
);
2043 return self
._document
.createTextNode(node
.toString());
2046 },isChildNode
:function(node
,_252
){
2047 var self
=MochiKit
.DOM
;
2048 if(typeof (node
)=="string"){
2049 node
=self
.getElement(node
);
2051 if(typeof (_252
)=="string"){
2052 _252
=self
.getElement(_252
);
2057 while(node
&&node
.tagName
.toUpperCase()!="BODY"){
2058 node
=node
.parentNode
;
2064 },setNodeAttribute
:function(node
,attr
,_256
){
2068 return MochiKit
.DOM
.updateNodeAttributes(node
,o
);
2073 },getNodeAttribute
:function(node
,attr
){
2074 var self
=MochiKit
.DOM
;
2075 var _25b
=self
.attributeArray
.renames
[attr
];
2076 node
=self
.getElement(node
);
2081 return node
.getAttribute(attr
);
2086 },removeNodeAttribute
:function(node
,attr
){
2087 var self
=MochiKit
.DOM
;
2088 var _25f
=self
.attributeArray
.renames
[attr
];
2089 node
=self
.getElement(node
);
2094 return node
.removeAttribute(attr
);
2099 },updateNodeAttributes
:function(node
,_261
){
2101 var self
=MochiKit
.DOM
;
2102 if(typeof (node
)=="string"){
2103 elem
=self
.getElement(node
);
2106 var _264
=MochiKit
.Base
.updatetree
;
2107 if(self
.attributeArray
.compliant
){
2110 if(typeof (v
)=="object"&&typeof (elem
[k
])=="object"){
2111 if(k
=="style"&&MochiKit
.Style
){
2112 MochiKit
.Style
.setStyle(elem
,v
);
2117 if(k
.substring(0,2)=="on"){
2118 if(typeof (v
)=="string"){
2123 elem
.setAttribute(k
,v
);
2128 var _267
=self
.attributeArray
.renames
;
2132 if(k
=="style"&&typeof (v
)=="string"){
2133 elem
.style
.cssText
=v
;
2135 if(typeof (_268
)=="string"){
2138 if(typeof (elem
[k
])=="object"&&typeof (v
)=="object"){
2139 if(k
=="style"&&MochiKit
.Style
){
2140 MochiKit
.Style
.setStyle(elem
,v
);
2145 if(k
.substring(0,2)=="on"){
2146 if(typeof (v
)=="string"){
2151 elem
.setAttribute(k
,v
);
2160 },appendChildNodes
:function(node
){
2162 var self
=MochiKit
.DOM
;
2163 if(typeof (node
)=="string"){
2164 elem
=self
.getElement(node
);
2166 var _26c
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
2167 var _26d
=MochiKit
.Base
.concat
;
2170 if(typeof (n
)=="undefined"||n
===null){
2172 if(typeof (n
.nodeType
)=="number"){
2173 elem
.appendChild(n
);
2180 },insertSiblingNodesBefore
:function(node
){
2182 var self
=MochiKit
.DOM
;
2183 if(typeof (node
)=="string"){
2184 elem
=self
.getElement(node
);
2186 var _272
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
2187 var _273
=elem
.parentNode
;
2188 var _274
=MochiKit
.Base
.concat
;
2191 if(typeof (n
)=="undefined"||n
===null){
2193 if(typeof (n
.nodeType
)=="number"){
2194 _273
.insertBefore(n
,elem
);
2201 },insertSiblingNodesAfter
:function(node
){
2203 var self
=MochiKit
.DOM
;
2204 if(typeof (node
)=="string"){
2205 elem
=self
.getElement(node
);
2207 var _279
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
2208 if(elem
.nextSibling
){
2209 return self
.insertSiblingNodesBefore(elem
.nextSibling
,_279
);
2211 return self
.appendChildNodes(elem
.parentNode
,_279
);
2213 },replaceChildNodes
:function(node
){
2215 var self
=MochiKit
.DOM
;
2216 if(typeof (node
)=="string"){
2217 elem
=self
.getElement(node
);
2221 while((_27d
=elem
.firstChild
)){
2222 elem
.removeChild(_27d
);
2224 if(arguments
.length
<2){
2227 return self
.appendChildNodes
.apply(this,arguments
);
2229 },createDOM
:function(name
,_27f
){
2231 var self
=MochiKit
.DOM
;
2232 var m
=MochiKit
.Base
;
2233 if(typeof (_27f
)=="string"||typeof (_27f
)=="number"){
2234 var args
=m
.extend([name
,null],arguments
,1);
2235 return arguments
.callee
.apply(this,args
);
2237 if(typeof (name
)=="string"){
2238 var _284
=self
._xhtml
;
2239 if(_27f
&&!self
.attributeArray
.compliant
){
2242 _285
+=" name=\""+self
.escapeHTML(_27f
.name
)+"\"";
2244 if(name
=="input"&&"type" in _27f
){
2245 _285
+=" type=\""+self
.escapeHTML(_27f
.type
)+"\"";
2248 name
="<"+name
+_285
+">";
2252 var d
=self
._document
;
2253 if(_284
&&d
===document
){
2254 elem
=d
.createElementNS("http://www.w3.org/1999/xhtml",name
);
2256 elem
=d
.createElement(name
);
2262 self
.updateNodeAttributes(elem
,_27f
);
2264 if(arguments
.length
<=2){
2267 var args
=m
.extend([elem
],arguments
,2);
2268 return self
.appendChildNodes
.apply(this,args
);
2270 },createDOMFunc
:function(){
2271 var m
=MochiKit
.Base
;
2272 return m
.partial
.apply(this,m
.extend([MochiKit
.DOM
.createDOM
],arguments
));
2273 },removeElement
:function(elem
){
2274 var e
=MochiKit
.DOM
.getElement(elem
);
2275 e
.parentNode
.removeChild(e
);
2277 },swapDOM
:function(dest
,src
){
2278 var self
=MochiKit
.DOM
;
2279 dest
=self
.getElement(dest
);
2280 var _28d
=dest
.parentNode
;
2282 src
=self
.getElement(src
);
2283 _28d
.replaceChild(src
,dest
);
2285 _28d
.removeChild(dest
);
2288 },getElement
:function(id
){
2289 var self
=MochiKit
.DOM
;
2290 if(arguments
.length
==1){
2291 return ((typeof (id
)=="string")?self
._document
.getElementById(id
):id
);
2293 return MochiKit
.Base
.map(self
.getElement
,arguments
);
2295 },getElementsByTagAndClassName
:function(_290
,_291
,_292
){
2296 var self
=MochiKit
.DOM
;
2297 if(typeof (_290
)=="undefined"||_290
===null){
2300 if(typeof (_292
)=="undefined"||_292
===null){
2301 _292
=self
._document
;
2303 _292
=self
.getElement(_292
);
2304 var _294
=(_292
.getElementsByTagName(_290
)||self
._document
.all
);
2305 if(typeof (_291
)=="undefined"||_291
===null){
2306 return MochiKit
.Base
.extend(null,_294
);
2309 for(var i
=0;i
<_294
.length
;i
++){
2311 var cls
=_297
.className
;
2315 var _299
=cls
.split(" ");
2316 for(var j
=0;j
<_299
.length
;j
++){
2324 },_newCallStack
:function(path
,once
){
2325 var rval
=function(){
2326 var _29e
=arguments
.callee
.callStack
;
2327 for(var i
=0;i
<_29e
.length
;i
++){
2328 if(_29e
[i
].apply(this,arguments
)===false){
2342 },addToCallStack
:function(_2a0
,path
,func
,once
){
2343 var self
=MochiKit
.DOM
;
2344 var _2a5
=_2a0
[path
];
2346 if(!(typeof (_2a5
)=="function"&&typeof (_2a5
.callStack
)=="object"&&_2a5
.callStack
!==null)){
2347 _2a6
=self
._newCallStack(path
,once
);
2348 if(typeof (_2a5
)=="function"){
2349 _2a6
.callStack
.push(_2a5
);
2353 _2a6
.callStack
.push(func
);
2354 },addLoadEvent
:function(func
){
2355 var self
=MochiKit
.DOM
;
2356 self
.addToCallStack(self
._window
,"onload",func
,true);
2357 },focusOnLoad
:function(_2a9
){
2358 var self
=MochiKit
.DOM
;
2359 self
.addLoadEvent(function(){
2360 _2a9
=self
.getElement(_2a9
);
2365 },setElementClass
:function(_2ab
,_2ac
){
2366 var self
=MochiKit
.DOM
;
2367 var obj
=self
.getElement(_2ab
);
2368 if(self
.attributeArray
.compliant
){
2369 obj
.setAttribute("class",_2ac
);
2371 obj
.setAttribute("className",_2ac
);
2373 },toggleElementClass
:function(_2af
){
2374 var self
=MochiKit
.DOM
;
2375 for(var i
=1;i
<arguments
.length
;i
++){
2376 var obj
=self
.getElement(arguments
[i
]);
2377 if(!self
.addElementClass(obj
,_2af
)){
2378 self
.removeElementClass(obj
,_2af
);
2381 },addElementClass
:function(_2b3
,_2b4
){
2382 var self
=MochiKit
.DOM
;
2383 var obj
=self
.getElement(_2b3
);
2384 var cls
=obj
.className
;
2385 if(cls
==undefined
||cls
.length
===0){
2386 self
.setElementClass(obj
,_2b4
);
2392 var _2b8
=cls
.split(" ");
2393 for(var i
=0;i
<_2b8
.length
;i
++){
2398 self
.setElementClass(obj
,cls
+" "+_2b4
);
2400 },removeElementClass
:function(_2ba
,_2bb
){
2401 var self
=MochiKit
.DOM
;
2402 var obj
=self
.getElement(_2ba
);
2403 var cls
=obj
.className
;
2404 if(cls
==undefined
||cls
.length
===0){
2408 self
.setElementClass(obj
,"");
2411 var _2bf
=cls
.split(" ");
2412 for(var i
=0;i
<_2bf
.length
;i
++){
2415 self
.setElementClass(obj
,_2bf
.join(" "));
2420 },swapElementClass
:function(_2c1
,_2c2
,_2c3
){
2421 var obj
=MochiKit
.DOM
.getElement(_2c1
);
2422 var res
=MochiKit
.DOM
.removeElementClass(obj
,_2c2
);
2424 MochiKit
.DOM
.addElementClass(obj
,_2c3
);
2427 },hasElementClass
:function(_2c6
,_2c7
){
2428 var obj
=MochiKit
.DOM
.getElement(_2c6
);
2429 var cls
=obj
.className
;
2433 var _2ca
=cls
.split(" ");
2434 for(var i
=1;i
<arguments
.length
;i
++){
2436 for(var j
=0;j
<_2ca
.length
;j
++){
2437 if(_2ca
[j
]==arguments
[i
]){
2447 },escapeHTML
:function(s
){
2448 return s
.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">");
2449 },toHTML
:function(dom
){
2450 return MochiKit
.DOM
.emitHTML(dom
).join("");
2451 },emitHTML
:function(dom
,lst
){
2452 if(typeof (lst
)=="undefined"||lst
===null){
2456 var self
=MochiKit
.DOM
;
2457 var _2d4
=self
.escapeHTML
;
2458 var _2d5
=self
.attributeArray
;
2461 if(typeof (dom
)=="string"){
2464 if(dom
.nodeType
==1){
2465 lst
.push("<"+dom
.tagName
.toLowerCase());
2468 for(var i
=0;i
<_2d7
.length
;i
++){
2470 _2d6
.push([" ",a
.name
,"=\"",_2d4(a
.value
),"\""]);
2473 for(i
=0;i
<_2d6
.length
;i
++){
2475 for(var j
=0;j
<_2da
.length
;j
++){
2479 if(dom
.hasChildNodes()){
2481 _2d2
.push("</"+dom
.tagName
.toLowerCase()+">");
2482 var _2dc
=dom
.childNodes
;
2483 for(i
=_2dc
.length
-1;i
>=0;i
--){
2490 if(dom
.nodeType
==3){
2491 lst
.push(_2d4(dom
.nodeValue
));
2497 },scrapeText
:function(node
,_2de
){
2500 var cn
=node
.childNodes
;
2502 for(var i
=0;i
<cn
.length
;i
++){
2503 arguments
.callee
.call(this,cn
[i
]);
2506 var _2e3
=node
.nodeValue
;
2507 if(typeof (_2e3
)=="string"){
2510 })(MochiKit
.DOM
.getElement(node
));
2514 return rval
.join("");
2516 },removeEmptyTextNodes
:function(_2e4
){
2517 _2e4
=MochiKit
.DOM
.getElement(_2e4
);
2518 for(var i
=0;i
<_2e4
.childNodes
.length
;i
++){
2519 var node
=_2e4
.childNodes
[i
];
2520 if(node
.nodeType
==3&&!/\S/.test(node
.nodeValue
)){
2521 node
.parentNode
.removeChild(node
);
2524 },makeClipping
:function(_2e7
){
2525 _2e7
=MochiKit
.DOM
.getElement(_2e7
);
2526 var _2e8
=_2e7
.style
.overflow
;
2527 if((MochiKit
.Style
.getStyle(_2e7
,"overflow")||"visible")!="hidden"){
2528 _2e7
.style
.overflow
="hidden";
2531 },undoClipping
:function(_2e9
,_2ea
){
2532 _2e9
=MochiKit
.DOM
.getElement(_2e9
);
2536 _2e9
.style
.overflow
=_2ea
;
2537 },makePositioned
:function(_2eb
){
2538 _2eb
=MochiKit
.DOM
.getElement(_2eb
);
2539 var pos
=MochiKit
.Style
.getStyle(_2eb
,"position");
2540 if(pos
=="static"||!pos
){
2541 _2eb
.style
.position
="relative";
2542 if(/Opera/.test(navigator
.userAgent
)){
2547 },undoPositioned
:function(_2ed
){
2548 _2ed
=MochiKit
.DOM
.getElement(_2ed
);
2549 if(_2ed
.style
.position
=="relative"){
2550 _2ed
.style
.position
=_2ed
.style
.top
=_2ed
.style
.left
=_2ed
.style
.bottom
=_2ed
.style
.right
="";
2552 },getFirstElementByTagAndClassName
:function(_2ee
,_2ef
,_2f0
){
2553 var self
=MochiKit
.DOM
;
2554 if(typeof (_2ee
)=="undefined"||_2ee
===null){
2557 if(typeof (_2f0
)=="undefined"||_2f0
===null){
2558 _2f0
=self
._document
;
2560 _2f0
=self
.getElement(_2f0
);
2561 var _2f2
=(_2f0
.getElementsByTagName(_2ee
)||self
._document
.all
);
2562 if(typeof (_2ef
)=="undefined"||_2ef
===null){
2565 for(var i
=0;i
<_2f2
.length
;i
++){
2567 var _2f5
=_2f4
.className
.split(" ");
2568 for(var j
=0;j
<_2f5
.length
;j
++){
2574 },getFirstParentByTagAndClassName
:function(elem
,_2f8
,_2f9
){
2575 var self
=MochiKit
.DOM
;
2576 elem
=self
.getElement(elem
);
2577 if(typeof (_2f8
)=="undefined"||_2f8
===null){
2580 _2f8
=_2f8
.toUpperCase();
2582 if(typeof (_2f9
)=="undefined"||_2f9
===null){
2587 while(elem
&&elem
.tagName
){
2588 elem
=elem
.parentNode
;
2589 if(_2f8
=="*"&&_2f9
===null){
2592 _2fb
=elem
.className
.split(" ");
2593 _2fc
=elem
.tagName
.toUpperCase();
2594 if(_2f9
===null&&_2f8
==_2fc
){
2598 for(var i
=0;i
<_2fb
.length
;i
++){
2599 if(_2f8
=="*"&&_2fb
[i
]==_2f9
){
2602 if(_2f8
==_2fc
&&_2fb
[i
]==_2f9
){
2611 },isParent
:function(_2fe
,_2ff
){
2612 if(!_2fe
.parentNode
||_2fe
==_2ff
){
2615 if(_2fe
.parentNode
==_2ff
){
2618 return MochiKit
.DOM
.isParent(_2fe
.parentNode
,_2ff
);
2619 },__new__
:function(win
){
2620 var m
=MochiKit
.Base
;
2621 if(typeof (document
)!="undefined"){
2622 this._document
=document
;
2623 var _302
="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
2624 this._xhtml
=(document
.documentElement
&&document
.createElementNS
&&document
.documentElement
.namespaceURI
===_302
);
2626 if(MochiKit
.MockDOM
){
2627 this._document
=MochiKit
.MockDOM
.document
;
2631 this.domConverters
=new m
.AdapterRegistry();
2632 var _303
=this._document
.createElement("span");
2634 if(_303
&&_303
.attributes
&&_303
.attributes
.length
>0){
2636 _304
=function(node
){
2637 return _305(_304
.ignoreAttrFilter
,node
.attributes
);
2640 var _307
=_303
.attributes
;
2641 var _308
=_304
.ignoreAttr
;
2642 for(var i
=0;i
<_307
.length
;i
++){
2644 _308
[a
.name
]=a
.value
;
2646 _304
.ignoreAttrFilter
=function(a
){
2647 return (_304
.ignoreAttr
[a
.name
]!=a
.value
);
2649 _304
.compliant
=false;
2650 _304
.renames
={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor","cellspacing":"cellSpacing","cellpadding":"cellPadding"};
2652 _304
=function(node
){
2653 return node
.attributes
;
2655 _304
.compliant
=true;
2658 this.attributeArray
=_304
;
2659 var _30d
=function(_30e
,arr
){
2660 var _310
=arr
[1].split(".");
2663 str
+="if (!MochiKit."+_310
[1]+") { throw new Error(\"";
2664 str
+="This function has been deprecated and depends on MochiKit.";
2665 str
+=_310
[1]+".\");}";
2666 str
+="return MochiKit."+_310
[1]+"."+arr
[0];
2667 str
+=".apply(this, arguments);";
2668 obj
[_310
[2]]=new Function(str
);
2669 MochiKit
.Base
.update(MochiKit
[_30e
],obj
);
2671 for(var i
;i
<MochiKit
.DOM
.DEPRECATED
.length
;i
++){
2672 _30d("DOM",MochiKit
.DOM
.DEPRECATED
[i
]);
2674 var _313
=this.createDOMFunc
;
2680 this.TBODY
=_313("tbody");
2681 this.THEAD
=_313("thead");
2682 this.TFOOT
=_313("tfoot");
2683 this.TABLE
=_313("table");
2685 this.INPUT
=_313("input");
2686 this.SPAN
=_313("span");
2688 this.DIV
=_313("div");
2689 this.IMG
=_313("img");
2690 this.BUTTON
=_313("button");
2692 this.PRE
=_313("pre");
2698 this.LABEL
=_313("label");
2699 this.TEXTAREA
=_313("textarea");
2700 this.FORM
=_313("form");
2702 this.SELECT
=_313("select");
2703 this.OPTION
=_313("option");
2704 this.OPTGROUP
=_313("optgroup");
2705 this.LEGEND
=_313("legend");
2706 this.FIELDSET
=_313("fieldset");
2707 this.STRONG
=_313("strong");
2708 this.CANVAS
=_313("canvas");
2709 this.$=this.getElement
;
2710 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
2711 m
.nameFunctions(this);
2713 MochiKit
.DOM
.__new__(((typeof (window
)=="undefined")?this:window
));
2714 if(MochiKit
.__export__
){
2715 withWindow
=MochiKit
.DOM
.withWindow
;
2716 withDocument
=MochiKit
.DOM
.withDocument
;
2718 MochiKit
.Base
._exportSymbols(this,MochiKit
.DOM
);
2719 if(typeof (dojo
)!="undefined"){
2720 dojo
.provide("MochiKit.Style");
2721 dojo
.require("MochiKit.Base");
2722 dojo
.require("MochiKit.DOM");
2724 if(typeof (JSAN
)!="undefined"){
2725 JSAN
.use("MochiKit.Base",[]);
2726 JSAN
.use("MochiKit.DOM",[]);
2729 if(typeof (MochiKit
.Base
)=="undefined"){
2734 throw "MochiKit.Style depends on MochiKit.Base!";
2737 if(typeof (MochiKit
.DOM
)=="undefined"){
2742 throw "MochiKit.Style depends on MochiKit.DOM!";
2744 if(typeof (MochiKit
.Style
)=="undefined"){
2747 MochiKit
.Style
.NAME
="MochiKit.Style";
2748 MochiKit
.Style
.VERSION
="1.4";
2749 MochiKit
.Style
.__repr__
=function(){
2750 return "["+this.NAME
+" "+this.VERSION
+"]";
2752 MochiKit
.Style
.toString
=function(){
2753 return this.__repr__();
2755 MochiKit
.Style
.EXPORT_OK
=[];
2756 MochiKit
.Style
.EXPORT
=["setStyle","setOpacity","getStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
2757 MochiKit
.Style
.Dimensions
=function(w
,h
){
2761 MochiKit
.Style
.Dimensions
.prototype.__repr__
=function(){
2762 var repr
=MochiKit
.Base
.repr
;
2763 return "{w: "+repr(this.w
)+", h: "+repr(this.h
)+"}";
2765 MochiKit
.Style
.Dimensions
.prototype.toString
=function(){
2766 return this.__repr__();
2768 MochiKit
.Style
.Coordinates
=function(x
,y
){
2772 MochiKit
.Style
.Coordinates
.prototype.__repr__
=function(){
2773 var repr
=MochiKit
.Base
.repr
;
2774 return "{x: "+repr(this.x
)+", y: "+repr(this.y
)+"}";
2776 MochiKit
.Style
.Coordinates
.prototype.toString
=function(){
2777 return this.__repr__();
2779 MochiKit
.Base
.update(MochiKit
.Style
,{getStyle
:function(elem
,_31b
){
2780 var dom
=MochiKit
.DOM
;
2781 var d
=dom
._document
;
2782 elem
=dom
.getElement(elem
);
2783 _31b
=MochiKit
.Base
.camelize(_31b
);
2787 if(_31b
=="opacity"&&elem
.filters
){
2788 var _31e
=(MochiKit
.Style
.getStyle(elem
,"filter")||"").match(/alpha\(opacity=(.*)\)/);
2790 return parseFloat(_31e
[1])/100;
2794 var _31f
=elem
.style
?elem
.style
[_31b
]:null;
2796 if(d
.defaultView
&&d
.defaultView
.getComputedStyle
){
2797 var css
=d
.defaultView
.getComputedStyle(elem
,null);
2798 _31b
=_31b
.replace(/([A-Z])/g,"-$1").toLowerCase();
2799 _31f
=css
?css
.getPropertyValue(_31b
):null;
2801 if(elem
.currentStyle
){
2802 _31f
=elem
.currentStyle
[_31b
];
2806 if(_31b
=="opacity"){
2807 _31f
=parseFloat(_31f
);
2809 if(/Opera/.test(navigator
.userAgent
)&&(MochiKit
.Base
.find(["left","top","right","bottom"],_31b
)!=-1)){
2810 if(MochiKit
.Style
.getStyle(elem
,"position")=="static"){
2814 return _31f
=="auto"?null:_31f
;
2815 },setStyle
:function(elem
,_322
){
2816 elem
=MochiKit
.DOM
.getElement(elem
);
2817 for(var name
in _322
){
2818 if(name
=="opacity"){
2819 MochiKit
.Style
.setOpacity(elem
,_322
[name
]);
2821 elem
.style
[MochiKit
.Base
.camelize(name
)]=_322
[name
];
2824 },setOpacity
:function(elem
,o
){
2825 elem
=MochiKit
.DOM
.getElement(elem
);
2826 var self
=MochiKit
.Style
;
2828 var _327
=/Gecko/.test(navigator
.userAgent
)&&!(/Konqueror|AppleWebKit|KHTML/.test(navigator
.userAgent
));
2829 elem
.style
["opacity"]=_327
?0.999999:1;
2830 if(/MSIE/.test(navigator
.userAgent
)){
2831 elem
.style
["filter"]=self
.getStyle(elem
,"filter").replace(/alpha\([^\)]*\)/gi,"");
2837 elem
.style
["opacity"]=o
;
2838 if(/MSIE/.test(navigator
.userAgent
)){
2839 elem
.style
["filter"]=self
.getStyle(elem
,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o
*100+")";
2842 },getElementPosition
:function(elem
,_329
){
2843 var self
=MochiKit
.Style
;
2844 var dom
=MochiKit
.DOM
;
2845 elem
=dom
.getElement(elem
);
2846 if(!elem
||(!(elem
.x
&&elem
.y
)&&(!elem
.parentNode
===null||self
.getStyle(elem
,"display")=="none"))){
2849 var c
=new self
.Coordinates(0,0);
2852 var d
=MochiKit
.DOM
._document
;
2853 var de
=d
.documentElement
;
2855 if(!elem
.parentNode
&&elem
.x
&&elem
.y
){
2859 if(elem
.getBoundingClientRect
){
2860 box
=elem
.getBoundingClientRect();
2861 c
.x
+=box
.left
+(de
.scrollLeft
||b
.scrollLeft
)-(de
.clientLeft
||0);
2862 c
.y
+=box
.top
+(de
.scrollTop
||b
.scrollTop
)-(de
.clientTop
||0);
2864 if(elem
.offsetParent
){
2865 c
.x
+=elem
.offsetLeft
;
2866 c
.y
+=elem
.offsetTop
;
2867 _32e
=elem
.offsetParent
;
2870 c
.x
+=_32e
.offsetLeft
;
2871 c
.y
+=_32e
.offsetTop
;
2872 _32e
=_32e
.offsetParent
;
2875 var ua
=navigator
.userAgent
.toLowerCase();
2876 if((typeof (opera
)!="undefined"&&parseFloat(opera
.version())<9)||(ua
.indexOf("AppleWebKit")!=-1&&self
.getStyle(elem
,"position")=="absolute")){
2883 if(typeof (_329
)!="undefined"){
2884 _329
=arguments
.callee(_329
);
2890 if(elem
.parentNode
){
2891 _32e
=elem
.parentNode
;
2896 var _333
=_32e
.tagName
.toUpperCase();
2897 if(_333
==="BODY"||_333
==="HTML"){
2900 var disp
=self
.getStyle(_32e
,"display");
2901 if(disp
!="inline"&&disp
!="table-row"){
2902 c
.x
-=_32e
.scrollLeft
;
2903 c
.y
-=_32e
.scrollTop
;
2905 if(_32e
.parentNode
){
2906 _32e
=_32e
.parentNode
;
2912 },setElementPosition
:function(elem
,_336
,_337
){
2913 elem
=MochiKit
.DOM
.getElement(elem
);
2914 if(typeof (_337
)=="undefined"){
2918 var _339
=MochiKit
.Base
.isUndefinedOrNull
;
2920 _338
["left"]=_336
.x
+_337
;
2923 _338
["top"]=_336
.y
+_337
;
2925 MochiKit
.DOM
.updateNodeAttributes(elem
,{"style":_338
});
2926 },getElementDimensions
:function(elem
){
2927 var self
=MochiKit
.Style
;
2928 var dom
=MochiKit
.DOM
;
2929 if(typeof (elem
.w
)=="number"||typeof (elem
.h
)=="number"){
2930 return new self
.Dimensions(elem
.w
||0,elem
.h
||0);
2932 elem
=dom
.getElement(elem
);
2936 var disp
=self
.getStyle(elem
,"display");
2937 if(disp
!="none"&&disp
!==""&&typeof (disp
)!="undefined"){
2938 return new self
.Dimensions(elem
.offsetWidth
||0,elem
.offsetHeight
||0);
2941 var _33f
=s
.visibility
;
2942 var _340
=s
.position
;
2943 s
.visibility
="hidden";
2944 s
.position
="absolute";
2946 var _341
=elem
.offsetWidth
;
2947 var _342
=elem
.offsetHeight
;
2951 return new self
.Dimensions(_341
,_342
);
2952 },setElementDimensions
:function(elem
,_344
,_345
){
2953 elem
=MochiKit
.DOM
.getElement(elem
);
2954 if(typeof (_345
)=="undefined"){
2958 var _347
=MochiKit
.Base
.isUndefinedOrNull
;
2960 _346
["width"]=_344
.w
+_345
;
2963 _346
["height"]=_344
.h
+_345
;
2965 MochiKit
.DOM
.updateNodeAttributes(elem
,{"style":_346
});
2966 },setDisplayForElement
:function(_348
,_349
){
2967 var _34a
=MochiKit
.Base
.extend(null,arguments
,1);
2968 var _34b
=MochiKit
.DOM
.getElement
;
2969 for(var i
=0;i
<_34a
.length
;i
++){
2972 _349
.style
.display
=_348
;
2975 },getViewportDimensions
:function(){
2976 var d
=new MochiKit
.Style
.Dimensions();
2977 var w
=MochiKit
.DOM
._window
;
2978 var b
=MochiKit
.DOM
._document
.body
;
2983 if(b
.parentElement
.clientWidth
){
2984 d
.w
=b
.parentElement
.clientWidth
;
2985 d
.h
=b
.parentElement
.clientHeight
;
2987 if(b
&&b
.clientWidth
){
2994 },getViewportPosition
:function(){
2995 var c
=new MochiKit
.Style
.Coordinates(0,0);
2996 var d
=MochiKit
.DOM
._document
;
2997 var de
=d
.documentElement
;
2999 if(de
&&(de
.scrollTop
||de
.scrollLeft
)){
3009 },__new__
:function(){
3010 var m
=MochiKit
.Base
;
3011 this.elementPosition
=this.getElementPosition
;
3012 this.elementDimensions
=this.getElementDimensions
;
3013 this.hideElement
=m
.partial(this.setDisplayForElement
,"none");
3014 this.showElement
=m
.partial(this.setDisplayForElement
,"block");
3015 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
3016 m
.nameFunctions(this);
3018 MochiKit
.Style
.__new__();
3019 MochiKit
.Base
._exportSymbols(this,MochiKit
.Style
);
3020 if(typeof (dojo
)!="undefined"){
3021 dojo
.provide("MochiKit.Color");
3022 dojo
.require("MochiKit.Base");
3023 dojo
.require("MochiKit.DOM");
3024 dojo
.require("MochiKit.Style");
3026 if(typeof (JSAN
)!="undefined"){
3027 JSAN
.use("MochiKit.Base",[]);
3028 JSAN
.use("MochiKit.DOM",[]);
3029 JSAN
.use("MochiKit.Style",[]);
3032 if(typeof (MochiKit
.Base
)=="undefined"){
3037 throw "MochiKit.Color depends on MochiKit.Base";
3040 if(typeof (MochiKit
.DOM
)=="undefined"){
3045 throw "MochiKit.Color depends on MochiKit.DOM";
3048 if(typeof (MochiKit
.Style
)=="undefined"){
3053 throw "MochiKit.Color depends on MochiKit.Style";
3055 if(typeof (MochiKit
.Color
)=="undefined"){
3058 MochiKit
.Color
.NAME
="MochiKit.Color";
3059 MochiKit
.Color
.VERSION
="1.4";
3060 MochiKit
.Color
.__repr__
=function(){
3061 return "["+this.NAME
+" "+this.VERSION
+"]";
3063 MochiKit
.Color
.toString
=function(){
3064 return this.__repr__();
3066 MochiKit
.Color
.Color
=function(red
,_356
,blue
,_358
){
3067 if(typeof (_358
)=="undefined"||_358
===null){
3070 this.rgb
={r
:red
,g
:_356
,b
:blue
,a
:_358
};
3072 MochiKit
.Color
.Color
.prototype={__class__
:MochiKit
.Color
.Color
,colorWithAlpha
:function(_359
){
3074 var m
=MochiKit
.Color
;
3075 return m
.Color
.fromRGB(rgb
.r
,rgb
.g
,rgb
.b
,_359
);
3076 },colorWithHue
:function(hue
){
3077 var hsl
=this.asHSL();
3079 var m
=MochiKit
.Color
;
3080 return m
.Color
.fromHSL(hsl
);
3081 },colorWithSaturation
:function(_35f
){
3082 var hsl
=this.asHSL();
3084 var m
=MochiKit
.Color
;
3085 return m
.Color
.fromHSL(hsl
);
3086 },colorWithLightness
:function(_362
){
3087 var hsl
=this.asHSL();
3089 var m
=MochiKit
.Color
;
3090 return m
.Color
.fromHSL(hsl
);
3091 },darkerColorWithLevel
:function(_365
){
3092 var hsl
=this.asHSL();
3093 hsl
.l
=Math
.max(hsl
.l
-_365
,0);
3094 var m
=MochiKit
.Color
;
3095 return m
.Color
.fromHSL(hsl
);
3096 },lighterColorWithLevel
:function(_368
){
3097 var hsl
=this.asHSL();
3098 hsl
.l
=Math
.min(hsl
.l
+_368
,1);
3099 var m
=MochiKit
.Color
;
3100 return m
.Color
.fromHSL(hsl
);
3101 },blendedColor
:function(_36b
,_36c
){
3102 if(typeof (_36c
)=="undefined"||_36c
===null){
3109 return MochiKit
.Color
.Color
.fromRGB((s
.r
*sf
)+(d
.r
*df
),(s
.g
*sf
)+(d
.g
*df
),(s
.b
*sf
)+(d
.b
*df
),(s
.a
*sf
)+(d
.a
*df
));
3110 },compareRGB
:function(_371
){
3113 return MochiKit
.Base
.compare([a
.r
,a
.g
,a
.b
,a
.a
],[b
.r
,b
.g
,b
.b
,b
.a
]);
3114 },isLight
:function(){
3115 return this.asHSL().b
>0.5;
3116 },isDark
:function(){
3117 return (!this.isLight());
3118 },toHSLString
:function(){
3120 var ccc
=MochiKit
.Color
.clampColorComponent
;
3121 var rval
=this._hslString
;
3123 var mid
=(ccc(c
.h
,360).toFixed(0)+","+ccc(c
.s
,100).toPrecision(4)+"%"+","+ccc(c
.l
,100).toPrecision(4)+"%");
3127 rval
="hsl("+mid
+")";
3132 rval
="hsla("+mid
+","+a
+")";
3134 this._hslString
=rval
;
3137 },toRGBString
:function(){
3139 var ccc
=MochiKit
.Color
.clampColorComponent
;
3140 var rval
=this._rgbString
;
3142 var mid
=(ccc(c
.r
,255).toFixed(0)+","+ccc(c
.g
,255).toFixed(0)+","+ccc(c
.b
,255).toFixed(0));
3144 rval
="rgba("+mid
+","+c
.a
+")";
3146 rval
="rgb("+mid
+")";
3148 this._rgbString
=rval
;
3152 return MochiKit
.Base
.clone(this.rgb
);
3153 },toHexString
:function(){
3154 var m
=MochiKit
.Color
;
3156 var ccc
=MochiKit
.Color
.clampColorComponent
;
3157 var rval
=this._hexString
;
3159 rval
=("#"+m
.toColorPart(ccc(c
.r
,255))+m
.toColorPart(ccc(c
.g
,255))+m
.toColorPart(ccc(c
.b
,255)));
3160 this._hexString
=rval
;
3166 if(typeof (hsv
)=="undefined"||hsv
===null){
3167 hsv
=MochiKit
.Color
.rgbToHSV(this.rgb
);
3170 return MochiKit
.Base
.clone(hsv
);
3174 if(typeof (hsl
)=="undefined"||hsl
===null){
3175 hsl
=MochiKit
.Color
.rgbToHSL(this.rgb
);
3178 return MochiKit
.Base
.clone(hsl
);
3179 },toString
:function(){
3180 return this.toRGBString();
3183 var col
=[c
.r
,c
.g
,c
.b
,c
.a
];
3184 return this.__class__
.NAME
+"("+col
.join(", ")+")";
3186 MochiKit
.Base
.update(MochiKit
.Color
.Color
,{fromRGB
:function(red
,_388
,blue
,_38a
){
3187 var _38b
=MochiKit
.Color
.Color
;
3188 if(arguments
.length
==1){
3193 if(typeof (rgb
.a
)=="undefined"){
3199 return new _38b(red
,_388
,blue
,_38a
);
3200 },fromHSL
:function(hue
,_38e
,_38f
,_390
){
3201 var m
=MochiKit
.Color
;
3202 return m
.Color
.fromRGB(m
.hslToRGB
.apply(m
,arguments
));
3203 },fromHSV
:function(hue
,_393
,_394
,_395
){
3204 var m
=MochiKit
.Color
;
3205 return m
.Color
.fromRGB(m
.hsvToRGB
.apply(m
,arguments
));
3206 },fromName
:function(name
){
3207 var _398
=MochiKit
.Color
.Color
;
3208 if(name
.charAt(0)=="\""){
3209 name
=name
.substr(1,name
.length
-2);
3211 var _399
=_398
._namedColors
[name
.toLowerCase()];
3212 if(typeof (_399
)=="string"){
3213 return _398
.fromHexString(_399
);
3215 if(name
=="transparent"){
3216 return _398
.transparentColor();
3220 },fromString
:function(_39a
){
3221 var self
=MochiKit
.Color
.Color
;
3222 var _39c
=_39a
.substr(0,3);
3224 return self
.fromRGBString(_39a
);
3227 return self
.fromHSLString(_39a
);
3229 if(_39a
.charAt(0)=="#"){
3230 return self
.fromHexString(_39a
);
3234 return self
.fromName(_39a
);
3235 },fromHexString
:function(_39d
){
3236 if(_39d
.charAt(0)=="#"){
3237 _39d
=_39d
.substring(1);
3243 hex
=_39d
.substr(i
,1);
3244 _39e
.push(parseInt(hex
+hex
,16)/255);
3248 hex
=_39d
.substr(i
,2);
3249 _39e
.push(parseInt(hex
,16)/255);
3252 var _3a1
=MochiKit
.Color
.Color
;
3253 return _3a1
.fromRGB
.apply(_3a1
,_39e
);
3254 },_fromColorString
:function(pre
,_3a3
,_3a4
,_3a5
){
3255 if(_3a5
.indexOf(pre
)===0){
3256 _3a5
=_3a5
.substring(_3a5
.indexOf("(",3)+1,_3a5
.length
-1);
3258 var _3a6
=_3a5
.split(/\s*,\s*/);
3260 for(var i
=0;i
<_3a6
.length
;i
++){
3263 var _3ab
=c
.substring(c
.length
-3);
3264 if(c
.charAt(c
.length
-1)=="%"){
3265 val
=0.01*parseFloat(c
.substring(0,c
.length
-1));
3268 val
=parseFloat(c
)/360;
3271 val
=parseFloat(c
)/(Math
.PI
*2);
3273 val
=_3a4
[i
]*parseFloat(c
);
3279 return this[_3a3
].apply(this,_3a7
);
3280 },fromComputedStyle
:function(elem
,_3ad
){
3282 var cls
=MochiKit
.Color
.Color
;
3283 for(elem
=d
.getElement(elem
);elem
;elem
=elem
.parentNode
){
3284 var _3b0
=MochiKit
.Style
.getStyle
.apply(d
,arguments
);
3288 var _3b1
=cls
.fromString(_3b0
);
3292 if(_3b1
.asRGB().a
>0){
3297 },fromBackground
:function(elem
){
3298 var cls
=MochiKit
.Color
.Color
;
3299 return cls
.fromComputedStyle(elem
,"backgroundColor","background-color")||cls
.whiteColor();
3300 },fromText
:function(elem
){
3301 var cls
=MochiKit
.Color
.Color
;
3302 return cls
.fromComputedStyle(elem
,"color","color")||cls
.blackColor();
3303 },namedColors
:function(){
3304 return MochiKit
.Base
.clone(MochiKit
.Color
.Color
._namedColors
);
3306 MochiKit
.Base
.update(MochiKit
.Color
,{clampColorComponent
:function(v
,_3b7
){
3317 },_hslValue
:function(n1
,n2
,hue
){
3333 val
=n1
+(n2
-n1
)*(4-hue
);
3340 },hsvToRGB
:function(hue
,_3bd
,_3be
,_3bf
){
3341 if(arguments
.length
==1){
3356 var i
=Math
.floor(hue
*6);
3358 var p
=_3be
*(1-_3bd
);
3359 var q
=_3be
*(1-(_3bd
*f
));
3360 var t
=_3be
*(1-(_3bd
*(1-f
)));
3395 return {r
:red
,g
:_3c2
,b
:blue
,a
:_3bf
};
3396 },hslToRGB
:function(hue
,_3ca
,_3cb
,_3cc
){
3397 if(arguments
.length
==1){
3416 m2
=_3cb
+_3ca
-(_3cb
*_3ca
);
3419 var f
=MochiKit
.Color
._hslValue
;
3425 return {r
:red
,g
:_3cf
,b
:blue
,a
:_3cc
};
3426 },rgbToHSV
:function(red
,_3d6
,blue
,_3d8
){
3427 if(arguments
.length
==1){
3434 var max
=Math
.max(Math
.max(red
,_3d6
),blue
);
3435 var min
=Math
.min(Math
.min(red
,_3d6
),blue
);
3446 hue
=(_3d6
-blue
)/_3df
;
3449 hue
=2+((blue
-red
)/_3df
);
3451 hue
=4+((red
-_3d6
)/_3df
);
3462 return {h
:hue
,s
:_3dd
,v
:_3de
,a
:_3d8
};
3463 },rgbToHSL
:function(red
,_3e1
,blue
,_3e3
){
3464 if(arguments
.length
==1){
3471 var max
=Math
.max(red
,Math
.max(_3e1
,blue
));
3472 var min
=Math
.min(red
,Math
.min(_3e1
,blue
));
3475 var _3e9
=(max
+min
)/2;
3482 _3e8
=_3ea
/(max
+min
);
3484 _3e8
=_3ea
/(2-max
-min
);
3487 hue
=(_3e1
-blue
)/_3ea
;
3490 hue
=2+((blue
-red
)/_3ea
);
3492 hue
=4+((red
-_3e1
)/_3ea
);
3503 return {h
:hue
,s
:_3e8
,l
:_3e9
,a
:_3e3
};
3504 },toColorPart
:function(num
){
3505 num
=Math
.round(num
);
3506 var _3ec
=num
.toString(16);
3511 },__new__
:function(){
3512 var m
=MochiKit
.Base
;
3513 this.Color
.fromRGBString
=m
.bind(this.Color
._fromColorString
,this.Color
,"rgb","fromRGB",[1/255,1/255,1/255,1]);
3514 this.Color
.fromHSLString
=m
.bind(this.Color
._fromColorString
,this.Color
,"hsl","fromHSL",[1/360,0.01,0.01,1]);
3516 var _3ef
={black
:[0,0,0],blue
:[0,0,1],brown
:[0.6,0.4,0.2],cyan
:[0,1,1],darkGray
:[_3ee
,_3ee
,_3ee
],gray
:[0.5,0.5,0.5],green
:[0,1,0],lightGray
:[2*_3ee
,2*_3ee
,2*_3ee
],magenta
:[1,0,1],orange
:[1,0.5,0],purple
:[0.5,0,0.5],red
:[1,0,0],transparent
:[0,0,0,0],white
:[1,1,1],yellow
:[1,1,0]};
3517 var _3f0
=function(name
,r
,g
,b
,a
){
3518 var rval
=this.fromRGB(r
,g
,b
,a
);
3519 this[name
]=function(){
3526 var _3f9
=m
.concat([_3f0
,this.Color
,name
],_3ef
[k
]);
3527 this.Color
[name
]=m
.bind
.apply(null,_3f9
);
3529 var _3fa
=function(){
3530 for(var i
=0;i
<arguments
.length
;i
++){
3531 if(!(arguments
[i
] instanceof Color
)){
3537 var _3fc
=function(a
,b
){
3538 return a
.compareRGB(b
);
3540 m
.nameFunctions(this);
3541 m
.registerComparator(this.Color
.NAME
,_3fa
,_3fc
);
3542 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
3544 MochiKit
.Color
.EXPORT
=["Color"];
3545 MochiKit
.Color
.EXPORT_OK
=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
3546 MochiKit
.Color
.__new__();
3547 MochiKit
.Base
._exportSymbols(this,MochiKit
.Color
);
3548 MochiKit
.Color
.Color
._namedColors
={aliceblue
:"#f0f8ff",antiquewhite
:"#faebd7",aqua
:"#00ffff",aquamarine
:"#7fffd4",azure
:"#f0ffff",beige
:"#f5f5dc",bisque
:"#ffe4c4",black
:"#000000",blanchedalmond
:"#ffebcd",blue
:"#0000ff",blueviolet
:"#8a2be2",brown
:"#a52a2a",burlywood
:"#deb887",cadetblue
:"#5f9ea0",chartreuse
:"#7fff00",chocolate
:"#d2691e",coral
:"#ff7f50",cornflowerblue
:"#6495ed",cornsilk
:"#fff8dc",crimson
:"#dc143c",cyan
:"#00ffff",darkblue
:"#00008b",darkcyan
:"#008b8b",darkgoldenrod
:"#b8860b",darkgray
:"#a9a9a9",darkgreen
:"#006400",darkgrey
:"#a9a9a9",darkkhaki
:"#bdb76b",darkmagenta
:"#8b008b",darkolivegreen
:"#556b2f",darkorange
:"#ff8c00",darkorchid
:"#9932cc",darkred
:"#8b0000",darksalmon
:"#e9967a",darkseagreen
:"#8fbc8f",darkslateblue
:"#483d8b",darkslategray
:"#2f4f4f",darkslategrey
:"#2f4f4f",darkturquoise
:"#00ced1",darkviolet
:"#9400d3",deeppink
:"#ff1493",deepskyblue
:"#00bfff",dimgray
:"#696969",dimgrey
:"#696969",dodgerblue
:"#1e90ff",firebrick
:"#b22222",floralwhite
:"#fffaf0",forestgreen
:"#228b22",fuchsia
:"#ff00ff",gainsboro
:"#dcdcdc",ghostwhite
:"#f8f8ff",gold
:"#ffd700",goldenrod
:"#daa520",gray
:"#808080",green
:"#008000",greenyellow
:"#adff2f",grey
:"#808080",honeydew
:"#f0fff0",hotpink
:"#ff69b4",indianred
:"#cd5c5c",indigo
:"#4b0082",ivory
:"#fffff0",khaki
:"#f0e68c",lavender
:"#e6e6fa",lavenderblush
:"#fff0f5",lawngreen
:"#7cfc00",lemonchiffon
:"#fffacd",lightblue
:"#add8e6",lightcoral
:"#f08080",lightcyan
:"#e0ffff",lightgoldenrodyellow
:"#fafad2",lightgray
:"#d3d3d3",lightgreen
:"#90ee90",lightgrey
:"#d3d3d3",lightpink
:"#ffb6c1",lightsalmon
:"#ffa07a",lightseagreen
:"#20b2aa",lightskyblue
:"#87cefa",lightslategray
:"#778899",lightslategrey
:"#778899",lightsteelblue
:"#b0c4de",lightyellow
:"#ffffe0",lime
:"#00ff00",limegreen
:"#32cd32",linen
:"#faf0e6",magenta
:"#ff00ff",maroon
:"#800000",mediumaquamarine
:"#66cdaa",mediumblue
:"#0000cd",mediumorchid
:"#ba55d3",mediumpurple
:"#9370db",mediumseagreen
:"#3cb371",mediumslateblue
:"#7b68ee",mediumspringgreen
:"#00fa9a",mediumturquoise
:"#48d1cc",mediumvioletred
:"#c71585",midnightblue
:"#191970",mintcream
:"#f5fffa",mistyrose
:"#ffe4e1",moccasin
:"#ffe4b5",navajowhite
:"#ffdead",navy
:"#000080",oldlace
:"#fdf5e6",olive
:"#808000",olivedrab
:"#6b8e23",orange
:"#ffa500",orangered
:"#ff4500",orchid
:"#da70d6",palegoldenrod
:"#eee8aa",palegreen
:"#98fb98",paleturquoise
:"#afeeee",palevioletred
:"#db7093",papayawhip
:"#ffefd5",peachpuff
:"#ffdab9",peru
:"#cd853f",pink
:"#ffc0cb",plum
:"#dda0dd",powderblue
:"#b0e0e6",purple
:"#800080",red
:"#ff0000",rosybrown
:"#bc8f8f",royalblue
:"#4169e1",saddlebrown
:"#8b4513",salmon
:"#fa8072",sandybrown
:"#f4a460",seagreen
:"#2e8b57",seashell
:"#fff5ee",sienna
:"#a0522d",silver
:"#c0c0c0",skyblue
:"#87ceeb",slateblue
:"#6a5acd",slategray
:"#708090",slategrey
:"#708090",snow
:"#fffafa",springgreen
:"#00ff7f",steelblue
:"#4682b4",tan
:"#d2b48c",teal
:"#008080",thistle
:"#d8bfd8",tomato
:"#ff6347",turquoise
:"#40e0d0",violet
:"#ee82ee",wheat
:"#f5deb3",white
:"#ffffff",whitesmoke
:"#f5f5f5",yellow
:"#ffff00",yellowgreen
:"#9acd32"};
3549 if(typeof (dojo
)!="undefined"){
3550 dojo
.provide("MochiKit.Signal");
3551 dojo
.require("MochiKit.Base");
3552 dojo
.require("MochiKit.DOM");
3553 dojo
.require("MochiKit.Style");
3555 if(typeof (JSAN
)!="undefined"){
3556 JSAN
.use("MochiKit.Base",[]);
3557 JSAN
.use("MochiKit.DOM",[]);
3558 JSAN
.use("MochiKit.Style",[]);
3561 if(typeof (MochiKit
.Base
)=="undefined"){
3566 throw "MochiKit.Signal depends on MochiKit.Base!";
3569 if(typeof (MochiKit
.DOM
)=="undefined"){
3574 throw "MochiKit.Signal depends on MochiKit.DOM!";
3577 if(typeof (MochiKit
.Style
)=="undefined"){
3582 throw "MochiKit.Signal depends on MochiKit.Style!";
3584 if(typeof (MochiKit
.Signal
)=="undefined"){
3587 MochiKit
.Signal
.NAME
="MochiKit.Signal";
3588 MochiKit
.Signal
.VERSION
="1.4";
3589 MochiKit
.Signal
._observers
=[];
3590 MochiKit
.Signal
.Event
=function(src
,e
){
3591 this._event
=e
||window
.event
;
3594 MochiKit
.Base
.update(MochiKit
.Signal
.Event
.prototype,{__repr__
:function(){
3595 var repr
=MochiKit
.Base
.repr
;
3596 var str
="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target());
3597 if(this.type()&&this.type().indexOf("key")===0||this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu"){
3598 str
+=", modifier(): "+"{alt: "+repr(this.modifier().alt
)+", ctrl: "+repr(this.modifier().ctrl
)+", meta: "+repr(this.modifier().meta
)+", shift: "+repr(this.modifier().shift
)+", any: "+repr(this.modifier().any
)+"}";
3600 if(this.type()&&this.type().indexOf("key")===0){
3601 str
+=", key(): {code: "+repr(this.key().code
)+", string: "+repr(this.key().string
)+"}";
3603 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3604 str
+=", mouse(): {page: "+repr(this.mouse().page
)+", client: "+repr(this.mouse().client
);
3605 if(this.type()!="mousemove"){
3606 str
+=", button: {left: "+repr(this.mouse().button
.left
)+", middle: "+repr(this.mouse().button
.middle
)+", right: "+repr(this.mouse().button
.right
)+"}}";
3611 if(this.type()=="mouseover"||this.type()=="mouseout"){
3612 str
+=", relatedTarget(): "+repr(this.relatedTarget());
3616 },toString
:function(){
3617 return this.__repr__();
3623 return this._event
.type
||undefined
;
3624 },target
:function(){
3625 return this._event
.target
||this._event
.srcElement
;
3626 },_relatedTarget
:null,relatedTarget
:function(){
3627 if(this._relatedTarget
!==null){
3628 return this._relatedTarget
;
3631 if(this.type()=="mouseover"){
3632 elem
=(this._event
.relatedTarget
||this._event
.fromElement
);
3634 if(this.type()=="mouseout"){
3635 elem
=(this._event
.relatedTarget
||this._event
.toElement
);
3639 this._relatedTarget
=elem
;
3643 },_modifier
:null,modifier
:function(){
3644 if(this._modifier
!==null){
3645 return this._modifier
;
3648 m
.alt
=this._event
.altKey
;
3649 m
.ctrl
=this._event
.ctrlKey
;
3650 m
.meta
=this._event
.metaKey
||false;
3651 m
.shift
=this._event
.shiftKey
;
3652 m
.any
=m
.alt
||m
.ctrl
||m
.shift
||m
.meta
;
3655 },_key
:null,key
:function(){
3656 if(this._key
!==null){
3660 if(this.type()&&this.type().indexOf("key")===0){
3661 if(this.type()=="keydown"||this.type()=="keyup"){
3662 k
.code
=this._event
.keyCode
;
3663 k
.string
=(MochiKit
.Signal
._specialKeys
[k
.code
]||"KEY_UNKNOWN");
3667 if(this.type()=="keypress"){
3670 if(typeof (this._event
.charCode
)!="undefined"&&this._event
.charCode
!==0&&!MochiKit
.Signal
._specialMacKeys
[this._event
.charCode
]){
3671 k
.code
=this._event
.charCode
;
3672 k
.string
=String
.fromCharCode(k
.code
);
3674 if(this._event
.keyCode
&&typeof (this._event
.charCode
)=="undefined"){
3675 k
.code
=this._event
.keyCode
;
3676 k
.string
=String
.fromCharCode(k
.code
);
3685 },_mouse
:null,mouse
:function(){
3686 if(this._mouse
!==null){
3691 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3692 m
.client
=new MochiKit
.Style
.Coordinates(0,0);
3693 if(e
.clientX
||e
.clientY
){
3694 m
.client
.x
=(!e
.clientX
||e
.clientX
<0)?0:e
.clientX
;
3695 m
.client
.y
=(!e
.clientY
||e
.clientY
<0)?0:e
.clientY
;
3697 m
.page
=new MochiKit
.Style
.Coordinates(0,0);
3698 if(e
.pageX
||e
.pageY
){
3699 m
.page
.x
=(!e
.pageX
||e
.pageX
<0)?0:e
.pageX
;
3700 m
.page
.y
=(!e
.pageY
||e
.pageY
<0)?0:e
.pageY
;
3702 var de
=MochiKit
.DOM
._document
.documentElement
;
3703 var b
=MochiKit
.DOM
._document
.body
;
3704 m
.page
.x
=e
.clientX
+(de
.scrollLeft
||b
.scrollLeft
)-(de
.clientLeft
||0);
3705 m
.page
.y
=e
.clientY
+(de
.scrollTop
||b
.scrollTop
)-(de
.clientTop
||0);
3707 if(this.type()!="mousemove"){
3709 m
.button
.left
=false;
3710 m
.button
.right
=false;
3711 m
.button
.middle
=false;
3713 m
.button
.left
=(e
.which
==1);
3714 m
.button
.middle
=(e
.which
==2);
3715 m
.button
.right
=(e
.which
==3);
3717 m
.button
.left
=!!(e
.button
&1);
3718 m
.button
.right
=!!(e
.button
&2);
3719 m
.button
.middle
=!!(e
.button
&4);
3727 this.stopPropagation();
3728 this.preventDefault();
3729 },stopPropagation
:function(){
3730 if(this._event
.stopPropagation
){
3731 this._event
.stopPropagation();
3733 this._event
.cancelBubble
=true;
3735 },preventDefault
:function(){
3736 if(this._event
.preventDefault
){
3737 this._event
.preventDefault();
3739 if(this._confirmUnload
===null){
3740 this._event
.returnValue
=false;
3743 },_confirmUnload
:null,confirmUnload
:function(msg
){
3744 if(this.type()=="beforeunload"){
3745 this._confirmUnload
=msg
;
3746 this._event
.returnValue
=msg
;
3749 MochiKit
.Signal
._specialMacKeys
={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
3751 var _40b
=MochiKit
.Signal
._specialMacKeys
;
3752 for(i
=63236;i
<=63242;i
++){
3753 _40b
[i
]="KEY_F"+(i
-63236+1);
3756 MochiKit
.Signal
._specialKeys
={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
3758 var _40c
=MochiKit
.Signal
._specialKeys
;
3759 for(var i
=48;i
<=57;i
++){
3760 _40c
[i
]="KEY_"+(i
-48);
3762 for(i
=65;i
<=90;i
++){
3763 _40c
[i
]="KEY_"+String
.fromCharCode(i
);
3765 for(i
=96;i
<=105;i
++){
3766 _40c
[i
]="KEY_NUM_PAD_"+(i
-96);
3768 for(i
=112;i
<=123;i
++){
3769 _40c
[i
]="KEY_F"+(i
-112+1);
3772 MochiKit
.Signal
.Ident
=function(_40e
){
3773 this.source
=_40e
.source
;
3774 this.signal
=_40e
.signal
;
3775 this.listener
=_40e
.listener
;
3776 this.isDOM
=_40e
.isDOM
;
3777 this.objOrFunc
=_40e
.objOrFunc
;
3778 this.funcOrStr
=_40e
.funcOrStr
;
3779 this.connected
=_40e
.connected
;
3781 MochiKit
.Signal
.Ident
.prototype={};
3782 MochiKit
.Base
.update(MochiKit
.Signal
,{__repr__
:function(){
3783 return "["+this.NAME
+" "+this.VERSION
+"]";
3784 },toString
:function(){
3785 return this.__repr__();
3786 },_unloadCache
:function(){
3787 var self
=MochiKit
.Signal
;
3788 var _410
=self
._observers
;
3789 for(var i
=0;i
<_410
.length
;i
++){
3790 if(_410
[i
].signal
!=="onload"&&_410
[i
].signal
!=="onunload"){
3791 self
._disconnect(_410
[i
]);
3794 },_listener
:function(src
,sig
,func
,obj
,_416
){
3795 var self
=MochiKit
.Signal
;
3798 return MochiKit
.Base
.bind(func
,obj
);
3801 if(typeof (func
)=="string"){
3802 if(sig
==="onload"||sig
==="onunload"){
3803 return function(_419
){
3804 obj
[func
].apply(obj
,[new E(src
,_419
)]);
3805 var _41a
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,objOrFunc
:obj
,funcOrStr
:func
});
3806 MochiKit
.Signal
._disconnect(_41a
);
3809 return function(_41b
){
3810 obj
[func
].apply(obj
,[new E(src
,_41b
)]);
3814 if(sig
==="onload"||sig
==="onunload"){
3815 return function(_41c
){
3816 func
.apply(obj
,[new E(src
,_41c
)]);
3817 MochiKit
.Signal
.disconnect(src
,sig
,func
);
3818 var _41d
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,objOrFunc
:func
});
3819 MochiKit
.Signal
._disconnect(_41d
);
3822 return function(_41e
){
3823 func
.apply(obj
,[new E(src
,_41e
)]);
3827 },_browserAlreadyHasMouseEnterAndLeave
:function(){
3828 return /MSIE/.test(navigator
.userAgent
);
3829 },_mouseEnterListener
:function(src
,sig
,func
,obj
){
3830 var E
=MochiKit
.Signal
.Event
;
3831 return function(_424
){
3832 var e
=new E(src
,_424
);
3834 e
.relatedTarget().nodeName
;
3840 if(MochiKit
.DOM
.isChildNode(e
.relatedTarget(),src
)){
3846 if(typeof (func
)=="string"){
3847 return obj
[func
].apply(obj
,[e
]);
3849 return func
.apply(obj
,[e
]);
3852 },_getDestPair
:function(_426
,_427
){
3855 if(typeof (_427
)!="undefined"){
3858 if(typeof (_427
)=="string"){
3859 if(typeof (_426
[_427
])!="function"){
3860 throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
3863 if(typeof (_427
)!="function"){
3864 throw new Error("'funcOrStr' must be a function or string");
3868 if(typeof (_426
)!="function"){
3869 throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
3875 },connect
:function(src
,sig
,_42c
,_42d
){
3876 src
=MochiKit
.DOM
.getElement(src
);
3877 var self
=MochiKit
.Signal
;
3878 if(typeof (sig
)!="string"){
3879 throw new Error("'sig' must be a string");
3881 var _42f
=self
._getDestPair(_42c
,_42d
);
3884 if(typeof (obj
)=="undefined"||obj
===null){
3887 var _432
=!!(src
.addEventListener
||src
.attachEvent
);
3888 if(_432
&&(sig
==="onmouseenter"||sig
==="onmouseleave")&&!self
._browserAlreadyHasMouseEnterAndLeave()){
3889 var _433
=self
._mouseEnterListener(src
,sig
.substr(2),func
,obj
);
3890 if(sig
==="onmouseenter"){
3896 var _433
=self
._listener(src
,sig
,func
,obj
,_432
);
3898 if(src
.addEventListener
){
3899 src
.addEventListener(sig
.substr(2),_433
,false);
3901 if(src
.attachEvent
){
3902 src
.attachEvent(sig
,_433
);
3905 var _434
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,listener
:_433
,isDOM
:_432
,objOrFunc
:_42c
,funcOrStr
:_42d
,connected
:true});
3906 self
._observers
.push(_434
);
3907 if(!_432
&&typeof (src
.__connect__
)=="function"){
3908 var args
=MochiKit
.Base
.extend([_434
],arguments
,1);
3909 src
.__connect__
.apply(src
,args
);
3912 },_disconnect
:function(_436
){
3913 if(!_436
.connected
){
3916 _436
.connected
=false;
3920 var src
=_436
.source
;
3921 var sig
=_436
.signal
;
3922 var _439
=_436
.listener
;
3923 if(src
.removeEventListener
){
3924 src
.removeEventListener(sig
.substr(2),_439
,false);
3926 if(src
.detachEvent
){
3927 src
.detachEvent(sig
,_439
);
3929 throw new Error("'src' must be a DOM element");
3932 },disconnect
:function(_43a
){
3933 var self
=MochiKit
.Signal
;
3934 var _43c
=self
._observers
;
3935 var m
=MochiKit
.Base
;
3936 if(arguments
.length
>1){
3937 var src
=MochiKit
.DOM
.getElement(arguments
[0]);
3938 var sig
=arguments
[1];
3939 var obj
=arguments
[2];
3940 var func
=arguments
[3];
3941 for(var i
=_43c
.length
-1;i
>=0;i
--){
3943 if(o
.source
===src
&&o
.signal
===sig
&&o
.objOrFunc
===obj
&&o
.funcOrStr
===func
){
3944 self
._disconnect(o
);
3954 var idx
=m
.findIdentical(_43c
,_43a
);
3956 self
._disconnect(_43a
);
3966 },disconnectAllTo
:function(_445
,_446
){
3967 var self
=MochiKit
.Signal
;
3968 var _448
=self
._observers
;
3969 var _449
=self
._disconnect
;
3970 var _44a
=self
._lock
;
3971 var _44b
=self
._dirty
;
3972 if(typeof (_446
)==="undefined"){
3975 for(var i
=_448
.length
-1;i
>=0;i
--){
3977 if(_44d
.objOrFunc
===_445
&&(_446
===null||_44d
.funcOrStr
===_446
)){
3987 },disconnectAll
:function(src
,sig
){
3988 src
=MochiKit
.DOM
.getElement(src
);
3989 var m
=MochiKit
.Base
;
3990 var _451
=m
.flattenArguments(m
.extend(null,arguments
,1));
3991 var self
=MochiKit
.Signal
;
3992 var _453
=self
._disconnect
;
3993 var _454
=self
._observers
;
3995 var _457
=self
._lock
;
3996 var _458
=self
._dirty
;
3997 if(_451
.length
===0){
3998 for(i
=_454
.length
-1;i
>=0;i
--){
4000 if(_456
.source
===src
){
4011 for(i
=0;i
<_451
.length
;i
++){
4014 for(i
=_454
.length
-1;i
>=0;i
--){
4016 if(_456
.source
===src
&&_456
.signal
in sigs
){
4027 },signal
:function(src
,sig
){
4028 var self
=MochiKit
.Signal
;
4029 var _45d
=self
._observers
;
4030 src
=MochiKit
.DOM
.getElement(src
);
4031 var args
=MochiKit
.Base
.extend(null,arguments
,2);
4034 for(var i
=0;i
<_45d
.length
;i
++){
4036 if(_461
.source
===src
&&_461
.signal
===sig
){
4038 _461
.listener
.apply(src
,args
);
4048 for(var i
=_45d
.length
-1;i
>=0;i
--){
4049 if(!_45d
[i
].connected
){
4058 var e
=new Error("Multiple errors thrown in handling 'sig', see errors property");
4064 MochiKit
.Signal
.EXPORT_OK
=[];
4065 MochiKit
.Signal
.EXPORT
=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
4066 MochiKit
.Signal
.__new__
=function(win
){
4067 var m
=MochiKit
.Base
;
4068 this._document
=document
;
4073 this.connect(window
,"onunload",this._unloadCache
);
4077 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
4078 m
.nameFunctions(this);
4080 MochiKit
.Signal
.__new__(this);
4081 if(MochiKit
.__export__
){
4082 connect
=MochiKit
.Signal
.connect
;
4083 disconnect
=MochiKit
.Signal
.disconnect
;
4084 disconnectAll
=MochiKit
.Signal
.disconnectAll
;
4085 signal
=MochiKit
.Signal
.signal
;
4087 MochiKit
.Base
._exportSymbols(this,MochiKit
.Signal
);
4092 PlotKit.PlotKit 0.9.1 : PACKED VERSION
4094 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
4095 diff against the source tree, not this file.
4097 For more information, <http://www.liquidx.net/plotkit/>.
4099 Copyright (c) 2006. Alastair Tse.
4104 if(typeof (MochiKit
.Base
)=="undefined"||typeof (MochiKit
.DOM
)=="undefined"||typeof (MochiKit
.Color
)=="undefined"||typeof (MochiKit
.Format
)=="undefined"){
4109 throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}";
4111 MochiKit
.Base
.update(MochiKit
.Color
.Color
.prototype,{asFillColor
:function(){
4112 return this.lighterColorWithLevel(0.3);
4113 },asStrokeColor
:function(){
4114 return this.darkerColorWithLevel(0.1);
4115 },asPointColor
:function(){
4116 return this.lighterColorWithLevel(0.1);
4118 if(typeof (PlotKit
)=="undefined"){
4121 PlotKit
.NAME
="PlotKit";
4122 PlotKit
.VERSION
="0.8";
4123 PlotKit
.__repr__
=function(){
4124 return "["+this.NAME
+" "+this.VERSION
+"]";
4126 PlotKit
.toString
=function(){
4127 return this.__repr__();
4129 if(typeof (PlotKit
.Base
)=="undefined"){
4132 PlotKit
.Base
.NAME
="PlotKit.Base";
4133 PlotKit
.Base
.VERSION
=PlotKit
.VERSION
;
4134 PlotKit
.Base
.__repr__
=function(){
4135 return "["+this.NAME
+" "+this.VERSION
+"]";
4137 PlotKit
.Base
.toString
=function(){
4138 return this.__repr__();
4140 PlotKit
.Base
.usingPrototype
=function(){
4142 return (typeof (Object
.extend
)=="function");
4148 MochiKit
.Base
.update(PlotKit
.Base
,{roundInterval
:function(_1
,_2
,_3
){
4149 var _4
=MochiKit
.Format
.roundToFixed
;
4151 return parseFloat(_4(_5
,_3
));
4152 },collapse
:function(_6
){
4153 var m
=MochiKit
.Base
;
4155 for(var i
=0;i
<_6
.length
;i
++){
4156 _8
=m
.concat(_8
,_6
[i
]);
4158 if(PlotKit
.Base
.usingPrototype()){
4164 },uniq
:function(_10
){
4165 var m
=MochiKit
.Base
;
4166 if(!m
.isArrayLike(_10
)||(_10
.length
<1)){
4169 var _11
=new Array();
4172 for(var i
=1;i
<_10
.length
;i
++){
4173 if(m
.compare(_10
[i
],_12
)!=0){
4179 },colorScheme
:function(){
4180 var mb
=MochiKit
.Base
;
4181 var mc
=MochiKit
.Color
;
4182 var _15
=["red","orange","yellow","green","cyan","blue","purple","magenta"];
4183 var _16
=function(_17
){
4184 return mc
.Color
[_17
+"Color"]();
4186 return mb
.map(_16
,_15
);
4187 },baseDarkPrimaryColors
:function(){
4188 var _18
=MochiKit
.Color
.Color
.fromHexString
;
4189 return [_18("#ad3f40"),_18("#ddac2c"),_18("#dfdd0c"),_18("#5276c4"),_18("#739c5a")];
4190 },basePrimaryColors
:function(){
4191 var _19
=MochiKit
.Color
.Color
.fromHexString
;
4192 return [_19("#d24c4d"),_19("#f2b32f"),_19("#ece90e"),_19("#5d83da"),_19("#78a15d")];
4193 },baseBlueColors
:function(){
4194 var _20
=MochiKit
.Color
.Color
.fromHexString
;
4195 return [_20("#4b6b94"),_20("#5d81b4"),_20("#acbad2")];
4196 },palette
:function(_21
,_22
,_23
,_24
){
4197 var _25
=MochiKit
.Base
.isUndefinedOrNull
;
4198 var _26
=new Array();
4213 var _28
=function(_29
,_30
){
4214 return _29
.lighterColorWithLevel(_30
);
4216 return MochiKit
.Base
.map(partial(_28
,_21
),_26
);
4217 },excanvasSupported
:function(){
4218 if(/MSIE/.test(navigator
.userAgent
)&&!window
.opera
){
4222 },findPosX
:function(obj
){
4224 if(obj
.offsetParent
){
4225 while(obj
.offsetParent
){
4226 _32
+=obj
.offsetLeft
;
4227 obj
=obj
.offsetParent
;
4235 },findPosY
:function(obj
){
4237 if(obj
.offsetParent
){
4238 while(obj
.offsetParent
){
4240 obj
=obj
.offsetParent
;
4248 },isFuncLike
:function(obj
){
4249 return (typeof (obj
)=="function");
4251 PlotKit
.Base
.map
=function(fn
,lst
){
4252 if(PlotKit
.Base
.usingPrototype()){
4255 if(typeof (lst
[x
])=="function"){
4258 _36
.push(fn(lst
[x
]));
4262 return MochiKit
.Base
.map(fn
,lst
);
4265 PlotKit
.Base
.items
=function(lst
){
4266 if(PlotKit
.Base
.usingPrototype()){
4269 if(typeof (lst
[x
])=="function"){
4272 _38
.push([x
,lst
[x
]]);
4276 return MochiKit
.Base
.items(lst
);
4279 PlotKit
.Base
.keys
=function(lst
){
4280 if(PlotKit
.Base
.usingPrototype()){
4283 if(typeof (lst
[x
])=="function"){
4290 return MochiKit
.Base
.keys(lst
);
4293 PlotKit
.Base
.baseColors
=function(){
4294 var _40
=MochiKit
.Color
.Color
.fromHexString
;
4295 return [_40("#476fb2"),_40("#be2c2b"),_40("#85b730"),_40("#734a99"),_40("#26a1c5"),_40("#fb8707"),_40("#000000")];
4297 PlotKit
.Base
.officeBaseStyle
={"axisLineWidth":2,"axisLabelColor":Color
.grayColor(),"axisLineColor":Color
.whiteColor(),"padding":{top
:5,bottom
:10,left
:30,right
:30}};
4298 MochiKit
.Base
.update(PlotKit
.Base
,{officeBlue
:function(){
4299 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[0]),"backgroundColor":PlotKit
.Base
.baseColors()[0].lighterColorWithLevel(0.45)};
4300 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4302 },officeRed
:function(){
4303 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[1]),"backgroundColor":PlotKit
.Base
.baseColors()[1].lighterColorWithLevel(0.5)};
4304 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4306 },officeGreen
:function(){
4307 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[2]),"backgroundColor":PlotKit
.Base
.baseColors()[2].lighterColorWithLevel(0.5)};
4308 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4310 },officePurple
:function(){
4311 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[3]),"backgroundColor":PlotKit
.Base
.baseColors()[3].lighterColorWithLevel(0.5)};
4312 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4314 },officeCyan
:function(){
4315 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[4]),"backgroundColor":PlotKit
.Base
.baseColors()[4].lighterColorWithLevel(0.5)};
4316 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4318 },officeOrange
:function(){
4319 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[5]),"backgroundColor":PlotKit
.Base
.baseColors()[5].lighterColorWithLevel(0.4)};
4320 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4322 },officeBlack
:function(){
4323 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[6],0,0.6),"backgroundColor":PlotKit
.Base
.baseColors()[6].lighterColorWithLevel(0.9)};
4324 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
4327 PlotKit
.Base
.EXPORT
=["baseColors","collapse","colorScheme","findPosX","findPosY","officeBaseStyle","officeBlue","officeRed","officeGreen","officePurple","officeCyan","officeOrange","officeBlack","roundInterval","uniq","isFuncLike","excanvasSupported"];
4328 PlotKit
.Base
.EXPORT_OK
=[];
4329 PlotKit
.Base
.__new__
=function(){
4330 var m
=MochiKit
.Base
;
4331 m
.nameFunctions(this);
4332 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
4334 PlotKit
.Base
.__new__();
4335 MochiKit
.Base
._exportSymbols(this,PlotKit
.Base
);
4337 if(typeof (PlotKit
.Base
)=="undefined"){
4342 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base";
4344 if(typeof (PlotKit
.Layout
)=="undefined"){
4347 PlotKit
.Layout
.NAME
="PlotKit.Layout";
4348 PlotKit
.Layout
.VERSION
=PlotKit
.VERSION
;
4349 PlotKit
.Layout
.__repr__
=function(){
4350 return "["+this.NAME
+" "+this.VERSION
+"]";
4352 PlotKit
.Layout
.toString
=function(){
4353 return this.__repr__();
4355 PlotKit
.Layout
.valid_styles
=["bar","line","pie","point"];
4356 PlotKit
.Layout
=function(_42
,_43
){
4357 this.options
={"barWidthFillFraction":0.75,"barOrientation":"vertical","xOriginIsZero":true,"yOriginIsZero":true,"xAxis":null,"yAxis":null,"xTicks":null,"yTicks":null,"xNumberOfTicks":10,"yNumberOfTicks":5,"xTickPrecision":1,"yTickPrecision":1,"pieRadius":0.4};
4359 MochiKit
.Base
.update(this.options
,_43
?_43
:{});
4360 if(!MochiKit
.Base
.isUndefinedOrNull(this.options
.xAxis
)){
4361 this.minxval
=this.options
.xAxis
[0];
4362 this.maxxval
=this.options
.xAxis
[1];
4363 this.xscale
=this.maxxval
-this.minxval
;
4369 if(!MochiKit
.Base
.isUndefinedOrNull(this.options
.yAxis
)){
4370 this.minyval
=this.options
.yAxis
[0];
4371 this.maxyval
=this.options
.yAxis
[1];
4372 this.yscale
=this.maxyval
-this.minyval
;
4378 this.bars
=new Array();
4379 this.points
=new Array();
4380 this.slices
=new Array();
4381 this.xticks
=new Array();
4382 this.yticks
=new Array();
4383 this.datasets
=new Array();
4387 this.hitTestCache
={x2maxy
:null};
4389 PlotKit
.Layout
.prototype.addDataset
=function(_44
,_45
){
4390 this.datasets
[_44
]=_45
;
4392 PlotKit
.Layout
.prototype.removeDataset
=function(_46
,_47
){
4393 delete this.datasets
[_46
];
4395 PlotKit
.Layout
.prototype.addDatasetFromTable
=function(_48
,_49
,_50
,_51
,_52
){
4396 var _53
=MochiKit
.Base
.isUndefinedOrNull
;
4397 var _54
=MochiKit
.DOM
.scrapeText
;
4398 var _55
=MochiKit
.Format
.strip
;
4408 var _56
=_49
.tBodies
[0].rows
;
4409 var _57
=new Array();
4410 var _58
=new Array();
4412 for(var i
=0;i
<_56
.length
;i
++){
4413 _57
.push([parseFloat(_55(_54(_56
[i
].cells
[_50
]))),parseFloat(_55(_54(_56
[i
].cells
[_51
])))]);
4415 _58
.push({v
:parseFloat(_55(_54(_56
[i
].cells
[_50
]))),label
:_55(_54(_56
[i
].cells
[_52
]))});
4418 this.addDataset(_48
,_57
);
4420 this.options
.xTicks
=_58
;
4426 PlotKit
.Layout
.prototype.evaluate
=function(){
4427 this._evaluateLimits();
4428 this._evaluateScales();
4429 if(this.style
=="bar"){
4430 if(this.options
.barOrientation
=="horizontal"){
4431 this._evaluateHorizBarCharts();
4433 this._evaluateBarCharts();
4435 this._evaluateBarTicks();
4437 if(this.style
=="line"){
4438 this._evaluateLineCharts();
4439 this._evaluateLineTicks();
4441 if(this.style
=="pie"){
4442 this._evaluatePieCharts();
4443 this._evaluatePieTicks();
4448 PlotKit
.Layout
.prototype.hitTest
=function(x
,y
){
4449 var f
=MochiKit
.Format
.twoDigitFloat
;
4450 if((this.style
=="bar")&&this.bars
&&(this.bars
.length
>0)){
4451 for(var i
=0;i
<this.bars
.length
;i
++){
4452 var bar
=this.bars
[i
];
4453 if((x
>=bar
.x
)&&(x
<=bar
.x
+bar
.w
)&&(y
>=bar
.y
)&&(y
-bar
.y
<=bar
.h
)){
4458 if(this.style
=="line"){
4459 if(this.hitTestCache
.x2maxy
==null){
4460 this._regenerateHitTestCache();
4462 var _62
=x
/this.xscale
;
4463 var _63
=this.hitTestCache
.xvalues
;
4466 for(var i
=1;i
<_63
.length
;i
++){
4474 var _66
=this.hitTestCache
.x2maxy
[_64
];
4475 var _67
=this.hitTestCache
.x2maxy
[_65
];
4476 var _68
=(1-y
)/this.yscale
;
4477 var _69
=(_67
-_66
)/(_65
-_64
);
4478 var _70
=_66
+_69
*(_62
-_64
);
4480 var obj
={xval
:_62
,yval
:_68
,xafter
:_65
,yafter
:_67
,xbefore
:_64
,ybefore
:_66
,yprojected
:_70
};
4485 if(this.style
=="pie"){
4486 var _71
=Math
.sqrt((y
-0.5)*(y
-0.5)+(x
-0.5)*(x
-0.5));
4487 if(_71
>this.options
.pieRadius
){
4490 var _72
=Math
.atan2(y
-0.5,x
-0.5)-Math
.PI
/2;
4491 for(var i
=0;i
<this.slices
.length
;i
++){
4492 var _73
=this.slices
[i
];
4493 if(_73
.startAngle
<_72
&&_73
.endAngle
>=_72
){
4502 PlotKit
.Layout
.prototype.rectForX
=function(x
){
4505 PlotKit
.Layout
.prototype.angleRangeForX
=function(x
){
4508 PlotKit
.Layout
.prototype._evaluateLimits
=function(){
4509 var map
=PlotKit
.Base
.map
;
4510 var _75
=PlotKit
.Base
.items
;
4511 var _76
=MochiKit
.Base
.itemgetter
;
4512 var _77
=PlotKit
.Base
.collapse
;
4513 var _78
=MochiKit
.Base
.listMin
;
4514 var _79
=MochiKit
.Base
.listMax
;
4515 var _80
=MochiKit
.Base
.isUndefinedOrNull
;
4516 var all
=_77(map(_76(1),_75(this.datasets
)));
4517 if(_80(this.options
.xAxis
)){
4518 if(this.options
.xOriginIsZero
){
4521 this.minxval
=_78(map(parseFloat
,map(_76(0),all
)));
4523 this.maxxval
=_79(map(parseFloat
,map(_76(0),all
)));
4525 this.minxval
=this.options
.xAxis
[0];
4526 this.maxxval
=this.options
.xAxis
[1];
4527 this.xscale
=this.maxval
-this.minxval
;
4529 if(_80(this.options
.yAxis
)){
4530 if(this.options
.yOriginIsZero
){
4533 this.minyval
=_78(map(parseFloat
,map(_76(1),all
)));
4535 this.maxyval
=_79(map(parseFloat
,map(_76(1),all
)));
4537 this.minyval
=this.options
.yAxis
[0];
4538 this.maxyval
=this.options
.yAxis
[1];
4539 this.yscale
=this.maxyval
-this.minyval
;
4542 PlotKit
.Layout
.prototype._evaluateScales
=function(){
4543 var _82
=MochiKit
.Base
.isUndefinedOrNull
;
4544 this.xrange
=this.maxxval
-this.minxval
;
4548 this.xscale
=1/this.xrange
;
4550 this.yrange
=this.maxyval
-this.minyval
;
4554 this.yscale
=1/this.yrange
;
4557 PlotKit
.Layout
.prototype._uniqueXValues
=function(){
4558 var _83
=PlotKit
.Base
.collapse
;
4559 var map
=PlotKit
.Base
.map
;
4560 var _84
=PlotKit
.Base
.uniq
;
4561 var _85
=MochiKit
.Base
.itemgetter
;
4562 var _86
=PlotKit
.Base
.items
;
4563 var _87
=map(parseFloat
,map(_85(0),_83(map(_85(1),_86(this.datasets
)))));
4564 _87
.sort(MochiKit
.Base
.compare
);
4567 PlotKit
.Layout
.prototype._evaluateBarCharts
=function(){
4568 var _88
=PlotKit
.Base
.items
;
4569 var _89
=_88(this.datasets
).length
;
4571 var _91
=this._uniqueXValues();
4572 for(var i
=1;i
<_91
.length
;i
++){
4573 _90
=Math
.min(Math
.abs(_91
[i
]-_91
[i
-1]),_90
);
4581 this.minxval
=_91
[0];
4582 _92
=1*this.options
.barWidthFillFraction
;
4584 _94
=(1-this.options
.barWidthFillFraction
)/2;
4592 this.xscale
=(1-_90
/this.xrange)/this.xrange
;
4595 _92
=_90
*this.xscale
*this.options
.barWidthFillFraction
;
4597 _94
=_90
*this.xscale
*(1-this.options
.barWidthFillFraction
)/2;
4600 this.bars
=new Array();
4602 for(var _95
in this.datasets
){
4603 var _96
=this.datasets
[_95
];
4604 if(PlotKit
.Base
.isFuncLike(_96
)){
4607 for(var j
=0;j
<_96
.length
;j
++){
4609 var _99
={x
:((parseFloat(_98
[0])-this.minxval
)*this.xscale
)+(i
*_93
)+_94
,y
:1-((parseFloat(_98
[1])-this.minyval
)*this.yscale
),w
:_93
,h
:((parseFloat(_98
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(_98
[0]),yval
:parseFloat(_98
[1]),name
:_95
};
4610 if((_99
.x
>=0)&&(_99
.x
<=1)&&(_99
.y
>=0)&&(_99
.y
<=1)){
4611 this.bars
.push(_99
);
4617 PlotKit
.Layout
.prototype._evaluateHorizBarCharts
=function(){
4618 var _100
=PlotKit
.Base
.items
;
4619 var _101
=_100(this.datasets
).length
;
4621 var _103
=this._uniqueXValues();
4622 for(var i
=1;i
<_103
.length
;i
++){
4623 _102
=Math
.min(Math
.abs(_103
[i
]-_103
[i
-1]),_102
);
4631 this.minxval
=_103
[0];
4632 _104
=1*this.options
.barWidthFillFraction
;
4634 _106
=(1-this.options
.barWidthFillFraction
)/2;
4636 this.xscale
=(1-_102
/this.xrange)/this.xrange
;
4637 _104
=_102
*this.xscale
*this.options
.barWidthFillFraction
;
4639 _106
=_102
*this.xscale
*(1-this.options
.barWidthFillFraction
)/2;
4641 this.minxdelta
=_102
;
4642 this.bars
=new Array();
4644 for(var _107
in this.datasets
){
4645 var _108
=this.datasets
[_107
];
4646 if(PlotKit
.Base
.isFuncLike(_108
)){
4649 for(var j
=0;j
<_108
.length
;j
++){
4651 var rect
={y
:((parseFloat(item
[0])-this.minxval
)*this.xscale
)+(i
*_105
)+_106
,x
:0,h
:_105
,w
:((parseFloat(item
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(item
[0]),yval
:parseFloat(item
[1]),name
:_107
};
4658 if((rect
.x
>=0)&&(rect
.x
<=1)){
4659 this.bars
.push(rect
);
4665 PlotKit
.Layout
.prototype._evaluateLineCharts
=function(){
4666 var _111
=PlotKit
.Base
.items
;
4667 var _112
=_111(this.datasets
).length
;
4668 this.points
=new Array();
4670 for(var _113
in this.datasets
){
4671 var _114
=this.datasets
[_113
];
4672 if(PlotKit
.Base
.isFuncLike(_114
)){
4675 _114
.sort(function(a
,b
){
4676 return compare(parseFloat(a
[0]),parseFloat(b
[0]));
4678 for(var j
=0;j
<_114
.length
;j
++){
4680 var _117
={x
:((parseFloat(item
[0])-this.minxval
)*this.xscale
),y
:1-((parseFloat(item
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(item
[0]),yval
:parseFloat(item
[1]),name
:_113
};
4687 if((_117
.x
>=0)&&(_117
.x
<=1)){
4688 this.points
.push(_117
);
4694 PlotKit
.Layout
.prototype._evaluatePieCharts
=function(){
4695 var _118
=PlotKit
.Base
.items
;
4696 var sum
=MochiKit
.Iter
.sum
;
4697 var _120
=MochiKit
.Base
.itemgetter
;
4698 var _121
=_118(this.datasets
).length
;
4699 var _122
=_118(this.datasets
)[0][1];
4700 var _123
=sum(map(_120(1),_122
));
4701 this.slices
=new Array();
4703 for(var i
=0;i
<_122
.length
;i
++){
4704 var _125
=_122
[i
][1]/_123
;
4705 var _126
=_124
*Math
.PI
*2;
4706 var _127
=(_124
+_125
)*Math
.PI
*2;
4707 var _128
={fraction
:_125
,xval
:_122
[i
][0],yval
:_122
[i
][1],startAngle
:_126
,endAngle
:_127
};
4709 this.slices
.push(_128
);
4714 PlotKit
.Layout
.prototype._evaluateLineTicksForXAxis
=function(){
4715 var _129
=MochiKit
.Base
.isUndefinedOrNull
;
4716 if(this.options
.xTicks
){
4717 this.xticks
=new Array();
4718 var _130
=function(tick
){
4719 var _132
=tick
.label
;
4721 _132
=tick
.v
.toString();
4723 var pos
=this.xscale
*(tick
.v
-this.minxval
);
4724 if((pos
>=0)&&(pos
<=1)){
4725 this.xticks
.push([pos
,_132
]);
4728 MochiKit
.Iter
.forEach(this.options
.xTicks
,bind(_130
,this));
4730 if(this.options
.xNumberOfTicks
){
4731 var _134
=this._uniqueXValues();
4732 var _135
=this.xrange
/this.options
.xNumberOfTicks
;
4734 this.xticks
=new Array();
4735 for(var i
=0;i
<=_134
.length
;i
++){
4736 if((_134
[i
]-this.minxval
)>=(_136
*_135
)){
4737 var pos
=this.xscale
*(_134
[i
]-this.minxval
);
4738 if((pos
>1)||(pos
<0)){
4741 this.xticks
.push([pos
,_134
[i
]]);
4744 if(_136
>this.options
.xNumberOfTicks
){
4751 PlotKit
.Layout
.prototype._evaluateLineTicksForYAxis
=function(){
4752 var _137
=MochiKit
.Base
.isUndefinedOrNull
;
4753 if(this.options
.yTicks
){
4754 this.yticks
=new Array();
4755 var _138
=function(tick
){
4756 var _139
=tick
.label
;
4758 _139
=tick
.v
.toString();
4760 var pos
=1-(this.yscale
*(tick
.v
-this.minyval
));
4761 if((pos
>=0)&&(pos
<=1)){
4762 this.yticks
.push([pos
,_139
]);
4765 MochiKit
.Iter
.forEach(this.options
.yTicks
,bind(_138
,this));
4767 if(this.options
.yNumberOfTicks
){
4768 this.yticks
=new Array();
4769 var _140
=PlotKit
.Base
.roundInterval
;
4770 var prec
=this.options
.yTickPrecision
;
4771 var _142
=_140(this.yrange
,this.options
.yNumberOfTicks
,prec
);
4772 for(var i
=0;i
<=this.options
.yNumberOfTicks
;i
++){
4773 var yval
=this.minyval
+(i
*_142
);
4774 var pos
=1-((yval
-this.minyval
)*this.yscale
);
4775 if((pos
>1)||(pos
<0)){
4778 this.yticks
.push([pos
,MochiKit
.Format
.roundToFixed(yval
,prec
)]);
4783 PlotKit
.Layout
.prototype._evaluateLineTicks
=function(){
4784 this._evaluateLineTicksForXAxis();
4785 this._evaluateLineTicksForYAxis();
4787 PlotKit
.Layout
.prototype._evaluateBarTicks
=function(){
4788 this._evaluateLineTicks();
4789 var _144
=function(tick
){
4790 return [tick
[0]+(this.minxdelta
*this.xscale
)/2,tick
[1]];
4792 this.xticks
=MochiKit
.Base
.map(bind(_144
,this),this.xticks
);
4793 if(this.options
.barOrientation
=="horizontal"){
4794 var _145
=this.xticks
;
4795 this.xticks
=this.yticks
;
4797 var _146
=function(tick
){
4798 return [1-tick
[0],tick
[1]];
4800 this.xticks
=MochiKit
.Base
.map(_146
,this.xticks
);
4803 PlotKit
.Layout
.prototype._evaluatePieTicks
=function(){
4804 var _147
=MochiKit
.Base
.isUndefinedOrNull
;
4805 var _148
=MochiKit
.Format
.numberFormatter("#%");
4806 this.xticks
=new Array();
4807 if(this.options
.xTicks
){
4808 var _149
=new Array();
4809 for(var i
=0;i
<this.slices
.length
;i
++){
4810 _149
[this.slices
[i
].xval
]=this.slices
[i
];
4812 for(var i
=0;i
<this.options
.xTicks
.length
;i
++){
4813 var tick
=this.options
.xTicks
[i
];
4814 var _150
=_149
[tick
.v
];
4815 var _151
=tick
.label
;
4818 _151
=tick
.v
.toString();
4820 _151
+=" ("+_148(_150
.fraction
)+")";
4821 this.xticks
.push([tick
.v
,_151
]);
4825 for(var i
=0;i
<this.slices
.length
;i
++){
4826 var _150
=this.slices
[i
];
4827 var _151
=_150
.xval
+" ("+_148(_150
.fraction
)+")";
4828 this.xticks
.push([_150
.xval
,_151
]);
4832 PlotKit
.Layout
.prototype._regenerateHitTestCache
=function(){
4833 this.hitTestCache
.xvalues
=this._uniqueXValues();
4834 this.hitTestCache
.xlookup
=new Array();
4835 this.hitTestCache
.x2maxy
=new Array();
4836 var _152
=MochiKit
.Base
.listMax
;
4837 var _153
=MochiKit
.Base
.itemgetter
;
4838 var map
=MochiKit
.Base
.map
;
4839 var _154
=keys(this.datasets
);
4840 for(var i
=0;i
<_154
.length
;i
++){
4841 var _155
=this.datasets
[_154
[i
]];
4842 for(var j
=0;j
<_155
.length
;j
++){
4843 var xval
=_155
[j
][0];
4844 var yval
=_155
[j
][1];
4845 if(this.hitTestCache
.xlookup
[xval
]){
4846 this.hitTestCache
.xlookup
[xval
].push([yval
,_154
[i
]]);
4848 this.hitTestCache
.xlookup
[xval
]=[[yval
,_154
[i
]]];
4852 for(var x
in this.hitTestCache
.xlookup
){
4853 var _157
=this.hitTestCache
.xlookup
[x
];
4854 this.hitTestCache
.x2maxy
[x
]=_152(map(_153(0),_157
));
4857 PlotKit
.LayoutModule
={};
4858 PlotKit
.LayoutModule
.Layout
=PlotKit
.Layout
;
4859 PlotKit
.LayoutModule
.EXPORT
=["Layout"];
4860 PlotKit
.LayoutModule
.EXPORT_OK
=[];
4861 PlotKit
.LayoutModule
.__new__
=function(){
4862 var m
=MochiKit
.Base
;
4863 m
.nameFunctions(this);
4864 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
4866 PlotKit
.LayoutModule
.__new__();
4867 MochiKit
.Base
._exportSymbols(this,PlotKit
.LayoutModule
);
4869 if((typeof (PlotKit
.Base
)=="undefined")||(typeof (PlotKit
.Layout
)=="undefined")){
4874 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}";
4876 if(typeof (PlotKit
.CanvasRenderer
)=="undefined"){
4877 PlotKit
.CanvasRenderer
={};
4879 PlotKit
.CanvasRenderer
.NAME
="PlotKit.CanvasRenderer";
4880 PlotKit
.CanvasRenderer
.VERSION
=PlotKit
.VERSION
;
4881 PlotKit
.CanvasRenderer
.__repr__
=function(){
4882 return "["+this.NAME
+" "+this.VERSION
+"]";
4884 PlotKit
.CanvasRenderer
.toString
=function(){
4885 return this.__repr__();
4887 PlotKit
.CanvasRenderer
=function(_158
,_159
,_160
){
4888 if(arguments
.length
>0){
4889 this.__init__(_158
,_159
,_160
);
4892 PlotKit
.CanvasRenderer
.prototype.__init__
=function(_161
,_162
,_163
){
4893 var _164
=MochiKit
.Base
.isUndefinedOrNull
;
4894 var _165
=MochiKit
.Color
.Color
;
4895 this.options
={"drawBackground":true,"backgroundColor":_165
.whiteColor(),"padding":{left
:30,right
:30,top
:5,bottom
:10},"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[0]),"strokeColor":_165
.whiteColor(),"strokeColorTransform":"asStrokeColor","strokeWidth":0.5,"shouldFill":true,"shouldStroke":true,"drawXAxis":true,"drawYAxis":true,"axisLineColor":_165
.blackColor(),"axisLineWidth":0.5,"axisTickSize":3,"axisLabelColor":_165
.blackColor(),"axisLabelFont":"Arial","axisLabelFontSize":9,"axisLabelWidth":50,"pieRadius":0.4,"enableEvents":true};
4896 MochiKit
.Base
.update(this.options
,_163
?_163
:{});
4898 this.element
=MochiKit
.DOM
.getElement(_161
);
4899 this.container
=this.element
.parentNode
;
4900 this.isIE
=PlotKit
.Base
.excanvasSupported();
4901 if(this.isIE
&&!_164(G_vmlCanvasManager
)){
4904 this.renderDelay
=null;
4905 this.clearDelay
=null;
4906 this.element
=G_vmlCanvasManager
.initElement(this.element
);
4908 this.height
=this.element
.height
;
4909 this.width
=this.element
.width
;
4910 if(_164(this.element
)){
4911 throw "CanvasRenderer() - passed canvas is not found";
4913 if(!this.isIE
&&!(PlotKit
.CanvasRenderer
.isSupported(this.element
))){
4914 throw "CanvasRenderer() - Canvas is not supported.";
4916 if(_164(this.container
)||(this.container
.nodeName
.toLowerCase()!="div")){
4917 throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
4919 this.xlabels
=new Array();
4920 this.ylabels
=new Array();
4921 this.isFirstRender
=true;
4922 this.area
={x
:this.options
.padding
.left
,y
:this.options
.padding
.top
,w
:this.width
-this.options
.padding
.left
-this.options
.padding
.right
,h
:this.height
-this.options
.padding
.top
-this.options
.padding
.bottom
};
4923 MochiKit
.DOM
.updateNodeAttributes(this.container
,{"style":{"position":"relative","width":this.width
+"px"}});
4925 PlotKit
.CanvasRenderer
.prototype.render
=function(){
4928 if(this.renderDelay
){
4929 this.renderDelay
.cancel();
4930 this.renderDelay
=null;
4932 var _166
=this.element
.getContext("2d");
4935 this.isFirstRender
=false;
4936 if(this.maxTries
-->0){
4937 this.renderDelay
=MochiKit
.Async
.wait(this.IEDelay
);
4938 this.renderDelay
.addCallback(bind(this.render
,this));
4943 if(this.options
.drawBackground
){
4944 this._renderBackground();
4946 if(this.layout
.style
=="bar"){
4947 this._renderBarChart();
4948 this._renderBarAxis();
4950 if(this.layout
.style
=="pie"){
4951 this._renderPieChart();
4952 this._renderPieAxis();
4954 if(this.layout
.style
=="line"){
4955 this._renderLineChart();
4956 this._renderLineAxis();
4961 PlotKit
.CanvasRenderer
.prototype._renderBarChartWrap
=function(data
,_168
){
4962 var _169
=this.element
.getContext("2d");
4963 var _170
=this.options
.colorScheme
.length
;
4964 var _171
=this.options
.colorScheme
;
4965 var _172
=MochiKit
.Base
.keys(this.layout
.datasets
);
4966 var _173
=_172
.length
;
4967 for(var i
=0;i
<_173
;i
++){
4969 var _175
=_171
[i
%_170
];
4971 _169
.fillStyle
=_175
.toRGBString();
4972 if(this.options
.strokeColor
){
4973 _169
.strokeStyle
=this.options
.strokeColor
.toRGBString();
4975 if(this.options
.strokeColorTransform
){
4976 _169
.strokeStyle
=_175
[this.options
.strokeColorTransform
]().toRGBString();
4979 _169
.lineWidth
=this.options
.strokeWidth
;
4980 var _176
=function(obj
){
4985 MochiKit
.Iter
.forEach(data
,bind(_176
,this));
4989 PlotKit
.CanvasRenderer
.prototype._renderBarChart
=function(){
4990 var bind
=MochiKit
.Base
.bind
;
4991 var _178
=function(_179
,bar
){
4992 var x
=this.area
.w
*bar
.x
+this.area
.x
;
4993 var y
=this.area
.h
*bar
.y
+this.area
.y
;
4994 var w
=this.area
.w
*bar
.w
;
4995 var h
=this.area
.h
*bar
.h
;
4999 if(this.options
.shouldFill
){
5000 _179
.fillRect(x
,y
,w
,h
);
5002 if(this.options
.shouldStroke
){
5003 _179
.strokeRect(x
,y
,w
,h
);
5006 this._renderBarChartWrap(this.layout
.bars
,bind(_178
,this));
5008 PlotKit
.CanvasRenderer
.prototype._renderLineChart
=function(){
5009 var _182
=this.element
.getContext("2d");
5010 var _183
=this.options
.colorScheme
.length
;
5011 var _184
=this.options
.colorScheme
;
5012 var _185
=MochiKit
.Base
.keys(this.layout
.datasets
);
5013 var _186
=_185
.length
;
5014 var bind
=MochiKit
.Base
.bind
;
5015 var _187
=MochiKit
.Base
.partial
;
5016 for(var i
=0;i
<_186
;i
++){
5018 var _189
=_184
[i
%_183
];
5019 var _190
=this.options
.strokeColorTransform
;
5021 _182
.fillStyle
=_189
.toRGBString();
5022 if(this.options
.strokeColor
){
5023 _182
.strokeStyle
=this.options
.strokeColor
.toRGBString();
5025 if(this.options
.strokeColorTransform
){
5026 _182
.strokeStyle
=_189
[_190
]().toRGBString();
5029 _182
.lineWidth
=this.options
.strokeWidth
;
5030 var _191
=function(ctx
){
5032 ctx
.moveTo(this.area
.x
,this.area
.y
+this.area
.h
);
5033 var _193
=function(ctx_
,_195
){
5034 if(_195
.name
==_188
){
5035 ctx_
.lineTo(this.area
.w
*_195
.x
+this.area
.x
,this.area
.h
*_195
.y
+this.area
.y
);
5038 MochiKit
.Iter
.forEach(this.layout
.points
,_187(_193
,ctx
),this);
5039 ctx
.lineTo(this.area
.w
+this.area
.x
,this.area
.h
+this.area
.y
);
5040 ctx
.lineTo(this.area
.x
,this.area
.y
+this.area
.h
);
5043 if(this.options
.shouldFill
){
5044 bind(_191
,this)(_182
);
5047 if(this.options
.shouldStroke
){
5048 bind(_191
,this)(_182
);
5054 PlotKit
.CanvasRenderer
.prototype._renderPieChart
=function(){
5055 var _196
=this.element
.getContext("2d");
5056 var _197
=this.options
.colorScheme
.length
;
5057 var _198
=this.layout
.slices
;
5058 var _199
=this.area
.x
+this.area
.w
*0.5;
5059 var _200
=this.area
.y
+this.area
.h
*0.5;
5060 var _201
=Math
.min(this.area
.w
*this.options
.pieRadius
,this.area
.h
*this.options
.pieRadius
);
5062 _199
=parseInt(_199
);
5063 _200
=parseInt(_200
);
5064 _201
=parseInt(_201
);
5066 for(var i
=0;i
<_198
.length
;i
++){
5067 var _202
=this.options
.colorScheme
[i
%_197
];
5069 _196
.fillStyle
=_202
.toRGBString();
5070 var _203
=function(){
5072 _196
.moveTo(_199
,_200
);
5073 _196
.arc(_199
,_200
,_201
,_198
[i
].startAngle
-Math
.PI
/2,_198[i].endAngle-Math.PI/2,false);
5074 _196
.lineTo(_199
,_200
);
5077 if(Math
.abs(_198
[i
].startAngle
-_198
[i
].endAngle
)>0.001){
5078 if(this.options
.shouldFill
){
5082 if(this.options
.shouldStroke
){
5084 _196
.lineWidth
=this.options
.strokeWidth
;
5085 if(this.options
.strokeColor
){
5086 _196
.strokeStyle
=this.options
.strokeColor
.toRGBString();
5088 if(this.options
.strokeColorTransform
){
5089 _196
.strokeStyle
=_202
[this.options
.strokeColorTransform
]().toRGBString();
5098 PlotKit
.CanvasRenderer
.prototype._renderBarAxis
=function(){
5101 PlotKit
.CanvasRenderer
.prototype._renderLineAxis
=function(){
5104 PlotKit
.CanvasRenderer
.prototype._renderAxis
=function(){
5105 if(!this.options
.drawXAxis
&&!this.options
.drawYAxis
){
5108 var _204
=this.element
.getContext("2d");
5109 var _205
={"style":{"position":"absolute","fontSize":this.options
.axisLabelFontSize
+"px","zIndex":10,"color":this.options
.axisLabelColor
.toRGBString(),"width":this.options
.axisLabelWidth
+"px","overflow":"hidden"}};
5111 _204
.strokeStyle
=this.options
.axisLineColor
.toRGBString();
5112 _204
.lineWidth
=this.options
.axisLineWidth
;
5113 if(this.options
.drawYAxis
){
5114 if(this.layout
.yticks
){
5115 var _206
=function(tick
){
5116 if(typeof (tick
)=="function"){
5120 var y
=this.area
.y
+tick
[0]*this.area
.h
;
5123 _204
.lineTo(x
-this.options
.axisTickSize
,y
);
5126 var _207
=DIV(_205
,tick
[1]);
5127 _207
.style
.top
=(y
-this.options
.axisLabelFontSize
)+"px";
5128 _207
.style
.left
=(x
-this.options
.padding
.left
-this.options
.axisTickSize
)+"px";
5129 _207
.style
.textAlign
="right";
5130 _207
.style
.width
=(this.options
.padding
.left
-this.options
.axisTickSize
*2)+"px";
5131 MochiKit
.DOM
.appendChildNodes(this.container
,_207
);
5132 this.ylabels
.push(_207
);
5134 MochiKit
.Iter
.forEach(this.layout
.yticks
,bind(_206
,this));
5137 _204
.moveTo(this.area
.x
,this.area
.y
);
5138 _204
.lineTo(this.area
.x
,this.area
.y
+this.area
.h
);
5142 if(this.options
.drawXAxis
){
5143 if(this.layout
.xticks
){
5144 var _206
=function(tick
){
5145 if(typeof (dataset
)=="function"){
5148 var x
=this.area
.x
+tick
[0]*this.area
.w
;
5149 var y
=this.area
.y
+this.area
.h
;
5152 _204
.lineTo(x
,y
+this.options
.axisTickSize
);
5155 var _208
=DIV(_205
,tick
[1]);
5156 _208
.style
.top
=(y
+this.options
.axisTickSize
)+"px";
5157 _208
.style
.left
=(x
-this.options
.axisLabelWidth
/2)+"px";
5158 _208
.style
.textAlign
="center";
5159 _208
.style
.width
=this.options
.axisLabelWidth
+"px";
5160 MochiKit
.DOM
.appendChildNodes(this.container
,_208
);
5161 this.xlabels
.push(_208
);
5163 MochiKit
.Iter
.forEach(this.layout
.xticks
,bind(_206
,this));
5166 _204
.moveTo(this.area
.x
,this.area
.y
+this.area
.h
);
5167 _204
.lineTo(this.area
.x
+this.area
.w
,this.area
.y
+this.area
.h
);
5173 PlotKit
.CanvasRenderer
.prototype._renderPieAxis
=function(){
5174 if(!this.options
.drawXAxis
){
5177 if(this.layout
.xticks
){
5178 var _209
=new Array();
5179 for(var i
=0;i
<this.layout
.slices
.length
;i
++){
5180 _209
[this.layout
.slices
[i
].xval
]=this.layout
.slices
[i
];
5182 var _210
=this.area
.x
+this.area
.w
*0.5;
5183 var _211
=this.area
.y
+this.area
.h
*0.5;
5184 var _212
=Math
.min(this.area
.w
*this.options
.pieRadius
,this.area
.h
*this.options
.pieRadius
);
5185 var _213
=this.options
.axisLabelWidth
;
5186 for(var i
=0;i
<this.layout
.xticks
.length
;i
++){
5187 var _214
=_209
[this.layout
.xticks
[i
][0]];
5188 if(MochiKit
.Base
.isUndefinedOrNull(_214
)){
5191 var _215
=(_214
.startAngle
+_214
.endAngle
)/2;
5194 _216
=_216
-Math
.PI
*2;
5197 _216
=_216
+Math
.PI
*2;
5200 var _217
=_210
+Math
.sin(_216
)*(_212
+10);
5201 var _218
=_211
-Math
.cos(_216
)*(_212
+10);
5202 var _219
={"position":"absolute","zIndex":11,"width":_213
+"px","fontSize":this.options
.axisLabelFontSize
+"px","overflow":"hidden","color":this.options
.axisLabelColor
.toHexString()};
5203 if(_216
<=Math
.PI
*0.5){
5204 _219
["textAlign"]="left";
5205 _219
["verticalAlign"]="top";
5206 _219
["left"]=_217
+"px";
5207 _219
["top"]=(_218
-this.options
.axisLabelFontSize
)+"px";
5209 if((_216
>Math
.PI
*0.5)&&(_216
<=Math
.PI
)){
5210 _219
["textAlign"]="left";
5211 _219
["verticalAlign"]="bottom";
5212 _219
["left"]=_217
+"px";
5213 _219
["top"]=_218
+"px";
5215 if((_216
>Math
.PI
)&&(_216
<=Math
.PI
*1.5)){
5216 _219
["textAlign"]="right";
5217 _219
["verticalAlign"]="bottom";
5218 _219
["left"]=(_217
-_213
)+"px";
5219 _219
["top"]=_218
+"px";
5221 _219
["textAlign"]="right";
5222 _219
["verticalAlign"]="bottom";
5223 _219
["left"]=(_217
-_213
)+"px";
5224 _219
["top"]=(_218
-this.options
.axisLabelFontSize
)+"px";
5228 var _220
=DIV({"style":_219
},this.layout
.xticks
[i
][1]);
5229 this.xlabels
.push(_220
);
5230 MochiKit
.DOM
.appendChildNodes(this.container
,_220
);
5234 PlotKit
.CanvasRenderer
.prototype._renderBackground
=function(){
5235 var _221
=this.element
.getContext("2d");
5237 _221
.fillStyle
=this.options
.backgroundColor
.toRGBString();
5238 _221
.fillRect(0,0,this.width
,this.height
);
5241 PlotKit
.CanvasRenderer
.prototype.clear
=function(){
5244 if(this.clearDelay
){
5245 this.clearDelay
.cancel();
5246 this.clearDelay
=null;
5248 var _222
=this.element
.getContext("2d");
5251 this.isFirstRender
=false;
5252 this.clearDelay
=MochiKit
.Async
.wait(this.IEDelay
);
5253 this.clearDelay
.addCallback(bind(this.clear
,this));
5257 var _222
=this.element
.getContext("2d");
5258 _222
.clearRect(0,0,this.width
,this.height
);
5259 MochiKit
.Iter
.forEach(this.xlabels
,MochiKit
.DOM
.removeElement
);
5260 MochiKit
.Iter
.forEach(this.ylabels
,MochiKit
.DOM
.removeElement
);
5261 this.xlabels
=new Array();
5262 this.ylabels
=new Array();
5264 PlotKit
.CanvasRenderer
.prototype._initialiseEvents
=function(){
5265 var _223
=MochiKit
.Signal
.connect
;
5266 var bind
=MochiKit
.Base
.bind
;
5267 _223(this.element
,"onclick",bind(this.onclick
,this));
5269 PlotKit
.CanvasRenderer
.prototype._resolveObject
=function(e
){
5270 var x
=(e
.mouse().page
.x
-PlotKit
.Base
.findPosX(this.element
)-this.area
.x
)/this.area
.w
;
5271 var y
=(e
.mouse().page
.y
-PlotKit
.Base
.findPosY(this.element
)-this.area
.y
)/this.area
.h
;
5272 var _225
=this.layout
.hitTest(x
,y
);
5278 PlotKit
.CanvasRenderer
.prototype._createEventObject
=function(_226
,e
){
5285 PlotKit
.CanvasRenderer
.prototype.onclick
=function(e
){
5286 var _227
=this._resolveObject(e
);
5287 var _228
=this._createEventObject(_227
,e
);
5289 MochiKit
.Signal
.signal(this,"onclick",_228
);
5292 PlotKit
.CanvasRenderer
.prototype.onmouseover
=function(e
){
5293 var _229
=this._resolveObject(e
);
5294 var _230
=this._createEventObject(_229
,e
);
5296 signal(this,"onmouseover",_230
);
5299 PlotKit
.CanvasRenderer
.prototype.onmouseout
=function(e
){
5300 var _231
=this._resolveObject(e
);
5301 var _232
=this._createEventObject(_231
,e
);
5303 signal(this,"onmouseout",e
);
5305 signal(this,"onmouseout",_232
);
5308 PlotKit
.CanvasRenderer
.prototype.onmousemove
=function(e
){
5309 var _233
=this._resolveObject(e
);
5310 var _234
=this._createEventObject(_233
,e
);
5311 if((_233
==null)&&(this.event_isinside
==null)){
5314 if((_233
!=null)&&(this.event_isinside
==null)){
5315 signal(this,"onmouseover",_234
);
5317 if((_233
==null)&&(this.event_isinside
!=null)){
5318 signal(this,"onmouseout",_234
);
5320 if((_233
!=null)&&(this.event_isinside
!=null)){
5321 signal(this,"onmousemove",_234
);
5323 this.event_isinside
=_233
;
5325 PlotKit
.CanvasRenderer
.isSupported
=function(_235
){
5328 if(MochiKit
.Base
.isUndefinedOrNull(_235
)){
5329 _236
=MochiKit
.DOM
.CANVAS({});
5331 _236
=MochiKit
.DOM
.getElement(_235
);
5333 var _237
=_236
.getContext("2d");
5336 var ie
=navigator
.appVersion
.match(/MSIE (\d\.\d)/);
5337 var _239
=(navigator
.userAgent
.toLowerCase().indexOf("opera")!=-1);
5338 if((!ie
)||(ie
[1]<6)||(_239
)){
5346 PlotKit
.Canvas
.CanvasRenderer
=PlotKit
.CanvasRenderer
;
5347 PlotKit
.Canvas
.EXPORT
=["CanvasRenderer"];
5348 PlotKit
.Canvas
.EXPORT_OK
=["CanvasRenderer"];
5349 PlotKit
.Canvas
.__new__
=function(){
5350 var m
=MochiKit
.Base
;
5351 m
.nameFunctions(this);
5352 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
5354 PlotKit
.Canvas
.__new__();
5355 MochiKit
.Base
._exportSymbols(this,PlotKit
.Canvas
);
5358 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
5359 // All Rights Reserved.
5362 * @fileoverview Subclasses various parts of PlotKit to meet the additional
5363 * needs of DateGraph: grid overlays and error bars
5366 // Subclass PlotKit.Layout to add:
5367 // 1. Sigma/errorBars properties
5368 // 2. Copy error terms for PlotKit.CanvasRenderer._renderLineChart
5371 * Creates a new DateGraphLayout object. Options are the same as those allowed
5372 * by the PlotKit.Layout constructor.
5373 * @param {Object} options Options for PlotKit.Layout
5374 * @return {Object} The DateGraphLayout object
5376 DateGraphLayout
= function(options
) {
5377 PlotKit
.Layout
.call(this, "line", options
);
5379 DateGraphLayout
.prototype = new PlotKit
.Layout();
5382 * Behaves the same way as PlotKit.Layout, but also copies the errors
5385 DateGraphLayout
.prototype.evaluateWithError
= function() {
5387 if (!this.options
.errorBars
) return;
5389 // Copy over the error terms
5390 var i
= 0; // index in this.points
5391 for (var setName
in this.datasets
) {
5393 var dataset
= this.datasets
[setName
];
5394 if (PlotKit
.Base
.isFuncLike(dataset
)) continue;
5395 for (var j
= 0; j
< dataset
.length
; j
++, i
++) {
5396 var item
= dataset
[j
];
5397 var xv
= parseFloat(item
[0]);
5398 var yv
= parseFloat(item
[1]);
5400 if (xv
== this.points
[i
].xval
&&
5401 yv
== this.points
[i
].yval
) {
5402 this.points
[i
].errorMinus
= parseFloat(item
[2]);
5403 this.points
[i
].errorPlus
= parseFloat(item
[3]);
5410 * Convenience function to remove all the data sets from a graph
5412 DateGraphLayout
.prototype.removeAllDatasets
= function() {
5413 delete this.datasets
;
5414 this.datasets
= new Array();
5418 * Change the values of various layout options
5419 * @param {Object} new_options an associative array of new properties
5421 DateGraphLayout
.prototype.updateOptions
= function(new_options
) {
5422 MochiKit
.Base
.update(this.options
, new_options
? new_options
: {});
5425 // Subclass PlotKit.CanvasRenderer to add:
5426 // 1. X/Y grid overlay
5427 // 2. Ability to draw error bars (if required)
5430 * Sets some PlotKit.CanvasRenderer options
5431 * @param {Object} element The canvas to attach to
5432 * @param {Layout} layout The DateGraphLayout object for this graph.
5433 * @param {Object} options Options to pass on to CanvasRenderer
5435 DateGraphCanvasRenderer
= function(element
, layout
, options
) {
5436 PlotKit
.CanvasRenderer
.call(this, element
, layout
, options
);
5437 this.options
.shouldFill
= false;
5438 this.options
.shouldStroke
= true;
5439 this.options
.drawYGrid
= true;
5440 this.options
.drawXGrid
= true;
5441 this.options
.gridLineColor
= MochiKit
.Color
.Color
.grayColor();
5442 MochiKit
.Base
.update(this.options
, options
);
5444 // TODO(danvk) This shouldn't be necessary: effects should be overlaid
5445 this.options
.drawBackground
= false;
5447 DateGraphCanvasRenderer
.prototype = new PlotKit
.CanvasRenderer();
5450 * Draw an X/Y grid on top of the existing plot
5452 DateGraphCanvasRenderer
.prototype.render
= function() {
5453 // Do the ordinary rendering, as before
5454 // TODO(danvk) Call super.render()
5455 this._renderLineChart();
5456 this._renderLineAxis();
5458 // Draw the new X/Y grid
5459 var ctx
= this.element
.getContext("2d");
5460 if (this.options
.drawYGrid
) {
5461 var ticks
= this.layout
.yticks
;
5463 ctx
.strokeStyle
= this.options
.gridLineColor
.toRGBString();
5464 ctx
.lineWidth
= this.options
.axisLineWidth
;
5465 for (var i
= 0; i
< ticks
.length
; i
++) {
5466 var x
= this.area
.x
;
5467 var y
= this.area
.y
+ ticks
[i
][0] * this.area
.h
;
5470 ctx
.lineTo(x
+ this.area
.w
, y
);
5476 if (this.options
.drawXGrid
) {
5477 var ticks
= this.layout
.xticks
;
5479 ctx
.strokeStyle
= this.options
.gridLineColor
.toRGBString();
5480 ctx
.lineWidth
= this.options
.axisLineWidth
;
5481 for (var i
=0; i
<ticks
.length
; i
++) {
5482 var x
= this.area
.x
+ ticks
[i
][0] * this.area
.w
;
5483 var y
= this.area
.y
+ this.area
.h
;
5486 ctx
.lineTo(x
, this.area
.y
);
5494 * Overrides the CanvasRenderer method to draw error bars
5496 DateGraphCanvasRenderer
.prototype._renderLineChart
= function() {
5497 var context
= this.element
.getContext("2d");
5498 var colorCount
= this.options
.colorScheme
.length
;
5499 var colorScheme
= this.options
.colorScheme
;
5500 var setNames
= MochiKit
.Base
.keys(this.layout
.datasets
);
5501 var errorBars
= this.layout
.options
.errorBars
;
5502 var setCount
= setNames
.length
;
5503 var bind
= MochiKit
.Base
.bind
;
5504 var partial
= MochiKit
.Base
.partial
;
5507 var updatePoint
= function(point
) {
5508 point
.canvasx
= this.area
.w
* point
.x
+ this.area
.x
;
5509 point
.canvasy
= this.area
.h
* point
.y
+ this.area
.y
;
5511 MochiKit
.Iter
.forEach(this.layout
.points
, updatePoint
, this);
5514 var makePath
= function(ctx
) {
5515 for (var i
= 0; i
< setCount
; i
++) {
5516 var setName
= setNames
[i
];
5517 var color
= colorScheme
[i
%colorCount
];
5518 var strokeX
= this.options
.strokeColorTransform
;
5520 // setup graphics context
5522 context
.strokeStyle
= color
.toRGBString();
5523 context
.lineWidth
= this.options
.strokeWidth
;
5525 var point
= this.layout
.points
[0];
5526 var first_point
= true;
5527 var addPoint
= function(ctx_
, point
) {
5528 if (point
.name
== setName
) {
5530 ctx_
.moveTo(point
.canvasx
, point
.canvasy
);
5532 ctx_
.lineTo(point
.canvasx
, point
.canvasy
);
5533 first_point
= false;
5536 MochiKit
.Iter
.forEach(this.layout
.points
, partial(addPoint
, ctx
), this);
5541 var makeErrorBars
= function(ctx
) {
5542 for (var i
= 0; i
< setCount
; i
++) {
5543 var setName
= setNames
[i
];
5544 var color
= colorScheme
[i
% colorCount
];
5545 var strokeX
= this.options
.strokeColorTransform
;
5547 // setup graphics context
5549 context
.strokeStyle
= color
.toRGBString();
5550 context
.lineWidth
= this.options
.strokeWidth
;
5552 var prevYs
= [-1, -1];
5554 var yscale
= this.layout
.yscale
;
5555 var errorTrapezoid
= function(ctx_
,point
) {
5557 if (point
.name
== setName
) {
5558 var newYs
= [ point
.y
- point
.errorPlus
* yscale
,
5559 point
.y
+ point
.errorMinus
* yscale
];
5560 newYs
[0] = this.area
.h
* newYs
[0] + this.area
.y
;
5561 newYs
[1] = this.area
.h
* newYs
[1] + this.area
.y
;
5563 ctx_
.moveTo(prevX
, prevYs
[0]);
5564 ctx_
.lineTo(point
.canvasx
, newYs
[0]);
5565 ctx_
.lineTo(point
.canvasx
, newYs
[1]);
5566 ctx_
.lineTo(prevX
, prevYs
[1]);
5569 prevYs
[0] = newYs
[0];
5570 prevYs
[1] = newYs
[1];
5571 prevX
= point
.canvasx
;
5574 // should be same color as the lines
5575 var err_color
= color
.colorWithAlpha(0.15);
5576 ctx
.fillStyle
= err_color
.toRGBString();
5578 MochiKit
.Iter
.forEach(this.layout
.points
, partial(errorTrapezoid
, ctx
), this);
5584 bind(makeErrorBars
, this)(context
);
5585 bind(makePath
, this)(context
);
5588 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
5589 // All Rights Reserved.
5592 * @fileoverview Creates an interactive, zoomable graph based on a CSV file or
5593 * string. DateGraph can handle multiple series with or without error bars. The
5594 * date/value ranges will be automatically set. DateGraph uses the
5595 * <canvas> tag, so it only works in FF1.5+.
5596 * @author danvdk@gmail.com (Dan Vanderkam)
5599 <div id="graphdiv" style="width:800px; height:500px;"></div>
5600 <script type="text/javascript">
5601 new DateGraph(document.getElementById("graphdiv"),
5603 ["Series 1", "Series 2"],
5607 The CSV file is of the form
5612 If null is passed as the third parameter (series names), then the first line
5613 of the CSV file is assumed to contain names for each series.
5615 If the 'errorBars' option is set in the constructor, the input should be of
5618 YYYYMMDD,A1,sigmaA1,B1,sigmaB1,...
5619 YYYYMMDD,A2,sigmaA2,B2,sigmaB2,...
5621 If the 'fractions' option is set, the input should be of the form:
5623 YYYYMMDD,A1/B1,A2/B2,...
5624 YYYYMMDD,A1/B1,A2/B2,...
5626 And error bars will be calculated automatically using a binomial distribution.
5628 For further documentation and examples, see http://www/~danvk/dg/
5633 * An interactive, zoomable graph
5634 * @param {String | Function} file A file containing CSV data or a function that
5635 * returns this data. The expected format for each line is
5636 * YYYYMMDD,val1,val2,... or, if attrs.errorBars is set,
5637 * YYYYMMDD,val1,stddev1,val2,stddev2,...
5638 * @param {Array.<String>} labels Labels for the data series
5639 * @param {Object} attrs Various other attributes, e.g. errorBars determines
5640 * whether the input data contains error ranges.
5642 DateGraph
= function(div
, file
, labels
, attrs
) {
5643 if (arguments
.length
> 0)
5644 this.__init__(div
, file
, labels
, attrs
);
5647 DateGraph
.NAME
= "DateGraph";
5648 DateGraph
.VERSION
= "1.1";
5649 DateGraph
.__repr__
= function() {
5650 return "[" + this.NAME
+ " " + this.VERSION
+ "]";
5652 DateGraph
.toString
= function() {
5653 return this.__repr__();
5656 // Various default values
5657 DateGraph
.DEFAULT_ROLL_PERIOD
= 1;
5658 DateGraph
.DEFAULT_WIDTH
= 480;
5659 DateGraph
.DEFAULT_HEIGHT
= 320;
5660 DateGraph
.DEFAULT_STROKE_WIDTH
= 1.0;
5661 DateGraph
.AXIS_LINE_WIDTH
= 0.3;
5664 * Initializes the DateGraph. This creates a new DIV and constructs the PlotKit
5665 * and interaction <canvas> inside of it. See the constructor for details
5666 * on the parameters.
5667 * @param {String | Function} file Source data
5668 * @param {Array.<String>} labels Names of the data series
5669 * @param {Object} attrs Miscellaneous other options
5672 DateGraph
.prototype.__init__
= function(div
, file
, labels
, attrs
) {
5673 // Copy the important bits into the object
5674 this.maindiv_
= div
;
5675 this.labels_
= labels
;
5677 this.rollPeriod_
= attrs
.rollPeriod
|| DateGraph
.DEFAULT_ROLL_PERIOD
;
5678 this.previousVerticalX_
= -1;
5679 this.width_
= parseInt(div
.style
.width
, 10);
5680 this.height_
= parseInt(div
.style
.height
, 10);
5681 this.errorBars_
= attrs
.errorBars
|| false;
5682 this.fractions_
= attrs
.fractions
|| false;
5683 this.strokeWidth_
= attrs
.strokeWidth
|| DateGraph
.DEFAULT_STROKE_WIDTH
;
5684 this.dateWindow_
= attrs
.dateWindow
|| null;
5685 this.valueRange_
= attrs
.valueRange
|| null;
5686 this.labelsSeparateLines
= attrs
.labelsSeparateLines
|| false;
5687 this.labelsDiv_
= attrs
.labelsDiv
|| null;
5688 this.labelsKMB_
= attrs
.labelsKMB
|| false;
5689 this.minTickSize_
= attrs
.minTickSize
|| 0;
5690 this.xValueParser_
= attrs
.xValueParser
|| DateGraph
.prototype.dateParser
;
5691 this.xValueFormatter_
= attrs
.xValueFormatter
||
5692 DateGraph
.prototype.dateString_
;
5693 this.xTicker_
= attrs
.xTicker
|| DateGraph
.prototype.dateTicker
;
5694 this.sigma_
= attrs
.sigma
|| 2.0;
5695 this.wilsonInterval_
= attrs
.wilsonInterval
|| true;
5696 this.customBars_
= attrs
.customBars
|| false;
5697 this.attrs_
= attrs
;
5699 // Make a note of whether labels will be pulled from the CSV file.
5700 this.labelsFromCSV_
= (this.labels_
== null);
5701 if (this.labels_
== null)
5704 // Prototype of the callback is "void clickCallback(event, date)"
5705 this.clickCallback_
= attrs
.clickCallback
|| null;
5707 // Prototype of zoom callback is "void dragCallback(minDate, maxDate)"
5708 this.zoomCallback_
= attrs
.zoomCallback
|| null;
5710 // Create the containing DIV and other interactive elements
5711 this.createInterface_();
5713 // Create the PlotKit grapher
5714 this.layoutOptions_
= { 'errorBars': (this.errorBars_
|| this.customBars_
),
5715 'xOriginIsZero': false };
5716 MochiKit
.Base
.update(this.layoutOptions_
, attrs
);
5717 this.setColors_(attrs
);
5719 this.layout_
= new DateGraphLayout(this.layoutOptions_
);
5721 this.renderOptions_
= { colorScheme
: this.colors_
,
5723 strokeWidth
: this.strokeWidth_
,
5724 axisLabelFontSize
: 14,
5725 axisLineWidth
: DateGraph
.AXIS_LINE_WIDTH
};
5726 MochiKit
.Base
.update(this.renderOptions_
, attrs
);
5727 this.plotter_
= new DateGraphCanvasRenderer(this.hidden_
, this.layout_
,
5728 this.renderOptions_
);
5730 this.createStatusMessage_();
5731 this.createRollInterface_();
5732 this.createDragInterface_();
5734 connect(window
, 'onload', this, function(e
) { this.start_(); });
5738 * Returns the current rolling period, as set by the user or an option.
5739 * @return {Number} The number of days in the rolling window
5741 DateGraph
.prototype.rollPeriod
= function() {
5742 return this.rollPeriod_
;
5746 * Generates interface elements for the DateGraph: a containing div, a div to
5747 * display the current point, and a textbox to adjust the rolling average
5751 DateGraph
.prototype.createInterface_
= function() {
5752 // Create the all-enclosing graph div
5753 var enclosing
= this.maindiv_
;
5755 this.graphDiv
= MochiKit
.DOM
.DIV( { style
: { 'width': this.width_
+ "px",
5756 'height': this.height_
+ "px"
5758 appendChildNodes(enclosing
, this.graphDiv
);
5760 // Create the canvas to store
5761 var canvas
= MochiKit
.DOM
.CANVAS
;
5762 this.canvas_
= canvas( { style
: { 'position': 'absolute' },
5764 height
: this.height_
});
5765 appendChildNodes(this.graphDiv
, this.canvas_
);
5767 this.hidden_
= this.createPlotKitCanvas_(this.canvas_
);
5768 connect(this.hidden_
, 'onmousemove', this, function(e
) { this.mouseMove_(e
) });
5769 connect(this.hidden_
, 'onmouseout', this, function(e
) { this.mouseOut_(e
) });
5773 * Creates the canvas containing the PlotKit graph. Only plotkit ever draws on
5774 * this particular canvas. All DateGraph work is done on this.canvas_.
5775 * @param {Object} canvas The DateGraph canvas to over which to overlay the plot
5776 * @return {Object} The newly-created canvas
5779 DateGraph
.prototype.createPlotKitCanvas_
= function(canvas
) {
5780 var h
= document
.createElement("canvas");
5781 h
.style
.position
= "absolute";
5782 h
.style
.top
= canvas
.style
.top
;
5783 h
.style
.left
= canvas
.style
.left
;
5784 h
.width
= this.width_
;
5785 h
.height
= this.height_
;
5786 MochiKit
.DOM
.appendChildNodes(this.graphDiv
, h
);
5791 * Generate a set of distinct colors for the data series. This is done with a
5792 * color wheel. Saturation/Value are customizable, and the hue is
5793 * equally-spaced around the color wheel. If a custom set of colors is
5794 * specified, that is used instead.
5795 * @param {Object} attrs Various attributes, e.g. saturation and value
5798 DateGraph
.prototype.setColors_
= function(attrs
) {
5799 var num
= this.labels_
.length
;
5801 if (!attrs
.colors
) {
5802 var sat
= attrs
.colorSaturation
|| 1.0;
5803 var val
= attrs
.colorValue
|| 0.5;
5804 for (var i
= 1; i
<= num
; i
++) {
5805 var hue
= (1.0*i
/(1+num
));
5806 this.colors_
.push( MochiKit
.Color
.Color
.fromHSV(hue
, sat
, val
) );
5809 for (var i
= 0; i
< num
; i
++) {
5810 var colorStr
= attrs
.colors
[i
% attrs
.colors
.length
];
5811 this.colors_
.push( MochiKit
.Color
.Color
.fromString(colorStr
) );
5817 * Create the div that contains information on the selected point(s)
5818 * This goes in the top right of the canvas, unless an external div has already
5822 DateGraph
.prototype.createStatusMessage_
= function(){
5823 if (!this.labelsDiv_
) {
5825 var messagestyle
= { "style": {
5826 "position": "absolute",
5829 "width": divWidth
+ "px",
5831 "left": this.width_
- divWidth
+ "px",
5832 "background": "white",
5833 "textAlign": "left",
5834 "overflow": "hidden"}};
5835 this.labelsDiv_
= MochiKit
.DOM
.DIV(messagestyle
);
5836 MochiKit
.DOM
.appendChildNodes(this.graphDiv
, this.labelsDiv_
);
5841 * Create the text box to adjust the averaging period
5842 * @return {Object} The newly-created text box
5845 DateGraph
.prototype.createRollInterface_
= function() {
5846 var padding
= this.plotter_
.options
.padding
;
5847 var textAttr
= { "type": "text",
5849 "value": this.rollPeriod_
,
5850 "style": { "position": "absolute",
5852 "top": (this.height_
- 25 - padding
.bottom
) + "px",
5853 "left": (padding
.left
+1) + "px" }
5855 var roller
= MochiKit
.DOM
.INPUT(textAttr
);
5856 var pa
= this.graphDiv
;
5857 MochiKit
.DOM
.appendChildNodes(pa
, roller
);
5858 connect(roller
, 'onchange', this,
5859 function() { this.adjustRoll(roller
.value
); });
5864 * Set up all the mouse handlers needed to capture dragging behavior for zoom
5865 * events. Uses MochiKit.Signal to attach all the event handlers.
5868 DateGraph
.prototype.createDragInterface_
= function() {
5871 // Tracks whether the mouse is down right now
5872 var mouseDown
= false;
5873 var dragStartX
= null;
5874 var dragStartY
= null;
5875 var dragEndX
= null;
5876 var dragEndY
= null;
5877 var prevEndX
= null;
5879 // Utility function to convert page-wide coordinates to canvas coords
5880 var px
= PlotKit
.Base
.findPosX(this.canvas_
);
5881 var py
= PlotKit
.Base
.findPosY(this.canvas_
);
5882 var getX
= function(e
) { return e
.mouse().page
.x
- px
};
5883 var getY
= function(e
) { return e
.mouse().page
.y
- py
};
5885 // Draw zoom rectangles when the mouse is down and the user moves around
5886 connect(this.hidden_
, 'onmousemove', function(event
) {
5888 dragEndX
= getX(event
);
5889 dragEndY
= getY(event
);
5891 self
.drawZoomRect_(dragStartX
, dragEndX
, prevEndX
);
5892 prevEndX
= dragEndX
;
5896 // Track the beginning of drag events
5897 connect(this.hidden_
, 'onmousedown', function(event
) {
5899 dragStartX
= getX(event
);
5900 dragStartY
= getY(event
);
5903 // If the user releases the mouse button during a drag, but not over the
5904 // canvas, then it doesn't count as a zooming action.
5905 connect(document
, 'onmouseup', this, function(event
) {
5913 // Temporarily cancel the dragging event when the mouse leaves the graph
5914 connect(this.hidden_
, 'onmouseout', this, function(event
) {
5921 // If the mouse is released on the canvas during a drag event, then it's a
5922 // zoom. Only do the zoom if it's over a large enough area (>= 10 pixels)
5923 connect(this.hidden_
, 'onmouseup', this, function(event
) {
5926 dragEndX
= getX(event
);
5927 dragEndY
= getY(event
);
5928 var regionWidth
= Math
.abs(dragEndX
- dragStartX
);
5929 var regionHeight
= Math
.abs(dragEndY
- dragStartY
);
5931 if (regionWidth
< 2 && regionHeight
< 2 &&
5932 self
.clickCallback_
!= null &&
5933 self
.lastx_
!= undefined
) {
5934 self
.clickCallback_(event
, new Date(self
.lastx_
));
5937 if (regionWidth
>= 10) {
5938 self
.doZoom_(Math
.min(dragStartX
, dragEndX
),
5939 Math
.max(dragStartX
, dragEndX
));
5941 self
.canvas_
.getContext("2d").clearRect(0, 0,
5943 self
.canvas_
.height
);
5951 // Double-clicking zooms back out
5952 connect(this.hidden_
, 'ondblclick', this, function(event
) {
5953 self
.dateWindow_
= null;
5954 self
.drawGraph_(self
.rawData_
);
5955 var minDate
= self
.rawData_
[0][0];
5956 var maxDate
= self
.rawData_
[self
.rawData_
.length
- 1][0];
5957 self
.zoomCallback_(minDate
, maxDate
);
5962 * Draw a gray zoom rectangle over the desired area of the canvas. Also clears
5963 * up any previous zoom rectangles that were drawn. This could be optimized to
5964 * avoid extra redrawing, but it's tricky to avoid interactions with the status
5966 * @param {Number} startX The X position where the drag started, in canvas
5968 * @param {Number} endX The current X position of the drag, in canvas coords.
5969 * @param {Number} prevEndX The value of endX on the previous call to this
5970 * function. Used to avoid excess redrawing
5973 DateGraph
.prototype.drawZoomRect_
= function(startX
, endX
, prevEndX
) {
5974 var ctx
= this.canvas_
.getContext("2d");
5976 // Clean up from the previous rect if necessary
5978 ctx
.clearRect(Math
.min(startX
, prevEndX
), 0,
5979 Math
.abs(startX
- prevEndX
), this.height_
);
5982 // Draw a light-grey rectangle to show the new viewing area
5983 if (endX
&& startX
) {
5984 ctx
.fillStyle
= "rgba(128,128,128,0.33)";
5985 ctx
.fillRect(Math
.min(startX
, endX
), 0,
5986 Math
.abs(endX
- startX
), this.height_
);
5991 * Zoom to something containing [lowX, highX]. These are pixel coordinates
5992 * in the canvas. The exact zoom window may be slightly larger if there are no
5993 * data points near lowX or highX. This function redraws the graph.
5994 * @param {Number} lowX The leftmost pixel value that should be visible.
5995 * @param {Number} highX The rightmost pixel value that should be visible.
5998 DateGraph
.prototype.doZoom_
= function(lowX
, highX
) {
5999 // Find the earliest and latest dates contained in this canvasx range.
6000 var points
= this.layout_
.points
;
6003 // Find the nearest [minDate, maxDate] that contains [lowX, highX]
6004 for (var i
= 0; i
< points
.length
; i
++) {
6005 var cx
= points
[i
].canvasx
;
6006 var x
= points
[i
].xval
;
6007 if (cx
< lowX
&& (minDate
== null || x
> minDate
)) minDate
= x
;
6008 if (cx
> highX
&& (maxDate
== null || x
< maxDate
)) maxDate
= x
;
6010 // Use the extremes if either is missing
6011 if (minDate
== null) minDate
= points
[0].xval
;
6012 if (maxDate
== null) maxDate
= points
[points
.length
-1].xval
;
6014 this.dateWindow_
= [minDate
, maxDate
];
6015 this.drawGraph_(this.rawData_
);
6016 this.zoomCallback_(minDate
, maxDate
);
6020 * When the mouse moves in the canvas, display information about a nearby data
6021 * point and draw dots over those points in the data series. This function
6022 * takes care of cleanup of previously-drawn dots.
6023 * @param {Object} event The mousemove event from the browser.
6026 DateGraph
.prototype.mouseMove_
= function(event
) {
6027 var canvasx
= event
.mouse().page
.x
- PlotKit
.Base
.findPosX(this.hidden_
);
6028 var points
= this.layout_
.points
;
6033 // Loop through all the points and find the date nearest to our current
6035 var minDist
= 1e+100;
6037 for (var i
= 0; i
< points
.length
; i
++) {
6038 var dist
= Math
.abs(points
[i
].canvasx
- canvasx
);
6039 if (dist
> minDist
) break;
6043 if (idx
>= 0) lastx
= points
[idx
].xval
;
6044 // Check that you can really highlight the last day's data
6045 if (canvasx
> points
[points
.length
-1].canvasx
)
6046 lastx
= points
[points
.length
-1].xval
;
6048 // Extract the points we've selected
6050 for (var i
= 0; i
< points
.length
; i
++) {
6051 if (points
[i
].xval
== lastx
) {
6052 selPoints
.push(points
[i
]);
6056 // Clear the previously drawn vertical, if there is one
6058 var ctx
= this.canvas_
.getContext("2d");
6059 if (this.previousVerticalX_
>= 0) {
6060 var px
= this.previousVerticalX_
;
6061 ctx
.clearRect(px
- circleSize
- 1, 0, 2 * circleSize
+ 2, this.height_
);
6064 if (selPoints
.length
> 0) {
6065 var canvasx
= selPoints
[0].canvasx
;
6067 // Set the status message to indicate the selected point(s)
6068 var replace
= this.xValueFormatter_(lastx
) + ":";
6069 var clen
= this.colors_
.length
;
6070 for (var i
= 0; i
< selPoints
.length
; i
++) {
6071 if (this.labelsSeparateLines
) {
6074 var point
= selPoints
[i
];
6075 replace
+= " <b><font color='" + this.colors_
[i
%clen
].toHexString() + "'>"
6076 + point
.name
+ "</font></b>:"
6077 + this.round_(point
.yval
, 2);
6079 this.labelsDiv_
.innerHTML
= replace
;
6081 // Save last x position for callbacks.
6082 this.lastx_
= lastx
;
6084 // Draw colored circles over the center of each selected point
6086 for (var i
= 0; i
< selPoints
.length
; i
++) {
6088 ctx
.fillStyle
= this.colors_
[i
%clen
].toRGBString();
6089 ctx
.arc(canvasx
, selPoints
[i
%clen
].canvasy
, circleSize
, 0, 360, false);
6094 this.previousVerticalX_
= canvasx
;
6099 * The mouse has left the canvas. Clear out whatever artifacts remain
6100 * @param {Object} event the mouseout event from the browser.
6103 DateGraph
.prototype.mouseOut_
= function(event
) {
6104 // Get rid of the overlay data
6105 var ctx
= this.canvas_
.getContext("2d");
6106 ctx
.clearRect(0, 0, this.width_
, this.height_
);
6107 this.labelsDiv_
.innerHTML
= "";
6111 * Convert a JS date (millis since epoch) to YYYY/MM/DD
6112 * @param {Number} date The JavaScript date (ms since epoch)
6113 * @return {String} A date of the form "YYYY/MM/DD"
6116 DateGraph
.prototype.dateString_
= function(date
) {
6117 var d
= new Date(date
);
6120 var year
= "" + d
.getFullYear();
6121 // Get a 0 padded month string
6122 var month
= "" + (d
.getMonth() + 1); //months are 0-offset, sigh
6123 if (month
.length
< 2) month
= "0" + month
;
6124 // Get a 0 padded day string
6125 var day
= "" + d
.getDate();
6126 if (day
.length
< 2) day
= "0" + day
;
6128 return year
+ "/" + month + "/" + day
;
6132 * Round a number to the specified number of digits past the decimal point.
6133 * @param {Number} num The number to round
6134 * @param {Number} places The number of decimals to which to round
6135 * @return {Number} The rounded number
6138 DateGraph
.prototype.round_
= function(num
, places
) {
6139 var shift
= Math
.pow(10, places
);
6140 return Math
.round(num
* shift
)/shift
;
6144 * Fires when there's data available to be graphed.
6145 * @param {String} data Raw CSV data to be plotted
6148 DateGraph
.prototype.loadedEvent_
= function(data
) {
6149 this.rawData_
= this.parseCSV_(data
);
6150 this.drawGraph_(this.rawData_
);
6153 DateGraph
.prototype.months
= ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
6154 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
6155 DateGraph
.prototype.quarters
= ["Jan", "Apr", "Jul", "Oct"];
6158 * Add ticks on the x-axis representing years, months, quarters, weeks, or days
6161 DateGraph
.prototype.addXTicks_
= function() {
6162 // Determine the correct ticks scale on the x-axis: quarterly, monthly, ...
6163 var startDate
, endDate
;
6164 if (this.dateWindow_
) {
6165 startDate
= this.dateWindow_
[0];
6166 endDate
= this.dateWindow_
[1];
6168 startDate
= this.rawData_
[0][0];
6169 endDate
= this.rawData_
[this.rawData_
.length
- 1][0];
6172 var xTicks
= this.xTicker_(startDate
, endDate
);
6173 this.layout_
.updateOptions({xTicks
: xTicks
});
6177 * Add ticks to the x-axis based on a date range.
6178 * @param {Number} startDate Start of the date window (millis since epoch)
6179 * @param {Number} endDate End of the date window (millis since epoch)
6180 * @return {Array.<Object>} Array of {label, value} tuples.
6183 DateGraph
.prototype.dateTicker
= function(startDate
, endDate
) {
6184 var ONE_DAY
= 24*60*60*1000;
6185 startDate
= startDate
/ ONE_DAY
;
6186 endDate
= endDate
/ ONE_DAY
;
6187 var dateSpan
= endDate
- startDate
;
6190 var isMonthly
= false;
6192 if (dateSpan
> 30 * 366) { // decadal
6196 } else if (dateSpan
> 4*366) { // annual
6199 } else if (dateSpan
> 366) { // quarterly
6200 scale
= this.quarters
;
6202 } else if (dateSpan
> 40) { // monthly
6203 scale
= this.months
;
6205 } else if (dateSpan
> 10) { // weekly
6206 for (var week
= startDate
- 14; week
< endDate
+ 14; week
+= 7) {
6207 scale
.push(week
* ONE_DAY
);
6210 for (var day
= startDate
- 14; day
< endDate
+ 14; day
+= 1) {
6211 scale
.push(day
* ONE_DAY
);
6218 var startYear
= 1900 + (new Date(startDate
* ONE_DAY
)).getYear();
6219 var endYear
= 1900 + (new Date(endDate
* ONE_DAY
)).getYear();
6220 for (var i
= startYear
; i
<= endYear
; i
++) {
6221 if (i
% yearMod
!= 0) continue;
6222 for (var j
= 0; j
< scale
.length
; j
++ ) {
6223 var date
= Date
.parse(scale
[j
] + " 1, " + i
);
6224 xTicks
.push( {label
: scale
[j
] + "'" + ("" + i
).substr(2,2), v
: date
} );
6228 for (var i
= 0; i
< scale
.length
; i
++) {
6229 var date
= new Date(scale
[i
]);
6230 var year
= date
.getFullYear().toString();
6231 var label
= this.months
[date
.getMonth()] + date
.getDate();
6232 label
+= "'" + year
.substr(year
.length
- 2, 2);
6233 xTicks
.push( {label
: label
, v
: date
} );
6240 * Add ticks when the x axis has numbers on it (instead of dates)
6241 * @param {Number} startDate Start of the date window (millis since epoch)
6242 * @param {Number} endDate End of the date window (millis since epoch)
6243 * @return {Array.<Object>} Array of {label, value} tuples.
6246 DateGraph
.prototype.numericTicks
= function(minV
, maxV
) {
6251 scale
= Math
.pow( 10, Math
.floor(Math
.log(maxV
)/Math
.log(10.0)) );
6254 // Add a smallish number of ticks at human-friendly points
6255 var nTicks
= (maxV
- minV
) / scale
;
6256 while (2 * nTicks
< 20) {
6259 if ((maxV
- minV
) / nTicks
< this.minTickSize_
) {
6260 nTicks
= this.round_((maxV
- minV
) / this.minTickSize_
, 1);
6263 // Construct labels for the ticks
6265 for (var i
= 0; i
<= nTicks
; i
++) {
6266 var tickV
= minV
+ i
* (maxV
- minV
) / nTicks
;
6267 var label
= this.round_(tickV
, 2);
6268 if (this.labelsKMB_
) {
6270 if (tickV
>= k
*k
*k
) {
6271 label
= this.round_(tickV
/(k
*k
*k
), 1) + "B";
6272 } else if (tickV
>= k
*k
) {
6273 label
= this.round_(tickV
/(k
*k
), 1) + "M";
6274 } else if (tickV
>= k
) {
6275 label
= this.round_(tickV
/k
, 1) + "K";
6278 ticks
.push( {label
: label
, v
: tickV
} );
6284 * Adds appropriate ticks on the y-axis
6285 * @param {Number} minY The minimum Y value in the data set
6286 * @param {Number} maxY The maximum Y value in the data set
6289 DateGraph
.prototype.addYTicks_
= function(minY
, maxY
) {
6290 // Set the number of ticks so that the labels are human-friendly.
6291 var ticks
= this.numericTicks(minY
, maxY
);
6292 this.layout_
.updateOptions( { yAxis
: [minY
, maxY
],
6297 * Update the graph with new data. Data is in the format
6298 * [ [date1, val1, val2, ...], [date2, val1, val2, ...] if errorBars=false
6299 * or, if errorBars=true,
6300 * [ [date1, [val1,stddev1], [val2,stddev2], ...], [date2, ...], ...]
6301 * @param {Array.<Object>} data The data (see above)
6304 DateGraph
.prototype.drawGraph_
= function(data
) {
6306 this.layout_
.removeAllDatasets();
6307 // Loop over all fields in the dataset
6308 for (var i
= 1; i
< data
[0].length
; i
++) {
6310 for (var j
= 0; j
< data
.length
; j
++) {
6311 var date
= data
[j
][0];
6312 series
[j
] = [date
, data
[j
][i
]];
6314 series
= this.rollingAverage(series
, this.rollPeriod_
);
6316 // Prune down to the desired range, if necessary (for zooming)
6317 var bars
= this.errorBars_
|| this.customBars_
;
6318 if (this.dateWindow_
) {
6319 var low
= this.dateWindow_
[0];
6320 var high
= this.dateWindow_
[1];
6322 for (var k
= 0; k
< series
.length
; k
++) {
6323 if (series
[k
][0] >= low
&& series
[k
][0] <= high
) {
6324 pruned
.push(series
[k
]);
6325 var y
= bars
? series
[k
][1][0] : series
[k
][1];
6326 if (maxY
== null || y
> maxY
) maxY
= y
;
6331 for (var j
= 0; j
< series
.length
; j
++) {
6332 var y
= bars
? series
[j
][1][0] : series
[j
][1];
6333 if (maxY
== null || y
> maxY
) {
6334 maxY
= bars
? y
+ series
[j
][1][1] : y
;
6341 for (var j
=0; j
<series
.length
; j
++)
6342 vals
[j
] = [series
[j
][0],
6343 series
[j
][1][0], series
[j
][1][1], series
[j
][1][2]];
6344 this.layout_
.addDataset(this.labels_
[i
- 1], vals
);
6346 this.layout_
.addDataset(this.labels_
[i
- 1], series
);
6350 // Use some heuristics to come up with a good maxY value, unless it's been
6351 // set explicitly by the user.
6352 if (this.valueRange_
!= null) {
6353 this.addYTicks_(this.valueRange_
[0], this.valueRange_
[1]);
6355 // Add some padding and round up to an integer to be human-friendly.
6357 if (maxY
<= 0.0) maxY
= 1.0;
6359 var scale
= Math
.pow(10, Math
.floor(Math
.log(maxY
) / Math
.log(10.0)));
6360 maxY
= scale
* Math
.ceil(maxY
/ scale
);
6362 this.addYTicks_(0, maxY
);
6367 // Tell PlotKit to use this new data and render itself
6368 this.layout_
.evaluateWithError();
6369 this.plotter_
.clear();
6370 this.plotter_
.render();
6371 this.canvas_
.getContext('2d').clearRect(0, 0,
6372 this.canvas_
.width
, this.canvas_
.height
);
6376 * Calculates the rolling average of a data set.
6377 * If originalData is [label, val], rolls the average of those.
6378 * If originalData is [label, [, it's interpreted as [value, stddev]
6379 * and the roll is returned in the same form, with appropriately reduced
6380 * stddev for each value.
6381 * Note that this is where fractional input (i.e. '5/10') is converted into
6383 * @param {Array} originalData The data in the appropriate format (see above)
6384 * @param {Number} rollPeriod The number of days over which to average the data
6386 DateGraph
.prototype.rollingAverage
= function(originalData
, rollPeriod
) {
6387 if (originalData
.length
< 2)
6388 return originalData
;
6389 var rollPeriod
= Math
.min(rollPeriod
, originalData
.length
- 1);
6390 var rollingData
= [];
6391 var sigma
= this.sigma_
;
6393 if (this.fractions_
) {
6395 var den
= 0; // numerator/denominator
6397 for (var i
= 0; i
< originalData
.length
; i
++) {
6398 num
+= originalData
[i
][1][0];
6399 den
+= originalData
[i
][1][1];
6400 if (i
- rollPeriod
>= 0) {
6401 num
-= originalData
[i
- rollPeriod
][1][0];
6402 den
-= originalData
[i
- rollPeriod
][1][1];
6405 var date
= originalData
[i
][0];
6406 var value
= den
? num
/ den
: 0.0;
6407 if (this.errorBars_
) {
6408 if (this.wilsonInterval_
) {
6409 // For more details on this confidence interval, see:
6410 // http://en.wikipedia.org/wiki
/Binomial_confidence_interval
6412 var p
= value
< 0 ? 0 : value
, n
= den
;
6413 var pm
= sigma
* Math
.sqrt(p
*(1-p
)/n + sigma*sigma/(4*n
*n
));
6414 var denom
= 1 + sigma
* sigma
/ den
;
6415 var low
= (p
+ sigma
* sigma
/ (2 * den) - pm) / denom
;
6416 var high
= (p
+ sigma
* sigma
/ (2 * den) + pm) / denom
;
6417 rollingData
[i
] = [date
,
6418 [p
* mult
, (p
- low
) * mult
, (high
- p
) * mult
]];
6420 rollingData
[i
] = [date
, [0, 0, 0]];
6423 var stddev
= den
? sigma
* Math
.sqrt(value
* (1 - value
) / den
) : 1.0;
6424 rollingData
[i
] = [date
, [mult
* value
, mult
* stddev
, mult
* stddev
]];
6427 rollingData
[i
] = [date
, mult
* value
];
6430 } else if (this.customBars_
) {
6431 // just ignore the rolling for now.
6432 // TODO(danvk): do something reasonable.
6433 for (var i
= 0; i
< originalData
.length
; i
++) {
6434 var data
= originalData
[i
][1];
6436 rollingData
[i
] = [originalData
[i
][0], [y
, y
- data
[0], data
[2] - y
]];
6439 // Calculate the rolling average for the first rollPeriod - 1 points where
6440 // there is not enough data to roll over the full number of days
6441 var num_init_points
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
6442 if (!this.errorBars_
){
6443 for (var i
= 0; i
< num_init_points
; i
++) {
6445 for (var j
= 0; j
< i
+ 1; j
++)
6446 sum
+= originalData
[j
][1];
6447 rollingData
[i
] = [originalData
[i
][0], sum
/ (i
+ 1)];
6449 // Calculate the rolling average for the remaining points
6450 for (var i
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
6451 i
< originalData
.length
;
6454 for (var j
= i
- rollPeriod
+ 1; j
< i
+ 1; j
++)
6455 sum
+= originalData
[j
][1];
6456 rollingData
[i
] = [originalData
[i
][0], sum
/ rollPeriod
];
6459 for (var i
= 0; i
< num_init_points
; i
++) {
6462 for (var j
= 0; j
< i
+ 1; j
++) {
6463 sum
+= originalData
[j
][1][0];
6464 variance
+= Math
.pow(originalData
[j
][1][1], 2);
6466 var stddev
= Math
.sqrt(variance
)/(i
+1);
6467 rollingData
[i
] = [originalData
[i
][0],
6468 [sum
/(i
+1), sigma
* stddev
, sigma
* stddev
]];
6470 // Calculate the rolling average for the remaining points
6471 for (var i
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
6472 i
< originalData
.length
;
6476 for (var j
= i
- rollPeriod
+ 1; j
< i
+ 1; j
++) {
6477 sum
+= originalData
[j
][1][0];
6478 variance
+= Math
.pow(originalData
[j
][1][1], 2);
6480 var stddev
= Math
.sqrt(variance
) / rollPeriod
;
6481 rollingData
[i
] = [originalData
[i
][0],
6482 [sum
/ rollPeriod
, sigma
* stddev
, sigma
* stddev
]];
6491 * Parses a date, returning the number of milliseconds since epoch. This can be
6492 * passed in as an xValueParser in the DateGraph constructor.
6493 * @param {String} A date in YYYYMMDD format.
6494 * @return {Number} Milliseconds since epoch.
6497 DateGraph
.prototype.dateParser
= function(dateStr
) {
6499 if (dateStr
.search("-") != -1) {
6500 dateStrSlashed
= dateStr
.replace("-", "/", "g");
6501 } else if (dateStr
.search("/") != -1) {
6502 return Date
.parse(dateStr
);
6504 dateStrSlashed
= dateStr
.substr(0,4) + "/" + dateStr
.substr(4,2)
6505 + "/" + dateStr
.substr(6,2);
6507 return Date
.parse(dateStrSlashed
);
6511 * Parses a string in a special csv format. We expect a csv file where each
6512 * line is a date point, and the first field in each line is the date string.
6513 * We also expect that all remaining fields represent series.
6514 * if this.errorBars_ is set, then interpret the fields as:
6515 * date, series1, stddev1, series2, stddev2, ...
6516 * @param {Array.<Object>} data See above.
6519 DateGraph
.prototype.parseCSV_
= function(data
) {
6521 var lines
= data
.split("\n");
6522 var start
= this.labelsFromCSV_
? 1 : 0;
6523 if (this.labelsFromCSV_
) {
6524 var labels
= lines
[0].split(",");
6525 labels
.shift(); // a "date" parameter is assumed.
6526 this.labels_
= labels
;
6527 // regenerate automatic colors.
6528 this.setColors_(this.attrs_
);
6529 this.renderOptions_
.colorScheme
= this.colors_
;
6530 MochiKit
.Base
.update(this.plotter_
.options
, this.renderOptions_
);
6531 MochiKit
.Base
.update(this.layoutOptions_
, this.attrs_
);
6534 for (var i
= start
; i
< lines
.length
; i
++) {
6535 var line
= lines
[i
];
6536 if (line
.length
== 0) continue; // skip blank lines
6537 var inFields
= line
.split(',');
6538 if (inFields
.length
< 2)
6542 fields
[0] = this.xValueParser_(inFields
[0]);
6544 // If fractions are expected, parse the numbers as "A/B
"
6545 if (this.fractions_) {
6546 for (var j = 1; j < inFields.length; j++) {
6547 // TODO(danvk): figure out an appropriate way to flag parse errors.
6548 var vals = inFields[j].split("/");
6549 fields[j] = [parseFloat(vals[0]), parseFloat(vals[1])];
6551 } else if (this.errorBars_) {
6552 // If there are error bars, values are (value, stddev) pairs
6553 for (var j = 1; j < inFields.length; j += 2)
6554 fields[(j + 1) / 2] = [parseFloat(inFields[j]),
6555 parseFloat(inFields[j + 1])];
6556 } else if (this.customBars_) {
6557 // Bars are a low;center;high tuple
6558 for (var j = 1; j < inFields.length; j++) {
6559 var vals = inFields[j].split(";");
6560 fields[j] = [ parseFloat(vals[0]),
6561 parseFloat(vals[1]),
6562 parseFloat(vals[2]) ];
6565 // Values are just numbers
6566 for (var j = 1; j < inFields.length; j++)
6567 fields[j] = parseFloat(inFields[j]);
6575 * Get the CSV data. If it's in a function, call that function. If it's in a
6576 * file, do an XMLHttpRequest to get it.
6579 DateGraph.prototype.start_ = function() {
6580 if (typeof this.file_ == 'function') {
6581 // Stubbed out to allow this to run off a filesystem
6582 this.loadedEvent_(this.file_());
6584 var req = new XMLHttpRequest();
6586 req.onreadystatechange = function () {
6587 if (req.readyState == 4) {
6588 if (req.status == 200) {
6589 caller.loadedEvent_(req.responseText);
6594 req.open("GET
", this.file_, true);
6600 * Changes various properties of the graph. These can include:
6602 * <li>file: changes the source data for the graph</li>
6603 * <li>errorBars: changes whether the data contains stddev</li>
6605 * @param {Object} attrs The new properties and values
6607 DateGraph.prototype.updateOptions = function(attrs) {
6608 if (attrs.errorBars) {
6609 this.errorBars_ = attrs.errorBars;
6611 if (attrs.customBars) {
6612 this.customBars_ = attrs.customBars;
6614 if (attrs.strokeWidth) {
6615 this.strokeWidth_ = attrs.strokeWidth;
6617 if (attrs.rollPeriod) {
6618 this.rollPeriod_ = attrs.rollPeriod;
6620 if (attrs.dateWindow) {
6621 this.dateWindow_ = attrs.dateWindow;
6623 if (attrs.valueRange) {
6624 this.valueRange_ = attrs.valueRange;
6626 if (attrs.minTickSize) {
6627 this.minTickSize_ = attrs.minTickSize;
6629 if (typeof(attrs.labels) != 'undefined') {
6630 this.labels_ = attrs.labels;
6631 this.labelsFromCSV_ = (attrs.labels == null);
6633 this.layout_.updateOptions({ 'errorBars': this.errorBars_ });
6634 if (attrs['file'] && attrs['file'] != this.file_) {
6635 this.file_ = attrs['file'];
6638 this.drawGraph_(this.rawData_);
6643 * Adjusts the number of days in the rolling average. Updates the graph to
6644 * reflect the new averaging period.
6645 * @param {Number} length Number of days over which to average the data.
6647 DateGraph.prototype.adjustRoll = function(length) {
6648 this.rollPeriod_ = length;
6649 this.drawGraph_(this.rawData_);