Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / adapter / ext / ext-base-debug.js
1 /*!
2  * Ext JS Library 3.0.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 \r
8 // for old browsers\r
9 window.undefined = window.undefined;\r
10 \r
11 /**\r
12  * @class Ext\r
13  * Ext core utilities and functions.\r
14  * @singleton\r
15  */\r
16 \r
17 Ext = {\r
18     /**\r
19      * The version of the framework\r
20      * @type String\r
21      */\r
22     version : '3.0'\r
23 };\r
24 \r
25 /**\r
26  * Copies all the properties of config to obj.\r
27  * @param {Object} obj The receiver of the properties\r
28  * @param {Object} config The source of the properties\r
29  * @param {Object} defaults A different object that will also be applied for default values\r
30  * @return {Object} returns obj\r
31  * @member Ext apply\r
32  */\r
33 Ext.apply = function(o, c, defaults){\r
34     // no "this" reference for friendly out of scope calls\r
35     if(defaults){\r
36         Ext.apply(o, defaults);\r
37     }\r
38     if(o && c && typeof c == 'object'){\r
39         for(var p in c){\r
40             o[p] = c[p];\r
41         }\r
42     }\r
43     return o;\r
44 };\r
45 \r
46 (function(){\r
47     var idSeed = 0,\r
48         toString = Object.prototype.toString,\r
49         //assume it's not null and not an array\r
50         isIterable = function(v){\r
51             //check for array or arguments\r
52             if(Ext.isArray(v) || v.callee){\r
53                 return true;\r
54             }\r
55             //check for node list type\r
56             if(/NodeList|HTMLCollection/.test(toString.call(v))){\r
57                 return true;\r
58             }\r
59             //NodeList has an item and length property\r
60             //IXMLDOMNodeList has nextNode method, needs to be checked first.\r
61             return ((v.nextNode || v.item) && Ext.isNumber(v.length));\r
62         },\r
63         ua = navigator.userAgent.toLowerCase(),\r
64         check = function(r){\r
65             return r.test(ua);\r
66         },\r
67         DOC = document,\r
68         isStrict = DOC.compatMode == "CSS1Compat",\r
69         isOpera = check(/opera/),\r
70         isChrome = check(/chrome/),\r
71         isWebKit = check(/webkit/),\r
72         isSafari = !isChrome && check(/safari/),\r
73         isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2\r
74         isSafari3 = isSafari && check(/version\/3/),\r
75         isSafari4 = isSafari && check(/version\/4/),\r
76         isIE = !isOpera && check(/msie/),\r
77         isIE7 = isIE && check(/msie 7/),\r
78         isIE8 = isIE && check(/msie 8/),\r
79         isIE6 = isIE && !isIE7 && !isIE8,\r
80         isGecko = !isWebKit && check(/gecko/),\r
81         isGecko2 = isGecko && check(/rv:1\.8/),\r
82         isGecko3 = isGecko && check(/rv:1\.9/),\r
83         isBorderBox = isIE && !isStrict,\r
84         isWindows = check(/windows|win32/),\r
85         isMac = check(/macintosh|mac os x/),\r
86         isAir = check(/adobeair/),\r
87         isLinux = check(/linux/),\r
88         isSecure = /^https/i.test(window.location.protocol);\r
89 \r
90     // remove css image flicker\r
91     if(isIE6){\r
92         try{\r
93             DOC.execCommand("BackgroundImageCache", false, true);\r
94         }catch(e){}\r
95     }\r
96 \r
97     Ext.apply(Ext, {\r
98         /**\r
99          * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent\r
100          * the IE insecure content warning (defaults to javascript:false).\r
101          * @type String\r
102          */\r
103         SSL_SECURE_URL : 'javascript:false',\r
104         /**\r
105          * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode\r
106          * @type Boolean\r
107          */\r
108         isStrict : isStrict,\r
109         /**\r
110          * True if the page is running over SSL\r
111          * @type Boolean\r
112          */\r
113         isSecure : isSecure,\r
114         /**\r
115          * True when the document is fully initialized and ready for action\r
116          * @type Boolean\r
117          */\r
118         isReady : false,\r
119 \r
120         /**\r
121          * True if the {@link Ext.Fx} Class is available\r
122          * @type Boolean\r
123          * @property enableFx\r
124          */\r
125 \r
126         /**\r
127          * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)\r
128          * @type Boolean\r
129          */\r
130         enableGarbageCollector : true,\r
131 \r
132         /**\r
133          * True to automatically purge event listeners after uncaching an element (defaults to false).\r
134          * Note: this only happens if {@link #enableGarbageCollector} is true.\r
135          * @type Boolean\r
136          */\r
137         enableListenerCollection : false,\r
138 \r
139         /**\r
140          * Indicates whether to use native browser parsing for JSON methods.\r
141          * This option is ignored if the browser does not support native JSON methods.\r
142          * <b>Note: Native JSON methods will not work with objects that have functions.\r
143          * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)\r
144          * @type Boolean\r
145          */\r
146         USE_NATIVE_JSON : false,\r
147 \r
148         /**\r
149          * Copies all the properties of config to obj if they don't already exist.\r
150          * @param {Object} obj The receiver of the properties\r
151          * @param {Object} config The source of the properties\r
152          * @return {Object} returns obj\r
153          */\r
154         applyIf : function(o, c){\r
155             if(o){\r
156                 for(var p in c){\r
157                     if(Ext.isEmpty(o[p])){\r
158                         o[p] = c[p];\r
159                     }\r
160                 }\r
161             }\r
162             return o;\r
163         },\r
164 \r
165         /**\r
166          * Generates unique ids. If the element already has an id, it is unchanged\r
167          * @param {Mixed} el (optional) The element to generate an id for\r
168          * @param {String} prefix (optional) Id prefix (defaults "ext-gen")\r
169          * @return {String} The generated Id.\r
170          */\r
171         id : function(el, prefix){\r
172             return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);\r
173         },\r
174 \r
175         /**\r
176          * Extends one class with another class and optionally overrides members with the passed literal. This class\r
177          * also adds the function "override()" to the class that can be used to override\r
178          * members on an instance.\r
179          * * <p>\r
180          * This function also supports a 2-argument call in which the subclass's constructor is\r
181          * not passed as an argument. In this form, the parameters are as follows:</p><p>\r
182          * <div class="mdetail-params"><ul>\r
183          * <li><code>superclass</code>\r
184          * <div class="sub-desc">The class being extended</div></li>\r
185          * <li><code>overrides</code>\r
186          * <div class="sub-desc">A literal with members which are copied into the subclass's\r
187          * prototype, and are therefore shared among all instances of the new class.<p>\r
188          * This may contain a special member named <tt><b>constructor</b></tt>. This is used\r
189          * to define the constructor of the new class, and is returned. If this property is\r
190          * <i>not</i> specified, a constructor is generated and returned which just calls the\r
191          * superclass's constructor passing on its parameters.</p></div></li>\r
192          * </ul></div></p><p>\r
193          * For example, to create a subclass of the Ext GridPanel:\r
194          * <pre><code>\r
195 MyGridPanel = Ext.extend(Ext.grid.GridPanel, {\r
196     constructor: function(config) {\r
197         // Your preprocessing here\r
198         MyGridPanel.superclass.constructor.apply(this, arguments);\r
199         // Your postprocessing here\r
200     },\r
201 \r
202     yourMethod: function() {\r
203         // etc.\r
204     }\r
205 });\r
206 </code></pre>\r
207          * </p>\r
208          * @param {Function} subclass The class inheriting the functionality\r
209          * @param {Function} superclass The class being extended\r
210          * @param {Object} overrides (optional) A literal with members which are copied into the subclass's\r
211          * prototype, and are therefore shared between all instances of the new class.\r
212          * @return {Function} The subclass constructor.\r
213          * @method extend\r
214          */\r
215         extend : function(){\r
216             // inline overrides\r
217             var io = function(o){\r
218                 for(var m in o){\r
219                     this[m] = o[m];\r
220                 }\r
221             };\r
222             var oc = Object.prototype.constructor;\r
223 \r
224             return function(sb, sp, overrides){\r
225                 if(Ext.isObject(sp)){\r
226                     overrides = sp;\r
227                     sp = sb;\r
228                     sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};\r
229                 }\r
230                 var F = function(){},\r
231                     sbp,\r
232                     spp = sp.prototype;\r
233 \r
234                 F.prototype = spp;\r
235                 sbp = sb.prototype = new F();\r
236                 sbp.constructor=sb;\r
237                 sb.superclass=spp;\r
238                 if(spp.constructor == oc){\r
239                     spp.constructor=sp;\r
240                 }\r
241                 sb.override = function(o){\r
242                     Ext.override(sb, o);\r
243                 };\r
244                 sbp.superclass = sbp.supr = (function(){\r
245                     return spp;\r
246                 });\r
247                 sbp.override = io;\r
248                 Ext.override(sb, overrides);\r
249                 sb.extend = function(o){Ext.extend(sb, o);};\r
250                 return sb;\r
251             };\r
252         }(),\r
253 \r
254         /**\r
255          * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.\r
256          * Usage:<pre><code>\r
257 Ext.override(MyClass, {\r
258     newMethod1: function(){\r
259         // etc.\r
260     },\r
261     newMethod2: function(foo){\r
262         // etc.\r
263     }\r
264 });\r
265 </code></pre>\r
266          * @param {Object} origclass The class to override\r
267          * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal\r
268          * containing one or more methods.\r
269          * @method override\r
270          */\r
271         override : function(origclass, overrides){\r
272             if(overrides){\r
273                 var p = origclass.prototype;\r
274                 Ext.apply(p, overrides);\r
275                 if(Ext.isIE && overrides.toString != origclass.toString){\r
276                     p.toString = overrides.toString;\r
277                 }\r
278             }\r
279         },\r
280 \r
281         /**\r
282          * Creates namespaces to be used for scoping variables and classes so that they are not global.\r
283          * Specifying the last node of a namespace implicitly creates all other nodes. Usage:\r
284          * <pre><code>\r
285 Ext.namespace('Company', 'Company.data');\r
286 Ext.namespace('Company.data'); // equivalent and preferable to above syntax\r
287 Company.Widget = function() { ... }\r
288 Company.data.CustomStore = function(config) { ... }\r
289 </code></pre>\r
290          * @param {String} namespace1\r
291          * @param {String} namespace2\r
292          * @param {String} etc\r
293          * @method namespace\r
294          */\r
295         namespace : function(){\r
296             var o, d;\r
297             Ext.each(arguments, function(v) {\r
298                 d = v.split(".");\r
299                 o = window[d[0]] = window[d[0]] || {};\r
300                 Ext.each(d.slice(1), function(v2){\r
301                     o = o[v2] = o[v2] || {};\r
302                 });\r
303             });\r
304             return o;\r
305         },\r
306 \r
307         /**\r
308          * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2".  Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.\r
309          * @param {Object} o\r
310          * @param {String} pre (optional) A prefix to add to the url encoded string\r
311          * @return {String}\r
312          */\r
313         urlEncode: function(o, pre){\r
314             var undef, buf = [], key, e = encodeURIComponent;\r
315 \r
316             for(key in o){\r
317                 undef = !Ext.isDefined(o[key]);\r
318                 Ext.each(undef ? key : o[key], function(val, i){\r
319                     buf.push("&", e(key), "=", (val != key || !undef) ? e(val) : "");\r
320                 });\r
321             }\r
322             if(!pre){\r
323                 buf.shift();\r
324                 pre = "";\r
325             }\r
326             return pre + buf.join('');\r
327         },\r
328 \r
329         /**\r
330          * Takes an encoded URL and and converts it to an object. Example: <pre><code>\r
331 Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}\r
332 Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}\r
333 </code></pre>\r
334          * @param {String} string\r
335          * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).\r
336          * @return {Object} A literal with members\r
337          */\r
338         urlDecode : function(string, overwrite){\r
339             var obj = {},\r
340                 pairs = string.split('&'),\r
341                 d = decodeURIComponent,\r
342                 name,\r
343                 value;\r
344             Ext.each(pairs, function(pair) {\r
345                 pair = pair.split('=');\r
346                 name = d(pair[0]);\r
347                 value = d(pair[1]);\r
348                 obj[name] = overwrite || !obj[name] ? value :\r
349                             [].concat(obj[name]).concat(value);\r
350             });\r
351             return obj;\r
352         },\r
353 \r
354         /**\r
355          * Appends content to the query string of a URL, which handles logic for whether to place\r
356          * a question mark or ampersand.\r
357          * @param {String} url The url to append to.\r
358          * @@param {String} s The content to append to the url.\r
359          * @return (String) The appended string\r
360          */\r
361         urlAppend : function(url, s){\r
362             if(!Ext.isEmpty(s)){\r
363                 return url + (url.indexOf('?') === -1 ? '?' : '&') + s;\r
364             }\r
365             return url;\r
366         },\r
367 \r
368         /**\r
369          * Converts any iterable (numeric indices and a length property) into a true array\r
370          * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.\r
371          * For strings, use this instead: "abc".match(/./g) => [a,b,c];\r
372          * @param {Iterable} the iterable object to be turned into a true Array.\r
373          * @return (Array) array\r
374          */\r
375         toArray : function(){\r
376             return isIE ?\r
377                 function(a, i, j, res){\r
378                     res = [];\r
379                     Ext.each(a, function(v) {\r
380                         res.push(v);\r
381                     });\r
382                     return res.slice(i || 0, j || res.length);\r
383                 } :\r
384                 function(a, i, j){\r
385                     return Array.prototype.slice.call(a, i || 0, j || a.length);\r
386                 }\r
387         }(),\r
388 \r
389         /**\r
390          * Iterates an array calling the passed function with each item, stopping if your function returns false. If the\r
391          * passed array is not really an array, your function is called once with it.\r
392          * The supplied function is called with (Object item, Number index, Array allItems).\r
393          * @param {Array/NodeList/Mixed} array\r
394          * @param {Function} fn\r
395          * @param {Object} scope\r
396          */\r
397         each: function(array, fn, scope){\r
398             if(Ext.isEmpty(array, true)){\r
399                 return;\r
400             }\r
401             if(!isIterable(array) || Ext.isPrimitive(array)){\r
402                 array = [array];\r
403             }\r
404             for(var i = 0, len = array.length; i < len; i++){\r
405                 if(fn.call(scope || array[i], array[i], i, array) === false){\r
406                     return i;\r
407                 };\r
408             }\r
409         },\r
410 \r
411         /**\r
412          * Iterates either the elements in an array, or each of the properties in an object.\r
413          * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.\r
414          * @param {Object/Array} object The object or array to be iterated\r
415          * @param {Function} fn The function to be called for each iteration.\r
416          * The iteration will stop if the supplied function returns false, or\r
417          * all array elements / object properties have been covered. The signature\r
418          * varies depending on the type of object being interated:\r
419          * <div class="mdetail-params"><ul>\r
420          * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>\r
421          * <div class="sub-desc">\r
422          * When iterating an array, the supplied function is called with each item.</div></li>\r
423          * <li>Objects : <tt>(String key, Object value)</tt>\r
424          * <div class="sub-desc">\r
425          * When iterating an object, the supplied function is called with each key-value pair in\r
426          * the object.</div></li>\r
427          * </ul></div>\r
428          * @param {Object} scope The scope to call the supplied function with, defaults to\r
429          * the specified <tt>object</tt>\r
430          */\r
431         iterate : function(obj, fn, scope){\r
432             if(isIterable(obj)){\r
433                 Ext.each(obj, fn, scope);\r
434                 return;\r
435             }else if(Ext.isObject(obj)){\r
436                 for(var prop in obj){\r
437                     if(obj.hasOwnProperty(prop)){\r
438                         if(fn.call(scope || obj, prop, obj[prop]) === false){\r
439                             return;\r
440                         };\r
441                     }\r
442                 }\r
443             }\r
444         },\r
445 \r
446         /**\r
447          * Return the dom node for the passed String (id), dom node, or Ext.Element.\r
448          * Here are some examples:\r
449          * <pre><code>\r
450 // gets dom node based on id\r
451 var elDom = Ext.getDom('elId');\r
452 // gets dom node based on the dom node\r
453 var elDom1 = Ext.getDom(elDom);\r
454 \r
455 // If we don&#39;t know if we are working with an\r
456 // Ext.Element or a dom node use Ext.getDom\r
457 function(el){\r
458     var dom = Ext.getDom(el);\r
459     // do something with the dom node\r
460 }\r
461          * </code></pre>\r
462          * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)\r
463          * when this method is called to be successful.\r
464          * @param {Mixed} el\r
465          * @return HTMLElement\r
466          */\r
467         getDom : function(el){\r
468             if(!el || !DOC){\r
469                 return null;\r
470             }\r
471             return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);\r
472         },\r
473 \r
474         /**\r
475          * Returns the current document body as an {@link Ext.Element}.\r
476          * @return Ext.Element The document body\r
477          */\r
478         getBody : function(){\r
479             return Ext.get(DOC.body || DOC.documentElement);\r
480         },\r
481 \r
482         /**\r
483          * Removes a DOM node from the document.  The body node will be ignored if passed in.\r
484          * @param {HTMLElement} node The node to remove\r
485          */\r
486         removeNode : isIE ? function(){\r
487             var d;\r
488             return function(n){\r
489                 if(n && n.tagName != 'BODY'){\r
490                     d = d || DOC.createElement('div');\r
491                     d.appendChild(n);\r
492                     d.innerHTML = '';\r
493                 }\r
494             }\r
495         }() : function(n){\r
496             if(n && n.parentNode && n.tagName != 'BODY'){\r
497                 n.parentNode.removeChild(n);\r
498             }\r
499         },\r
500 \r
501         /**\r
502          * <p>Returns true if the passed value is empty.</p>\r
503          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>\r
504          * <li>null</li>\r
505          * <li>undefined</li>\r
506          * <li>an empty array</li>\r
507          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>\r
508          * </ul></div>\r
509          * @param {Mixed} value The value to test\r
510          * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)\r
511          * @return {Boolean}\r
512          */\r
513         isEmpty : function(v, allowBlank){\r
514             return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);\r
515         },\r
516 \r
517         /**\r
518          * Returns true if the passed object is a JavaScript array, otherwise false.\r
519          * @param {Object} object The object to test\r
520          * @return {Boolean}\r
521          */\r
522         isArray : function(v){\r
523             return toString.apply(v) === '[object Array]';\r
524         },\r
525 \r
526         /**\r
527          * Returns true if the passed object is a JavaScript Object, otherwise false.\r
528          * @param {Object} object The object to test\r
529          * @return {Boolean}\r
530          */\r
531         isObject : function(v){\r
532             return v && typeof v == "object";\r
533         },\r
534 \r
535         /**\r
536          * Returns true if the passed object is a JavaScript 'primitive', a string, number or boolean.\r
537          * @param {Mixed} value The value to test\r
538          * @return {Boolean}\r
539          */\r
540         isPrimitive : function(v){\r
541             return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);\r
542         },\r
543 \r
544         /**\r
545          * Returns true if the passed object is a JavaScript Function, otherwise false.\r
546          * @param {Object} object The object to test\r
547          * @return {Boolean}\r
548          */\r
549         isFunction : function(v){\r
550             return toString.apply(v) === '[object Function]';\r
551         },\r
552 \r
553         /**\r
554          * Returns true if the passed object is a number. Returns false for non-finite numbers.\r
555          * @param {Object} v The object to test\r
556          * @return {Boolean}\r
557          */\r
558         isNumber: function(v){\r
559             return typeof v === 'number' && isFinite(v);\r
560         },\r
561 \r
562         /**\r
563          * Returns true if the passed object is a string.\r
564          * @param {Object} v The object to test\r
565          * @return {Boolean}\r
566          */\r
567         isString: function(v){\r
568             return typeof v === 'string';\r
569         },\r
570 \r
571         /**\r
572          * Returns true if the passed object is a boolean.\r
573          * @param {Object} v The object to test\r
574          * @return {Boolean}\r
575          */\r
576         isBoolean: function(v){\r
577             return typeof v === 'boolean';\r
578         },\r
579 \r
580         /**\r
581          * Returns true if the passed object is not undefined.\r
582          * @param {Object} v The object to test\r
583          * @return {Boolean}\r
584          */\r
585         isDefined: function(v){\r
586             return typeof v !== 'undefined';\r
587         },\r
588 \r
589         /**\r
590          * True if the detected browser is Opera.\r
591          * @type Boolean\r
592          */\r
593         isOpera : isOpera,\r
594         /**\r
595          * True if the detected browser uses WebKit.\r
596          * @type Boolean\r
597          */\r
598         isWebKit: isWebKit,\r
599         /**\r
600          * True if the detected browser is Chrome.\r
601          * @type Boolean\r
602          */\r
603         isChrome : isChrome,\r
604         /**\r
605          * True if the detected browser is Safari.\r
606          * @type Boolean\r
607          */\r
608         isSafari : isSafari,\r
609         /**\r
610          * True if the detected browser is Safari 3.x.\r
611          * @type Boolean\r
612          */\r
613         isSafari3 : isSafari3,\r
614         /**\r
615          * True if the detected browser is Safari 4.x.\r
616          * @type Boolean\r
617          */\r
618         isSafari4 : isSafari4,\r
619         /**\r
620          * True if the detected browser is Safari 2.x.\r
621          * @type Boolean\r
622          */\r
623         isSafari2 : isSafari2,\r
624         /**\r
625          * True if the detected browser is Internet Explorer.\r
626          * @type Boolean\r
627          */\r
628         isIE : isIE,\r
629         /**\r
630          * True if the detected browser is Internet Explorer 6.x.\r
631          * @type Boolean\r
632          */\r
633         isIE6 : isIE6,\r
634         /**\r
635          * True if the detected browser is Internet Explorer 7.x.\r
636          * @type Boolean\r
637          */\r
638         isIE7 : isIE7,\r
639         /**\r
640          * True if the detected browser is Internet Explorer 8.x.\r
641          * @type Boolean\r
642          */\r
643         isIE8 : isIE8,\r
644         /**\r
645          * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).\r
646          * @type Boolean\r
647          */\r
648         isGecko : isGecko,\r
649         /**\r
650          * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).\r
651          * @type Boolean\r
652          */\r
653         isGecko2 : isGecko2,\r
654         /**\r
655          * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).\r
656          * @type Boolean\r
657          */\r
658         isGecko3 : isGecko3,\r
659         /**\r
660          * True if the detected browser is Internet Explorer running in non-strict mode.\r
661          * @type Boolean\r
662          */\r
663         isBorderBox : isBorderBox,\r
664         /**\r
665          * True if the detected platform is Linux.\r
666          * @type Boolean\r
667          */\r
668         isLinux : isLinux,\r
669         /**\r
670          * True if the detected platform is Windows.\r
671          * @type Boolean\r
672          */\r
673         isWindows : isWindows,\r
674         /**\r
675          * True if the detected platform is Mac OS.\r
676          * @type Boolean\r
677          */\r
678         isMac : isMac,\r
679         /**\r
680          * True if the detected platform is Adobe Air.\r
681          * @type Boolean\r
682          */\r
683         isAir : isAir\r
684     });\r
685 \r
686     /**\r
687      * Creates namespaces to be used for scoping variables and classes so that they are not global.\r
688      * Specifying the last node of a namespace implicitly creates all other nodes. Usage:\r
689      * <pre><code>\r
690 Ext.namespace('Company', 'Company.data');\r
691 Ext.namespace('Company.data'); // equivalent and preferable to above syntax\r
692 Company.Widget = function() { ... }\r
693 Company.data.CustomStore = function(config) { ... }\r
694 </code></pre>\r
695      * @param {String} namespace1\r
696      * @param {String} namespace2\r
697      * @param {String} etc\r
698      * @method namespace\r
699      */\r
700     Ext.ns = Ext.namespace;\r
701 })();\r
702 \r
703 Ext.ns("Ext", "Ext.util", "Ext.lib", "Ext.data");\r
704 \r
705 \r
706 /**\r
707  * @class Function\r
708  * These functions are available on every Function object (any JavaScript function).\r
709  */\r
710 Ext.apply(Function.prototype, {\r
711      /**\r
712      * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,\r
713      * the original one is not called. The resulting function returns the results of the original function.\r
714      * The passed fcn is called with the parameters of the original function. Example usage:\r
715      * <pre><code>\r
716 var sayHi = function(name){\r
717     alert('Hi, ' + name);\r
718 }\r
719 \r
720 sayHi('Fred'); // alerts "Hi, Fred"\r
721 \r
722 // create a new function that validates input without\r
723 // directly modifying the original function:\r
724 var sayHiToFriend = sayHi.createInterceptor(function(name){\r
725     return name == 'Brian';\r
726 });\r
727 \r
728 sayHiToFriend('Fred');  // no alert\r
729 sayHiToFriend('Brian'); // alerts "Hi, Brian"\r
730 </code></pre>\r
731      * @param {Function} fcn The function to call before the original\r
732      * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)\r
733      * @return {Function} The new function\r
734      */\r
735     createInterceptor : function(fcn, scope){\r
736         var method = this;\r
737         return !Ext.isFunction(fcn) ?\r
738                 this :\r
739                 function() {\r
740                     var me = this,\r
741                         args = arguments;\r
742                     fcn.target = me;\r
743                     fcn.method = method;\r
744                     return (fcn.apply(scope || me || window, args) !== false) ?\r
745                             method.apply(me || window, args) :\r
746                             null;\r
747                 };\r
748     },\r
749 \r
750      /**\r
751      * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...\r
752      * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>\r
753      * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the\r
754      * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always\r
755      * executes in the window scope.\r
756      * <p>This method is required when you want to pass arguments to a callback function.  If no arguments\r
757      * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).\r
758      * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function\r
759      * would simply execute immediately when the code is parsed. Example usage:\r
760      * <pre><code>\r
761 var sayHi = function(name){\r
762     alert('Hi, ' + name);\r
763 }\r
764 \r
765 // clicking the button alerts "Hi, Fred"\r
766 new Ext.Button({\r
767     text: 'Say Hi',\r
768     renderTo: Ext.getBody(),\r
769     handler: sayHi.createCallback('Fred')\r
770 });\r
771 </code></pre>\r
772      * @return {Function} The new function\r
773     */\r
774     createCallback : function(/*args...*/){\r
775         // make args available, in function below\r
776         var args = arguments,\r
777             method = this;\r
778         return function() {\r
779             return method.apply(window, args);\r
780         };\r
781     },\r
782 \r
783     /**\r
784      * Creates a delegate (callback) that sets the scope to obj.\r
785      * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>\r
786      * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the\r
787      * callback points to obj. Example usage:\r
788      * <pre><code>\r
789 var sayHi = function(name){\r
790     // Note this use of "this.text" here.  This function expects to\r
791     // execute within a scope that contains a text property.  In this\r
792     // example, the "this" variable is pointing to the btn object that\r
793     // was passed in createDelegate below.\r
794     alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');\r
795 }\r
796 \r
797 var btn = new Ext.Button({\r
798     text: 'Say Hi',\r
799     renderTo: Ext.getBody()\r
800 });\r
801 \r
802 // This callback will execute in the scope of the\r
803 // button instance. Clicking the button alerts\r
804 // "Hi, Fred. You clicked the "Say Hi" button."\r
805 btn.on('click', sayHi.createDelegate(btn, ['Fred']));\r
806 </code></pre>\r
807      * @param {Object} obj (optional) The object for which the scope is set\r
808      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)\r
809      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,\r
810      *                                             if a number the args are inserted at the specified position\r
811      * @return {Function} The new function\r
812      */\r
813     createDelegate : function(obj, args, appendArgs){\r
814         var method = this;\r
815         return function() {\r
816             var callArgs = args || arguments;\r
817             if (appendArgs === true){\r
818                 callArgs = Array.prototype.slice.call(arguments, 0);\r
819                 callArgs = callArgs.concat(args);\r
820             }else if (Ext.isNumber(appendArgs)){\r
821                 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first\r
822                 var applyArgs = [appendArgs, 0].concat(args); // create method call params\r
823                 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in\r
824             }\r
825             return method.apply(obj || window, callArgs);\r
826         };\r
827     },\r
828 \r
829     /**\r
830      * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:\r
831      * <pre><code>\r
832 var sayHi = function(name){\r
833     alert('Hi, ' + name);\r
834 }\r
835 \r
836 // executes immediately:\r
837 sayHi('Fred');\r
838 \r
839 // executes after 2 seconds:\r
840 sayHi.defer(2000, this, ['Fred']);\r
841 \r
842 // this syntax is sometimes useful for deferring\r
843 // execution of an anonymous function:\r
844 (function(){\r
845     alert('Anonymous');\r
846 }).defer(100);\r
847 </code></pre>\r
848      * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)\r
849      * @param {Object} obj (optional) The object for which the scope is set\r
850      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)\r
851      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,\r
852      *                                             if a number the args are inserted at the specified position\r
853      * @return {Number} The timeout id that can be used with clearTimeout\r
854      */\r
855     defer : function(millis, obj, args, appendArgs){\r
856         var fn = this.createDelegate(obj, args, appendArgs);\r
857         if(millis > 0){\r
858             return setTimeout(fn, millis);\r
859         }\r
860         fn();\r
861         return 0;\r
862     }\r
863 });\r
864 \r
865 /**\r
866  * @class String\r
867  * These functions are available on every String object.\r
868  */\r
869 Ext.applyIf(String, {\r
870     /**\r
871      * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each\r
872      * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:\r
873      * <pre><code>\r
874 var cls = 'my-class', text = 'Some text';\r
875 var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);\r
876 // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'\r
877      * </code></pre>\r
878      * @param {String} string The tokenized string to be formatted\r
879      * @param {String} value1 The value to replace token {0}\r
880      * @param {String} value2 Etc...\r
881      * @return {String} The formatted string\r
882      * @static\r
883      */\r
884     format : function(format){\r
885         var args = Ext.toArray(arguments, 1);\r
886         return format.replace(/\{(\d+)\}/g, function(m, i){\r
887             return args[i];\r
888         });\r
889     }\r
890 });\r
891 \r
892 /**\r
893  * @class Array\r
894  */\r
895 Ext.applyIf(Array.prototype, {\r
896     /**\r
897      * Checks whether or not the specified object exists in the array.\r
898      * @param {Object} o The object to check for\r
899      * @return {Number} The index of o in the array (or -1 if it is not found)\r
900      */\r
901     indexOf : function(o){\r
902         for (var i = 0, len = this.length; i < len; i++){\r
903             if(this[i] == o){\r
904                 return i;\r
905             }\r
906         }\r
907         return -1;\r
908     },\r
909 \r
910     /**\r
911      * Removes the specified object from the array.  If the object is not found nothing happens.\r
912      * @param {Object} o The object to remove\r
913      * @return {Array} this array\r
914      */\r
915     remove : function(o){\r
916         var index = this.indexOf(o);\r
917         if(index != -1){\r
918             this.splice(index, 1);\r
919         }\r
920         return this;\r
921     }\r
922 });\r
923 /**
924  * @class Ext
925  */
926
927 Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
928        "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
929     /**
930      * Namespace alloted for extensions to the framework.
931      * @property ux
932      * @type Object
933      */
934
935 Ext.apply(Ext, function(){
936     var E = Ext, idSeed = 0;
937
938     return {
939         /**
940         * A reusable empty function
941         * @property
942         * @type Function
943         */
944         emptyFn : function(){},
945
946         /**
947          * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. 
948          * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
949          * For other browsers it uses an inline data URL.
950          * @type String
951          */
952         BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ?
953                             'http:/' + '/extjs.com/s.gif' :
954                             'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
955
956         extendX : function(supr, fn){
957             return Ext.extend(supr, fn(supr.prototype));
958         },
959
960         /**
961          * Returns the current HTML document object as an {@link Ext.Element}.
962          * @return Ext.Element The document
963          */
964         getDoc : function(){
965             return Ext.get(document);
966         },
967
968         /**
969          * Returns true if the passed object is a JavaScript date object, otherwise false.
970          * @param {Object} object The object to test
971          * @return {Boolean}
972          */
973         isDate : function(v){
974             return Object.prototype.toString.apply(v) === '[object Date]';
975         },
976
977         /**
978          * Utility method for validating that a value is numeric, returning the specified default value if it is not.
979          * @param {Mixed} value Should be a number, but any type will be handled appropriately
980          * @param {Number} defaultValue The value to return if the original value is non-numeric
981          * @return {Number} Value, if numeric, else defaultValue
982          */
983         num : function(v, defaultValue){
984             v = Number(v === null || typeof v == 'boolean'? NaN : v);
985             return isNaN(v)? defaultValue : v;
986         },
987
988         /**
989          * <p>Utility method for returning a default value if the passed value is empty.</p>
990          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
991          * <li>null</li>
992          * <li>undefined</li>
993          * <li>an empty array</li>
994          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
995          * </ul></div>
996          * @param {Mixed} value The value to test
997          * @param {Mixed} defaultValue The value to return if the original value is empty
998          * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
999          * @return {Mixed} value, if non-empty, else defaultValue
1000          */
1001         value : function(v, defaultValue, allowBlank){
1002             return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
1003         },
1004
1005         /**
1006          * Escapes the passed string for use in a regular expression
1007          * @param {String} str
1008          * @return {String}
1009          */
1010         escapeRe : function(s) {
1011             return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
1012         },
1013
1014         sequence : function(o, name, fn, scope){
1015             o[name] = o[name].createSequence(fn, scope);
1016         },
1017
1018         /**
1019          * Applies event listeners to elements by selectors when the document is ready.
1020          * The event name is specified with an <tt>&#64;</tt> suffix.
1021          * <pre><code>
1022 Ext.addBehaviors({
1023     // add a listener for click on all anchors in element with id foo
1024     '#foo a&#64;click' : function(e, t){
1025         // do something
1026     },
1027     
1028     // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
1029     '#foo a, #bar span.some-class&#64;mouseover' : function(){
1030         // do something
1031     }
1032 });
1033          * </code></pre> 
1034          * @param {Object} obj The list of behaviors to apply
1035          */
1036         addBehaviors : function(o){
1037             if(!Ext.isReady){
1038                 Ext.onReady(function(){
1039                     Ext.addBehaviors(o);
1040                 });
1041             } else {
1042                 var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
1043                     parts,
1044                     b,
1045                     s;
1046                 for (b in o) {
1047                     if ((parts = b.split('@'))[1]) { // for Object prototype breakers
1048                         s = parts[0];
1049                         if(!cache[s]){
1050                             cache[s] = Ext.select(s);
1051                         }
1052                         cache[s].on(parts[1], o[b]);
1053                     }
1054                 }
1055                 cache = null;
1056             }
1057         },
1058
1059
1060         // deprecated
1061         combine : function(){
1062             var as = arguments, l = as.length, r = [];
1063             for(var i = 0; i < l; i++){
1064                 var a = as[i];
1065                 if(Ext.isArray(a)){
1066                     r = r.concat(a);
1067                 }else if(a.length !== undefined && !a.substr){
1068                     r = r.concat(Array.prototype.slice.call(a, 0));
1069                 }else{
1070                     r.push(a);
1071                 }
1072             }
1073             return r;
1074         },
1075
1076         /**
1077          * Copies a set of named properties fom the source object to the destination object.
1078          * <p>example:<pre><code>
1079 ImageComponent = Ext.extend(Ext.BoxComponent, {
1080     initComponent: function() {
1081         this.autoEl = { tag: 'img' };
1082         MyComponent.superclass.initComponent.apply(this, arguments);
1083         this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
1084     }
1085 });
1086          * </code></pre> 
1087          * @param {Object} The destination object.
1088          * @param {Object} The source object.
1089          * @param {Array/String} Either an Array of property names, or a comma-delimited list
1090          * of property names to copy.
1091          * @return {Object} The modified object.
1092         */
1093         copyTo : function(dest, source, names){
1094             if(typeof names == 'string'){
1095                 names = names.split(/[,;\s]/);
1096             }
1097             Ext.each(names, function(name){
1098                 if(source.hasOwnProperty(name)){
1099                     dest[name] = source[name];
1100                 }
1101             }, this);
1102             return dest;
1103         },
1104
1105         /**
1106          * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
1107          * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
1108          * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
1109          * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
1110          * passed into this function in a single call as separate arguments.
1111          * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
1112          * @param {Mixed} arg2 (optional)
1113          * @param {Mixed} etc... (optional)
1114          */
1115         destroy : function(){
1116             Ext.each(arguments, function(arg){
1117                 if(arg){
1118                     if(Ext.isArray(arg)){
1119                         this.destroy.apply(this, arg);
1120                     }else if(Ext.isFunction(arg.destroy)){
1121                         arg.destroy();
1122                     }else if(arg.dom){
1123                         arg.remove();
1124                     }    
1125                 }
1126             }, this);
1127         },
1128
1129         /**
1130          * Attempts to destroy and then remove a set of named properties of the passed object.
1131          * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
1132          * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
1133          * @param {Mixed} etc... More property names to destroy and remove.
1134          */
1135         destroyMembers : function(o, arg1, arg2, etc){
1136             for(var i = 1, a = arguments, len = a.length; i < len; i++) {
1137                 Ext.destroy(o[a[i]]);
1138                 delete o[a[i]];
1139             }
1140         },
1141
1142         /**
1143          * Creates a copy of the passed Array with falsy values removed.
1144          * @param {Array/NodeList} arr The Array from which to remove falsy values.
1145          * @return {Array} The new, compressed Array.
1146          */
1147         clean : function(arr){
1148             var ret = [];
1149             Ext.each(arr, function(v){
1150                 if(!!v){
1151                     ret.push(v);
1152                 }
1153             });
1154             return ret;
1155         },
1156
1157         /**
1158          * Creates a copy of the passed Array, filtered to contain only unique values.
1159          * @param {Array} arr The Array to filter
1160          * @return {Array} The new Array containing unique values.
1161          */
1162         unique : function(arr){
1163             var ret = [],
1164                 collect = {};
1165
1166             Ext.each(arr, function(v) {
1167                 if(!collect[v]){
1168                     ret.push(v);
1169                 }
1170                 collect[v] = true;
1171             });
1172             return ret;
1173         },
1174
1175         /**
1176          * Recursively flattens into 1-d Array. Injects Arrays inline.
1177          * @param {Array} arr The array to flatten
1178          * @return {Array} The new, flattened array.
1179          */
1180         flatten : function(arr){
1181             var worker = [];
1182             function rFlatten(a) {
1183                 Ext.each(a, function(v) {
1184                     if(Ext.isArray(v)){
1185                         rFlatten(v);
1186                     }else{
1187                         worker.push(v);
1188                     }
1189                 });
1190                 return worker;
1191             }
1192             return rFlatten(arr);
1193         },
1194
1195         /**
1196          * Returns the minimum value in the Array.
1197          * @param {Array|NodeList} arr The Array from which to select the minimum value.
1198          * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
1199          *                   If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
1200          * @return {Object} The minimum value in the Array.
1201          */
1202         min : function(arr, comp){
1203             var ret = arr[0];
1204             comp = comp || function(a,b){ return a < b ? -1 : 1; };
1205             Ext.each(arr, function(v) {
1206                 ret = comp(ret, v) == -1 ? ret : v;
1207             });
1208             return ret;
1209         },
1210
1211         /**
1212          * Returns the maximum value in the Array
1213          * @param {Array|NodeList} arr The Array from which to select the maximum value.
1214          * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
1215          *                   If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
1216          * @return {Object} The maximum value in the Array.
1217          */
1218         max : function(arr, comp){
1219             var ret = arr[0];
1220             comp = comp || function(a,b){ return a > b ? 1 : -1; };
1221             Ext.each(arr, function(v) {
1222                 ret = comp(ret, v) == 1 ? ret : v;
1223             });
1224             return ret;
1225         },
1226
1227         /**
1228          * Calculates the mean of the Array
1229          * @param {Array} arr The Array to calculate the mean value of.
1230          * @return {Number} The mean.
1231          */
1232         mean : function(arr){
1233            return Ext.sum(arr) / arr.length;
1234         },
1235
1236         /**
1237          * Calculates the sum of the Array
1238          * @param {Array} arr The Array to calculate the sum value of.
1239          * @return {Number} The sum.
1240          */
1241         sum : function(arr){
1242            var ret = 0;
1243            Ext.each(arr, function(v) {
1244                ret += v;
1245            });
1246            return ret;
1247         },
1248
1249         /**
1250          * Partitions the set into two sets: a true set and a false set.
1251          * Example: 
1252          * Example2: 
1253          * <pre><code>
1254 // Example 1:
1255 Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
1256
1257 // Example 2:
1258 Ext.partition(
1259     Ext.query("p"),
1260     function(val){
1261         return val.className == "class1"
1262     }
1263 );
1264 // true are those paragraph elements with a className of "class1",
1265 // false set are those that do not have that className.
1266          * </code></pre>
1267          * @param {Array|NodeList} arr The array to partition
1268          * @param {Function} truth (optional) a function to determine truth.  If this is omitted the element
1269          *                   itself must be able to be evaluated for its truthfulness.
1270          * @return {Array} [true<Array>,false<Array>]
1271          */
1272         partition : function(arr, truth){
1273             var ret = [[],[]];
1274             Ext.each(arr, function(v, i, a) {
1275                 ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
1276             });
1277             return ret;
1278         },
1279
1280         /**
1281          * Invokes a method on each item in an Array.
1282          * <pre><code>
1283 // Example:
1284 Ext.invoke(Ext.query("p"), "getAttribute", "id");
1285 // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
1286          * </code></pre>
1287          * @param {Array|NodeList} arr The Array of items to invoke the method on.
1288          * @param {String} methodName The method name to invoke.
1289          * @param {Anything} ... Arguments to send into the method invocation.
1290          * @return {Array} The results of invoking the method on each item in the array.
1291          */
1292         invoke : function(arr, methodName){
1293             var ret = [],
1294                 args = Array.prototype.slice.call(arguments, 2);
1295             Ext.each(arr, function(v,i) {
1296                 if (v && typeof v[methodName] == "function") {
1297                     ret.push(v[methodName].apply(v, args));
1298                 } else {
1299                     ret.push(undefined);
1300                 }
1301             });
1302             return ret;
1303         },
1304
1305         /**
1306          * Plucks the value of a property from each item in the Array
1307          * <pre><code>
1308 // Example:
1309 Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
1310          * </code></pre>
1311          * @param {Array|NodeList} arr The Array of items to pluck the value from.
1312          * @param {String} prop The property name to pluck from each element.
1313          * @return {Array} The value from each item in the Array.
1314          */
1315         pluck : function(arr, prop){
1316             var ret = [];
1317             Ext.each(arr, function(v) {
1318                 ret.push( v[prop] );
1319             });
1320             return ret;
1321         },
1322
1323         /**
1324          * <p>Zips N sets together.</p>
1325          * <pre><code>
1326 // Example 1:
1327 Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
1328 // Example 2:
1329 Ext.zip(
1330     [ "+", "-", "+"],
1331     [  12,  10,  22],
1332     [  43,  15,  96],
1333     function(a, b, c){
1334         return "$" + a + "" + b + "." + c
1335     }
1336 ); // ["$+12.43", "$-10.15", "$+22.96"]
1337          * </code></pre>
1338          * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
1339          * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
1340          * @return {Array} The zipped set.
1341          */
1342         zip : function(){
1343             var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
1344                 arrs = parts[0],
1345                 fn = parts[1][0],
1346                 len = Ext.max(Ext.pluck(arrs, "length")),
1347                 ret = [];
1348
1349             for (var i = 0; i < len; i++) {
1350                 ret[i] = [];
1351                 if(fn){
1352                     ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
1353                 }else{
1354                     for (var j = 0, aLen = arrs.length; j < aLen; j++){
1355                         ret[i].push( arrs[j][i] );
1356                     }
1357                 }
1358             }
1359             return ret;
1360         },
1361
1362         /**
1363          * This is shorthand reference to {@link Ext.ComponentMgr#get}.
1364          * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
1365          * @param {String} id The component {@link Ext.Component#id id}
1366          * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
1367          * Class was found.
1368         */
1369         getCmp : function(id){
1370             return Ext.ComponentMgr.get(id);
1371         },
1372
1373         /**
1374          * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
1375          * you may want to set this to true.
1376          * @type Boolean
1377          */
1378         useShims: E.isIE6 || (E.isMac && E.isGecko2),
1379
1380         // inpired by a similar function in mootools library
1381         /**
1382          * Returns the type of object that is passed in. If the object passed in is null or undefined it
1383          * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
1384          * <li><b>string</b>: If the object passed is a string</li>
1385          * <li><b>number</b>: If the object passed is a number</li>
1386          * <li><b>boolean</b>: If the object passed is a boolean value</li>
1387          * <li><b>date</b>: If the object passed is a Date object</li>
1388          * <li><b>function</b>: If the object passed is a function reference</li>
1389          * <li><b>object</b>: If the object passed is an object</li>
1390          * <li><b>array</b>: If the object passed is an array</li>
1391          * <li><b>regexp</b>: If the object passed is a regular expression</li>
1392          * <li><b>element</b>: If the object passed is a DOM Element</li>
1393          * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
1394          * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
1395          * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
1396          * </ul></div>
1397          * @param {Mixed} object
1398          * @return {String}
1399          */
1400         type : function(o){
1401             if(o === undefined || o === null){
1402                 return false;
1403             }
1404             if(o.htmlElement){
1405                 return 'element';
1406             }
1407             var t = typeof o;
1408             if(t == 'object' && o.nodeName) {
1409                 switch(o.nodeType) {
1410                     case 1: return 'element';
1411                     case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
1412                 }
1413             }
1414             if(t == 'object' || t == 'function') {
1415                 switch(o.constructor) {
1416                     case Array: return 'array';
1417                     case RegExp: return 'regexp';
1418                     case Date: return 'date';
1419                 }
1420                 if(typeof o.length == 'number' && typeof o.item == 'function') {
1421                     return 'nodelist';
1422                 }
1423             }
1424             return t;
1425         },
1426
1427         intercept : function(o, name, fn, scope){
1428             o[name] = o[name].createInterceptor(fn, scope);
1429         },
1430
1431         // internal
1432         callback : function(cb, scope, args, delay){
1433             if(Ext.isFunction(cb)){
1434                 if(delay){
1435                     cb.defer(delay, scope, args || []);
1436                 }else{
1437                     cb.apply(scope, args || []);
1438                 }
1439             }
1440         }
1441     };
1442 }());
1443
1444 /**
1445  * @class Function
1446  * These functions are available on every Function object (any JavaScript function).
1447  */
1448 Ext.apply(Function.prototype, {
1449     /**
1450      * Create a combined function call sequence of the original function + the passed function.
1451      * The resulting function returns the results of the original function.
1452      * The passed fcn is called with the parameters of the original function. Example usage:
1453      * <pre><code>
1454 var sayHi = function(name){
1455     alert('Hi, ' + name);
1456 }
1457
1458 sayHi('Fred'); // alerts "Hi, Fred"
1459
1460 var sayGoodbye = sayHi.createSequence(function(name){
1461     alert('Bye, ' + name);
1462 });
1463
1464 sayGoodbye('Fred'); // both alerts show
1465 </code></pre>
1466      * @param {Function} fcn The function to sequence
1467      * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
1468      * @return {Function} The new function
1469      */
1470     createSequence : function(fcn, scope){
1471         var method = this;
1472         return !Ext.isFunction(fcn) ?
1473                 this :
1474                 function(){
1475                     var retval = method.apply(this || window, arguments);
1476                     fcn.apply(scope || this || window, arguments);
1477                     return retval;
1478                 };
1479     }
1480 });
1481
1482
1483 /**
1484  * @class String
1485  * These functions are available as static methods on the JavaScript String object.
1486  */
1487 Ext.applyIf(String, {
1488
1489     /**
1490      * Escapes the passed string for ' and \
1491      * @param {String} string The string to escape
1492      * @return {String} The escaped string
1493      * @static
1494      */
1495     escape : function(string) {
1496         return string.replace(/('|\\)/g, "\\$1");
1497     },
1498
1499     /**
1500      * Pads the left side of a string with a specified character.  This is especially useful
1501      * for normalizing number and date strings.  Example usage:
1502      * <pre><code>
1503 var s = String.leftPad('123', 5, '0');
1504 // s now contains the string: '00123'
1505      * </code></pre>
1506      * @param {String} string The original string
1507      * @param {Number} size The total length of the output string
1508      * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
1509      * @return {String} The padded string
1510      * @static
1511      */
1512     leftPad : function (val, size, ch) {
1513         var result = String(val);
1514         if(!ch) {
1515             ch = " ";
1516         }
1517         while (result.length < size) {
1518             result = ch + result;
1519         }
1520         return result;
1521     }
1522 });
1523
1524 /**
1525  * Utility function that allows you to easily switch a string between two alternating values.  The passed value
1526  * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
1527  * they are already different, the first value passed in is returned.  Note that this method returns the new value
1528  * but does not change the current string.
1529  * <pre><code>
1530 // alternate sort directions
1531 sort = sort.toggle('ASC', 'DESC');
1532
1533 // instead of conditional logic:
1534 sort = (sort == 'ASC' ? 'DESC' : 'ASC');
1535 </code></pre>
1536  * @param {String} value The value to compare to the current string
1537  * @param {String} other The new value to use if the string already equals the first value passed in
1538  * @return {String} The new value
1539  */
1540 String.prototype.toggle = function(value, other){
1541     return this == value ? other : value;
1542 };
1543
1544 /**
1545  * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
1546  * <pre><code>
1547 var s = '  foo bar  ';
1548 alert('-' + s + '-');         //alerts "- foo bar -"
1549 alert('-' + s.trim() + '-');  //alerts "-foo bar-"
1550 </code></pre>
1551  * @return {String} The trimmed string
1552  */
1553 String.prototype.trim = function(){
1554     var re = /^\s+|\s+$/g;
1555     return function(){ return this.replace(re, ""); };
1556 }();
1557
1558 // here to prevent dependency on Date.js
1559 /**
1560  Returns the number of milliseconds between this date and date
1561  @param {Date} date (optional) Defaults to now
1562  @return {Number} The diff in milliseconds
1563  @member Date getElapsed
1564  */
1565 Date.prototype.getElapsed = function(date) {
1566     return Math.abs((date || new Date()).getTime()-this.getTime());
1567 };
1568
1569
1570 /**
1571  * @class Number
1572  */
1573 Ext.applyIf(Number.prototype, {
1574     /**
1575      * Checks whether or not the current number is within a desired range.  If the number is already within the
1576      * range it is returned, otherwise the min or max value is returned depending on which side of the range is
1577      * exceeded.  Note that this method returns the constrained value but does not change the current number.
1578      * @param {Number} min The minimum number in the range
1579      * @param {Number} max The maximum number in the range
1580      * @return {Number} The constrained value if outside the range, otherwise the current value
1581      */
1582     constrain : function(min, max){
1583         return Math.min(Math.max(this, min), max);
1584     }
1585 });
1586 /**
1587  * @class Ext.util.TaskRunner
1588  * Provides the ability to execute one or more arbitrary tasks in a multithreaded
1589  * manner.  Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
1590  * if needed, you can create separate instances of TaskRunner.  Any number of
1591  * separate tasks can be started at any time and will run independently of each
1592  * other. Example usage:
1593  * <pre><code>
1594 // Start a simple clock task that updates a div once per second
1595 var updateClock = function(){
1596     Ext.fly('clock').update(new Date().format('g:i:s A'));
1597
1598 var task = {
1599     run: updateClock,
1600     interval: 1000 //1 second
1601 }
1602 var runner = new Ext.util.TaskRunner();
1603 runner.start(task);
1604
1605 // equivalent using TaskMgr
1606 Ext.TaskMgr.start({
1607     run: updateClock,
1608     interval: 1000
1609 });
1610
1611  * </code></pre>
1612  * Also see {@link Ext.util.DelayedTask}. 
1613  * 
1614  * @constructor
1615  * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
1616  * (defaults to 10)
1617  */
1618 Ext.util.TaskRunner = function(interval){
1619     interval = interval || 10;
1620     var tasks = [], 
1621         removeQueue = [],
1622         id = 0,
1623         running = false,
1624
1625         // private
1626         stopThread = function(){
1627                 running = false;
1628                 clearInterval(id);
1629                 id = 0;
1630             },
1631
1632         // private
1633         startThread = function(){
1634                 if(!running){
1635                     running = true;
1636                     id = setInterval(runTasks, interval);
1637                 }
1638             },
1639
1640         // private
1641         removeTask = function(t){
1642                 removeQueue.push(t);
1643                 if(t.onStop){
1644                     t.onStop.apply(t.scope || t);
1645                 }
1646             },
1647             
1648         // private
1649         runTasks = function(){
1650                 var rqLen = removeQueue.length,
1651                         now = new Date().getTime();                                             
1652             
1653                 if(rqLen > 0){
1654                     for(var i = 0; i < rqLen; i++){
1655                         tasks.remove(removeQueue[i]);
1656                     }
1657                     removeQueue = [];
1658                     if(tasks.length < 1){
1659                         stopThread();
1660                         return;
1661                     }
1662                 }               
1663                 for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
1664                     t = tasks[i];
1665                     itime = now - t.taskRunTime;
1666                     if(t.interval <= itime){
1667                         rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
1668                         t.taskRunTime = now;
1669                         if(rt === false || t.taskRunCount === t.repeat){
1670                             removeTask(t);
1671                             return;
1672                         }
1673                     }
1674                     if(t.duration && t.duration <= (now - t.taskStartTime)){
1675                         removeTask(t);
1676                     }
1677                 }
1678             };
1679
1680     /**
1681      * Starts a new task.
1682      * @method start
1683      * @param {Object} task A config object that supports the following properties:<ul>
1684      * <li><code>run</code> : Function<div class="sub-desc">The function to execute each time the task is run. The
1685      * function will be called at each interval and passed the <code>args</code> argument if specified.  If a
1686      * particular scope is required, be sure to specify it using the <code>scope</code> argument.</div></li>
1687      * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
1688      * should be executed.</div></li>
1689      * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
1690      * specified by <code>run</code>.</div></li>
1691      * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
1692      * <code>run</code> function. Defaults to the task config object.</div></li>
1693      * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to execute
1694      * the task before stopping automatically (defaults to indefinite).</div></li>
1695      * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to execute the task before
1696      * stopping automatically (defaults to indefinite).</div></li>
1697      * </ul>
1698      * @return {Object} The task
1699      */
1700     this.start = function(task){
1701         tasks.push(task);
1702         task.taskStartTime = new Date().getTime();
1703         task.taskRunTime = 0;
1704         task.taskRunCount = 0;
1705         startThread();
1706         return task;
1707     };
1708
1709     /**
1710      * Stops an existing running task.
1711      * @method stop
1712      * @param {Object} task The task to stop
1713      * @return {Object} The task
1714      */
1715     this.stop = function(task){
1716         removeTask(task);
1717         return task;
1718     };
1719
1720     /**
1721      * Stops all tasks that are currently running.
1722      * @method stopAll
1723      */
1724     this.stopAll = function(){
1725         stopThread();
1726         for(var i = 0, len = tasks.length; i < len; i++){
1727             if(tasks[i].onStop){
1728                 tasks[i].onStop();
1729             }
1730         }
1731         tasks = [];
1732         removeQueue = [];
1733     };
1734 };
1735
1736 /**
1737  * @class Ext.TaskMgr
1738  * @extends Ext.util.TaskRunner
1739  * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks.  See
1740  * {@link Ext.util.TaskRunner} for supported methods and task config properties.
1741  * <pre><code>
1742 // Start a simple clock task that updates a div once per second
1743 var task = {
1744     run: function(){
1745         Ext.fly('clock').update(new Date().format('g:i:s A'));
1746     },
1747     interval: 1000 //1 second
1748 }
1749 Ext.TaskMgr.start(task);
1750 </code></pre>
1751  * @singleton
1752  */
1753 Ext.TaskMgr = new Ext.util.TaskRunner();(function(){\r
1754         var libFlyweight;\r
1755         \r
1756         function fly(el) {\r
1757         if (!libFlyweight) {\r
1758             libFlyweight = new Ext.Element.Flyweight();\r
1759         }\r
1760         libFlyweight.dom = el;\r
1761         return libFlyweight;\r
1762     }\r
1763     \r
1764     (function(){\r
1765         var doc = document,\r
1766                 isCSS1 = doc.compatMode == "CSS1Compat",\r
1767                 MAX = Math.max,         \r
1768                 PARSEINT = parseInt;\r
1769                 \r
1770         Ext.lib.Dom = {\r
1771             isAncestor : function(p, c) {\r
1772                     var ret = false;\r
1773                         \r
1774                         p = Ext.getDom(p);\r
1775                         c = Ext.getDom(c);\r
1776                         if (p && c) {\r
1777                                 if (p.contains) {\r
1778                                         return p.contains(c);\r
1779                                 } else if (p.compareDocumentPosition) {\r
1780                                         return !!(p.compareDocumentPosition(c) & 16);\r
1781                                 } else {\r
1782                                         while (c = c.parentNode) {\r
1783                                                 ret = c == p || ret;                                    \r
1784                                         }\r
1785                                 }                   \r
1786                         }       \r
1787                         return ret;\r
1788                 },\r
1789                 \r
1790         getViewWidth : function(full) {\r
1791             return full ? this.getDocumentWidth() : this.getViewportWidth();\r
1792         },\r
1793 \r
1794         getViewHeight : function(full) {\r
1795             return full ? this.getDocumentHeight() : this.getViewportHeight();\r
1796         },\r
1797 \r
1798         getDocumentHeight: function() {            \r
1799             return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight());\r
1800         },\r
1801 \r
1802         getDocumentWidth: function() {            \r
1803             return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth());\r
1804         },\r
1805 \r
1806         getViewportHeight: function(){\r
1807                 return Ext.isIE ? \r
1808                            (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :\r
1809                            self.innerHeight;\r
1810         },\r
1811 \r
1812         getViewportWidth : function() {\r
1813                 return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth :\r
1814                            Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;\r
1815         },\r
1816         \r
1817         getY : function(el) {\r
1818             return this.getXY(el)[1];\r
1819         },\r
1820 \r
1821         getX : function(el) {\r
1822             return this.getXY(el)[0];\r
1823         },\r
1824 \r
1825         getXY : function(el) {\r
1826             var p, \r
1827                 pe, \r
1828                 b,\r
1829                 bt, \r
1830                 bl,     \r
1831                 dbd,            \r
1832                 x = 0,\r
1833                 y = 0, \r
1834                 scroll,\r
1835                 hasAbsolute, \r
1836                 bd = (doc.body || doc.documentElement),\r
1837                 ret = [0,0];\r
1838                 \r
1839             el = Ext.getDom(el);\r
1840 \r
1841             if(el != bd){\r
1842                     if (el.getBoundingClientRect) {\r
1843                         b = el.getBoundingClientRect();\r
1844                         scroll = fly(document).getScroll();\r
1845                         ret = [b.left + scroll.left, b.top + scroll.top];\r
1846                     } else {  \r
1847                             p = el;             \r
1848                             hasAbsolute = fly(el).isStyle("position", "absolute");\r
1849                 \r
1850                             while (p) {\r
1851                                     pe = fly(p);                \r
1852                                 x += p.offsetLeft;\r
1853                                 y += p.offsetTop;\r
1854                 \r
1855                                 hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");\r
1856                                                 \r
1857                                 if (Ext.isGecko) {                                  \r
1858                                     y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0;\r
1859                                     x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0;        \r
1860                 \r
1861                                     if (p != el && !pe.isStyle('overflow','visible')) {\r
1862                                         x += bl;\r
1863                                         y += bt;\r
1864                                     }\r
1865                                 }\r
1866                                 p = p.offsetParent;\r
1867                             }\r
1868                 \r
1869                             if (Ext.isSafari && hasAbsolute) {\r
1870                                 x -= bd.offsetLeft;\r
1871                                 y -= bd.offsetTop;\r
1872                             }\r
1873                 \r
1874                             if (Ext.isGecko && !hasAbsolute) {\r
1875                                 dbd = fly(bd);\r
1876                                 x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0;\r
1877                                 y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0;\r
1878                             }\r
1879                 \r
1880                             p = el.parentNode;\r
1881                             while (p && p != bd) {\r
1882                                 if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {\r
1883                                     x -= p.scrollLeft;\r
1884                                     y -= p.scrollTop;\r
1885                                 }\r
1886                                 p = p.parentNode;\r
1887                             }\r
1888                             ret = [x,y];\r
1889                     }\r
1890                 }\r
1891             return ret\r
1892         },\r
1893 \r
1894         setXY : function(el, xy) {\r
1895             (el = Ext.fly(el, '_setXY')).position();\r
1896             \r
1897             var pts = el.translatePoints(xy),\r
1898                 style = el.dom.style,\r
1899                 pos;                    \r
1900             \r
1901             for (pos in pts) {              \r
1902                     if(!isNaN(pts[pos])) style[pos] = pts[pos] + "px"\r
1903             }\r
1904         },\r
1905 \r
1906         setX : function(el, x) {\r
1907             this.setXY(el, [x, false]);\r
1908         },\r
1909 \r
1910         setY : function(el, y) {\r
1911             this.setXY(el, [false, y]);\r
1912         }\r
1913     };\r
1914 })();Ext.lib.Dom.getRegion = function(el) {\r
1915     return Ext.lib.Region.getRegion(el);\r
1916 };Ext.lib.Event = function() {\r
1917     var loadComplete = false,\r
1918         listeners = [],\r
1919         unloadListeners = [],\r
1920         retryCount = 0,\r
1921         onAvailStack = [],\r
1922         _interval,\r
1923         locked = false,\r
1924         win = window,\r
1925         doc = document,\r
1926         \r
1927         // constants            \r
1928         POLL_RETRYS = 200,\r
1929         POLL_INTERVAL = 20,\r
1930         EL = 0,\r
1931         TYPE = 1,\r
1932         FN = 2,\r
1933         WFN = 3,\r
1934         OBJ = 3,\r
1935         ADJ_SCOPE = 4,   \r
1936         SCROLLLEFT = 'scrollLeft',\r
1937         SCROLLTOP = 'scrollTop',\r
1938         UNLOAD = 'unload',\r
1939         MOUSEOVER = 'mouseover',\r
1940         MOUSEOUT = 'mouseout',\r
1941         // private\r
1942         doAdd = function() {\r
1943             var ret;\r
1944             if (win.addEventListener) {\r
1945                 ret = function(el, eventName, fn, capture) {\r
1946                     if (eventName == 'mouseenter') {\r
1947                         fn = fn.createInterceptor(checkRelatedTarget);\r
1948                         el.addEventListener(MOUSEOVER, fn, (capture));\r
1949                     } else if (eventName == 'mouseleave') {\r
1950                         fn = fn.createInterceptor(checkRelatedTarget);\r
1951                         el.addEventListener(MOUSEOUT, fn, (capture));\r
1952                     } else {\r
1953                         el.addEventListener(eventName, fn, (capture));\r
1954                     }\r
1955                     return fn;\r
1956                 };\r
1957             } else if (win.attachEvent) {\r
1958                 ret = function(el, eventName, fn, capture) {\r
1959                     el.attachEvent("on" + eventName, fn);\r
1960                     return fn;\r
1961                 };\r
1962             } else {\r
1963                 ret = function(){};\r
1964             }\r
1965             return ret;\r
1966         }(),    \r
1967         // private\r
1968         doRemove = function(){\r
1969             var ret;\r
1970             if (win.removeEventListener) {\r
1971                 ret = function (el, eventName, fn, capture) {\r
1972                     if (eventName == 'mouseenter') {\r
1973                         eventName = MOUSEOVER;\r
1974                     } else if (eventName == 'mouseleave') {\r
1975                         eventName = MOUSEOUT;\r
1976                     }                        \r
1977                     el.removeEventListener(eventName, fn, (capture));\r
1978                 };\r
1979             } else if (win.detachEvent) {\r
1980                 ret = function (el, eventName, fn) {\r
1981                     el.detachEvent("on" + eventName, fn);\r
1982                 };\r
1983             } else {\r
1984                 ret = function(){};\r
1985             }\r
1986             return ret;\r
1987         }();        \r
1988 \r
1989     var isXUL = Ext.isGecko ? function(node){ \r
1990         return Object.prototype.toString.call(node) == '[object XULElement]';\r
1991     } : function(){};\r
1992         \r
1993     var isTextNode = Ext.isGecko ? function(node){\r
1994         try{\r
1995             return node.nodeType == 3;\r
1996         }catch(e) {\r
1997             return false;\r
1998         }\r
1999 \r
2000     } : function(node){\r
2001         return node.nodeType == 3;\r
2002     };\r
2003         \r
2004     function checkRelatedTarget(e) {\r
2005         var related = pub.getRelatedTarget(e);\r
2006         return !(isXUL(related) || elContains(e.currentTarget,related));\r
2007     }\r
2008 \r
2009     function elContains(parent, child) {\r
2010        if(parent && parent.firstChild){  \r
2011          while(child) {\r
2012             if(child === parent) {\r
2013                 return true;\r
2014             }\r
2015             try {\r
2016                 child = child.parentNode;\r
2017             } catch(e) {\r
2018                 // In FF if you mouseout an text input element\r
2019                 // thats inside a div sometimes it randomly throws\r
2020                 // Permission denied to get property HTMLDivElement.parentNode\r
2021                 // See https://bugzilla.mozilla.org/show_bug.cgi?id=208427\r
2022                 \r
2023                 return false;\r
2024             }                \r
2025             if(child && (child.nodeType != 1)) {\r
2026                 child = null;\r
2027             }\r
2028           }\r
2029         }\r
2030         return false;\r
2031     }\r
2032 \r
2033         \r
2034     // private  \r
2035     function _getCacheIndex(el, eventName, fn) {\r
2036         var index = -1;\r
2037         Ext.each(listeners, function (v,i) {\r
2038             if(v && v[FN] == fn && v[EL] == el && v[TYPE] == eventName) {\r
2039                 index = i;\r
2040             }\r
2041         });\r
2042         return index;\r
2043     }\r
2044                     \r
2045     // private\r
2046     function _tryPreloadAttach() {\r
2047         var ret = false,                \r
2048             notAvail = [],\r
2049             element,\r
2050             tryAgain = !loadComplete || (retryCount > 0);                       \r
2051         \r
2052         if (!locked) {\r
2053             locked = true;\r
2054             \r
2055             Ext.each(onAvailStack, function (v,i,a){\r
2056                 if(v && (element = doc.getElementById(v.id))){\r
2057                     if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {\r
2058                         element = v.override ? (v.override === true ? v.obj : v.override) : element;\r
2059                         v.fn.call(element, v.obj);\r
2060                         onAvailStack[i] = null;\r
2061                     } else {\r
2062                         notAvail.push(v);\r
2063                     }\r
2064                 }   \r
2065             });\r
2066 \r
2067             retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;\r
2068 \r
2069             if (tryAgain) { \r
2070                 startInterval();\r
2071             } else {\r
2072                 clearInterval(_interval);\r
2073                 _interval = null;\r
2074             }\r
2075 \r
2076             ret = !(locked = false);\r
2077         }\r
2078         return ret;\r
2079     }\r
2080     \r
2081     // private              \r
2082     function startInterval() {            \r
2083         if(!_interval){                    \r
2084             var callback = function() {\r
2085                 _tryPreloadAttach();\r
2086             };\r
2087             _interval = setInterval(callback, POLL_INTERVAL);\r
2088         }\r
2089     }\r
2090     \r
2091     // private \r
2092     function getScroll() {\r
2093         var dd = doc.documentElement, \r
2094             db = doc.body;\r
2095         if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){\r
2096             return [dd[SCROLLLEFT], dd[SCROLLTOP]];\r
2097         }else if(db){\r
2098             return [db[SCROLLLEFT], db[SCROLLTOP]];\r
2099         }else{\r
2100             return [0, 0];\r
2101         }\r
2102     }\r
2103         \r
2104     // private\r
2105     function getPageCoord (ev, xy) {\r
2106         ev = ev.browserEvent || ev;\r
2107         var coord  = ev['page' + xy];\r
2108         if (!coord && coord !== 0) {\r
2109             coord = ev['client' + xy] || 0;\r
2110 \r
2111             if (Ext.isIE) {\r
2112                 coord += getScroll()[xy == "X" ? 0 : 1];\r
2113             }\r
2114         }\r
2115 \r
2116         return coord;\r
2117     }\r
2118 \r
2119     var pub =  {\r
2120         onAvailable : function(p_id, p_fn, p_obj, p_override) {             \r
2121             onAvailStack.push({ \r
2122                 id:         p_id,\r
2123                 fn:         p_fn,\r
2124                 obj:        p_obj,\r
2125                 override:   p_override,\r
2126                 checkReady: false });\r
2127 \r
2128             retryCount = POLL_RETRYS;\r
2129             startInterval();\r
2130         },\r
2131 \r
2132 \r
2133         addListener: function(el, eventName, fn) {\r
2134             var ret;                \r
2135             el = Ext.getDom(el);                \r
2136             if (el && fn) {\r
2137                 if (UNLOAD == eventName) {\r
2138                     ret = !!(unloadListeners[unloadListeners.length] = [el, eventName, fn]);                    \r
2139                 } else {\r
2140                     listeners.push([el, eventName, fn, ret = doAdd(el, eventName, fn, false)]);\r
2141                 }\r
2142             }\r
2143             return !!ret;\r
2144         },\r
2145 \r
2146         removeListener: function(el, eventName, fn) {\r
2147             var ret = false,\r
2148                 index, \r
2149                 cacheItem;\r
2150 \r
2151             el = Ext.getDom(el);\r
2152 \r
2153             if(!fn) {                   \r
2154                 ret = this.purgeElement(el, false, eventName);\r
2155             } else if (UNLOAD == eventName) {   \r
2156                 Ext.each(unloadListeners, function(v, i, a) {\r
2157                     if( v && v[0] == el && v[1] == eventName && v[2] == fn) {\r
2158                         unloadListeners.splice(i, 1);\r
2159                         ret = true;\r
2160                     }\r
2161                 });\r
2162             } else {    \r
2163                 index = arguments[3] || _getCacheIndex(el, eventName, fn);\r
2164                 cacheItem = listeners[index];\r
2165                 \r
2166                 if (el && cacheItem) {\r
2167                     doRemove(el, eventName, cacheItem[WFN], false);     \r
2168                     cacheItem[WFN] = cacheItem[FN] = null;                       \r
2169                     listeners.splice(index, 1);     \r
2170                     ret = true;\r
2171                 }\r
2172             }\r
2173             return ret;\r
2174         },\r
2175 \r
2176         getTarget : function(ev) {\r
2177             ev = ev.browserEvent || ev;                \r
2178             return this.resolveTextNode(ev.target || ev.srcElement);\r
2179         },\r
2180 \r
2181         resolveTextNode : function(node) {\r
2182             return node && !isXUL(node) && isTextNode(node) ? node.parentNode : node;\r
2183         },\r
2184 \r
2185         getRelatedTarget : function(ev) {\r
2186             ev = ev.browserEvent || ev;\r
2187             return this.resolveTextNode(ev.relatedTarget || \r
2188                     (ev.type == MOUSEOUT ? ev.toElement :\r
2189                      ev.type == MOUSEOVER ? ev.fromElement : null));\r
2190         },\r
2191         \r
2192         getPageX : function(ev) {\r
2193             return getPageCoord(ev, "X");\r
2194         },\r
2195 \r
2196         getPageY : function(ev) {\r
2197             return getPageCoord(ev, "Y");\r
2198         },\r
2199 \r
2200 \r
2201         getXY : function(ev) {                             \r
2202             return [this.getPageX(ev), this.getPageY(ev)];\r
2203         },\r
2204 \r
2205 // Is this useful?  Removing to save space unless use case exists.\r
2206 //             getTime: function(ev) {\r
2207 //                 ev = ev.browserEvent || ev;\r
2208 //                 if (!ev.time) {\r
2209 //                     var t = new Date().getTime();\r
2210 //                     try {\r
2211 //                         ev.time = t;\r
2212 //                     } catch(ex) {\r
2213 //                         return t;\r
2214 //                     }\r
2215 //                 }\r
2216 \r
2217 //                 return ev.time;\r
2218 //             },\r
2219 \r
2220         stopEvent : function(ev) {                            \r
2221             this.stopPropagation(ev);\r
2222             this.preventDefault(ev);\r
2223         },\r
2224 \r
2225         stopPropagation : function(ev) {\r
2226             ev = ev.browserEvent || ev;\r
2227             if (ev.stopPropagation) {\r
2228                 ev.stopPropagation();\r
2229             } else {\r
2230                 ev.cancelBubble = true;\r
2231             }\r
2232         },\r
2233 \r
2234         preventDefault : function(ev) {\r
2235             ev = ev.browserEvent || ev;\r
2236             if (ev.preventDefault) {\r
2237                 ev.preventDefault();\r
2238             } else {\r
2239                 ev.returnValue = false;\r
2240             }\r
2241         },\r
2242         \r
2243         getEvent : function(e) {\r
2244             e = e || win.event;\r
2245             if (!e) {\r
2246                 var c = this.getEvent.caller;\r
2247                 while (c) {\r
2248                     e = c.arguments[0];\r
2249                     if (e && Event == e.constructor) {\r
2250                         break;\r
2251                     }\r
2252                     c = c.caller;\r
2253                 }\r
2254             }\r
2255             return e;\r
2256         },\r
2257 \r
2258         getCharCode : function(ev) {\r
2259             ev = ev.browserEvent || ev;\r
2260             return ev.charCode || ev.keyCode || 0;\r
2261         },\r
2262 \r
2263         //clearCache: function() {},\r
2264 \r
2265         _load : function(e) {\r
2266             loadComplete = true;\r
2267             var EU = Ext.lib.Event;    \r
2268             if (Ext.isIE && e !== true) {\r
2269         // IE8 complains that _load is null or not an object\r
2270         // so lets remove self via arguments.callee\r
2271                 doRemove(win, "load", arguments.callee);\r
2272             }\r
2273         },            \r
2274         \r
2275         purgeElement : function(el, recurse, eventName) {\r
2276             var me = this;\r
2277             Ext.each( me.getListeners(el, eventName), function(v){\r
2278                 if(v){\r
2279                     me.removeListener(el, v.type, v.fn);\r
2280                 }\r
2281             });\r
2282 \r
2283             if (recurse && el && el.childNodes) {\r
2284                 Ext.each(el.childNodes, function(v){\r
2285                     me.purgeElement(v, recurse, eventName);\r
2286                 });\r
2287             }\r
2288         },\r
2289 \r
2290         getListeners : function(el, eventName) {\r
2291             var me = this,\r
2292                 results = [], \r
2293                 searchLists;\r
2294 \r
2295             if (eventName){  \r
2296                 searchLists = eventName == UNLOAD ? unloadListeners : listeners;\r
2297             }else{\r
2298                 searchLists = listeners.concat(unloadListeners);\r
2299             }\r
2300 \r
2301             Ext.each(searchLists, function(v, i){\r
2302                 if (v && v[EL] == el && (!eventName || eventName == v[TYPE])) {\r
2303                     results.push({\r
2304                                 type:   v[TYPE],\r
2305                                 fn:     v[FN],\r
2306                                 obj:    v[OBJ],\r
2307                                 adjust: v[ADJ_SCOPE],\r
2308                                 index:  i\r
2309                             });\r
2310                 }   \r
2311             });                \r
2312 \r
2313             return results.length ? results : null;\r
2314         },\r
2315 \r
2316         _unload : function(e) {\r
2317              var EU = Ext.lib.Event, \r
2318                 i, \r
2319                 j, \r
2320                 l, \r
2321                 len, \r
2322                 index,\r
2323                 scope;\r
2324                 \r
2325 \r
2326             Ext.each(unloadListeners, function(v) {\r
2327                 if (v) {\r
2328                     try{\r
2329                         scope =  v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) :  win; \r
2330                         v[FN].call(scope, EU.getEvent(e), v[OBJ]);\r
2331                     }catch(ex){}\r
2332                 }   \r
2333             });     \r
2334 \r
2335             unloadListeners = null;\r
2336 \r
2337             if(listeners && (j = listeners.length)){                    \r
2338                 while(j){                        \r
2339                     if((l = listeners[index = --j])){\r
2340                         EU.removeListener(l[EL], l[TYPE], l[FN], index);\r
2341                     }                        \r
2342                 }\r
2343                 //EU.clearCache();\r
2344             }\r
2345 \r
2346             doRemove(win, UNLOAD, EU._unload);\r
2347         }            \r
2348     };        \r
2349     \r
2350     // Initialize stuff.\r
2351     pub.on = pub.addListener;\r
2352     pub.un = pub.removeListener;\r
2353     if (doc && doc.body) {\r
2354         pub._load(true);\r
2355     } else {\r
2356         doAdd(win, "load", pub._load);\r
2357     }\r
2358     doAdd(win, UNLOAD, pub._unload);    \r
2359     _tryPreloadAttach();\r
2360     \r
2361     return pub;\r
2362 }();/*\r
2363  * Portions of this file are based on pieces of Yahoo User Interface Library\r
2364  * Copyright (c) 2007, Yahoo! Inc. All rights reserved.\r
2365  * YUI licensed under the BSD License:\r
2366  * http://developer.yahoo.net/yui/license.txt\r
2367  */\r
2368     Ext.lib.Ajax = function() {     \r
2369             var activeX = ['MSXML2.XMLHTTP.3.0',\r
2370                                    'MSXML2.XMLHTTP',\r
2371                                    'Microsoft.XMLHTTP'],\r
2372             CONTENTTYPE = 'Content-Type';\r
2373                                    \r
2374                 // private\r
2375                 function setHeader(o) {\r
2376                 var conn = o.conn,\r
2377                         prop;\r
2378                 \r
2379                 function setTheHeaders(conn, headers){\r
2380                         for (prop in headers) {\r
2381                     if (headers.hasOwnProperty(prop)) {\r
2382                         conn.setRequestHeader(prop, headers[prop]);\r
2383                     }\r
2384                 }   \r
2385                 }               \r
2386                 \r
2387             if (pub.defaultHeaders) {\r
2388                     setTheHeaders(conn, pub.defaultHeaders);\r
2389             }\r
2390 \r
2391             if (pub.headers) {\r
2392                                 setTheHeaders(conn, pub.headers);\r
2393                 pub.headers = null;                \r
2394             }\r
2395         }    \r
2396         \r
2397         // private\r
2398         function createExceptionObject(tId, callbackArg, isAbort, isTimeout) {          \r
2399             return {\r
2400                     tId : tId,\r
2401                     status : isAbort ? -1 : 0,\r
2402                     statusText : isAbort ? 'transaction aborted' : 'communication failure',\r
2403                     isAbort: true,\r
2404                     isTimeout: true,\r
2405                     argument : callbackArg\r
2406             };\r
2407         }  \r
2408         \r
2409         // private \r
2410         function initHeader(label, value) {         \r
2411                         (pub.headers = pub.headers || {})[label] = value;                                   \r
2412         }\r
2413             \r
2414         // private\r
2415         function createResponseObject(o, callbackArg) {\r
2416             var headerObj = {},\r
2417                 headerStr,              \r
2418                 conn = o.conn,\r
2419                 t,\r
2420                 s;\r
2421 \r
2422             try {\r
2423                 headerStr = o.conn.getAllResponseHeaders();   \r
2424                 Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){\r
2425                     t = v.indexOf(':');\r
2426                     if(t >= 0){\r
2427                         s = v.substr(0, t).toLowerCase();\r
2428                         if(v.charAt(t + 1) == ' '){\r
2429                             ++t;\r
2430                         }\r
2431                         headerObj[s] = v.substr(t + 1);\r
2432                     }\r
2433                 });\r
2434             } catch(e) {}\r
2435                         \r
2436             return {\r
2437                 tId : o.tId,\r
2438                 status : conn.status,\r
2439                 statusText : conn.statusText,\r
2440                 getResponseHeader : function(header){return headerObj[header.toLowerCase()];},\r
2441                 getAllResponseHeaders : function(){return headerStr},\r
2442                 responseText : conn.responseText,\r
2443                 responseXML : conn.responseXML,\r
2444                 argument : callbackArg\r
2445             };\r
2446         }\r
2447         \r
2448         // private\r
2449         function releaseObject(o) {\r
2450             o.conn = null;\r
2451             o = null;\r
2452         }        \r
2453             \r
2454         // private\r
2455         function handleTransactionResponse(o, callback, isAbort, isTimeout) {\r
2456             if (!callback) {\r
2457                 releaseObject(o);\r
2458                 return;\r
2459             }\r
2460 \r
2461             var httpStatus, responseObject;\r
2462 \r
2463             try {\r
2464                 if (o.conn.status !== undefined && o.conn.status != 0) {\r
2465                     httpStatus = o.conn.status;\r
2466                 }\r
2467                 else {\r
2468                     httpStatus = 13030;\r
2469                 }\r
2470             }\r
2471             catch(e) {\r
2472                 httpStatus = 13030;\r
2473             }\r
2474 \r
2475             if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {\r
2476                 responseObject = createResponseObject(o, callback.argument);\r
2477                 if (callback.success) {\r
2478                     if (!callback.scope) {\r
2479                         callback.success(responseObject);\r
2480                     }\r
2481                     else {\r
2482                         callback.success.apply(callback.scope, [responseObject]);\r
2483                     }\r
2484                 }\r
2485             }\r
2486             else {\r
2487                 switch (httpStatus) {\r
2488                     case 12002:\r
2489                     case 12029:\r
2490                     case 12030:\r
2491                     case 12031:\r
2492                     case 12152:\r
2493                     case 13030:\r
2494                         responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout);\r
2495                         if (callback.failure) {\r
2496                             if (!callback.scope) {\r
2497                                 callback.failure(responseObject);\r
2498                             }\r
2499                             else {\r
2500                                 callback.failure.apply(callback.scope, [responseObject]);\r
2501                             }\r
2502                         }\r
2503                         break;\r
2504                     default:\r
2505                         responseObject = createResponseObject(o, callback.argument);\r
2506                         if (callback.failure) {\r
2507                             if (!callback.scope) {\r
2508                                 callback.failure(responseObject);\r
2509                             }\r
2510                             else {\r
2511                                 callback.failure.apply(callback.scope, [responseObject]);\r
2512                             }\r
2513                         }\r
2514                 }\r
2515             }\r
2516 \r
2517             releaseObject(o);\r
2518             responseObject = null;\r
2519         }  \r
2520         \r
2521         // private\r
2522         function handleReadyState(o, callback){\r
2523             callback = callback || {};\r
2524             var conn = o.conn,\r
2525                 tId = o.tId,\r
2526                 poll = pub.poll,\r
2527                 cbTimeout = callback.timeout || null;\r
2528 \r
2529             if (cbTimeout) {\r
2530                 pub.timeout[tId] = setTimeout(function() {\r
2531                     pub.abort(o, callback, true);\r
2532                 }, cbTimeout);\r
2533             }\r
2534 \r
2535             poll[tId] = setInterval(\r
2536                 function() {\r
2537                     if (conn && conn.readyState == 4) {\r
2538                         clearInterval(poll[tId]);\r
2539                         poll[tId] = null;\r
2540 \r
2541                         if (cbTimeout) {\r
2542                             clearTimeout(pub.timeout[tId]);\r
2543                             pub.timeout[tId] = null;\r
2544                         }\r
2545 \r
2546                         handleTransactionResponse(o, callback);\r
2547                     }\r
2548                 },\r
2549                 pub.pollInterval);\r
2550         }\r
2551         \r
2552         // private\r
2553         function asyncRequest(method, uri, callback, postData) {\r
2554             var o = getConnectionObject() || null;\r
2555 \r
2556             if (o) {\r
2557                 o.conn.open(method, uri, true);\r
2558 \r
2559                 if (pub.useDefaultXhrHeader) {                    \r
2560                         initHeader('X-Requested-With', pub.defaultXhrHeader);\r
2561                 }\r
2562 \r
2563                 if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){\r
2564                     initHeader(CONTENTTYPE, pub.defaultPostHeader);\r
2565                 }\r
2566 \r
2567                 if (pub.defaultHeaders || pub.headers) {\r
2568                     setHeader(o);\r
2569                 }\r
2570 \r
2571                 handleReadyState(o, callback);\r
2572                 o.conn.send(postData || null);\r
2573             }\r
2574             return o;\r
2575         }\r
2576         \r
2577         // private\r
2578         function getConnectionObject() {\r
2579             var o;              \r
2580 \r
2581             try {\r
2582                 if (o = createXhrObject(pub.transactionId)) {\r
2583                     pub.transactionId++;\r
2584                 }\r
2585             } catch(e) {\r
2586             } finally {\r
2587                 return o;\r
2588             }\r
2589         }\r
2590                \r
2591         // private\r
2592         function createXhrObject(transactionId) {\r
2593             var http;\r
2594                 \r
2595             try {\r
2596                 http = new XMLHttpRequest();                \r
2597             } catch(e) {\r
2598                 for (var i = 0; i < activeX.length; ++i) {                  \r
2599                     try {\r
2600                         http = new ActiveXObject(activeX[i]);                        \r
2601                         break;\r
2602                     } catch(e) {}\r
2603                 }\r
2604             } finally {\r
2605                 return {conn : http, tId : transactionId};\r
2606             }\r
2607         }\r
2608                  \r
2609             var pub = {\r
2610                 request : function(method, uri, cb, data, options) {\r
2611                             if(options){\r
2612                                 var me = this,                  \r
2613                                         xmlData = options.xmlData,\r
2614                                         jsonData = options.jsonData,\r
2615                         hs;\r
2616                                         \r
2617                                 Ext.applyIf(me, options);               \r
2618                             \r
2619                             if(xmlData || jsonData){\r
2620                         hs = me.headers;\r
2621                         if(!hs || !hs[CONTENTTYPE]){\r
2622                                         initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json');\r
2623                         }\r
2624                                     data = xmlData || (Ext.isObject(jsonData) ? Ext.encode(jsonData) : jsonData);\r
2625                                 }\r
2626                             }                               \r
2627                             return asyncRequest(method || options.method || "POST", uri, cb, data);\r
2628                 },\r
2629         \r
2630                 serializeForm : function(form) {\r
2631                         var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,\r
2632                         hasSubmit = false,\r
2633                         encoder = encodeURIComponent,\r
2634                                 element,\r
2635                         options, \r
2636                         name, \r
2637                         val,                    \r
2638                         data = '',\r
2639                         type;\r
2640                         \r
2641                         Ext.each(fElements, function(element) {                     \r
2642                         name = element.name;                 \r
2643                                         type = element.type;\r
2644                                         \r
2645                         if (!element.disabled && name){\r
2646                                 if(/select-(one|multiple)/i.test(type)){                                        \r
2647                                             Ext.each(element.options, function(opt) {\r
2648                                                     if (opt.selected) {\r
2649                                                             data += String.format("{0}={1}&",                                                                                             \r
2650                                                                                                  encoder(name),                                                                                          \r
2651                                                                                                   (opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified) ? opt.value : opt.text);\r
2652                                 }                                                               \r
2653                             });\r
2654                                 } else if(!/file|undefined|reset|button/i.test(type)) {\r
2655                                         if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){\r
2656                                     \r
2657                                 data += encoder(name) + '=' + encoder(element.value) + '&';                     \r
2658                                 hasSubmit = /submit/i.test(type);    \r
2659                             }                           \r
2660                                 } \r
2661                         }\r
2662                     });            \r
2663                     return data.substr(0, data.length - 1);\r
2664                 },\r
2665                 \r
2666                 useDefaultHeader : true,\r
2667                 defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',\r
2668                 useDefaultXhrHeader : true,\r
2669                 defaultXhrHeader : 'XMLHttpRequest',        \r
2670                 poll : {},\r
2671                 timeout : {},\r
2672                 pollInterval : 50,\r
2673                 transactionId : 0,\r
2674                 \r
2675 //      This is never called - Is it worth exposing this?                       \r
2676 //              setProgId : function(id) {\r
2677 //                  activeX.unshift(id);\r
2678 //              },\r
2679 \r
2680 //      This is never called - Is it worth exposing this?       \r
2681 //              setDefaultPostHeader : function(b) {\r
2682 //                  this.useDefaultHeader = b;\r
2683 //              },\r
2684                 \r
2685 //      This is never called - Is it worth exposing this?       \r
2686 //              setDefaultXhrHeader : function(b) {\r
2687 //                  this.useDefaultXhrHeader = b;\r
2688 //              },\r
2689 \r
2690 //      This is never called - Is it worth exposing this?               \r
2691 //              setPollingInterval : function(i) {\r
2692 //                  if (typeof i == 'number' && isFinite(i)) {\r
2693 //                      this.pollInterval = i;\r
2694 //                  }\r
2695 //              },\r
2696                 \r
2697 //      This is never called - Is it worth exposing this?\r
2698 //              resetDefaultHeaders : function() {\r
2699 //                  this.defaultHeaders = null;\r
2700 //              },\r
2701         \r
2702                 abort : function(o, callback, isTimeout) {\r
2703                         var me = this,\r
2704                                 tId = o.tId,\r
2705                                 isAbort = false;\r
2706                         \r
2707                     if (me.isCallInProgress(o)) {\r
2708                         o.conn.abort();\r
2709                         clearInterval(me.poll[tId]);\r
2710                         me.poll[tId] = null;\r
2711                         if (isTimeout) {\r
2712                             me.timeout[tId] = null;\r
2713                         }\r
2714                                         \r
2715                         handleTransactionResponse(o, callback, (isAbort = true), isTimeout);                \r
2716                     }\r
2717                     return isAbort;\r
2718                 },\r
2719         \r
2720                 isCallInProgress : function(o) {\r
2721                     // if there is a connection and readyState is not 0 or 4\r
2722                     return o.conn && !{0:true,4:true}[o.conn.readyState];               \r
2723                 }\r
2724             };\r
2725             return pub;\r
2726     }();        Ext.lib.Region = function(t, r, b, l) {\r
2727                 var me = this;\r
2728         me.top = t;\r
2729         me[1] = t;\r
2730         me.right = r;\r
2731         me.bottom = b;\r
2732         me.left = l;\r
2733         me[0] = l;\r
2734     };\r
2735 \r
2736     Ext.lib.Region.prototype = {\r
2737         contains : function(region) {\r
2738                 var me = this;\r
2739             return ( region.left >= me.left &&\r
2740                      region.right <= me.right &&\r
2741                      region.top >= me.top &&\r
2742                      region.bottom <= me.bottom );\r
2743 \r
2744         },\r
2745 \r
2746         getArea : function() {\r
2747                 var me = this;\r
2748             return ( (me.bottom - me.top) * (me.right - me.left) );\r
2749         },\r
2750 \r
2751         intersect : function(region) {\r
2752             var me = this,\r
2753                 t = Math.max(me.top, region.top),\r
2754                 r = Math.min(me.right, region.right),\r
2755                 b = Math.min(me.bottom, region.bottom),\r
2756                 l = Math.max(me.left, region.left);\r
2757 \r
2758             if (b >= t && r >= l) {\r
2759                 return new Ext.lib.Region(t, r, b, l);\r
2760             }\r
2761         },\r
2762         \r
2763         union : function(region) {\r
2764                 var me = this,\r
2765                 t = Math.min(me.top, region.top),\r
2766                 r = Math.max(me.right, region.right),\r
2767                 b = Math.max(me.bottom, region.bottom),\r
2768                 l = Math.min(me.left, region.left);\r
2769 \r
2770             return new Ext.lib.Region(t, r, b, l);\r
2771         },\r
2772 \r
2773         constrainTo : function(r) {\r
2774                 var me = this;\r
2775             me.top = me.top.constrain(r.top, r.bottom);\r
2776             me.bottom = me.bottom.constrain(r.top, r.bottom);\r
2777             me.left = me.left.constrain(r.left, r.right);\r
2778             me.right = me.right.constrain(r.left, r.right);\r
2779             return me;\r
2780         },\r
2781 \r
2782         adjust : function(t, l, b, r) {\r
2783                 var me = this;\r
2784             me.top += t;\r
2785             me.left += l;\r
2786             me.right += r;\r
2787             me.bottom += b;\r
2788             return me;\r
2789         }\r
2790     };\r
2791 \r
2792     Ext.lib.Region.getRegion = function(el) {\r
2793         var p = Ext.lib.Dom.getXY(el),\r
2794                 t = p[1],\r
2795                 r = p[0] + el.offsetWidth,\r
2796                 b = p[1] + el.offsetHeight,\r
2797                 l = p[0];\r
2798 \r
2799         return new Ext.lib.Region(t, r, b, l);\r
2800     };  Ext.lib.Point = function(x, y) {\r
2801         if (Ext.isArray(x)) {\r
2802             y = x[1];\r
2803             x = x[0];\r
2804         }\r
2805         var me = this;\r
2806         me.x = me.right = me.left = me[0] = x;\r
2807         me.y = me.top = me.bottom = me[1] = y;\r
2808     };\r
2809 \r
2810     Ext.lib.Point.prototype = new Ext.lib.Region();\r
2811 (function(){    \r
2812     var EXTLIB = Ext.lib,\r
2813         noNegatives = /width|height|opacity|padding/i,\r
2814         offsetAttribute = /^((width|height)|(top|left))$/,\r
2815         defaultUnit = /width|height|top$|bottom$|left$|right$/i,\r
2816         offsetUnit =  /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,\r
2817         isset = function(v){\r
2818             return typeof v !== 'undefined';\r
2819         },\r
2820         now = function(){\r
2821             return new Date();    \r
2822         };\r
2823         \r
2824     EXTLIB.Anim = {\r
2825         motion : function(el, args, duration, easing, cb, scope) {\r
2826             return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);\r
2827         },\r
2828 \r
2829         run : function(el, args, duration, easing, cb, scope, type) {\r
2830             type = type || Ext.lib.AnimBase;\r
2831             if (typeof easing == "string") {\r
2832                 easing = Ext.lib.Easing[easing];\r
2833             }\r
2834             var anim = new type(el, args, duration, easing);\r
2835             anim.animateX(function() {\r
2836                 if(Ext.isFunction(cb)){\r
2837                     cb.call(scope);\r
2838                 }\r
2839             });\r
2840             return anim;\r
2841         }\r
2842     };\r
2843     \r
2844     EXTLIB.AnimBase = function(el, attributes, duration, method) {\r
2845         if (el) {\r
2846             this.init(el, attributes, duration, method);\r
2847         }\r
2848     };\r
2849 \r
2850     EXTLIB.AnimBase.prototype = {\r
2851         doMethod: function(attr, start, end) {\r
2852             var me = this;\r
2853             return me.method(me.curFrame, start, end - start, me.totalFrames);\r
2854         },\r
2855 \r
2856 \r
2857         setAttr: function(attr, val, unit) {\r
2858             if (noNegatives.test(attr) && val < 0) {\r
2859                 val = 0;\r
2860             }\r
2861             Ext.fly(this.el, '_anim').setStyle(attr, val + unit);\r
2862         },\r
2863 \r
2864 \r
2865         getAttr: function(attr) {\r
2866             var el = Ext.fly(this.el),\r
2867                 val = el.getStyle(attr),\r
2868                 a = offsetAttribute.exec(attr) || []\r
2869 \r
2870             if (val !== 'auto' && !offsetUnit.test(val)) {\r
2871                 return parseFloat(val);\r
2872             }\r
2873 \r
2874             return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0;\r
2875         },\r
2876 \r
2877 \r
2878         getDefaultUnit: function(attr) {\r
2879             return defaultUnit.test(attr) ? 'px' : '';\r
2880         },\r
2881 \r
2882         animateX : function(callback, scope) {\r
2883             var me = this,\r
2884                 f = function() {\r
2885                 me.onComplete.removeListener(f);\r
2886                 if (Ext.isFunction(callback)) {\r
2887                     callback.call(scope || me, me);\r
2888                 }\r
2889             };\r
2890             me.onComplete.addListener(f, me);\r
2891             me.animate();\r
2892         },\r
2893 \r
2894 \r
2895         setRunAttr: function(attr) {            \r
2896             var me = this,\r
2897                 a = this.attributes[attr],\r
2898                 to = a.to,\r
2899                 by = a.by,\r
2900                 from = a.from,\r
2901                 unit = a.unit,\r
2902                 ra = (this.runAttrs[attr] = {}),\r
2903                 end;\r
2904 \r
2905             if (!isset(to) && !isset(by)){\r
2906                 return false;\r
2907             }\r
2908 \r
2909             var start = isset(from) ? from : me.getAttr(attr);\r
2910             if (isset(to)) {\r
2911                 end = to;\r
2912             }else if(isset(by)) {\r
2913                 if (Ext.isArray(start)){\r
2914                     end = [];\r
2915                     Ext.each(start, function(v, i){\r
2916                         end[i] = v + by[i];\r
2917                     });\r
2918                 }else{\r
2919                     end = start + by;\r
2920                 }\r
2921             }\r
2922 \r
2923             Ext.apply(ra, {\r
2924                 start: start,\r
2925                 end: end,\r
2926                 unit: isset(unit) ? unit : me.getDefaultUnit(attr)\r
2927             });\r
2928         },\r
2929 \r
2930 \r
2931         init: function(el, attributes, duration, method) {\r
2932             var me = this,\r
2933                 actualFrames = 0,\r
2934                 mgr = EXTLIB.AnimMgr;\r
2935                 \r
2936             Ext.apply(me, {\r
2937                 isAnimated: false,\r
2938                 startTime: null,\r
2939                 el: Ext.getDom(el),\r
2940                 attributes: attributes || {},\r
2941                 duration: duration || 1,\r
2942                 method: method || EXTLIB.Easing.easeNone,\r
2943                 useSec: true,\r
2944                 curFrame: 0,\r
2945                 totalFrames: mgr.fps,\r
2946                 runAttrs: {},\r
2947                 animate: function(){\r
2948                     var me = this,\r
2949                         d = me.duration;\r
2950                     \r
2951                     if(me.isAnimated){\r
2952                         return false;\r
2953                     }\r
2954 \r
2955                     me.curFrame = 0;\r
2956                     me.totalFrames = me.useSec ? Math.ceil(mgr.fps * d) : d;\r
2957                     mgr.registerElement(me); \r
2958                 },\r
2959                 \r
2960                 stop: function(finish){\r
2961                     var me = this;\r
2962                 \r
2963                     if(finish){\r
2964                         me.curFrame = me.totalFrames;\r
2965                         me._onTween.fire();\r
2966                     }\r
2967                     mgr.stop(me);\r
2968                 }\r
2969             });\r
2970 \r
2971             var onStart = function(){\r
2972                 var me = this,\r
2973                     attr;\r
2974                 \r
2975                 me.onStart.fire();\r
2976                 me.runAttrs = {};\r
2977                 for(attr in this.attributes){\r
2978                     this.setRunAttr(attr);\r
2979                 }\r
2980 \r
2981                 me.isAnimated = true;\r
2982                 me.startTime = now();\r
2983                 actualFrames = 0;\r
2984             };\r
2985 \r
2986 \r
2987             var onTween = function(){\r
2988                 var me = this;\r
2989 \r
2990                 me.onTween.fire({\r
2991                     duration: now() - me.startTime,\r
2992                     curFrame: me.curFrame\r
2993                 });\r
2994 \r
2995                 var ra = me.runAttrs;\r
2996                 for (var attr in ra) {\r
2997                     this.setAttr(attr, me.doMethod(attr, ra[attr].start, ra[attr].end), ra[attr].unit);\r
2998                 }\r
2999 \r
3000                 ++actualFrames;\r
3001             };\r
3002 \r
3003             var onComplete = function() {\r
3004                 var me = this,\r
3005                     actual = (now() - me.startTime) / 1000,\r
3006                     data = {\r
3007                         duration: actual,\r
3008                         frames: actualFrames,\r
3009                         fps: actualFrames / actual\r
3010                     };\r
3011 \r
3012                 me.isAnimated = false;\r
3013                 actualFrames = 0;\r
3014                 me.onComplete.fire(data);\r
3015             };\r
3016 \r
3017             me.onStart = new Ext.util.Event(me);\r
3018             me.onTween = new Ext.util.Event(me);            \r
3019             me.onComplete = new Ext.util.Event(me);\r
3020             (me._onStart = new Ext.util.Event(me)).addListener(onStart);\r
3021             (me._onTween = new Ext.util.Event(me)).addListener(onTween);\r
3022             (me._onComplete = new Ext.util.Event(me)).addListener(onComplete); \r
3023         }\r
3024     };\r
3025 \r
3026 \r
3027     Ext.lib.AnimMgr = new function() {\r
3028         var me = this,\r
3029             thread = null,\r
3030             queue = [],\r
3031             tweenCount = 0;\r
3032 \r
3033 \r
3034         Ext.apply(me, {\r
3035             fps: 1000,\r
3036             delay: 1,\r
3037             registerElement: function(tween){\r
3038                 queue.push(tween);\r
3039                 ++tweenCount;\r
3040                 tween._onStart.fire();\r
3041                 me.start();\r
3042             },\r
3043             \r
3044             unRegister: function(tween, index){\r
3045                 tween._onComplete.fire();\r
3046                 index = index || getIndex(tween);\r
3047                 if (index != -1) {\r
3048                     queue.splice(index, 1);\r
3049                 }\r
3050 \r
3051                 if (--tweenCount <= 0) {\r
3052                     me.stop();\r
3053                 }\r
3054             },\r
3055             \r
3056             start: function(){\r
3057                 if(thread === null){\r
3058                     thread = setInterval(me.run, me.delay);\r
3059                 }\r
3060             },\r
3061             \r
3062             stop: function(tween){\r
3063                 if(!tween){\r
3064                     clearInterval(thread);\r
3065                     for(var i = 0, len = queue.length; i < len; ++i){\r
3066                         if(queue[0].isAnimated){\r
3067                             me.unRegister(queue[0], 0);\r
3068                         }\r
3069                     }\r
3070 \r
3071                     queue = [];\r
3072                     thread = null;\r
3073                     tweenCount = 0;\r
3074                 }else{\r
3075                     me.unRegister(tween);\r
3076                 }\r
3077             },\r
3078             \r
3079             run: function(){\r
3080                 var tf;\r
3081                 Ext.each(queue, function(tween){\r
3082                     if(tween && tween.isAnimated){\r
3083                         tf = tween.totalFrames;\r
3084                         if(tween.curFrame < tf || tf === null){\r
3085                             ++tween.curFrame;\r
3086                             if(tween.useSec){\r
3087                                 correctFrame(tween);\r
3088                             }\r
3089                             tween._onTween.fire();\r
3090                         }else{\r
3091                             me.stop(tween);\r
3092                         }\r
3093                     }\r
3094                 }, me);\r
3095             }\r
3096         });\r
3097 \r
3098         var getIndex = function(anim) {\r
3099             var out = -1;\r
3100             Ext.each(queue, function(item, idx){\r
3101                 if(item == anim){\r
3102                     out = idx;\r
3103                     return false;\r
3104                 }\r
3105             });\r
3106             return out;\r
3107         };\r
3108 \r
3109 \r
3110         var correctFrame = function(tween) {\r
3111             var frames = tween.totalFrames,\r
3112                 frame = tween.curFrame,\r
3113                 duration = tween.duration,\r
3114                 expected = (frame * duration * 1000 / frames),\r
3115                 elapsed = (now() - tween.startTime),\r
3116                 tweak = 0;\r
3117 \r
3118             if(elapsed < duration * 1000){\r
3119                 tweak = Math.round((elapsed / expected - 1) * frame);\r
3120             }else{\r
3121                 tweak = frames - (frame + 1);\r
3122             }\r
3123             if(tweak > 0 && isFinite(tweak)){\r
3124                 if(tween.curFrame + tweak >= frames){\r
3125                     tweak = frames - (frame + 1);\r
3126                 }\r
3127                 tween.curFrame += tweak;\r
3128             }\r
3129         };\r
3130     };\r
3131 \r
3132     EXTLIB.Bezier = new function() {\r
3133 \r
3134         this.getPosition = function(points, t) {\r
3135             var n = points.length,\r
3136                 tmp = [],\r
3137                 c = 1 - t, \r
3138                 i,\r
3139                 j;\r
3140 \r
3141             for (i = 0; i < n; ++i) {\r
3142                 tmp[i] = [points[i][0], points[i][1]];\r
3143             }\r
3144 \r
3145             for (j = 1; j < n; ++j) {\r
3146                 for (i = 0; i < n - j; ++i) {\r
3147                     tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];\r
3148                     tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];\r
3149                 }\r
3150             }\r
3151 \r
3152             return [ tmp[0][0], tmp[0][1] ];\r
3153 \r
3154         };\r
3155     };\r
3156 \r
3157 \r
3158     EXTLIB.Easing = {\r
3159         easeNone: function (t, b, c, d) {\r
3160             return c * t / d + b;\r
3161         },\r
3162 \r
3163 \r
3164         easeIn: function (t, b, c, d) {\r
3165             return c * (t /= d) * t + b;\r
3166         },\r
3167 \r
3168 \r
3169         easeOut: function (t, b, c, d) {\r
3170             return -c * (t /= d) * (t - 2) + b;\r
3171         }\r
3172     };\r
3173 \r
3174     (function() {\r
3175         EXTLIB.Motion = function(el, attributes, duration, method) {\r
3176             if (el) {\r
3177                 EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method);\r
3178             }\r
3179         };\r
3180 \r
3181         Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase);\r
3182 \r
3183         var superclass = EXTLIB.Motion.superclass,\r
3184             proto = EXTLIB.Motion.prototype,\r
3185             pointsRe = /^points$/i;\r
3186 \r
3187         Ext.apply(EXTLIB.Motion.prototype, {\r
3188             setAttr: function(attr, val, unit){\r
3189                 var me = this,\r
3190                     setAttr = superclass.setAttr;\r
3191                     \r
3192                 if (pointsRe.test(attr)) {\r
3193                     unit = unit || 'px';\r
3194                     setAttr.call(me, 'left', val[0], unit);\r
3195                     setAttr.call(me, 'top', val[1], unit);\r
3196                 } else {\r
3197                     setAttr.call(me, attr, val, unit);\r
3198                 }\r
3199             },\r
3200             \r
3201             getAttr: function(attr){\r
3202                 var me = this,\r
3203                     getAttr = superclass.getAttr;\r
3204                     \r
3205                 return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr);\r
3206             },\r
3207             \r
3208             doMethod: function(attr, start, end){\r
3209                 var me = this;\r
3210                 \r
3211                 return pointsRe.test(attr)\r
3212                         ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100)\r
3213                         : superclass.doMethod.call(me, attr, start, end);\r
3214             },\r
3215             \r
3216             setRunAttr: function(attr){\r
3217                 if(pointsRe.test(attr)){\r
3218                     \r
3219                     var me = this,\r
3220                         el = this.el,\r
3221                         points = this.attributes.points,\r
3222                         control = points.control || [],\r
3223                         from = points.from,\r
3224                         to = points.to,\r
3225                         by = points.by,\r
3226                         DOM = EXTLIB.Dom,\r
3227                         start,\r
3228                         i,\r
3229                         end,\r
3230                         len,\r
3231                         ra;\r
3232                   \r
3233 \r
3234                     if(control.length > 0 && !Ext.isArray(control[0])){\r
3235                         control = [control];\r
3236                     }else{\r
3237                         /*\r
3238                         var tmp = [];\r
3239                         for (i = 0,len = control.length; i < len; ++i) {\r
3240                             tmp[i] = control[i];\r
3241                         }\r
3242                         control = tmp;\r
3243                         */\r
3244                     }\r
3245 \r
3246                     Ext.fly(el, '_anim').position();\r
3247                     DOM.setXY(el, isset(from) ? from : DOM.getXY(el));\r
3248                     start = me.getAttr('points');\r
3249 \r
3250 \r
3251                     if(isset(to)){\r
3252                         end = translateValues.call(me, to, start);\r
3253                         for (i = 0,len = control.length; i < len; ++i) {\r
3254                             control[i] = translateValues.call(me, control[i], start);\r
3255                         }\r
3256                     } else if (isset(by)) {\r
3257                         end = [start[0] + by[0], start[1] + by[1]];\r
3258 \r
3259                         for (i = 0,len = control.length; i < len; ++i) {\r
3260                             control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];\r
3261                         }\r
3262                     }\r
3263 \r
3264                     ra = this.runAttrs[attr] = [start];\r
3265                     if (control.length > 0) {\r
3266                         ra = ra.concat(control);\r
3267                     }\r
3268 \r
3269                     ra[ra.length] = end;\r
3270                 }else{\r
3271                     superclass.setRunAttr.call(this, attr);\r
3272                 }\r
3273             }\r
3274         });\r
3275 \r
3276         var translateValues = function(val, start) {\r
3277             var pageXY = EXTLIB.Dom.getXY(this.el);\r
3278             return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];\r
3279         };\r
3280     })();\r
3281 })();// Easing functions\r
3282 (function(){\r
3283         // shortcuts to aid compression\r
3284         var abs = Math.abs,\r
3285                 pi = Math.PI,\r
3286                 asin = Math.asin,\r
3287                 pow = Math.pow,\r
3288                 sin = Math.sin,\r
3289                 EXTLIB = Ext.lib;\r
3290                 \r
3291     Ext.apply(EXTLIB.Easing, {\r
3292         \r
3293         easeBoth: function (t, b, c, d) {\r
3294                 return ((t /= d / 2) < 1)  ?  c / 2 * t * t + b  :  -c / 2 * ((--t) * (t - 2) - 1) + b;               \r
3295         },\r
3296         \r
3297         easeInStrong: function (t, b, c, d) {\r
3298             return c * (t /= d) * t * t * t + b;\r
3299         },\r
3300 \r
3301         easeOutStrong: function (t, b, c, d) {\r
3302             return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r
3303         },\r
3304 \r
3305         easeBothStrong: function (t, b, c, d) {\r
3306             return ((t /= d / 2) < 1)  ?  c / 2 * t * t * t * t + b  :  -c / 2 * ((t -= 2) * t * t * t - 2) + b;\r
3307         },\r
3308 \r
3309         elasticIn: function (t, b, c, d, a, p) {\r
3310                 if (t == 0 || (t /= d) == 1) {\r
3311                 return t == 0 ? b : b + c;\r
3312             }               \r
3313             p = p || (d * .3);              \r
3314 \r
3315                         var s;\r
3316                         if (a >= abs(c)) {\r
3317                                 s = p / (2 * pi) * asin(c / a);\r
3318                         } else {\r
3319                                 a = c;\r
3320                                 s = p / 4;\r
3321                         }\r
3322         \r
3323             return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b;\r
3324                       \r
3325         },      \r
3326         \r
3327                 elasticOut: function (t, b, c, d, a, p) {\r
3328                 if (t == 0 || (t /= d) == 1) {\r
3329                 return t == 0 ? b : b + c;\r
3330             }               \r
3331             p = p || (d * .3);              \r
3332 \r
3333                         var s;\r
3334                         if (a >= abs(c)) {\r
3335                                 s = p / (2 * pi) * asin(c / a);\r
3336                         } else {\r
3337                                 a = c;\r
3338                                 s = p / 4;\r
3339                         }\r
3340         \r
3341             return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b;        \r
3342         },      \r
3343         \r
3344         elasticBoth: function (t, b, c, d, a, p) {\r
3345             if (t == 0 || (t /= d / 2) == 2) {\r
3346                 return t == 0 ? b : b + c;\r
3347             }                           \r
3348                     \r
3349             p = p || (d * (.3 * 1.5));              \r
3350 \r
3351             var s;\r
3352             if (a >= abs(c)) {\r
3353                     s = p / (2 * pi) * asin(c / a);\r
3354             } else {\r
3355                     a = c;\r
3356                 s = p / 4;\r
3357             }\r
3358 \r
3359             return t < 1 ?\r
3360                         -.5 * (a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b :\r
3361                     a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b;\r
3362         },\r
3363 \r
3364         backIn: function (t, b, c, d, s) {\r
3365             s = s ||  1.70158;              \r
3366             return c * (t /= d) * t * ((s + 1) * t - s) + b;\r
3367         },\r
3368 \r
3369 \r
3370         backOut: function (t, b, c, d, s) {\r
3371             if (!s) {\r
3372                 s = 1.70158;\r
3373             }\r
3374             return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\r
3375         },\r
3376 \r
3377 \r
3378         backBoth: function (t, b, c, d, s) {\r
3379             s = s || 1.70158;               \r
3380 \r
3381             return ((t /= d / 2 ) < 1) ?\r
3382                     c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b :                  \r
3383                         c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\r
3384         },\r
3385 \r
3386 \r
3387         bounceIn: function (t, b, c, d) {\r
3388             return c - EXTLIB.Easing.bounceOut(d - t, 0, c, d) + b;\r
3389         },\r
3390 \r
3391 \r
3392         bounceOut: function (t, b, c, d) {\r
3393         if ((t /= d) < (1 / 2.75)) {\r
3394                 return c * (7.5625 * t * t) + b;\r
3395             } else if (t < (2 / 2.75)) {\r
3396                 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;\r
3397             } else if (t < (2.5 / 2.75)) {\r
3398                 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;\r
3399             }\r
3400             return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;\r
3401         },\r
3402 \r
3403 \r
3404         bounceBoth: function (t, b, c, d) {\r
3405             return (t < d / 2) ?\r
3406                    EXTLIB.Easing.bounceIn(t * 2, 0, c, d) * .5 + b : \r
3407                    EXTLIB.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;\r
3408         }\r
3409     });\r
3410 })();\r
3411 \r
3412 (function() {\r
3413     var EXTLIB = Ext.lib;\r
3414         // Color Animation\r
3415         EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) {\r
3416             return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim);\r
3417         }\r
3418         \r
3419     EXTLIB.ColorAnim = function(el, attributes, duration, method) {\r
3420         EXTLIB.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);\r
3421     };\r
3422 \r
3423     Ext.extend(EXTLIB.ColorAnim, EXTLIB.AnimBase);\r
3424 \r
3425     var superclass = EXTLIB.ColorAnim.superclass,\r
3426         colorRE = /color$/i,\r
3427         transparentRE = /^transparent|rgba\(0, 0, 0, 0\)$/,\r
3428         rgbRE = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,\r
3429         hexRE= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,\r
3430         hex3RE = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,\r
3431         isset = function(v){\r
3432             return typeof v !== 'undefined';\r
3433         }\r
3434                 \r
3435         // private      \r
3436     function parseColor(s) {    \r
3437         var pi = parseInt,\r
3438             base,\r
3439             out = null,\r
3440             c;\r
3441         \r
3442             if (s.length == 3) {\r
3443             return s;\r
3444         }\r
3445         \r
3446         Ext.each([hexRE, rgbRE, hex3RE], function(re, idx){\r
3447             base = (idx % 2 == 0) ? 16 : 10;\r
3448             c = re.exec(s);\r
3449             if(c && c.length == 4){\r
3450                 out = [pi(c[1], base), pi(c[2], base), pi(c[3], base)];\r
3451                 return false;\r
3452             }\r
3453         });\r
3454         return out;\r
3455     }   \r
3456 \r
3457     Ext.apply(EXTLIB.ColorAnim.prototype, {\r
3458         getAttr : function(attr) {\r
3459             var me = this,\r
3460                 el = me.el,\r
3461                 val;                \r
3462             if(colorRE.test(attr)){\r
3463                 while(el && transparentRE.test(val = Ext.fly(el).getStyle(attr))){\r
3464                     el = el.parentNode;\r
3465                     val = "fff";\r
3466                 }\r
3467             }else{\r
3468                 val = superclass.getAttr.call(me, attr);\r
3469             }\r
3470             return val;\r
3471         },\r
3472 \r
3473         doMethod : function(attr, start, end) {\r
3474             var me = this,\r
3475                 val,\r
3476                 floor = Math.floor;            \r
3477 \r
3478             if(colorRE.test(attr)){\r
3479                 val = [];\r
3480              \r
3481                     Ext.each(start, function(v, i) {\r
3482                     val[i] = superclass.doMethod.call(me, attr, v, end[i]);\r
3483                 });\r
3484 \r
3485                 val = 'rgb(' + floor(val[0]) + ',' + floor(val[1]) + ',' + floor(val[2]) + ')';\r
3486             }else{\r
3487                 val = superclass.doMethod.call(me, attr, start, end);\r
3488             }\r
3489             return val;\r
3490         },\r
3491 \r
3492         setRunAttr : function(attr) {\r
3493             var me = this,\r
3494                 a = me.attributes[attr],\r
3495                 to = a.to,\r
3496                 by = a.by,\r
3497                 ra;\r
3498                 \r
3499             superclass.setRunAttr.call(me, attr);\r
3500             ra = me.runAttrs[attr];\r
3501             if(colorRE.test(attr)){\r
3502                 var start = parseColor(ra.start),\r
3503                     end = parseColor(ra.end);\r
3504 \r
3505                 if(!isset(to) && isset(by)){\r
3506                     end = parseColor(by);\r
3507                     Ext.each(start, function(item, i){\r
3508                         end[i] = item + end[i];\r
3509                     });\r
3510                 }\r
3511                 ra.start = start;\r
3512                 ra.end = end;\r
3513             }\r
3514         }\r
3515         });\r
3516 })();   \r
3517 \r
3518         \r
3519 (function() {\r
3520             // Scroll Animation \r
3521     var EXTLIB = Ext.lib;\r
3522         EXTLIB.Anim.scroll = function(el, args, duration, easing, cb, scope) {          \r
3523             return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.Scroll);\r
3524         }\r
3525         \r
3526     EXTLIB.Scroll = function(el, attributes, duration, method) {\r
3527         if(el){\r
3528             EXTLIB.Scroll.superclass.constructor.call(this, el, attributes, duration, method);\r
3529         }\r
3530     };\r
3531 \r
3532     Ext.extend(EXTLIB.Scroll, EXTLIB.ColorAnim);\r
3533 \r
3534     var superclass = EXTLIB.Scroll.superclass,\r
3535         SCROLL = 'scroll';\r
3536 \r
3537     Ext.apply(EXTLIB.Scroll.prototype, {\r
3538 \r
3539         doMethod : function(attr, start, end) {\r
3540             var val,\r
3541                 me = this,\r
3542                 curFrame = me.curFrame,\r
3543                 totalFrames = me.totalFrames;\r
3544 \r
3545             if(attr == SCROLL){\r
3546                 val = [me.method(curFrame, start[0], end[0] - start[0], totalFrames),\r
3547                        me.method(curFrame, start[1], end[1] - start[1], totalFrames)];\r
3548             }else{\r
3549                 val = superclass.doMethod.call(me, attr, start, end);\r
3550             }\r
3551             return val;\r
3552         },\r
3553 \r
3554         getAttr : function(attr) {\r
3555             var me = this;\r
3556 \r
3557             if (attr == SCROLL) {\r
3558                 return [me.el.scrollLeft, me.el.scrollTop];\r
3559             }else{\r
3560                 return superclass.getAttr.call(me, attr);\r
3561             }\r
3562         },\r
3563 \r
3564         setAttr : function(attr, val, unit) {\r
3565             var me = this;\r
3566 \r
3567             if(attr == SCROLL){\r
3568                 me.el.scrollLeft = val[0];\r
3569                 me.el.scrollTop = val[1];\r
3570             }else{\r
3571                 superclass.setAttr.call(me, attr, val, unit);\r
3572             }\r
3573         }\r
3574     });\r
3575 })();   \r
3576         if(Ext.isIE) {\r
3577         function fnCleanUp() {\r
3578             var p = Function.prototype;\r
3579             delete p.createSequence;\r
3580             delete p.defer;\r
3581             delete p.createDelegate;\r
3582             delete p.createCallback;\r
3583             delete p.createInterceptor;\r
3584 \r
3585             window.detachEvent("onunload", fnCleanUp);\r
3586         }\r
3587         window.attachEvent("onunload", fnCleanUp);\r
3588     }\r
3589 })();