source: ext/3.4.1/adapter/ext/ext-base-debug.js @ 2909

Last change on this file since 2909 was 2909, checked in by fredj, 5 years ago

Adding Ext 3.4.1

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