PageSourceSearch

https://michaeldunahee.ca/js/lib/ext/ext-all-debug.js?r=

js michaeldunahee.ca collected 2026-10-08 21:21:32 UTC 1,408,181 bytes, 52,079 lines download raw bytes

1
2(function(){
3
4var EXTUTIL = Ext.util,
5    EACH = Ext.each,
6    TRUE = true,
7    FALSE = false;
8
9EXTUTIL.Observable = function(){
10    
11    var me = this, e = me.events;
12    if(me.listeners){
13        me.on(me.listeners);
14        delete me.listeners;
15    }
16    me.events = e || {};
17};
18
19EXTUTIL.Observable.prototype = {
20    
21    filterOptRe : /^(?:scope|delay|buffer|single)$/,
22
23    
24    fireEvent : function(){
25        var a = Array.prototype.slice.call(arguments, 0),
26            ename = a[0].toLowerCase(),
27            me = this,
28            ret = TRUE,
29            ce = me.events[ename],
30            cc,
31            q,
32            c;
33        if (me.eventsSuspended === TRUE) {
34            if (q = me.eventQueue) {
35                q.push(a);
36            }
37        }
38        else if(typeof ce == 'object') {
39            if (ce.bubble){
40                if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
41                    return FALSE;
42                }
43                c = me.getBubbleTarget && me.getBubbleTarget();
44                if(c && c.enableBubble) {
45                    cc = c.events[ename];
46                    if(!cc || typeof cc != 'object' || !cc.bubble) {
47                        c.enableBubble(ename);
48                    }
49                    return c.fireEvent.apply(c, a);
50                }
51            }
52            else {
53                a.shift();
54                ret = ce.fire.apply(ce, a);
55            }
56        }
57        return ret;
58    },
59
60    
61    addListener : function(eventName, fn, scope, o){
62        var me = this,
63            e,
64            oe,
65            ce;
66            
67        if (typeof eventName == 'object') {
68            o = eventName;
69            for (e in o) {
70                oe = o[e];
71                if (!me.filterOptRe.test(e)) {
72                    me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
73                }
74            }
75        } else {
76            eventName = eventName.toLowerCase();
77            ce = me.events[eventName] || TRUE;
78            if (typeof ce == 'boolean') {
79                me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
80            }
81            ce.addListener(fn, scope, typeof o == 'object' ? o : {});
82        }
83    },
84
85    
86    removeListener : function(eventName, fn, scope){
87        var ce = this.events[eventName.toLowerCase()];
88        if (typeof ce == 'object') {
89            ce.removeListener(fn, scope);
90        }
91    },
92
93    
94    purgeListeners : function(){
95        var events = this.events,
96            evt,
97            key;
98        for(key in events){
99            evt = events[key];
100            if(typeof evt == 'object'){
101                evt.clearListeners();
102            }
103        }
104    },
105
106    
107    addEvents : function(o){
108        var me = this;
109        me.events = me.events || {};
110        if (typeof o == 'string') {
111            var a = arguments,
112                i = a.length;
113            while(i--) {
114                me.events[a[i]] = me.events[a[i]] || TRUE;
115            }
116        } else {
117            Ext.applyIf(me.events, o);
118        }
119    },
120
121    
122    hasListener : function(eventName){
123        var e = this.events[eventName.toLowerCase()];
124        return typeof e == 'object' && e.listeners.length > 0;
125    },
126
127    
128    suspendEvents : function(queueSuspended){
129        this.eventsSuspended = TRUE;
130        if(queueSuspended && !this.eventQueue){
131            this.eventQueue = [];
132        }
133    },
134
135    
136    resumeEvents : function(){
137        var me = this,
138            queued = me.eventQueue || [];
139        me.eventsSuspended = FALSE;
140        delete me.eventQueue;
141        EACH(queued, function(e) {
142            me.fireEvent.apply(me, e);
143        });
144    }
145};
146
147var OBSERVABLE = EXTUTIL.Observable.prototype;
148
149OBSERVABLE.on = OBSERVABLE.addListener;
150
151OBSERVABLE.un = OBSERVABLE.removeListener;
152
153
154EXTUTIL.Observable.releaseCapture = function(o){
155    o.fireEvent = OBSERVABLE.fireEvent;
156};
157
158function createTargeted(h, o, scope){
159    return function(){
160        if(o.target == arguments[0]){
161            h.apply(scope, Array.prototype.slice.call(arguments, 0));
162        }
163    };
164};
165
166function createBuffered(h, o, l, scope){
167    l.task = new EXTUTIL.DelayedTask();
168    return function(){
169        l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
170    };
171};
172
173function createSingle(h, e, fn, scope){
174    return function(){
175        e.removeListener(fn, scope);
176        return h.apply(scope, arguments);
177    };
178};
179
180function createDelayed(h, o, l, scope){
181    return function(){
182        var task = new EXTUTIL.DelayedTask(),
183            args = Array.prototype.slice.call(arguments, 0);
184        if(!l.tasks) {
185            l.tasks = [];
186        }
187        l.tasks.push(task);
188        task.delay(o.delay || 10, function(){
189            l.tasks.remove(task);
190            h.apply(scope, args);
191        }, scope);
192    };
193};
194
195EXTUTIL.Event = function(obj, name){
196    this.name = name;
197    this.obj = obj;
198    this.listeners = [];
199};
200
201EXTUTIL.Event.prototype = {
202    addListener : function(fn, scope, options){
203        var me = this,
204            l;
205        scope = scope || me.obj;
206        if(!me.isListening(fn, scope)){
207            l = me.createListener(fn, scope, options);
208            if(me.firing){ 
209                me.listeners = me.listeners.slice(0);
210            }
211            me.listeners.push(l);
212        }
213    },
214
215    createListener: function(fn, scope, o){
216        o = o || {};
217        scope = scope || this.obj;
218        var l = {
219            fn: fn,
220            scope: scope,
221            options: o
222        }, h = fn;
223        if(o.target){
224            h = createTargeted(h, o, scope);
225        }
226        if(o.delay){
227            h = createDelayed(h, o, l, scope);
228        }
229        if(o.single){
230            h = createSingle(h, this, fn, scope);
231        }
232        if(o.buffer){
233            h = createBuffered(h, o, l, scope);
234        }
235        l.fireFn = h;
236        return l;
237    },
238
239    findListener : function(fn, scope){
240        var list = this.listeners,
241            i = list.length,
242            l;
243
244        scope = scope || this.obj;
245        while(i--){
246            l = list[i];
247            if(l){
248                if(l.fn == fn && l.scope == scope){
249                    return i;
250                }
251            }
252        }
253        return -1;
254    },
255
256    isListening : function(fn, scope){
257        return this.findListener(fn, scope) != -1;
258    },
259
260    removeListener : function(fn, scope){
261        var index,
262            l,
263            k,
264            me = this,
265            ret = FALSE;
266        if((index = me.findListener(fn, scope)) != -1){
267            if (me.firing) {
268                me.listeners = me.listeners.slice(0);
269            }
270            l = me.listeners[index];
271            if(l.task) {
272                l.task.cancel();
273                delete l.task;
274            }
275            k = l.tasks && l.tasks.length;
276            if(k) {
277                while(k--) {
278                    l.tasks[k].cancel();
279                }
280                delete l.tasks;
281            }
282            me.listeners.splice(index, 1);
283            ret = TRUE;
284        }
285        return ret;
286    },
287
288    
289    clearListeners : function(){
290        var me = this,
291            l = me.listeners,
292            i = l.length;
293        while(i--) {
294            me.removeListener(l[i].fn, l[i].scope);
295        }
296    },
297
298    fire : function(){
299        var me = this,
300            listeners = me.listeners,
301            len = listeners.length,
302            i = 0,
303            l;
304
305        if(len > 0){
306            me.firing = TRUE;
307            var args = Array.prototype.slice.call(arguments, 0);
308            for (; i < len; i++) {
309                l = listeners[i];
310                if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
311                    return (me.firing = FALSE);
312                }
313            }
314        }
315        me.firing = FALSE;
316        return TRUE;
317    }
318
319};
320})();
321
322Ext.DomHelper = function(){
323    var tempTableEl = null,
324        emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
325        tableRe = /^table|tbody|tr|td$/i,
326        confRe = /tag|children|cn|html$/i,
327        tableElRe = /td|tr|tbody/i,
328        cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
329        endRe = /end/i,
330        pub,
331        
332        afterbegin = 'afterbegin',
333        afterend = 'afterend',
334        beforebegin = 'beforebegin',
335        beforeend = 'beforeend',
336        ts = '<table>',
337        te = '</table>',
338        tbs = ts+'<tbody>',
339        tbe = '</tbody>'+te,
340        trs = tbs + '<tr>',
341        tre = '</tr>'+tbe;
342
343    
344    function doInsert(el, o, returnElement, pos, sibling, append){
345        var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
346        return returnElement ? Ext.get(newNode, true) : newNode;
347    }
348
349    
350    function createHtml(o){
351        var b = '',
352            attr,
353            val,
354            key,
355            cn;
356
357        if(typeof o == "string"){
358            b = o;
359        } else if (Ext.isArray(o)) {
360            for (var i=0; i < o.length; i++) {
361                if(o[i]) {
362                    b += createHtml(o[i]);
363                }
364            };
365        } else {
366            b += '<' + (o.tag = o.tag || 'div');
367            for (attr in o) {
368                val = o[attr];
369                if(!confRe.test(attr)){
370                    if (typeof val == "object") {
371                        b += ' ' + attr + '="';
372                        for (key in val) {
373                            b += key + ':' + val[key] + ';';
374                        };
375                        b += '"';
376                    }else{
377                        b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
378                    }
379                }
380            };
381            
382            if (emptyTags.test(o.tag)) {
383                b += '/>';
384            } else {
385                b += '>';
386                if ((cn = o.children || o.cn)) {
387                    b += createHtml(cn);
388                } else if(o.html){
389                    b += o.html;
390                }
391                b += '</' + o.tag + '>';
392            }
393        }
394        return b;
395    }
396
397    function ieTable(depth, s, h, e){
398        tempTableEl.innerHTML = [s, h, e].join('');
399        var i = -1,
400            el = tempTableEl,
401            ns;
402        while(++i < depth){
403            el = el.firstChild;
404        }
405
406        if(ns = el.nextSibling){
407            var df = document.createDocumentFragment();
408            while(el){
409                ns = el.nextSibling;
410                df.appendChild(el);
411                el = ns;
412            }
413            el = df;
414        }
415        return el;
416    }
417
418    
419    function insertIntoTable(tag, where, el, html) {
420        var node,
421            before;
422
423        tempTableEl = tempTableEl || document.createElement('div');
424
425        if(tag == 'td' && (where == afterbegin || where == beforeend) ||
426           !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
427            return;
428        }
429        before = where == beforebegin ? el :
430                 where == afterend ? el.nextSibling :
431                 where == afterbegin ? el.firstChild : null;
432
433        if (where == beforebegin || where == afterend) {
434            el = el.parentNode;
435        }
436
437        if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
438            node = ieTable(4, trs, html, tre);
439        } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
440                   (tag == 'tr' && (where == beforebegin || where == afterend))) {
441            node = ieTable(3, tbs, html, tbe);
442        } else {
443            node = ieTable(2, ts, html, te);
444        }
445        el.insertBefore(node, before);
446        return node;
447    }
448
449       
450    function createContextualFragment(html){
451        var div = document.createElement("div"),
452            fragment = document.createDocumentFragment(),
453            i = 0,
454            length, childNodes;
455        
456        div.innerHTML = html;
457        childNodes = div.childNodes;
458        length = childNodes.length;
459        
460        for (; i < length; i++) {
461            fragment.appendChild(childNodes[i].cloneNode(true));
462        }
463        
464        return fragment;
465    }
466    
467    pub = {
468        
469        markup : function(o){
470            return createHtml(o);
471        },
472
473        
474        applyStyles : function(el, styles){
475            if (styles) {
476                var matches;
477
478                el = Ext.fly(el);
479                if (typeof styles == "function") {
480                    styles = styles.call();
481                }
482                if (typeof styles == "string") {
483                    
484                    cssRe.lastIndex = 0;
485                    while ((matches = cssRe.exec(styles))) {
486                        el.setStyle(matches[1], matches[2]);
487                    }
488                } else if (typeof styles == "object") {
489                    el.setStyle(styles);
490                }
491            }
492        },
493        
494        insertHtml : function(where, el, html){
495            var hash = {},
496                hashVal,
497                range,
498                rangeEl,
499                setStart,
500                frag,
501                rs;
502
503            where = where.toLowerCase();
504            
505            hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
506            hash[afterend] = ['AfterEnd', 'nextSibling'];
507
508            if (el.insertAdjacentHTML) {
509                if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
510                    return rs;
511                }
512                
513                hash[afterbegin] = ['AfterBegin', 'firstChild'];
514                hash[beforeend] = ['BeforeEnd', 'lastChild'];
515                if ((hashVal = hash[where])) {
516                    el.insertAdjacentHTML(hashVal[0], html);
517                    return el[hashVal[1]];
518                }
519            } else {
520                range = el.ownerDocument.createRange();
521                setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
522                if (hash[where]) {
523                    range[setStart](el);
524                    if (!range.createContextualFragment) {
525                        frag = createContextualFragment(html);
526                    }
527                    else {
528                        frag = range.createContextualFragment(html);
529                    }
530                    el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
531                    return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
532                } else {
533                    rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
534                    if (el.firstChild) {
535                        range[setStart](el[rangeEl]);
536                        if (!range.createContextualFragment) {
537                            frag = createContextualFragment(html);
538                        }
539                        else {
540                            frag = range.createContextualFragment(html);
541                        }
542                        if(where == afterbegin){
543                            el.insertBefore(frag, el.firstChild);
544                        }else{
545                            el.appendChild(frag);
546                        }
547                    } else {
548                        el.innerHTML = html;
549                    }
550                    return el[rangeEl];
551                }
552            }
553            throw 'Illegal insertion point -> "' + where + '"';
554        },
555
556        
557        insertBefore : function(el, o, returnElement){
558            return doInsert(el, o, returnElement, beforebegin);
559        },
560
561        
562        insertAfter : function(el, o, returnElement){
563            return doInsert(el, o, returnElement, afterend, 'nextSibling');
564        },
565
566        
567        insertFirst : function(el, o, returnElement){
568            return doInsert(el, o, returnElement, afterbegin, 'firstChild');
569        },
570
571        
572        append : function(el, o, returnElement){
573            return doInsert(el, o, returnElement, beforeend, '', true);
574        },
575
576        
577        overwrite : function(el, o, returnElement){
578            el = Ext.getDom(el);
579            el.innerHTML = createHtml(o);
580            return returnElement ? Ext.get(el.firstChild) : el.firstChild;
581        },
582
583        createHtml : createHtml
584    };
585    return pub;
586}();
587
588Ext.Template = function(html){
589    var me = this,
590        a = arguments,
591        buf = [],
592        v;
593
594    if (Ext.isArray(html)) {
595        html = html.join("");
596    } else if (a.length > 1) {
597        for(var i = 0, len = a.length; i < len; i++){
598            v = a[i];
599            if(typeof v == 'object'){
600                Ext.apply(me, v);
601            } else {
602                buf.push(v);
603            }
604        };
605        html = buf.join('');
606    }
607
608    
609    me.html = html;
610    
611    if (me.compiled) {
612        me.compile();
613    }
614};
615Ext.Template.prototype = {
616    
617    re : /\{([\w\-]+)\}/g,
618    
619
620    
621    applyTemplate : function(values){
622        var me = this;
623
624        return me.compiled ?
625                me.compiled(values) :
626                me.html.replace(me.re, function(m, name){
627                    return values[name] !== undefined ? values[name] : "";
628                });
629    },
630
631    
632    set : function(html, compile){
633        var me = this;
634        me.html = html;
635        me.compiled = null;
636        return compile ? me.compile() : me;
637    },
638
639    
640    compile : function(){
641        var me = this,
642            sep = Ext.isGecko ? "+" : ",";
643
644        function fn(m, name){
645            name = "values['" + name + "']";
646            return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
647        }
648
649        eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
650             me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
651             (Ext.isGecko ?  "';};" : "'].join('');};"));
652        return me;
653    },
654
655    
656    insertFirst: function(el, values, returnElement){
657        return this.doInsert('afterBegin', el, values, returnElement);
658    },
659
660    
661    insertBefore: function(el, values, returnElement){
662        return this.doInsert('beforeBegin', el, values, returnElement);
663    },
664
665    
666    insertAfter : function(el, values, returnElement){
667        return this.doInsert('afterEnd', el, values, returnElement);
668    },
669
670    
671    append : function(el, values, returnElement){
672        return this.doInsert('beforeEnd', el, values, returnElement);
673    },
674
675    doInsert : function(where, el, values, returnEl){
676        el = Ext.getDom(el);
677        var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
678        return returnEl ? Ext.get(newNode, true) : newNode;
679    },
680
681    
682    overwrite : function(el, values, returnElement){
683        el = Ext.getDom(el);
684        el.innerHTML = this.applyTemplate(values);
685        return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
686    }
687};
688
689Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
690
691
692Ext.Template.from = function(el, config){
693    el = Ext.getDom(el);
694    return new Ext.Template(el.value || el.innerHTML, config || '');
695};
696
697
698Ext.DomQuery = function(){
699    var cache = {}, 
700    	simpleCache = {}, 
701    	valueCache = {},
702    	nonSpace = /\S/,
703    	trimRe = /^\s+|\s+$/g,
704    	tplRe = /\{(\d+)\}/g,
705    	modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
706    	tagTokenRe = /^(#)?([\w\-\*]+)/,
707    	nthRe = /(\d*)n\+?(\d*)/, 
708    	nthRe2 = /\D/,
709    	
710	
711	
712	isIE = window.ActiveXObject ? true : false,
713	key = 30803;
714    
715    
716    
717    eval("var batch = 30803;");    	
718
719    
720    
721    function child(parent, index){
722        var i = 0,
723            n = parent.firstChild;
724        while(n){
725            if(n.nodeType == 1){
726               if(++i == index){
727                   return n;
728               }
729            }
730            n = n.nextSibling;
731        }
732        return null;
733    }
734
735    
736    function next(n){	
737        while((n = n.nextSibling) && n.nodeType != 1);
738        return n;
739    }
740
741    
742    function prev(n){
743        while((n = n.previousSibling) && n.nodeType != 1);
744        return n;
745    }
746
747    
748    
749    function children(parent){
750        var n = parent.firstChild,
751	    nodeIndex = -1,
752	    nextNode;
753	while(n){
754	    nextNode = n.nextSibling;
755	    
756	    if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
757		parent.removeChild(n);
758	    }else{
759		
760		n.nodeIndex = ++nodeIndex;
761	    }
762	    n = nextNode;
763	}
764	return this;
765    }
766
767
768    
769    
770    function byClassName(nodeSet, cls){
771        if(!cls){
772            return nodeSet;
773        }
774        var result = [], ri = -1;
775        for(var i = 0, ci; ci = nodeSet[i]; i++){
776            if((' '+ci.className+' ').indexOf(cls) != -1){
777                result[++ri] = ci;
778            }
779        }
780        return result;
781    };
782
783    function attrValue(n, attr){
784	
785        if(!n.tagName && typeof n.length != "undefined"){
786            n = n[0];
787        }
788        if(!n){
789            return null;
790        }
791
792        if(attr == "for"){
793            return n.htmlFor;
794        }
795        if(attr == "class" || attr == "className"){
796            return n.className;
797        }
798        return n.getAttribute(attr) || n[attr];
799
800    };
801
802
803    
804    
805    
806    function getNodes(ns, mode, tagName){
807        var result = [], ri = -1, cs;
808        if(!ns){
809            return result;
810        }
811        tagName = tagName || "*";
812	
813        if(typeof ns.getElementsByTagName != "undefined"){
814            ns = [ns];
815        }
816	
817	
818	
819        if(!mode){
820            for(var i = 0, ni; ni = ns[i]; i++){
821                cs = ni.getElementsByTagName(tagName);
822                for(var j = 0, ci; ci = cs[j]; j++){
823                    result[++ri] = ci;
824                }
825            }
826	
827	
828        } else if(mode == "/" || mode == ">"){
829            var utag = tagName.toUpperCase();
830            for(var i = 0, ni, cn; ni = ns[i]; i++){
831                cn = ni.childNodes;
832                for(var j = 0, cj; cj = cn[j]; j++){
833                    if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){
834                        result[++ri] = cj;
835                    }
836                }
837            }
838	
839	
840        }else if(mode == "+"){
841            var utag = tagName.toUpperCase();
842            for(var i = 0, n; n = ns[i]; i++){
843                while((n = n.nextSibling) && n.nodeType != 1);
844                if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
845                    result[++ri] = n;
846                }
847            }
848	
849	
850        }else if(mode == "~"){
851            var utag = tagName.toUpperCase();
852            for(var i = 0, n; n = ns[i]; i++){
853                while((n = n.nextSibling)){
854                    if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
855                        result[++ri] = n;
856                    }
857                }
858            }
859        }
860        return result;
861    }
862
863    function concat(a, b){
864        if(b.slice){
865            return a.concat(b);
866        }
867        for(var i = 0, l = b.length; i < l; i++){
868            a[a.length] = b[i];
869        }
870        return a;
871    }
872
873    function byTag(cs, tagName){
874        if(cs.tagName || cs == document){
875            cs = [cs];
876        }
877        if(!tagName){
878            return cs;
879        }
880        var result = [], ri = -1;
881        tagName = tagName.toLowerCase();
882        for(var i = 0, ci; ci = cs[i]; i++){
883            if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
884                result[++ri] = ci;
885            }
886        }
887        return result;
888    }
889
890    function byId(cs, id){
891        if(cs.tagName || cs == document){
892            cs = [cs];
893        }
894        if(!id){
895            return cs;
896        }
897        var result = [], ri = -1;
898        for(var i = 0, ci; ci = cs[i]; i++){
899            if(ci && ci.id == id){
900                result[++ri] = ci;
901                return result;
902            }
903        }
904        return result;
905    }
906
907    
908    
909    function byAttribute(cs, attr, value, op, custom){
910        var result = [], 
911            ri = -1, 
912            useGetStyle = custom == "{",	    
913            fn = Ext.DomQuery.operators[op],	    
914            a,
915            xml,
916            hasXml;
917            
918        for(var i = 0, ci; ci = cs[i]; i++){
919	    
920            if(ci.nodeType != 1){
921                continue;
922            }
923            
924            if(!hasXml){
925                xml = Ext.DomQuery.isXml(ci);
926                hasXml = true;
927            }
928	    
929            
930            if(!xml){
931                if(useGetStyle){
932                    a = Ext.DomQuery.getStyle(ci, attr);
933                } else if (attr == "class" || attr == "className"){
934                    a = ci.className;
935                } else if (attr == "for"){
936                    a = ci.htmlFor;
937                } else if (attr == "href"){
938		    
939		    
940                    a = ci.getAttribute("href", 2);
941                } else{
942                    a = ci.getAttribute(attr);
943                }
944            }else{
945                a = ci.getAttribute(attr);
946            }
947            if((fn && fn(a, value)) || (!fn && a)){
948                result[++ri] = ci;
949            }
950        }
951        return result;
952    }
953
954    function byPseudo(cs, name, value){
955        return Ext.DomQuery.pseudos[name](cs, value);
956    }
957
958    function nodupIEXml(cs){
959        var d = ++key, 
960            r;
961        cs[0].setAttribute("_nodup", d);
962        r = [cs[0]];
963        for(var i = 1, len = cs.length; i < len; i++){
964            var c = cs[i];
965            if(!c.getAttribute("_nodup") != d){
966                c.setAttribute("_nodup", d);
967                r[r.length] = c;
968            }
969        }
970        for(var i = 0, len = cs.length; i < len; i++){
971            cs[i].removeAttribute("_nodup");
972        }
973        return r;
974    }
975
976    function nodup(cs){
977        if(!cs){
978            return [];
979        }
980        var len = cs.length, c, i, r = cs, cj, ri = -1;
981        if(!len || typeof cs.nodeType != "undefined" || len == 1){
982            return cs;
983        }
984        if(isIE && typeof cs[0].selectSingleNode != "undefined"){
985            return nodupIEXml(cs);
986        }
987        var d = ++key;
988        cs[0]._nodup = d;
989        for(i = 1; c = cs[i]; i++){
990            if(c._nodup != d){
991                c._nodup = d;
992            }else{
993                r = [];
994                for(var j = 0; j < i; j++){
995                    r[++ri] = cs[j];
996                }
997                for(j = i+1; cj = cs[j]; j++){
998                    if(cj._nodup != d){
999                        cj._nodup = d;
1000                        r[++ri] = cj;
1001                    }
1002                }
1003                return r;
1004            }
1005        }
1006        return r;
1007    }
1008
1009    function quickDiffIEXml(c1, c2){
1010        var d = ++key,
1011            r = [];
1012        for(var i = 0, len = c1.length; i < len; i++){
1013            c1[i].setAttribute("_qdiff", d);
1014        }        
1015        for(var i = 0, len = c2.length; i < len; i++){
1016            if(c2[i].getAttribute("_qdiff") != d){
1017                r[r.length] = c2[i];
1018            }
1019        }
1020        for(var i = 0, len = c1.length; i < len; i++){
1021           c1[i].removeAttribute("_qdiff");
1022        }
1023        return r;
1024    }
1025
1026    function quickDiff(c1, c2){
1027        var len1 = c1.length,
1028        	d = ++key,
1029        	r = [];
1030        if(!len1){
1031            return c2;
1032        }
1033        if(isIE && typeof c1[0].selectSingleNode != "undefined"){
1034            return quickDiffIEXml(c1, c2);
1035        }        
1036        for(var i = 0; i < len1; i++){
1037            c1[i]._qdiff = d;
1038        }        
1039        for(var i = 0, len = c2.length; i < len; i++){
1040            if(c2[i]._qdiff != d){
1041                r[r.length] = c2[i];
1042            }
1043        }
1044        return r;
1045    }
1046
1047    function quickId(ns, mode, root, id){
1048        if(ns == root){
1049           var d = root.ownerDocument || root;
1050           return d.getElementById(id);
1051        }
1052        ns = getNodes(ns, mode, "*");
1053        return byId(ns, id);
1054    }
1055
1056    return {
1057        getStyle : function(el, name){
1058            return Ext.fly(el).getStyle(name);
1059        },
1060        
1061        compile : function(path, type){
1062            type = type || "select";
1063
1064    	    
1065            var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
1066        		mode,		
1067        		lastPath,
1068            	matchers = Ext.DomQuery.matchers,
1069            	matchersLn = matchers.length,
1070            	modeMatch,
1071            	
1072            	lmode = path.match(modeRe);
1073            
1074            if(lmode && lmode[1]){
1075                fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
1076                path = path.replace(lmode[1], "");
1077            }
1078	    
1079            
1080            while(path.substr(0, 1)=="/"){
1081                path = path.substr(1);
1082            }
1083
1084            while(path && lastPath != path){
1085                lastPath = path;
1086                var tokenMatch = path.match(tagTokenRe);
1087                if(type == "select"){
1088                    if(tokenMatch){
1089			
1090                        if(tokenMatch[1] == "#"){
1091                            fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';			
1092                        }else{
1093                            fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
1094                        }
1095                        path = path.replace(tokenMatch[0], "");
1096                    }else if(path.substr(0, 1) != '@'){
1097                        fn[fn.length] = 'n = getNodes(n, mode, "*");';
1098                    }
1099		
1100                }else{
1101                    if(tokenMatch){
1102                        if(tokenMatch[1] == "#"){
1103                            fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
1104                        }else{
1105                            fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
1106                        }
1107                        path = path.replace(tokenMatch[0], "");
1108                    }
1109                }
1110                while(!(modeMatch = path.match(modeRe))){
1111                    var matched = false;
1112                    for(var j = 0; j < matchersLn; j++){
1113                        var t = matchers[j];
1114                        var m = path.match(t.re);
1115                        if(m){
1116                            fn[fn.length] = t.select.replace(tplRe, function(x, i){
1117				return m[i];
1118			    });
1119                            path = path.replace(m[0], "");
1120                            matched = true;
1121                            break;
1122                        }
1123                    }
1124                    
1125                    if(!matched){
1126                        throw 'Error parsing selector, parsing failed at "' + path + '"';
1127                    }
1128                }
1129                if(modeMatch[1]){
1130                    fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
1131                    path = path.replace(modeMatch[1], "");
1132                }
1133            }
1134	    
1135            fn[fn.length] = "return nodup(n);\n}";
1136	    
1137	    
1138            eval(fn.join(""));
1139            return f;
1140        },
1141
1142        
1143	jsSelect: function(path, root, type){
1144	    
1145	    root = root || document;
1146	    
1147            if(typeof root == "string"){
1148                root = document.getElementById(root);
1149            }
1150            var paths = path.split(","),
1151            	results = [];
1152		
1153	    
1154            for(var i = 0, len = paths.length; i < len; i++){		
1155                var subPath = paths[i].replace(trimRe, "");
1156		
1157                if(!cache[subPath]){
1158                    cache[subPath] = Ext.DomQuery.compile(subPath);
1159                    if(!cache[subPath]){
1160                        throw subPath + " is not a valid selector";
1161                    }
1162                }
1163                var result = cache[subPath](root);
1164                if(result && result != document){
1165                    results = results.concat(result);
1166                }
1167            }
1168	    
1169	    
1170	    
1171            if(paths.length > 1){
1172                return nodup(results);
1173            }
1174            return results;
1175        },
1176	isXml: function(el) {
1177	    var docEl = (el ? el.ownerDocument || el : 0).documentElement;
1178	    return docEl ? docEl.nodeName !== "HTML" : false;
1179	},
1180        select : document.querySelectorAll ? function(path, root, type) {
1181	    root = root || document;
1182	    if (!Ext.DomQuery.isXml(root)) {
1183		try {
1184		    var cs = root.querySelectorAll(path);
1185		    return Ext.toArray(cs);
1186		}
1187		catch (ex) {}		
1188	    }	    
1189	    return Ext.DomQuery.jsSelect.call(this, path, root, type);
1190	} : function(path, root, type) {
1191	    return Ext.DomQuery.jsSelect.call(this, path, root, type);
1192	},
1193
1194        
1195        selectNode : function(path, root){
1196            return Ext.DomQuery.select(path, root)[0];
1197        },
1198
1199        
1200        selectValue : function(path, root, defaultValue){
1201            path = path.replace(trimRe, "");
1202            if(!valueCache[path]){
1203                valueCache[path] = Ext.DomQuery.compile(path, "select");
1204            }
1205            var n = valueCache[path](root), v;
1206            n = n[0] ? n[0] : n;
1207            	    
1208	    
1209	    
1210	    
1211	    
1212            if (typeof n.normalize == 'function') n.normalize();
1213            
1214            v = (n && n.firstChild ? n.firstChild.nodeValue : null);
1215            return ((v === null||v === undefined||v==='') ? defaultValue : v);
1216        },
1217
1218        
1219        selectNumber : function(path, root, defaultValue){
1220            var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0
1220);
1221            return parseFloat(v);
1222        },
1223
1224        
1225        is : function(el, ss){
1226            if(typeof el == "string"){
1227                el = document.getElementById(el);
1228            }
1229            var isArray = Ext.isArray(el),
1230            	result = Ext.DomQuery.filter(isArray ? el : [el], ss);
1231            return isArray ? (result.length == el.length) : (result.length > 0);
1232        },
1233
1234        
1235        filter : function(els, ss, nonMatches){
1236            ss = ss.replace(trimRe, "");
1237            if(!simpleCache[ss]){
1238                simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
1239            }
1240            var result = simpleCache[ss](els);
1241            return nonMatches ? quickDiff(result, els) : result;
1242        },
1243
1244        
1245        matchers : [{
1246                re: /^\.([\w\-]+)/,
1247                select: 'n = byClassName(n, " {1} ");'
1248            }, {
1249                re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
1250                select: 'n = byPseudo(n, "{1}", "{2}");'
1251            },{
1252                re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,
1253                select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'
1254            }, {
1255                re: /^#([\w\-]+)/,
1256                select: 'n = byId(n, "{1}");'
1257            },{
1258                re: /^@([\w\-]+)/,
1259                select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
1260            }
1261        ],
1262
1263        /**
1264         * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=.
1265         * New operators can be added as long as the match the format <i>c</i>= where <i>c</i> is any character other than space, &gt; &lt;.
1266         */
1267        operators : {
1268            "=" : function(a, v){
1269                return a == v;
1270            },
1271            "!=" : function(a, v){
1272                return a != v;
1273            },
1274            "^=" : function(a, v){
1275                return a && a.substr(0, v.length) == v;
1276            },
1277            "$=" : function(a, v){
1278                return a && a.substr(a.length-v.length) == v;
1279            },
1280            "*=" : function(a, v){
1281                return a && a.indexOf(v) !== -1;
1282            },
1283            "%=" : function(a, v){
1284                return (a % v) == 0;
1285            },
1286            "|=" : function(a, v){
1287                return a && (a == v || a.substr(0, v.length+1) == v+'-');
1288            },
1289            "~=" : function(a, v){
1290                return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1291            }
1292        },
1293
1294        /**
1295         * <p>Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed
1296         * two parameters:</p><div class="mdetail-params"><ul>
1297         * <li><b>c</b> : Array<div class="sub-desc">An Array of DOM elements to filter.</div></li>
1298         * <li><b>v</b> : String<div class="sub-desc">The argument (if any) supplied in the selector.</div></li>
1299         * </ul></div>
1300         * <p>A filter function returns an Array of DOM elements which conform to the pseudo class.</p>
1301         * <p>In addition to the provided pseudo classes listed above such as <code>first-child</code> and <code>nth-child</code>,
1302         * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.</p>
1303         * <p>For example, to filter <code>&lt;a></code> elements to only return links to <i>external</i> resources:</p>
1304         * <code><pre>
1305Ext.DomQuery.pseudos.external = function(c, v){
1306    var r = [], ri = -1;
1307    for(var i = 0, ci; ci = c[i]; i++){
1308//      Include in result set only if it's a link to an external resource
1309        if(ci.hostname != location.hostname){
1310            r[++ri] = ci;
1311        }
1312    }
1313    return r;
1314};</pre></code>
1315         * Then external links could be gathered with the following statement:<code><pre>
1316var externalLinks = Ext.select("a:external");
1317</code></pre>
1318         */
1319        pseudos : {
1320            "first-child" : function(c){
1321                var r = [], ri = -1, n;
1322                for(var i = 0, ci; ci = n = c[i]; i++){
1323                    while((n = n.previousSibling) && n.nodeType != 1);
1324                    if(!n){
1325                        r[++ri] = ci;
1326                    }
1327                }
1328                return r;
1329            },
1330
1331            "last-child" : function(c){
1332                var r = [], ri = -1, n;
1333                for(var i = 0, ci; ci = n = c[i]; i++){
1334                    while((n = n.nextSibling) && n.nodeType != 1);
1335                    if(!n){
1336                        r[++ri] = ci;
1337                    }
1338                }
1339                return r;
1340            },
1341
1342            "nth-child" : function(c, a) {
1343                var r = [], ri = -1,
1344                	m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
1345                	f = (m[1] || 1) - 0, l = m[2] - 0;
1346                for(var i = 0, n; n = c[i]; i++){
1347                    var pn = n.parentNode;
1348                    if (batch != pn._batch) {
1349                        var j = 0;
1350                        for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1351                            if(cn.nodeType == 1){
1352                               cn.nodeIndex = ++j;
1353                            }
1354                        }
1355                        pn._batch = batch;
1356                    }
1357                    if (f == 1) {
1358                        if (l == 0 || n.nodeIndex == l){
1359                            r[++ri] = n;
1360                        }
1361                    } else if ((n.nodeIndex + l) % f == 0){
1362                        r[++ri] = n;
1363                    }
1364                }
1365
1366                return r;
1367            },
1368
1369            "only-child" : function(c){
1370                var r = [], ri = -1;;
1371                for(var i = 0, ci; ci = c[i]; i++){
1372                    if(!prev(ci) && !next(ci)){
1373                        r[++ri] = ci;
1374                    }
1375                }
1376                return r;
1377            },
1378
1379            "empty" : function(c){
1380                var r = [], ri = -1;
1381                for(var i = 0, ci; ci = c[i]; i++){
1382                    var cns = ci.childNodes, j = 0, cn, empty = true;
1383                    while(cn = cns[j]){
1384                        ++j;
1385                        if(cn.nodeType == 1 || cn.nodeType == 3){
1386                            empty = false;
1387                            break;
1388                        }
1389                    }
1390                    if(empty){
1391                        r[++ri] = ci;
1392                    }
1393                }
1394                return r;
1395            },
1396
1397            "contains" : function(c, v){
1398                var r = [], ri = -1;
1399                for(var i = 0, ci; ci = c[i]; i++){
1400                    if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1401                        r[++ri] = ci;
1402                    }
1403                }
1404                return r;
1405            },
1406
1407            "nodeValue" : function(c, v){
1408                var r = [], ri = -1;
1409                for(var i = 0, ci; ci = c[i]; i++){
1410                    if(ci.firstChild && ci.firstChild.nodeValue == v){
1411                        r[++ri] = ci;
1412                    }
1413                }
1414                return r;
1415            },
1416
1417            "checked" : function(c){
1418                var r = [], ri = -1;
1419                for(var i = 0, ci; ci = c[i]; i++){
1420                    if(ci.checked == true){
1421                        r[++ri] = ci;
1422                    }
1423                }
1424                return r;
1425            },
1426
1427            "not" : function(c, ss){
1428                return Ext.DomQuery.filter(c, ss, true);
1429            },
1430
1431            "any" : function(c, selectors){
1432                var ss = selectors.split('|'),
1433                	r = [], ri = -1, s;
1434                for(var i = 0, ci; ci = c[i]; i++){
1435                    for(var j = 0; s = ss[j]; j++){
1436                        if(Ext.DomQuery.is(ci, s)){
1437                            r[++ri] = ci;
1438                            break;
1439                        }
1440                    }
1441                }
1442                return r;
1443            },
1444
1445            "odd" : function(c){
1446                return this["nth-child"](c, "odd");
1447            },
1448
1449            "even" : function(c){
1450                return this["nth-child"](c, "even");
1451            },
1452
1453            "nth" : function(c, a){
1454                return c[a-1] || [];
1455            },
1456
1457            "first" : function(c){
1458                return c[0] || [];
1459            },
1460
1461            "last" : function(c){
1462                return c[c.length-1] || [];
1463            },
1464
1465            "has" : function(c, ss){
1466                var s = Ext.DomQuery.select,
1467                	r = [], ri = -1;
1468                for(var i = 0, ci; ci = c[i]; i++){
1469                    if(s(ss, ci).length > 0){
1470                        r[++ri] = ci;
1471                    }
1472                }
1473                return r;
1474            },
1475
1476            "next" : function(c, ss){
1477                var is = Ext.DomQuery.is,
1478                	r = [], ri = -1;
1479                for(var i = 0, ci; ci = c[i]; i++){
1480                    var n = next(ci);
1481                    if(n && is(n, ss)){
1482                        r[++ri] = ci;
1483                    }
1484                }
1485                return r;
1486            },
1487
1488            "prev" : function(c, ss){
1489                var is = Ext.DomQuery.is,
1490                	r = [], ri = -1;
1491                for(var i = 0, ci; ci = c[i]; i++){
1492                    var n = prev(ci);
1493                    if(n && is(n, ss)){
1494                        r[++ri] = ci;
1495                    }
1496                }
1497                return r;
1498            }
1499        }
1500    };
1501}();
1502
1503/**
1504 * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select}
1505 * @param {String} path The selector/xpath query
1506 * @param {Node} root (optional) The start of the query (defaults to document).
1507 * @return {Array}
1508 * @member Ext
1509 * @method query
1510 */
1511Ext.query = Ext.DomQuery.select;
1512/**
1513 * @class Ext.util.DelayedTask
1514 * <p> The DelayedTask class provides a convenient way to "buffer" the execution of a method,
1515 * performing setTimeout where a new timeout cancels the old timeout. When called, the
1516 * task will wait the specified time period before executing. If durng that time period,
1517 * the task is called again, the original call will be cancelled. This continues so that
1518 * the function is only called a single time for each iteration.</p>
1519 * <p>This method is especially useful for things like detecting whether a user has finished
1520 * typing in a text field. An example would be performing validation on a keypress. You can
1521 * use this class to buffer the keypress events for a certain number of milliseconds, and
1522 * perform only if they stop for that amount of time.  Usage:</p><pre><code>
1523var task = new Ext.util.DelayedTask(function(){
1524    alert(Ext.getDom('myInputField').value.length);
1525});
1526// Wait 500ms before calling our function. If the user presses another key 
1527// during that 500ms, it will be cancelled and we'll wait another 500ms.
1528Ext.get('myInputField').on('keypress', function(){
1529    task.{@link #delay}(500); 
1530});
1531 * </code></pre> 
1532 * <p>Note that we are using a DelayedTask here to illustrate a point. The configuration
1533 * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will
1534 * also setup a delayed task for you to buffer events.</p> 
1535 * @constructor The parameters to this constructor serve as defaults and are not required.
1536 * @param {Function} fn (optional) The default function to call.
1537 * @param {Object} scope The default scope (The <code><b>this</b></code> reference) in which the
1538 * function is called. If not specified, <code>this</code> will refer to the browser window.
1539 * @param {Array} args (optional) The default Array of arguments.
1540 */
1541Ext.util.DelayedTask = function(fn, scope, args){
1542    var me = this,
1543    	id,    	
1544    	call = function(){
1545    		clearInterval(id);
1546	        id = null;
1547	        fn.apply(scope, args || []);
1548	    };
1549	    
1550    /**
1551     * Cancels any pending timeout and queues a new one
1552     * @param {Number} delay The milliseconds to delay
1553     * @param {Function} newFn (optional) Overrides function passed to constructor
1554     * @param {Object} newScope (optional) Overrides scope passed to constructor. Remember that if no scope
1555     * is specified, <code>this</code> will refer to the browser window.
1556     * @param {Array} newArgs (optional) Overrides args passed to constructor
1557     */
1558    me.delay = function(delay, newFn, newScope, newArgs){
1559        me.cancel();
1560        fn = newFn || fn;
1561        scope = newScope || scope;
1562        args = newArgs || args;
1563        id = setInterval(call, delay);
1564    };
1565
1566    /**
1567     * Cancel the last queued timeout
1568     */
1569    me.cancel = function(){
1570        if(id){
1571            clearInterval(id);
1572            id = null;
1573        }
1574    };
1575};/**
1576 * @class Ext.Element
1577 * <p>Encapsulates a DOM element, adding simple DOM manipulation facilities, normalizing for browser differences.</p>
1578 * <p>All instances of this class inherit the methods of {@link Ext.Fx} making visual effects easily available to all DOM elements.</p>
1579 * <p>Note that the events documented in this class are not Ext events, they encapsulate browser events. To
1580 * access the underlying browser event, see {@link Ext.EventObject#browserEvent}. Some older
1581 * browsers may not support the full range of events. Which events are supported is beyond the control of ExtJs.</p>
1582 * Usage:<br>
1583<pre><code>
1584// by id
1585var el = Ext.get("my-div");
1586
1587// by DOM element reference
1588var el = Ext.get(myDivElement);
1589</code></pre>
1590 * <b>Animations</b><br />
1591 * <p>When an element is manipulated, by default there is no animation.</p>
1592 * <pre><code>
1593var el = Ext.get("my-div");
1594
1595// no animation
1596el.setWidth(100);
1597 * </code></pre>
1598 * <p>Many of the functions for manipulating an element have an optional "animate" parameter.  This
1599 * parameter can be specified as boolean (<tt>true</tt>) for default animation effects.</p>
1600 * <pre><code>
1601// default animation
1602el.setWidth(100, true);
1603 * </code></pre>
1604 *
1605 * <p>To configure the effects, an object literal with animation options to use as the Element animation
1606 * configuration object can also be specified. Note that the supported Element animation configuration
1607 * options are a subset of the {@link Ext.Fx} animation options specific to Fx effects.  The supported
1608 * Element animation configuration options are:</p>
1609<pre>
1610Option    Default   Description
1611--------- --------  ---------------------------------------------
1612{@link Ext.Fx#duration duration}  .35       The duration of the animation in seconds
1613{@link Ext.Fx#easing easing}    easeOut   The easing method
1614{@link Ext.Fx#callback callback}  none      A function to execute when the anim completes
1615{@link Ext.Fx#scope scope}     this      The scope (this) of the callback function
1616</pre>
1617 *
1618 * <pre><code>
1619// Element animation options object
1620var opt = {
1621    {@link Ext.Fx#duration duration}: 1,
1622    {@link Ext.Fx#easing easing}: 'elasticIn',
1623    {@link Ext.Fx#callback callback}: this.foo,
1624    {@link Ext.Fx#scope scope}: this
1625};
1626// animation with some options set
1627el.setWidth(100, opt);
1628 * </code></pre>
1629 * <p>The Element animation object being used for the animation will be set on the options
1630 * object as "anim", which allows you to stop or manipulate the animation. Here is an example:</p>
1631 * <pre><code>
1632// using the "anim" property to get the Anim object
1633if(opt.anim.isAnimated()){
1634    opt.anim.stop();
1635}
1636 * </code></pre>
1637 * <p>Also see the <tt>{@link #animate}</tt> method for another animation technique.</p>
1638 * <p><b> Composite (Collections of) Elements</b></p>
1639 * <p>For working with collections of Elements, see {@link Ext.CompositeElement}</p>
1640 * @constructor Create a new Element directly.
1641 * @param {String/HTMLElement} element
1642 * @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class).
1643 */
1644(function(){
1645var DOC = document;
1646
1647Ext.Element = function(element, forceNew){
1648    var dom = typeof element == "string" ?
1649              DOC.getElementById(element) : element,
1650        id;
1651
1652    if(!dom) return null;
1653
1654    id = dom.id;
1655
1656    if(!forceNew && id && Ext.elCache[id]){ // element object already exists
1657        return Ext.elCache[id].el;
1658    }
1659
1660    /**
1661     * The DOM element
1662     * @type HTMLElement
1663     */
1664    this.dom = dom;
1665
1666    /**
1667     * The DOM element ID
1668     * @type String
1669     */
1670    this.id = id || Ext.id(dom);
1671};
1672
1673var DH = Ext.DomHelper,
1674    El = Ext.Element,
1675    EC = Ext.elCache;
1676
1677El.prototype = {
1678    /**
1679     * Sets the passed attributes as attributes of this element (a style attribute can be a string, object or function)
1680     * @param {Object} o The object with the attributes
1681     * @param {Boolean} useSet (optional) false to override the default setAttribute to use expandos.
1682     * @return {Ext.Element} this
1683     */
1684    set : function(o, useSet){
1685        var el = this.dom,
1686            attr,
1687            val,
1688            useSet = (useSet !== false) && !!el.setAttribute;
1689
1690        for (attr in o) {
1691            if (o.hasOwnProperty(attr)) {
1692                val = o[attr];
1693                if (attr == 'style') {
1694                    DH.applyStyles(el, val);
1695                } else if (attr == 'cls') {
1696                    el.className = val;
1697                } else if (useSet) {
1698                    el.setAttribute(attr, val);
1699                } else {
1700                    el[attr] = val;
1701                }
1702            }
1703        }
1704        return this;
1705    },
1706
1707//  Mouse events
1708    /**
1709     * @event click
1710     * Fires when a mouse click is detected within the element.
1711     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1712     * @param {HtmlElement} t The target of the event.
1713     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1714     */
1715    /**
1716     * @event contextmenu
1717     * Fires when a right click is detected within the element.
1718     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1719     * @param {HtmlElement} t The target of the event.
1720     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1721     */
1722    /**
1723     * @event dblclick
1724     * Fires when a mouse double click is detected within the element.
1725     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1726     * @param {HtmlElement} t The target of the event.
1727     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1728     */
1729    /**
1730     * @event mousedown
1731     * Fires when a mousedown is detected within the element.
1732     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1733     * @param {HtmlElement} t The target of the event.
1734     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1735     */
1736    /**
1737     * @event mouseup
1738     * Fires when a mouseup is detected within the element.
1739     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1740     * @param {HtmlElement} t The target of the event.
1741     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1742     */
1743    /**
1744     * @event mouseover
1745     * Fires when a mouseover is detected within the element.
1746     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1747     * @param {HtmlElement} t The target of the event.
1748     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1749     */
1750    /**
1751     * @event mousemove
1752     * Fires when a mousemove is detected with the element.
1753     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1754     * @param {HtmlElement} t The target of the event.
1755     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1756     */
1757    /**
1758     * @event mouseout
1759     * Fires when a mouseout is detected with the element.
1760     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1761     * @param {HtmlElement} t The target of the event.
1762     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1763     */
1764    /**
1765     * @event mouseenter
1766     * Fires when the mouse enters the element.
1767     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1768     * @param {HtmlElement} t The target of the event.
1769     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1770     */
1771    /**
1772     * @event mouseleave
1773     * Fires when the mouse leaves the element.
1774     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1775     * @param {HtmlElement} t The target of the event.
1776     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1777     */
1778
1779//  Keyboard events
1780    /**
1781     * @event keypress
1782     * Fires when a keypress is detected within the element.
1783     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1784     * @param {HtmlElement} t The target of the event.
1785     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1786     */
1787    /**
1788     * @event keydown
1789     * Fires when a keydown is detected within the element.
1790     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1791     * @param {HtmlElement} t The target of the event.
1792     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1793     */
1794    /**
1795     * @event keyup
1796     * Fires when a keyup is detected within the element.
1797     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1798     * @param {HtmlElement} t The target of the event.
1799     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1800     */
1801
1802
1803//  HTML frame/object events
1804    /**
1805     * @event load
1806     * Fires when the user agent finishes loading all content within the element. Only supported by window, frames, objects and images.
1807     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1808     * @param {HtmlElement} t The target of the event.
1809     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1810     */
1811    /**
1812     * @event unload
1813     * Fires when the user agent removes all content from a window or frame. For elements, it fires when the target element or any of its content has been removed.
1814     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1815     * @param {HtmlElement} t The target of the event.
1816     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1817     */
1818    /**
1819     * @event abort
1820     * Fires when an object/image is stopped from loading before completely loaded.
1821     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1822     * @param {HtmlElement} t The target of the event.
1823     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1824     */
1825    /**
1826     * @event error
1827     * Fires when an object/image/frame cannot be loaded properly.
1828     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1829     * @param {HtmlElement} t The target of the event.
1830     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1831     */
1832    /**
1833     * @event resize
1834     * Fires when a document view is resized.
1835     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1836     * @param {HtmlElement} t The target of the event.
1837     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1838     */
1839    /**
1840     * @event scroll
1841     * Fires when a document view is scrolled.
1842     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1843     * @param {HtmlElement} t The target of the event.
1844     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1845     */
1846
1847//  Form events
1848    /**
1849     * @event select
1850     * Fires when a user selects some text in a text field, including input and textarea.
1851     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1852     * @param {HtmlElement} t The target of the event.
1853     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1854     */
1855    /**
1856     * @event change
1857     * Fires when a control loses the input focus and its value has been modified since gaining focus.
1858     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1859     * @param {HtmlElement} t The target of the event.
1860     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1861     */
1862    /**
1863     * @event submit
1864     * Fires when a form is submitted.
1865     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1866     * @param {HtmlElement} t The target of the event.
1867     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1868     */
1869    /**
1870     * @event reset
1871     * Fires when a form is reset.
1872     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1873     * @param {HtmlElement} t The target of the event.
1874     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1875     */
1876    /**
1877     * @event focus
1878     * Fires when an element receives focus either via the pointing device or by tab navigation.
1879     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1880     * @param {HtmlElement} t The target of the event.
1881     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1882     */
1883    /**
1884     * @event blur
1885     * Fires when an element loses focus either via the pointing device or by tabbing navigation.
1886     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1887     * @param {HtmlElement} t The target of the event.
1888     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1889     */
1890
1891//  User Interface events
1892    /**
1893     * @event DOMFocusIn
1894     * Where supported. Similar to HTML focus event, but can be applied to any focusable element.
1895     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1896     * @param {HtmlElement} t The target of the event.
1897     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1898     */
1899    /**
1900     * @event DOMFocusOut
1901     * Where supported. Similar to HTML blur event, but can be applied to any focusable element.
1902     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1903     * @param {HtmlElement} t The target of the event.
1904     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1905     */
1906    /**
1907     * @event DOMActivate
1908     * Where supported. Fires when an element is activated, for instance, through a mouse click or a keypress.
1909     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1910     * @param {HtmlElement} t The target of the event.
1911     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1912     */
1913
1914//  DOM Mutation events
1915    /**
1916     * @event DOMSubtreeModified
1917     * Where supported. Fires when the subtree is modified.
1918     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1919     * @param {HtmlElement} t The target of the event.
1920     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1921     */
1922    /**
1923     * @event DOMNodeInserted
1924     * Where supported. Fires when a node has been added as a child of another node.
1925     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1926     * @param {HtmlElement} t The target of the event.
1927     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1928     */
1929    /**
1930     * @event DOMNodeRemoved
1931     * Where supported. Fires when a descendant node of the element is removed.
1932     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1933     * @param {HtmlElement} t The target of the event.
1934     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1935     */
1936    /**
1937     * @event DOMNodeRemovedFromDocument
1938     * Where supported. Fires when a node is being removed from a document.
1939     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1940     * @param {HtmlElement} t The target of the event.
1941     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1942     */
1943    /**
1944     * @event DOMNodeInsertedIntoDocument
1945     * Where supported. Fires when a node is being inserted into a document.
1946     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1947     * @param {HtmlElement} t The target of the event.
1948     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1949     */
1950    /**
1951     * @event DOMAttrModified
1952     * Where supported. Fires when an attribute has been modified.
1953     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1954     * @param {HtmlElement} t The target of the event.
1955     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1956     */
1957    /**
1958     * @event DOMCharacterDataModified
1959     * Where supported. Fires when the character data has been modified.
1960     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
1961     * @param {HtmlElement} t The target of the event.
1962     * @param {Object} o The options configuration passed to the {@link #addListener} call.
1963     */
1964
1965    /**
1966     * The default unit to append to CSS values where a unit isn't provided (defaults to px).
1967     * @type String
1968     */
1969    defaultUnit : "px",
1970
1971    /**
1972     * Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child)
1973     * @param {String} selector The simple selector to test
1974     * @return {Boolean} True if this element matches the selector, else false
1975     */
1976    is : function(simpleSelector){
1977        return Ext.DomQuery.is(this.dom, simpleSelector);
1978    },
1979
1980    /**
1981     * Tries to focus the element. Any exceptions are caught and ignored.
1982     * @param {Number} defer (optional) Milliseconds to defer the focus
1983     * @return {Ext.Element} this
1984     */
1985    focus : function(defer, /* private */ dom) {
1986        var me = this,
1987            dom = dom || me.dom;
1988        try{
1989            if(Number(defer)){
1990                me.focus.defer(defer, null, [null, dom]);
1991            }else{
1992                dom.focus();
1993            }
1994        }catch(e){}
1995        return me;
1996    },
1997
1998    /**
1999     * Tries to blur the element. Any exceptions are caught and ignored.
2000     * @return {Ext.Element} this
2001     */
2002    blur : function() {
2003        try{
2004            this.dom.blur();
2005        }catch(e){}
2006        return this;
2007    },
2008
2009    /**
2010     * Returns the value of the "value" attribute
2011     * @param {Boolean} asNumber true to parse the value as a number
2012     * @return {String/Number}
2013     */
2014    getValue : function(asNumber){
2015        var val = this.dom.value;
2016        return asNumber ? parseInt(val, 10) : val;
2017    },
2018
2019    /**
2020     * Appends an event handler to this element.  The shorthand version {@link #on} is equivalent.
2021     * @param {String} eventName The name of event to handle.
2022     * @param {Function} fn The handler function the event invokes. This function is passed
2023     * the following parameters:<ul>
2024     * <li><b>evt</b> : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
2025     * <li><b>el</b> : HtmlElement<div class="sub-desc">The DOM element which was the target of the event.
2026     * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
2027     * <li><b>o</b> : Object<div class="sub-desc">The options object from the addListener call.</div></li>
2028     * </ul>
2029     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
2030     * <b>If omitted, defaults to this Element.</b>.
2031     * @param {Object} options (optional) An object containing handler configuration properties.
2032     * This may contain any of the following properties:<ul>
2033     * <li><b>scope</b> Object : <div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
2034     * <b>If omitted, defaults to this Element.</b></div></li>
2035     * <li><b>delegate</b> String: <div class="sub-desc">A simple selector to filter the target or look for a descendant of the target. See below for additional details.</div></li>
2036     * <li><b>stopEvent</b> Boolean: <div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
2037     * <li><b>preventDefault</b> Boolean: <div class="sub-desc">True to prevent the default action</div></li>
2038     * <li><b>stopPropagation</b> Boolean: <div class="sub-desc">True to prevent event propagation</div></li>
2039     * <li><b>normalized</b> Boolean: <div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
2040     * <li><b>target</b> Ext.Element: <div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
2041     * <li><b>delay</b> Number: <div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
2042     * <li><b>single</b> Boolean: <div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
2043     * <li><b>buffer</b> Number: <div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
2044     * by the specified number of milliseconds. If the event fires again within that time, the original
2045     * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
2046     * </ul><br>
2047     * <p>
2048     * <b>Combining Options</b><br>
2049     * In the following examples, the shorthand form {@link #on} is used rather than the more verbose
2050     * addListener.  The two are equivalent.  Using the options argument, it is possible to combine different
2051     * types of listeners:<br>
2052     * <br>
2053     * A delayed, one-time listener that auto stops the event and adds a custom argument (forumId) to the
2054     * options object. The options object is available as the third parameter in the handler function.<div style="margin: 5px 20px 20px;">
2055     * Code:<pre><code>
2056el.on('click', this.onClick, this, {
2057    single: true,
2058    delay: 100,
2059    stopEvent : true,
2060    forumId: 4
2061});</code></pre></p>
2062     * <p>
2063     * <b>Attaching multiple handlers in 1 call</b><br>
2064     * The method also allows for a single argument to be passed which is a config object containing properties
2065     * which specify multiple handlers.</p>
2066     * <p>
2067     * Code:<pre><code>
2068el.on({
2069    'click' : {
2070        fn: this.onClick,
2071        scope: this,
2072        delay: 100
2073    },
2074    'mouseover' : {
2075        fn: this.onMouseOver,
2076        scope: this
2077    },
2078    'mouseout' : {
2079        fn: this.onMouseOut,
2080        scope: this
2081    }
2082});</code></pre>
2083     * <p>
2084     * Or a shorthand syntax:<br>
2085     * Code:<pre><code></p>
2086el.on({
2087    'click' : this.onClick,
2088    'mouseover' : this.onMouseOver,
2089    'mouseout' : this.onMouseOut,
2090    scope: this
2091});
2092     * </code></pre></p>
2093     * <p><b>delegate</b></p>
2094     * <p>This is a configuration option that you can pass along when registering a handler for
2095     * an event to assist with event delegation. Event delegation is a technique that is used to
2096     * reduce memory consumption and prevent exposure to memory-leaks. By registering an event
2097     * for a container element as opposed to each element within a container. By setting this
2098     * configuration option to a simple selector, the target element will be filtered to look for
2099     * a descendant of the target.
2100     * For example:<pre><code>
2101// using this markup:
2102&lt;div id='elId'>
2103    &lt;p id='p1'>paragraph one&lt;/p>
2104    &lt;p id='p2' class='clickable'>paragraph two&lt;/p>
2105    &lt;p id='p3'>paragraph three&lt;/p>
2106&lt;/div>
2107// utilize event delegation to registering just one handler on the container element:
2108el = Ext.get('elId');
2109el.on(
2110    'click',
2111    function(e,t) {
2112        // handle click
2113        console.info(t.id); // 'p2'
2114    },
2115    this,
2116    {
2117        // filter the target element to be a descendant with the class 'clickable'
2118        delegate: '.clickable'
2119    }
2120);
2121     * </code></pre></p>
2122     * @return {Ext.Element} this
2123     */
2124    addListener : function(eventName, fn, scope, options){
2125        Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
2126        return this;
2127    },
2128
2129    /**
2130     * Removes an event handler from this element.  The shorthand version {@link #un} is equivalent.
2131     * <b>Note</b>: if a <i>scope</i> was explicitly specified when {@link #addListener adding} the
2132     * listener, the same scope must be specified here.
2133     * Example:
2134     * <pre><code>
2135el.removeListener('click', this.handlerFn);
2136// or
2137el.un('click', this.handlerFn);
2138</code></pre>
2139     * @param {String} eventName The name of the event from which to remove the handler.
2140     * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
2141     * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
2142     * then this must refer to the same object.
2143     * @return {Ext.Element} this
2144     */
2145    removeListener : function(eventName, fn, scope){
2146        Ext.EventManager.removeListener(this.dom,  eventName, fn, scope || this);
2147        return this;
2148    },
2149
2150    /**
2151     * Removes all previous added listeners from this element
2152     * @return {Ext.Element} this
2153     */
2154    removeAllListeners : function(){
2155        Ext.EventManager.removeAll(this.dom);
2156        return this;
2157    },
2158
2159    /**
2160     * Recursively removes all previous added listeners from this element and its children
2161     * @return {Ext.Element} this
2162     */
2163    purgeAllListeners : function() {
2164        Ext.EventManager.purgeElement(this, true);
2165        return this;
2166    },
2167    /**
2168     * @private Test if size has a unit, otherwise appends the default
2169     */
2170    addUnits : function(size){
2171        if(size === "" || size == "auto" || size === undefined){
2172            size = size || '';
2173        } else if(!isNaN(size) || !unitPattern.test(size)){
2174            size = size + (this.defaultUnit || 'px');
2175        }
2176        return size;
2177    },
2178
2179    /**
2180     * <p>Updates the <a href="http:
2181     * from a specified URL. Note that this is subject to the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a></p>
2182     * <p>Updating innerHTML of an element will <b>not</b> execute embedded <tt>&lt;script></tt> elements. This is a browser restriction.</p>
2183     * @param {Mixed} options. Either a sring containing the URL from which to load the HTML, or an {@link Ext.Ajax#request} options object specifying
2184     * exactly how to request the HTML.
2185     * @return {Ext.Element} this
2186     */
2187    load : function(url, params, cb){
2188        Ext.Ajax.request(Ext.apply({
2189            params: params,
2190            url: url.url || url,
2191            callback: cb,
2192            el: this.dom,
2193            indicatorText: url.indicatorText || ''
2194        }, Ext.isObject(url) ? url : {}));
2195        return this;
2196    },
2197
2198    
2199    isBorderBox : function(){
2200        return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()];
2201    },
2202
2203    
2204    remove : function(){
2205        var me = this,
2206            dom = me.dom;
2207
2208        if (dom) {
2209            delete me.dom;
2210            Ext.removeNode(dom);
2211        }
2212    },
2213
2214    
2215    hover : function(overFn, outFn, scope, options){
2216        var me = this;
2217        me.on('mouseenter', overFn, scope || me.dom, options);
2218        me.on('mouseleave', outFn, scope || me.dom, options);
2219        return me;
2220    },
2221
2222    
2223    contains : function(el){
2224        return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
2225    },
2226
2227    
2228    getAttributeNS : function(ns, name){
2229        return this.getAttribute(name, ns);
2230    },
2231
2232    
2233    getAttribute: (function(){
2234        var test = document.createElement('table'),
2235            isBrokenOnTable = false,
2236            hasGetAttribute = 'getAttribute' in test,
2237            unknownRe = /undefined|unknown/;
2238            
2239        if (hasGetAttribute) {
2240            
2241            try {
2242                test.getAttribute('ext:qtip');
2243            } catch (e) {
2244                isBrokenOnTable = true;
2245            }
2246            
2247            return function(name, ns) {
2248                var el = this.dom,
2249                    value;
2250                
2251                if (el.getAttributeNS) {
2252                    value  = el.getAttributeNS(ns, name) || null;
2253                }
2254            
2255                if (value == null) {
2256                    if (ns) {
2257                        if (isBrokenOnTable && el.tagName.toUpperCase() == 'TABLE') {
2258                            try {
2259                                value = el.getAttribute(ns + ':' + name);
2260                            } catch (e) {
2261                                value = '';
2262                            }
2263                        } else {
2264                            value = el.getAttribute(ns + ':' + name);
2265                        }
2266                    } else {
2267                        value = el.getAttribute(name) || el[name];
2268                    }
2269                }
2270                return value || '';
2271            };
2272        } else {
2273            return function(name, ns) {
2274                var el = this.om,
2275                    value,
2276                    attribute;
2277                
2278                if (ns) {
2279                    attribute = el[ns + ':' + name];
2280                    value = unknownRe.test(typeof attribute) ? undefined : attribute;
2281                } else {
2282                    value = el[name];
2283                }
2284                return value || '';
2285            };
2286        }
2287        test = null;
2288    })(),
2289        
2290    
2291    update : function(html) {
2292        if (this.dom) {
2293            this.dom.innerHTML = html;
2294        }
2295        return this;
2296    }
2297};
2298
2299var ep = El.prototype;
2300
2301El.addMethods = function(o){
2302   Ext.apply(ep, o);
2303};
2304
2305
2306ep.on = ep.addListener;
2307
2308
2309ep.un = ep.removeListener;
2310
2311
2312ep.autoBoxAdjust = true;
2313
2314
2315var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
2316    docEl;
2317
2318
2319
2320
2321El.get = function(el){
2322    var ex,
2323        elm,
2324        id;
2325    if(!el){ return null; }
2326    if (typeof el == "string") { 
2327        if (!(elm = DOC.getElementById(el))) {
2328            return null;
2329        }
2330        if (EC[el] && EC[el].el) {
2331            ex = EC[el].el;
2332            ex.dom = elm;
2333        } else {
2334            ex = El.addToCache(new El(elm));
2335        }
2336        return ex;
2337    } else if (el.tagName) { 
2338        if(!(id = el.id)){
2339            id = Ext.id(el);
2340        }
2341        if (EC[id] && EC[id].el) {
2342            ex = EC[id].el;
2343            ex.dom = el;
2344        } else {
2345            ex = El.addToCache(new El(el));
2346        }
2347        return ex;
2348    } else if (el instanceof El) {
2349        if(el != docEl){
2350            
2351            
2352
2353            
2354            if (Ext.isIE && (el.id == undefined || el.id == '')) {
2355                el.dom = el.dom;
2356            } else {
2357                el.dom = DOC.getElementById(el.id) || el.dom;
2358            }
2359        }
2360        return el;
2361    } else if(el.isComposite) {
2362        return el;
2363    } else if(Ext.isArray(el)) {
2364        return El.select(el);
2365    } else if(el == DOC) {
2366        
2367        if(!docEl){
2368            var f = function(){};
2369            f.prototype = El.prototype;
2370            docEl = new f();
2371            docEl.dom = DOC;
2372        }
2373        return docEl;
2374    }
2375    return null;
2376};
2377
2378El.addToCache = function(el, id){
2379    id = id || el.id;
2380    EC[id] = {
2381        el:  el,
2382        data: {},
2383        events: {}
2384    };
2385    return el;
2386};
2387
2388
2389El.data = function(el, key, value){
2390    el = El.get(el);
2391    if (!el) {
2392        return null;
2393    }
2394    var c = EC[el.id].data;
2395    if(arguments.length == 2){
2396        return c[key];
2397    }else{
2398        return (c[key] = value);
2399    }
2400};
2401
2402
2403
2404
2405function garbageCollect(){
2406    if(!Ext.enableGarbageCollector){
2407        clearInterval(El.collectorThreadId);
2408    } else {
2409        var eid,
2410            el,
2411            d,
2412            o;
2413
2414        for(eid in EC){
2415            o = EC[eid];
2416            if(o.skipGC){
2417                continue;
2418            }
2419            el = o.el;
2420            d = el.dom;
2421            
2422            
2423            
2424            
2425            
2426            
2427            
2428            
2429            
2430            
2431            
2432            
2433            
2434            
2435            
2436            
2437            
2438            if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
2439                if(Ext.enableListenerCollection){
2440                    Ext.EventManager.removeAll(d);
2441                }
2442                delete EC[eid];
2443            }
2444        }
2445        
2446        if (Ext.isIE) {
2447            var t = {};
2448            for (eid in EC) {
2449                t[eid] = EC[eid];
2450            }
2451            EC = Ext.elCache = t;
2452        }
2453    }
2454}
2455El.collectorThreadId = setInterval(garbageCollect, 30000);
2456
2457var flyFn = function(){};
2458flyFn.prototype = El.prototype;
2459
2460
2461El.Flyweight = function(dom){
2462    this.dom = dom;
2463};
2464
2465El.Flyweight.prototype = new flyFn();
2466El.Flyweight.prototype.isFlyweight = true;
2467El._flyweights = {};
2468
2469
2470El.fly = function(el, named){
2471    var ret = null;
2472    named = named || '_global';
2473
2474    if (el = Ext.getDom(el)) {
2475        (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
2476        ret = El._flyweights[named];
2477    }
2478    return ret;
2479};
2480
2481
2482Ext.get = El.get;
2483
2484
2485Ext.fly = El.fly;
2486
2487
2488var noBoxAdjust = Ext.isStrict ? {
2489    select:1
2490} : {
2491    input:1, select:1, textarea:1
2492};
2493if(Ext.isIE || Ext.isGecko){
2494    noBoxAdjust['button'] = 1;
2495}
2496
2497})();
2498
2499Ext.Element.addMethods(function(){
2500	var PARENTNODE = 'parentNode',
2501		NEXTSIBLING = 'nextSibling',
2502		PREVIOUSSIBLING = 'previousSibling',
2503		DQ = Ext.DomQuery,
2504		GET = Ext.get;
2505	
2506	return {
2507		
2508	    findParent : function(simpleSelector, maxDepth, returnEl){
2509	        var p = this.dom,
2510	        	b = document.body, 
2511	        	depth = 0, 	        	
2512	        	stopEl;	        
2513            if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
2514                return null;
2515            }
2516	        maxDepth = maxDepth || 50;
2517	        if (isNaN(maxDepth)) {
2518	            stopEl = Ext.getDom(maxDepth);
2519	            maxDepth = Number.MAX_VALUE;
2520	        }
2521	        while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
2522	            if(DQ.is(p, simpleSelector)){
2523	                return returnEl ? GET(p) : p;
2524	            }
2525	            depth++;
2526	            p = p.parentNode;
2527	        }
2528	        return null;
2529	    },
2530	
2531	    
2532	    findParentNode : function(simpleSelector, maxDepth, returnEl){
2533	        var p = Ext.fly(this.dom.parentNode, '_internal');
2534	        return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
2535	    },
2536	
2537	    
2538	    up : function(simpleSelector, maxDepth){
2539	        return this.findParentNode(simpleSelector, maxDepth, true);
2540	    },
2541	
2542	    
2543	    select : function(selector){
2544	        return Ext.Element.select(selector, this.dom);
2545	    },
2546	
2547	    
2548	    query : function(selector){
2549	        return DQ.select(selector, this.dom);
2550	    },
2551	
2552	    
2553	    child : function(selector, returnDom){
2554	        var n = DQ.selectNode(selector, this.dom);
2555	        return returnDom ? n : GET(n);
2556	    },
2557	
2558	    
2559	    down : function(selector, returnDom){
2560	        var n = DQ.selectNode(" > " + selector, this.dom);
2561	        return returnDom ? n : GET(n);
2562	    },
2563	
2564		 
2565	    parent : function(selector, returnDom){
2566	        return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
2567	    },
2568	
2569	     
2570	    next : function(selector, returnDom){
2571	        return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
2572	    },
2573	
2574	    
2575	    prev : function(selector, returnDom){
2576	        return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
2577	    },
2578	
2579	
2580	    
2581	    first : function(selector, returnDom){
2582	        return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
2583	    },
2584	
2585	    
2586	    last : function(selector, returnDom){
2587	        return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
2588	    },
2589	    
2590	    matchNode : function(dir, start, selector, returnDom){
2591	        var n = this.dom[start];
2592	        while(n){
2593	            if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
2594	                return !returnDom ? GET(n) : n;
2595	            }
2596	            n = n[dir];
2597	        }
2598	        return null;
2599	    }	
2600    };
2601}());
2602Ext.Element.addMethods(
2603function() {
2604	var GETDOM = Ext.getDom,
2605		GET = Ext.get,
2606		DH = Ext.DomHelper;
2607	
2608	return {
2609	    
2610	    appendChild: function(el){        
2611	        return GET(el).appendTo(this);        
2612	    },
2613	
2614	    
2615	    appendTo: function(el){        
2616	        GETDOM(el).appendChild(this.dom);        
2617	        return this;
2618	    },
2619	
2620	    
2621	    insertBefore: function(el){  	          
2622	        (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
2623	        return this;
2624	    },
2625	
2626	    
2627	    insertAfter: function(el){
2628	        (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
2629	        return this;
2630	    },
2631	
2632	    
2633	    insertFirst: function(el, returnDom){
2634            el = el || {};
2635            if(el.nodeType || el.dom || typeof el == 'string'){ 
2636                el = GETDOM(el);
2637                this.dom.insertBefore(el, this.dom.firstChild);
2638                return !returnDom ? GET(el) : el;
2639            }else{ 
2640                return this.createChild(el, this.dom.firstChild, returnDom);
2641            }
2642        },
2643	
2644	    
2645	    replace: function(el){
2646	        el = GET(el);
2647	        this.insertBefore(el);
2648	        el.remove();
2649	        return this;
2650	    },
2651	
2652	    
2653	    replaceWith: function(el){
2654		    var me = this;
2655                
2656            if(el.nodeType || el.dom || typeof el == 'string'){
2657                el = GETDOM(el);
2658                me.dom.parentNode.insertBefore(el, me.dom);
2659            }else{
2660                el = DH.insertBefore(me.dom, el);
2661            }
2662	        
2663	        delete Ext.elCache[me.id];
2664	        Ext.removeNode(me.dom);      
2665	        me.id = Ext.id(me.dom = el);
2666	        Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);     
2667            return me;
2668	    },
2669	    
2670		
2671		createChild: function(config, insertBefore, returnDom){
2672		    config = config || {tag:'div'};
2673		    return insertBefore ? 
2674		    	   DH.insertBefore(insertBefore, config, returnDom !== true) :	
2675		    	   DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
2676		},
2677		
2678		
2679		wrap: function(config, returnDom){        
2680		    var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
2681		    newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
2682		    return newEl;
2683		},
2684		
2685		
2686		insertHtml : function(where, html, returnEl){
2687		    var el = DH.insertHtml(where, this.dom, html);
2688		    return returnEl ? Ext.get(el) : el;
2689		}
2690	};
2691}());
2692Ext.Element.addMethods(function(){
2693    
2694    var supports = Ext.supports,
2695        propCache = {},
2696        camelRe = /(-[a-z])/gi,
2697        view = document.defaultView,
2698        opacityRe = /alpha\(opacity=(.*)\)/i,
2699        trimRe = /^\s+|\s+$/g,
2700        EL = Ext.Element,
2701        spacesRe = /\s+/,
2702        wordsRe = /\w/g,
2703        PADDING = "padding",
2704        MARGIN = "margin",
2705        BORDER = "border",
2706        LEFT = "-left",
2707        RIGHT = "-right",
2708        TOP = "-top",
2709        BOTTOM = "-bottom",
2710        WIDTH = "-width",
2711        MATH = Math,
2712        HIDDEN = 'hidden',
2713        ISCLIPPED = 'isClipped',
2714        OVERFLOW = 'overflow',
2715        OVERFLOWX = 'overflow-x',
2716        OVERFLOWY = 'overflow-y',
2717        ORIGINALCLIP = 'originalClip',
2718        
2719        borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
2720        paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
2721        margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
2722        data = Ext.Element.data;
2723
2724
2725    
2726    function camelFn(m, a) {
2727        return a.charAt(1).toUpperCase();
2728    }
2729
2730    function chkCache(prop) {
2731        return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
2732    }
2733
2734    return {
2735        
2736        adjustWidth : function(width) {
2737            var me = this;
2738            var isNum = (typeof width == "number");
2739            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
2740               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
2741            }
2742            return (isNum && width < 0) ? 0 : width;
2743        },
2744
2745        
2746        adjustHeight : function(height) {
2747            var me = this;
2748            var isNum = (typeof height == "number");
2749            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
2750               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
2751            }
2752            return (isNum && height < 0) ? 0 : height;
2753        },
2754
2755
2756        
2757        addClass : function(className){
2758            var me = this,
2759                i,
2760                len,
2761                v,
2762                cls = [];
2763            
2764            if (!Ext.isArray(className)) {
2765                if (typeof className == 'string' && !this.hasClass(className)) {
2766                    me.dom.className += " " + className;
2767                }
2768            }
2769            else {
2770                for (i = 0, len = className.length; i < len; i++) {
2771                    v = className[i];
2772                    if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
2773                        cls.push(v);
2774                    }
2775                }
2776                if (cls.length) {
2777                    me.dom.className += " " + cls.join(" ");
2778                }
2779            }
2780            return me;
2781        },
2782
2783        
2784        removeClass : function(className){
2785            var me = this,
2786                i,
2787                idx,
2788                len,
2789                cls,
2790                elClasses;
2791            if (!Ext.isArray(className)){
2792                className = [className];
2793            }
2794            if (me.dom && me.dom.className) {
2795                elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
2796                for (i = 0, len = className.length; i < len; i++) {
2797                    cls = className[i];
2798                    if (typeof cls == 'string') {
2799                        cls = cls.replace(trimRe, '');
2800                        idx = elClasses.indexOf(cls);
2801                        if (idx != -1) {
2802                            elClasses.splice(idx, 1);
2803                        }
2804                    }
2805                }
2806                me.dom.className = elClasses.join(" ");
2807            }
2808            return me;
2809        },
2810
2811        
2812        radioClass : function(className){
2813            var cn = this.dom.parentNode.childNodes,
2814                v,
2815                i,
2816                len;
2817            className = Ext.isArray(className) ? className : [className];
2818            for (i = 0, len = cn.length; i < len; i++) {
2819                v = cn[i];
2820                if (v && v.nodeType == 1) {
2821                    Ext.fly(v, '_internal').removeClass(className);
2822                }
2823            };
2824            return this.addClass(className);
2825        },
2826
2827        
2828        toggleClass : function(className){
2829            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
2830        },
2831
2832        
2833        hasClass : function(className){
2834            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2835        },
2836
2837        
2838        replaceClass : function(oldClassName, newClassName){
2839            return this.removeClass(oldClassName).addClass(newClassName);
2840        },
2841
2842        isStyle : function(style, val) {
2843            return this.getStyle(style) == val;
2844        },
2845
2846        
2847        getStyle : function(){
2848            return view && view.getComputedStyle ?
2849                function(prop){
2850                    var el = this.dom,
2851                        v,
2852                        cs,
2853                        out,
2854                        display;
2855
2856                    if(el == document){
2857                        return null;
2858                    }
2859                    prop = chkCache(prop);
2860                    out = (v = el.style[prop]) ? v :
2861                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
2862                           
2863                    
2864                    
2865                    if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){
2866                        display = el.style.display;
2867                        el.style.display = 'inline-block';
2868                        out = view.getComputedStyle(el, '').marginRight;
2869                        el.style.display = display;
2870                    }
2871                    
2872                    if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){
2873                        out = 'transparent';
2874                    }
2875                    return out;
2876                } :
2877                function(prop){
2878                    var el = this.dom,
2879                        m,
2880                        cs;
2881
2882                    if(el == document) return null;
2883                    if (prop == 'opacity') {
2884                        if (el.style.filter.match) {
2885                            if(m = el.style.filter.match(opacityRe)){
2886                                var fv = parseFloat(m[1]);
2887                                if(!isNaN(fv)){
2888                                    return fv ? fv / 100 : 0;
2889                                }
2890                            }
2891                        }
2892                        return 1;
2893                    }
2894                    prop = chkCache(prop);
2895                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
2896                };
2897        }(),
2898
2899        
2900        getColor : function(attr, defaultValue, prefix){
2901            var v = this.getStyle(attr),
2902                color = (typeof prefix != 'undefined') ? prefix : '#',
2903                h;
2904
2905            if(!v || (/transparent|inherit/.test(v))) {
2906                return defaultValue;
2907            }
2908            if(/^r/.test(v)){
2909                Ext.each(v.slice(4, v.length -1).split(','), function(s){
2910                    h = parseInt(s, 10);
2911                    color += (h < 16 ? '0' : '') + h.toString(16);
2912                });
2913            }else{
2914                v = v.replace('#', '');
2915                color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
2916            }
2917            return(color.length > 5 ? color.toLowerCase() : defaultValue);
2918        },
2919
2920        
2921        setStyle : function(prop, value){
2922            var tmp, style;
2923            
2924            if (typeof prop != 'object') {
2925                tmp = {};
2926                tmp[prop] = value;
2927                prop = tmp;
2928            }
2929            for (style in prop) {
2930                value = prop[style];
2931                style == 'opacity' ?
2932                    this.setOpacity(value) :
2933                    this.dom.style[chkCache(style)] = value;
2934            }
2935            return this;
2936        },
2937
2938        
2939         setOpacity : function(opacity, animate){
2940            var me = this,
2941                s = me.dom.style;
2942
2943            if(!animate || !me.anim){
2944                if(Ext.isIE){
2945                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
2946                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');
2947
2948                    s.zoom = 1;
2949                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;
2950                }else{
2951                    s.opacity = opacity;
2952                }
2953            }else{
2954                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
2955            }
2956            return me;
2957        },
2958
2959        
2960        clearOpacity : function(){
2961            var style = this.dom.style;
2962            if(Ext.isIE){
2963                if(!Ext.isEmpty(style.filter)){
2964                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
2965                }
2966            }else{
2967                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
2968            }
2969            return this;
2970        },
2971
2972        
2973        getHeight : function(contentHeight){
2974            var me = this,
2975                dom = me.dom,
2976                hidden = Ext.isIE && me.isStyle('display', 'none'),
2977                h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
2978
2979            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
2980            return h < 0 ? 0 : h;
2981        },
2982
2983        
2984        getWidth : function(contentWidth){
2985            var me = this,
2986                dom = me.dom,
2987                hidden = Ext.isIE && me.isStyle('display', 'none'),
2988                w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
2989            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
2990            return w < 0 ? 0 : w;
2991        },
2992
2993        
2994        setWidth : function(width, animate){
2995            var me = this;
2996            width = me.adjustWidth(width);
2997            !animate || !me.anim ?
2998                me.dom.style.width = me.addUnits(width) :
2999                me.anim({width : {to : width}}, me.preanim(arguments, 1));
3000            return me;
3001        },
3002
3003        
3004         setHeight : function(height, animate){
3005            var me = this;
3006            height = me.adjustHeight(height);
3007            !animate || !me.anim ?
3008                me.dom.style.height = me.addUnits(height) :
3009                me.anim({height : {to : height}}, me.preanim(arguments, 1));
3010            return me;
3011        },
3012
3013        
3014        getBorderWidth : function(side){
3015            return this.addStyles(side, borders);
3016        },
3017
3018        
3019        getPadding : function(side){
3020            return this.addStyles(side, paddings);
3021        },
3022
3023        
3024        clip : function(){
3025            var me = this,
3026                dom = me.dom;
3027
3028            if(!data(dom, ISCLIPPED)){
3029                data(dom, ISCLIPPED, true);
3030                data(dom, ORIGINALCLIP, {
3031                    o: me.getStyle(OVERFLOW),
3032                    x: me.getStyle(OVERFLOWX),
3033                    y: me.getStyle(OVERFLOWY)
3034                });
3035                me.setStyle(OVERFLOW, HIDDEN);
3036                me.setStyle(OVERFLOWX, HIDDEN);
3037                me.setStyle(OVERFLOWY, HIDDEN);
3038            }
3039            return me;
3040        },
3041
3042        
3043        unclip : function(){
3044            var me = this,
3045                dom = me.dom;
3046
3047            if(data(dom, ISCLIPPED)){
3048                data(dom, ISCLIPPED, false);
3049                var o = data(dom, ORIGINALCLIP);
3050                if(o.o){
3051                    me.setStyle(OVERFLOW, o.o);
3052                }
3053                if(o.x){
3054                    me.setStyle(OVERFLOWX, o.x);
3055                }
3056                if(o.y){
3057                    me.setStyle(OVERFLOWY, o.y);
3058                }
3059            }
3060            return me;
3061        },
3062
3063        
3064        addStyles : function(sides, styles){
3065            var ttlSize = 0,
3066                sidesArr = sides.match(wordsRe),
3067                side,
3068                size,
3069                i,
3070                len = sidesArr.length;
3071            for (i = 0; i < len; i++) {
3072                side = sidesArr[i];
3073                size = side && parseInt(this.getStyle(styles[side]), 10);
3074                if (size) {
3075                    ttlSize += MATH.abs(size);
3076                }
3077            }
3078            return ttlSize;
3079        },
3080
3081        margins : margins
3082    };
3083}()
3084);
3085
3086(function(){
3087var D = Ext.lib.Dom,
3088        LEFT = "left",
3089        RIGHT = "right",
3090        TOP = "top",
3091        BOTTOM = "bottom",
3092        POSITION = "position",
3093        STATIC = "static",
3094        RELATIVE = "relative",
3095        AUTO = "auto",
3096        ZINDEX = "z-index";
3097
3098Ext.Element.addMethods({
3099	
3100    getX : function(){
3101        return D.getX(this.dom);
3102    },
3103
3104    
3105    getY : function(){
3106        return D.getY(this.dom);
3107    },
3108
3109    
3110    getXY : function(){
3111        return D.getXY(this.dom);
3112    },
3113
3114    
3115    getOffsetsTo : function(el){
3116        var o = this.getXY(),
3117        	e = Ext.fly(el, '_internal').getXY();
3118        return [o[0]-e[0],o[1]-e[1]];
3119    },
3120
3121    
3122    setX : function(x, animate){	    
3123	    return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
3124    },
3125
3126    
3127    setY : function(y, animate){	    
3128	    return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
3129    },
3130
3131    
3132    setLeft : function(left){
3133        this.setStyle(LEFT, this.addUnits(left));
3134        return this;
3135    },
3136
3137    
3138    setTop : function(top){
3139        this.setStyle(TOP, this.addUnits(top));
3140        return this;
3141    },
3142
3143    
3144    setRight : function(right){
3145        this.setStyle(RIGHT, this.addUnits(right));
3146        return this;
3147    },
3148
3149    
3150    setBottom : function(bottom){
3151        this.setStyle(BOTTOM, this.addUnits(bottom));
3152        return this;
3153    },
3154
3155    
3156    setXY : function(pos, animate){
3157	    var me = this;
3158        if(!animate || !me.anim){
3159            D.setXY(me.dom, pos);
3160        }else{
3161            me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
3162        }
3163        return me;
3164    },
3165
3166    
3167    setLocation : function(x, y, animate){
3168        return this.setXY([x, y], this.animTest(arguments, animate, 2));
3169    },
3170
3171    
3172    moveTo : function(x, y, animate){
3173        return this.setXY([x, y], this.animTest(arguments, animate, 2));        
3174    },    
3175    
3176    
3177    getLeft : function(local){
3178	    return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
3179    },
3180
3181    
3182    getRight : function(local){
3183	    var me = this;
3184	    return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
3185    },
3186
3187    
3188    getTop : function(local) {
3189	    return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
3190    },
3191
3192    
3193    getBottom : function(local){
3194	    var me = this;
3195	    return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
3196    },
3197
3198    
3199    position : function(pos, zIndex, x, y){
3200	    var me = this;
3201	    
3202        if(!pos && me.isStyle(POSITION, STATIC)){           
3203            me.setStyle(POSITION, RELATIVE);           
3204        } else if(pos) {
3205            me.setStyle(POSITION, pos);
3206        }
3207        if(zIndex){
3208            me.setStyle(ZINDEX, zIndex);
3209        }
3210        if(x || y) me.setXY([x || false, y || false]);
3211    },
3212
3213    
3214    clearPositioning : function(value){
3215        value = value || '';
3216        this.setStyle({
3217            left : value,
3218            right : value,
3219            top : value,
3220            bottom : value,
3221            "z-index" : "",
3222            position : STATIC
3223        });
3224        return this;
3225    },
3226
3227    
3228    getPositioning : function(){
3229        var l = this.getStyle(LEFT);
3230        var t = this.getStyle(TOP);
3231        return {
3232            "position" : this.getStyle(POSITION),
3233            "left" : l,
3234            "right" : l ? "" : this.getStyle(RIGHT),
3235            "top" : t,
3236            "bottom" : t ? "" : this.getStyle(BOTTOM),
3237            "z-index" : this.getStyle(ZINDEX)
3238        };
3239    },
3240    
3241    
3242    setPositioning : function(pc){
3243	    var me = this,
3244	    	style = me.dom.style;
3245	    	
3246        me.setStyle(pc);
3247        
3248        if(pc.right == AUTO){
3249            style.right = "";
3250        }
3251        if(pc.bottom == AUTO){
3252            style.bottom = "";
3253        }
3254        
3255        return me;
3256    },    
3257	
3258    
3259    translatePoints : function(x, y){        	     
3260	    y = isNaN(x[1]) ? y : x[1];
3261        x = isNaN(x[0]) ? x : x[0];
3262        var me = this,
3263        	relative = me.isStyle(POSITION, RELATIVE),
3264        	o = me.getXY(),
3265        	l = parseInt(me.getStyle(LEFT), 10),
3266        	t = parseInt(me.getStyle(TOP), 10);
3267        
3268        l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
3269        t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);        
3270
3271        return {left: (x - o[0] + l), top: (y - o[1] + t)}; 
3272    },
3273    
3274    animTest : function(args, animate, i) {
3275        return !!animate && this.preanim ? this.preanim(args, i) : false;
3276    }
3277});
3278})();
3279Ext.Element.addMethods({
3280    
3281    isScrollable : function(){
3282        var dom = this.dom;
3283        return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
3284    },
3285
3286    
3287    scrollTo : function(side, value){
3288        this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
3289        return this;
3290    },
3291
3292    
3293    getScroll : function(){
3294        var d = this.dom, 
3295            doc = document,
3296            body = doc.body,
3297            docElement = doc.documentElement,
3298            l,
3299            t,
3300            ret;
3301
3302        if(d == doc || d == body){
3303            if(Ext.isIE && Ext.isStrict){
3304                l = docElement.scrollLeft; 
3305                t = docElement.scrollTop;
3306            }else{
3307                l = window.pageXOffset;
3308                t = window.pageYOffset;
3309            }
3310            ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
3311        }else{
3312            ret = {left: d.scrollLeft, top: d.scrollTop};
3313        }
3314        return ret;
3315    }
3316});
3317
3318Ext.Element.VISIBILITY = 1;
3319
3320Ext.Element.DISPLAY = 2;
3321
3322
3323Ext.Element.OFFSETS = 3;
3324
3325
3326Ext.Element.ASCLASS = 4;
3327
3328
3329Ext.Element.visibilityCls = 'x-hide-nosize';
3330
3331Ext.Element.addMethods(function(){
3332    var El = Ext.Element,
3333        OPACITY = "opacity",
3334        VISIBILITY = "visibility",
3335        DISPLAY = "display",
3336        HIDDEN = "hidden",
3337        OFFSETS = "offsets",
3338        ASCLASS = "asclass",
3339        NONE = "none",
3340        NOSIZE = 'nosize',
3341        ORIGINALDISPLAY = 'originalDisplay',
3342        VISMODE = 'visibilityMode',
3343        ISVISIBLE = 'isVisible',
3344        data = El.data,
3345        getDisplay = function(dom){
3346            var d = data(dom, ORIGINALDISPLAY);
3347            if(d === undefined){
3348                data(dom, ORIGINALDISPLAY, d = '');
3349            }
3350            return d;
3351        },
3352        getVisMode = function(dom){
3353            var m = data(dom, VISMODE);
3354            if(m === undefined){
3355                data(dom, VISMODE, m = 1);
3356            }
3357            return m;
3358        };
3359
3360    return {
3361        
3362        originalDisplay : "",
3363        visibilityMode : 1,
3364
3365        
3366        setVisibilityMode : function(visMode){
3367            data(this.dom, VISMODE, visMode);
3368            return this;
3369        },
3370
3371        
3372        animate : function(args, duration, onComplete, easing, animType){
3373            this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
3374            return this;
3375        },
3376
3377        
3378        anim : function(args, opt, animType, defaultDur, defaultEase, cb){
3379            animType = animType || 'run';
3380            opt = opt || {};
3381            var me = this,
3382                anim = Ext.lib.Anim[animType](
3383                    me.dom,
3384                    args,
3385                    (opt.duration || defaultDur) || .35,
3386                    (opt.easing || defaultEase) || 'easeOut',
3387                    function(){
3388                        if(cb) cb.call(me);
3389                        if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
3390                    },
3391                    me
3392                );
3393            opt.anim = anim;
3394            return anim;
3395        },
3396
3397        
3398        preanim : function(a, i){
3399            return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
3400        },
3401
3402        
3403        isVisible : function() {
3404            var me = this,
3405                dom = me.dom,
3406                visible = data(dom, ISVISIBLE);
3407
3408            if(typeof visible == 'boolean'){ 
3409                return visible;
3410            }
3411            
3412            visible = !me.isStyle(VISIBILITY, HIDDEN) &&
3413                      !me.isStyle(DISPLAY, NONE) &&
3414                      !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls));
3415
3416            data(dom, ISVISIBLE, visible);
3417            return visible;
3418        },
3419
3420        
3421        setVisible : function(visible, animate){
3422            var me = this, isDisplay, isVisibility, isOffsets, isNosize,
3423                dom = me.dom,
3424                visMode = getVisMode(dom);
3425
3426
3427            
3428            if (typeof animate == 'string'){
3429                switch (animate) {
3430                    case DISPLAY:
3431                        visMode = El.DISPLAY;
3432                        break;
3433                    case VISIBILITY:
3434                        visMode = El.VISIBILITY;
3435                        break;
3436                    case OFFSETS:
3437                        visMode = El.OFFSETS;
3438                        break;
3439                    case NOSIZE:
3440                    case ASCLASS:
3441                        visMode = El.ASCLASS;
3442                        break;
3443                }
3444                me.setVisibilityMode(visMode);
3445                animate = false;
3446            }
3447
3448            if (!animate || !me.anim) {
3449                if(visMode == El.ASCLASS ){
3450
3451                    me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls);
3452
3453                } else if (visMode == El.DISPLAY){
3454
3455                    return me.setDisplayed(visible);
3456
3457                } else if (visMode == El.OFFSETS){
3458
3459                    if (!visible){
3460                        me.hideModeStyles = {
3461                            position: me.getStyle('position'),
3462                            top: me.getStyle('top'),
3463                            left: me.getStyle('left')
3464                        };
3465                        me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
3466                    } else {
3467                        me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
3468                        delete me.hideModeStyles;
3469                    }
3470
3471                }else{
3472                    me.fixDisplay();
3473                    dom.style.visibility = visible ? "visible" : HIDDEN;
3474                }
3475            }else{
3476                
3477                if(visible){
3478                    me.setOpacity(.01);
3479                    me.setVisible(true);
3480                }
3481                me.anim({opacity: { to: (visible?1:0) }},
3482                        me.preanim(arguments, 1),
3483                        null,
3484                        .35,
3485                        'easeIn',
3486                        function(){
3487                            visible || me.setVisible(false).setOpacity(1);
3488                        });
3489            }
3490            data(dom, ISVISIBLE, visible);  
3491            return me;
3492        },
3493
3494
3495        
3496        hasMetrics  : function(){
3497            var dom = this.dom;
3498            return this.isVisible() || (getVisMode(dom) == El.VISIBILITY);
3499        },
3500
3501        
3502        toggle : function(animate){
3503            var me = this;
3504            me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
3505            return me;
3506        },
3507
3508        
3509        setDisplayed : function(value) {
3510            if(typeof value == "boolean"){
3511               value = value ? getDisplay(this.dom) : NONE;
3512            }
3513            this.setStyle(DISPLAY, value);
3514            return this;
3515        },
3516
3517        
3518        fixDisplay : function(){
3519            var me = this;
3520            if(me.isStyle(DISPLAY, NONE)){
3521                me.setStyle(VISIBILITY, HIDDEN);
3522                me.setStyle(DISPLAY, getDisplay(this.dom)); 
3523                if(me.isStyle(DISPLAY, NONE)){ 
3524                    me.setStyle(DISPLAY, "block");
3525                }
3526            }
3527        },
3528
3529        
3530        hide : function(animate){
3531            
3532            if (typeof animate == 'string'){
3533                this.setVisible(false, animate);
3534                return this;
3535            }
3536            this.setVisible(false, this.preanim(arguments, 0));
3537            return this;
3538        },
3539
3540        
3541        show : function(animate){
3542            
3543            if (typeof animate == 'string'){
3544                this.setVisible(true, animate);
3545                return this;
3546            }
3547            this.setVisible(true, this.preanim(arguments, 0));
3548            return this;
3549        }
3550    };
3551}());(function(){
3552    
3553    var NULL = null,
3554        UNDEFINED = undefined,
3555        TRUE = true,
3556        FALSE = false,
3557        SETX = "setX",
3558        SETY = "setY",
3559        SETXY = "setXY",
3560        LEFT = "left",
3561        BOTTOM = "bottom",
3562        TOP = "top",
3563        RIGHT = "right",
3564        HEIGHT = "height",
3565        WIDTH = "width",
3566        POINTS = "points",
3567        HIDDEN = "hidden",
3568        ABSOLUTE = "absolute",
3569        VISIBLE = "visible",
3570        MOTION = "motion",
3571        POSITION = "position",
3572        EASEOUT = "easeOut",
3573        
3574        flyEl = new Ext.Element.Flyweight(),
3575        queues = {},
3576        getObject = function(o){
3577            return o || {};
3578        },
3579        fly = function(dom){
3580            flyEl.dom = dom;
3581            flyEl.id = Ext.id(dom);
3582            return flyEl;
3583        },
3584        
3585        getQueue = function(id){
3586            if(!queues[id]){
3587                queues[id] = [];
3588            }
3589            return queues[id];
3590        },
3591        setQueue = function(id, value){
3592            queues[id] = value;
3593        };
3594        
3595
3596Ext.enableFx = TRUE;
3597
3598
3599Ext.Fx = {
3600    
3601    
3602    
3603    switchStatements : function(key, fn, argHash){
3604        return fn.apply(this, argHash[key]);
3605    },
3606    
3607    
3608    slideIn : function(anchor, o){ 
3609        o = getObject(o);
3610        var me = this,
3611            dom = me.dom,
3612            st = dom.style,
3613            xy,
3614            r,
3615            b,              
3616            wrap,               
3617            after,
3618            st,
3619            args, 
3620            pt,
3621            bw,
3622            bh;
3623            
3624        anchor = anchor || "t";
3625
3626        me.queueFx(o, function(){            
3627            xy = fly(dom).getXY();
3628            
3629            fly(dom).fixDisplay();            
3630            
3631            
3632            r = fly(dom).getFxRestore();      
3633            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
3634            b.right = b.x + b.width;
3635            b.bottom = b.y + b.height;
3636            
3637            
3638            fly(dom).setWidth(b.width).setHeight(b.height);            
3639            
3640            
3641            wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
3642            
3643            st.visibility = VISIBLE;
3644            st.position = ABSOLUTE;
3645            
3646            
3647            function after(){
3648                 fly(dom).fxUnwrap(wrap, r.pos, o);
3649                 st.width = r.width;
3650                 st.height = r.height;
3651                 fly(dom).afterFx(o);
3652            }
3653            
3654            
3655            pt = {to: [b.x, b.y]}; 
3656            bw = {to: b.width};
3657            bh = {to: b.height};
3658                
3659            function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){                    
3660                var ret = {};
3661                fly(wrap).setWidth(ww).setHeight(wh);
3662                if(fly(wrap)[sXY]){
3663                    fly(wrap)[sXY](sXYval);                  
3664                }
3665                style[s1] = style[s2] = "0";                    
3666                if(w){
3667                    ret.width = w;
3668                }
3669                if(h){
3670                    ret.height = h;
3671                }
3672                if(p){
3673                    ret.points = p;
3674                }
3675                return ret;
3676            };
3677
3678            args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
3679                    t  : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
3680                    l  : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
3681                    r  : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
3682                    b  : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
3683                    tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
3684                    bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
3685                    br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
3686                    tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
3687                });
3688            
3689            st.visibility = VISIBLE;
3690            fly(wrap).show();
3691
3692            arguments.callee.anim = fly(wrap).fxanim(args,
3693                o,
3694                MOTION,
3695                .5,
3696                EASEOUT, 
3697                after);
3698        });
3699        return me;
3700    },
3701    
3702    
3703    slideOut : function(anchor, o){
3704        o = getObject(o);
3705        var me = this,
3706            dom = me.dom,
3707            st = dom.style,
3708            xy = me.getXY(),
3709            wrap,
3710            r,
3711            b,
3712            a,
3713            zero = {to: 0}; 
3714                    
3715        anchor = anchor || "t";
3716
3717        me.queueFx(o, function(){
3718            
3719            
3720            r = fly(dom).getFxRestore(); 
3721            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
3722            b.right = b.x + b.width;
3723            b.bottom = b.y + b.height;
3724                
3725            
3726            fly(dom).setWidth(b.width).setHeight(b.height);
3727
3728            
3729            wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
3730                
3731            st.visibility = VISIBLE;
3732            st.position = ABSOLUTE;
3733            fly(wrap).setWidth(b.width).setHeight(b.height);            
3734
3735            function after(){
3736                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                
3737                fly(dom).fxUnwrap(wrap, r.pos, o);
3738                st.width = r.width;
3739                st.height = r.height;
3740                fly(dom).afterFx(o);
3741            }            
3742            
3743            function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){                    
3744                var ret = {};
3745                
3746                style[s1] = style[s2] = "0";
3747                ret[p1] = v1;               
3748                if(p2){
3749                    ret[p2] = v2;               
3750                }
3751                if(p3){
3752                    ret[p3] = v3;
3753                }
3754                
3755                return ret;
3756            };
3757            
3758            a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
3759                t  : [st, LEFT, BOTTOM, HEIGHT, zero],
3760                l  : [st, RIGHT, TOP, WIDTH, zero],
3761                r  : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
3762                b  : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}
3762],
3763                tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
3764                bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
3765                br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
3766                tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
3767            });
3768            
3769            arguments.callee.anim = fly(wrap).fxanim(a,
3770                o,
3771                MOTION,
3772                .5,
3773                EASEOUT, 
3774                after);
3775        });
3776        return me;
3777    },
3778
3779    
3780    puff : function(o){
3781        o = getObject(o);
3782        var me = this,
3783            dom = me.dom,
3784            st = dom.style,
3785            width,
3786            height,
3787            r;
3788
3789        me.queueFx(o, function(){
3790            width = fly(dom).getWidth();
3791            height = fly(dom).getHeight();
3792            fly(dom).clearOpacity();
3793            fly(dom).show();
3794
3795            
3796            r = fly(dom).getFxRestore();                   
3797            
3798            function after(){
3799                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                  
3800                fly(dom).clearOpacity();  
3801                fly(dom).setPositioning(r.pos);
3802                st.width = r.width;
3803                st.height = r.height;
3804                st.fontSize = '';
3805                fly(dom).afterFx(o);
3806            }   
3807
3808            arguments.callee.anim = fly(dom).fxanim({
3809                    width : {to : fly(dom).adjustWidth(width * 2)},
3810                    height : {to : fly(dom).adjustHeight(height * 2)},
3811                    points : {by : [-width * .5, -height * .5]},
3812                    opacity : {to : 0},
3813                    fontSize: {to : 200, unit: "%"}
3814                },
3815                o,
3816                MOTION,
3817                .5,
3818                EASEOUT,
3819                 after);
3820        });
3821        return me;
3822    },
3823
3824    
3825    switchOff : function(o){
3826        o = getObject(o);
3827        var me = this,
3828            dom = me.dom,
3829            st = dom.style,
3830            r;
3831
3832        me.queueFx(o, function(){
3833            fly(dom).clearOpacity();
3834            fly(dom).clip();
3835
3836            
3837            r = fly(dom).getFxRestore();
3838                
3839            function after(){
3840                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();  
3841                fly(dom).clearOpacity();
3842                fly(dom).setPositioning(r.pos);
3843                st.width = r.width;
3844                st.height = r.height;   
3845                fly(dom).afterFx(o);
3846            };
3847
3848            fly(dom).fxanim({opacity : {to : 0.3}}, 
3849                NULL, 
3850                NULL, 
3851                .1, 
3852                NULL, 
3853                function(){                                 
3854                    fly(dom).clearOpacity();
3855                        (function(){                            
3856                            fly(dom).fxanim({
3857                                height : {to : 1},
3858                                points : {by : [0, fly(dom).getHeight() * .5]}
3859                            }, 
3860                            o, 
3861                            MOTION, 
3862                            0.3, 
3863                            'easeIn', 
3864                            after);
3865                        }).defer(100);
3866                });
3867        });
3868        return me;
3869    },
3870
3871     
3872    highlight : function(color, o){
3873        o = getObject(o);
3874        var me = this,
3875            dom = me.dom,
3876            attr = o.attr || "backgroundColor",
3877            a = {},
3878            restore;
3879
3880        me.queueFx(o, function(){
3881            fly(dom).clearOpacity();
3882            fly(dom).show();
3883
3884            function after(){
3885                dom.style[attr] = restore;
3886                fly(dom).afterFx(o);
3887            }            
3888            restore = dom.style[attr];
3889            a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
3890            arguments.callee.anim = fly(dom).fxanim(a,
3891                o,
3892                'color',
3893                1,
3894                'easeIn', 
3895                after);
3896        });
3897        return me;
3898    },
3899
3900   
3901    frame : function(color, count, o){
3902        o = getObject(o);
3903        var me = this,
3904            dom = me.dom,
3905            proxy,
3906            active;
3907
3908        me.queueFx(o, function(){
3909            color = color || '#C3DAF9';
3910            if(color.length == 6){
3911                color = '#' + color;
3912            }            
3913            count = count || 1;
3914            fly(dom).show();
3915
3916            var xy = fly(dom).getXY(),
3917                b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
3918                queue = function(){
3919                    proxy = fly(document.body || document.documentElement).createChild({
3920                        style:{
3921                            position : ABSOLUTE,
3922                            'z-index': 35000, 
3923                            border : '0px solid ' + color
3924                        }
3925                    });
3926                    return proxy.queueFx({}, animFn);
3927                };
3928            
3929            
3930            arguments.callee.anim = {
3931                isAnimated: true,
3932                stop: function() {
3933                    count = 0;
3934                    proxy.stopFx();
3935                }
3936            };
3937            
3938            function animFn(){
3939                var scale = Ext.isBorderBox ? 2 : 1;
3940                active = proxy.anim({
3941                    top : {from : b.y, to : b.y - 20},
3942                    left : {from : b.x, to : b.x - 20},
3943                    borderWidth : {from : 0, to : 10},
3944                    opacity : {from : 1, to : 0},
3945                    height : {from : b.height, to : b.height + 20 * scale},
3946                    width : {from : b.width, to : b.width + 20 * scale}
3947                },{
3948                    duration: o.duration || 1,
3949                    callback: function() {
3950                        proxy.remove();
3951                        --count > 0 ? queue() : fly(dom).afterFx(o);
3952                    }
3953                });
3954                arguments.callee.anim = {
3955                    isAnimated: true,
3956                    stop: function(){
3957                        active.stop();
3958                    }
3959                };
3960            };
3961            queue();
3962        });
3963        return me;
3964    },
3965
3966   
3967    pause : function(seconds){        
3968        var dom = this.dom,
3969            t;
3970
3971        this.queueFx({}, function(){
3972            t = setTimeout(function(){
3973                fly(dom).afterFx({});
3974            }, seconds * 1000);
3975            arguments.callee.anim = {
3976                isAnimated: true,
3977                stop: function(){
3978                    clearTimeout(t);
3979                    fly(dom).afterFx({});
3980                }
3981            };
3982        });
3983        return this;
3984    },
3985
3986   
3987    fadeIn : function(o){
3988        o = getObject(o);
3989        var me = this,
3990            dom = me.dom,
3991            to = o.endOpacity || 1;
3992        
3993        me.queueFx(o, function(){
3994            fly(dom).setOpacity(0);
3995            fly(dom).fixDisplay();
3996            dom.style.visibility = VISIBLE;
3997            arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
3998                o, NULL, .5, EASEOUT, function(){
3999                if(to == 1){
4000                    fly(dom).clearOpacity();
4001                }
4002                fly(dom).afterFx(o);
4003            });
4004        });
4005        return me;
4006    },
4007
4008   
4009    fadeOut : function(o){
4010        o = getObject(o);
4011        var me = this,
4012            dom = me.dom,
4013            style = dom.style,
4014            to = o.endOpacity || 0;         
4015        
4016        me.queueFx(o, function(){  
4017            arguments.callee.anim = fly(dom).fxanim({ 
4018                opacity : {to : to}},
4019                o, 
4020                NULL, 
4021                .5, 
4022                EASEOUT, 
4023                function(){
4024                    if(to == 0){
4025                        Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? 
4026                            style.display = "none" :
4027                            style.visibility = HIDDEN;
4028                            
4029                        fly(dom).clearOpacity();
4030                    }
4031                    fly(dom).afterFx(o);
4032            });
4033        });
4034        return me;
4035    },
4036
4037   
4038    scale : function(w, h, o){
4039        this.shift(Ext.apply({}, o, {
4040            width: w,
4041            height: h
4042        }));
4043        return this;
4044    },
4045
4046   
4047    shift : function(o){
4048        o = getObject(o);
4049        var dom = this.dom,
4050            a = {};
4051                
4052        this.queueFx(o, function(){
4053            for (var prop in o) {
4054                if (o[prop] != UNDEFINED) {                                                 
4055                    a[prop] = {to : o[prop]};                   
4056                }
4057            } 
4058            
4059            a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
4060            a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;   
4061            
4062            if (a.x || a.y || a.xy) {
4063                a.points = a.xy || 
4064                           {to : [ a.x ? a.x.to : fly(dom).getX(),
4065                                   a.y ? a.y.to : fly(dom).getY()]};                  
4066            }
4067
4068            arguments.callee.anim = fly(dom).fxanim(a,
4069                o, 
4070                MOTION, 
4071                .35, 
4072                EASEOUT, 
4073                function(){
4074                    fly(dom).afterFx(o);
4075                });
4076        });
4077        return this;
4078    },
4079
4080    
4081    ghost : function(anchor, o){
4082        o = getObject(o);
4083        var me = this,
4084            dom = me.dom,
4085            st = dom.style,
4086            a = {opacity: {to: 0}, points: {}},
4087            pt = a.points,
4088            r,
4089            w,
4090            h;
4091            
4092        anchor = anchor || "b";
4093
4094        me.queueFx(o, function(){
4095            
4096            r = fly(dom).getFxRestore();
4097            w = fly(dom).getWidth();
4098            h = fly(dom).getHeight();
4099            
4100            function after(){
4101                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();   
4102                fly(dom).clearOpacity();
4103                fly(dom).setPositioning(r.pos);
4104                st.width = r.width;
4105                st.height = r.height;
4106                fly(dom).afterFx(o);
4107            }
4108                
4109            pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
4110               t  : [0, -h],
4111               l  : [-w, 0],
4112               r  : [w, 0],
4113               b  : [0, h],
4114               tl : [-w, -h],
4115               bl : [-w, h],
4116               br : [w, h],
4117               tr : [w, -h] 
4118            });
4119                
4120            arguments.callee.anim = fly(dom).fxanim(a,
4121                o,
4122                MOTION,
4123                .5,
4124                EASEOUT, after);
4125        });
4126        return me;
4127    },
4128
4129    
4130    syncFx : function(){
4131        var me = this;
4132        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
4133            block : FALSE,
4134            concurrent : TRUE,
4135            stopFx : FALSE
4136        });
4137        return me;
4138    },
4139
4140    
4141    sequenceFx : function(){
4142        var me = this;
4143        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
4144            block : FALSE,
4145            concurrent : FALSE,
4146            stopFx : FALSE
4147        });
4148        return me;
4149    },
4150
4151    
4152    nextFx : function(){        
4153        var ef = getQueue(this.dom.id)[0];
4154        if(ef){
4155            ef.call(this);
4156        }
4157    },
4158
4159    
4160    hasActiveFx : function(){
4161        return getQueue(this.dom.id)[0];
4162    },
4163
4164    
4165    stopFx : function(finish){
4166        var me = this,
4167            id = me.dom.id;
4168        if(me.hasActiveFx()){
4169            var cur = getQueue(id)[0];
4170            if(cur && cur.anim){
4171                if(cur.anim.isAnimated){
4172                    setQueue(id, [cur]); 
4173                    cur.anim.stop(finish !== undefined ? finish : TRUE);
4174                }else{
4175                    setQueue(id, []);
4176                }
4177            }
4178        }
4179        return me;
4180    },
4181
4182    
4183    beforeFx : function(o){
4184        if(this.hasActiveFx() && !o.concurrent){
4185           if(o.stopFx){
4186               this.stopFx();
4187               return TRUE;
4188           }
4189           return FALSE;
4190        }
4191        return TRUE;
4192    },
4193
4194    
4195    hasFxBlock : function(){
4196        var q = getQueue(this.dom.id);
4197        return q && q[0] && q[0].block;
4198    },
4199
4200    
4201    queueFx : function(o, fn){
4202        var me = fly(this.dom);
4203        if(!me.hasFxBlock()){
4204            Ext.applyIf(o, me.fxDefaults);
4205            if(!o.concurrent){
4206                var run = me.beforeFx(o);
4207                fn.block = o.block;
4208                getQueue(me.dom.id).push(fn);
4209                if(run){
4210                    me.nextFx();
4211                }
4212            }else{
4213                fn.call(me);
4214            }
4215        }
4216        return me;
4217    },
4218
4219    
4220    fxWrap : function(pos, o, vis){ 
4221        var dom = this.dom,
4222            wrap,
4223            wrapXY;
4224        if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){            
4225            if(o.fixPosition){
4226                wrapXY = fly(dom).getXY();
4227            }
4228            var div = document.createElement("div");
4229            div.style.visibility = vis;
4230            wrap = dom.parentNode.insertBefore(div, dom);
4231            fly(wrap).setPositioning(pos);
4232            if(fly(wrap).isStyle(POSITION, "static")){
4233                fly(wrap).position("relative");
4234            }
4235            fly(dom).clearPositioning('auto');
4236            fly(wrap).clip();
4237            wrap.appendChild(dom);
4238            if(wrapXY){
4239                fly(wrap).setXY(wrapXY);
4240            }
4241        }
4242        return wrap;
4243    },
4244
4245    
4246    fxUnwrap : function(wrap, pos, o){      
4247        var dom = this.dom;
4248        fly(dom).clearPositioning();
4249        fly(dom).setPositioning(pos);
4250        if(!o.wrap){
4251            var pn = fly(wrap).dom.parentNode;
4252            pn.insertBefore(dom, wrap); 
4253            fly(wrap).remove();
4254        }
4255    },
4256
4257    
4258    getFxRestore : function(){
4259        var st = this.dom.style;
4260        return {pos: this.getPositioning(), width: st.width, height : st.height};
4261    },
4262
4263    
4264    afterFx : function(o){
4265        var dom = this.dom,
4266            id = dom.id;
4267        if(o.afterStyle){
4268            fly(dom).setStyle(o.afterStyle);            
4269        }
4270        if(o.afterCls){
4271            fly(dom).addClass(o.afterCls);
4272        }
4273        if(o.remove == TRUE){
4274            fly(dom).remove();
4275        }
4276        if(o.callback){
4277            o.callback.call(o.scope, fly(dom));
4278        }
4279        if(!o.concurrent){
4280            getQueue(id).shift();
4281            fly(dom).nextFx();
4282        }
4283    },
4284
4285    
4286    fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
4287        animType = animType || 'run';
4288        opt = opt || {};
4289        var anim = Ext.lib.Anim[animType](
4290                this.dom, 
4291                args,
4292                (opt.duration || defaultDur) || .35,
4293                (opt.easing || defaultEase) || EASEOUT,
4294                cb,            
4295                this
4296            );
4297        opt.anim = anim;
4298        return anim;
4299    }
4300};
4301
4302
4303Ext.Fx.resize = Ext.Fx.scale;
4304
4305
4306
4307Ext.Element.addMethods(Ext.Fx);
4308})();
4309
4310Ext.CompositeElementLite = function(els, root){
4311    
4312    this.elements = [];
4313    this.add(els, root);
4314    this.el = new Ext.Element.Flyweight();
4315};
4316
4317Ext.CompositeElementLite.prototype = {
4318    isComposite: true,
4319
4320    
4321    getElement : function(el){
4322        
4323        var e = this.el;
4324        e.dom = el;
4325        e.id = el.id;
4326        return e;
4327    },
4328
4329    
4330    transformElement : function(el){
4331        return Ext.getDom(el);
4332    },
4333
4334    
4335    getCount : function(){
4336        return this.elements.length;
4337    },
4338    
4339    add : function(els, root){
4340        var me = this,
4341            elements = me.elements;
4342        if(!els){
4343            return this;
4344        }
4345        if(typeof els == "string"){
4346            els = Ext.Element.selectorFunction(els, root);
4347        }else if(els.isComposite){
4348            els = els.elements;
4349        }else if(!Ext.isIterable(els)){
4350            els = [els];
4351        }
4352
4353        for(var i = 0, len = els.length; i < len; ++i){
4354            elements.push(me.transformElement(els[i]));
4355        }
4356        return me;
4357    },
4358
4359    invoke : function(fn, args){
4360        var me = this,
4361            els = me.elements,
4362            len = els.length,
4363            e,
4364            i;
4365
4366        for(i = 0; i < len; i++) {
4367            e = els[i];
4368            if(e){
4369                Ext.Element.prototype[fn].apply(me.getElement(e), args);
4370            }
4371        }
4372        return me;
4373    },
4374    
4375    item : function(index){
4376        var me = this,
4377            el = me.elements[index],
4378            out = null;
4379
4380        if(el){
4381            out = me.getElement(el);
4382        }
4383        return out;
4384    },
4385
4386    
4387    addListener : function(eventName, handler, scope, opt){
4388        var els = this.elements,
4389            len = els.length,
4390            i, e;
4391
4392        for(i = 0; i<len; i++) {
4393            e = els[i];
4394            if(e) {
4395                Ext.EventManager.on(e, eventName, handler, scope || e, opt);
4396            }
4397        }
4398        return this;
4399    },
4400    
4401    each : function(fn, scope){
4402        var me = this,
4403            els = me.elements,
4404            len = els.length,
4405            i, e;
4406
4407        for(i = 0; i<len; i++) {
4408            e = els[i];
4409            if(e){
4410                e = this.getElement(e);
4411                if(fn.call(scope || e, e, me, i) === false){
4412                    break;
4413                }
4414            }
4415        }
4416        return me;
4417    },
4418
4419    
4420    fill : function(els){
4421        var me = this;
4422        me.elements = [];
4423        me.add(els);
4424        return me;
4425    },
4426
4427    
4428    filter : function(selector){
4429        var els = [],
4430            me = this,
4431            fn = Ext.isFunction(selector) ? selector
4432                : function(el){
4433                    return el.is(selector);
4434                };
4435
4436        me.each(function(el, self, i) {
4437            if (fn(el, i) !== false) {
4438                els[els.length] = me.transformElement(el);
4439            }
4440        });
4441        
4442        me.elements = els;
4443        return me;
4444    },
4445
4446    
4447    indexOf : function(el){
4448        return this.elements.indexOf(this.transformElement(el));
4449    },
4450
4451    
4452    replaceElement : function(el, replacement, domReplace){
4453        var index = !isNaN(el) ? el : this.indexOf(el),
4454            d;
4455        if(index > -1){
4456            replacement = Ext.getDom(replacement);
4457            if(domReplace){
4458                d = this.elements[index];
4459                d.parentNode.insertBefore(replacement, d);
4460                Ext.removeNode(d);
4461            }
4462            this.elements.splice(index, 1, replacement);
4463        }
4464        return this;
4465    },
4466
4467    
4468    clear : function(){
4469        this.elements = [];
4470    }
4471};
4472
4473Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
4474
4475
4476Ext.CompositeElementLite.importElementMethods = function() {
4477    var fnName,
4478        ElProto = Ext.Element.prototype,
4479        CelProto = Ext.CompositeElementLite.prototype;
4480
4481    for (fnName in ElProto) {
4482        if (typeof ElProto[fnName] == 'function'){
4483            (function(fnName) {
4484                CelProto[fnName] = CelProto[fnName] || function() {
4485                    return this.invoke(fnName, arguments);
4486                };
4487            }).call(CelProto, fnName);
4488
4489        }
4490    }
4491};
4492
4493Ext.CompositeElementLite.importElementMethods();
4494
4495if(Ext.DomQuery){
4496    Ext.Element.selectorFunction = Ext.DomQuery.select;
4497}
4498
4499
4500Ext.Element.select = function(selector, root){
4501    var els;
4502    if(typeof selector == "string"){
4503        els = Ext.Element.selectorFunction(selector, root);
4504    }else if(selector.length !== undefined){
4505        els = selector;
4506    }else{
4507        throw "Invalid selector";
4508    }
4509    return new Ext.CompositeElementLite(els);
4510};
4511
4512Ext.select = Ext.Element.select;
4513(function(){
4514    var BEFOREREQUEST = "beforerequest",
4515        REQUESTCOMPLETE = "requestcomplete",
4516        REQUESTEXCEPTION = "requestexception",
4517        UNDEFINED = undefined,
4518        LOAD = 'load',
4519        POST = 'POST',
4520        GET = 'GET',
4521        WINDOW = window;
4522
4523    
4524    Ext.data.Connection = function(config){
4525        Ext.apply(this, config);
4526        this.addEvents(
4527            
4528            BEFOREREQUEST,
4529            
4530            REQUESTCOMPLETE,
4531            
4532            REQUESTEXCEPTION
4533        );
4534        Ext.data.Connection.superclass.constructor.call(this);
4535    };
4536
4537    Ext.extend(Ext.data.Connection, Ext.util.Observable, {
4538        
4539        
4540        
4541        
4542        
4543        timeout : 30000,
4544        
4545        autoAbort:false,
4546
4547        
4548        disableCaching: true,
4549
4550        
4551        disableCachingParam: '_dc',
4552
4553        
4554        request : function(o){
4555            var me = this;
4556            if(me.fireEvent(BEFOREREQUEST, me, o)){
4557                if (o.el) {
4558                    if(!Ext.isEmpty(o.indicatorText)){
4559                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
4560                    }
4561                    if(me.indicatorText) {
4562                        Ext.getDom(o.el).innerHTML = me.indicatorText;
4563                    }
4564                    o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
4565                        Ext.getDom(o.el).innerHTML = response.responseText;
4566                    });
4567                }
4568
4569                var p = o.params,
4570                    url = o.url || me.url,
4571                    method,
4572                    cb = {success: me.handleResponse,
4573                          failure: me.handleFailure,
4574                          scope: me,
4575                          argument: {options: o},
4576                          timeout : Ext.num(o.timeout, me.timeout)
4577                    },
4578                    form,
4579                    serForm;
4580
4581
4582                if (Ext.isFunction(p)) {
4583                    p = p.call(o.scope||WINDOW, o);
4584                }
4585
4586                p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
4587
4588                if (Ext.isFunction(url)) {
4589                    url = url.call(o.scope || WINDOW, o);
4590                }
4591
4592                if((form = Ext.getDom(o.form))){
4593                    url = url || form.action;
4594                     if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) {
4595                         return me.doFormUpload.call(me, o, p, url);
4596                     }
4597                    serForm = Ext.lib.Ajax.serializeForm(form);
4598                    p = p ? (p + '&' + serForm) : serForm;
4599                }
4600
4601                method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
4602
4603                if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
4604                    var dcp = o.disableCachingParam || me.disableCachingParam;
4605                    url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
4606                }
4607
4608                o.headers = Ext.applyIf(o.headers || {}, me.defaultHeaders || {});
4609
4610                if(o.autoAbort === true || me.autoAbort) {
4611                    me.abort();
4612                }
4613
4614                if((method == GET || o.xmlData || o.jsonData) && p){
4615                    url = Ext.urlAppend(url, p);
4616                    p = '';
4617                }
4618                return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
4619            }else{
4620                return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
4621            }
4622        },
4623
4624        
4625        isLoading : function(transId){
4626            return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
4627        },
4628
4629        
4630        abort : function(transId){
4631            if(transId || this.isLoading()){
4632                Ext.lib.Ajax.abort(transId || this.transId);
4633            }
4634        },
4635
4636        
4637        handleResponse : function(response){
4638            this.transId = false;
4639            var options = response.argument.options;
4640            response.argument = options ? options.argument : null;
4641            this.fireEvent(REQUESTCOMPLETE, this, response, options);
4642            if(options.success){
4643                options.success.call(options.scope, response, options);
4644            }
4645            if(options.callback){
4646                options.callback.call(options.scope, options, true, response);
4647            }
4648        },
4649
4650        
4651        handleFailure : function(response, e){
4652            this.transId = false;
4653            var options = response.argument.options;
4654            response.argument = options ? options.argument : null;
4655            this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
4656            if(options.failure){
4657                options.failure.call(options.scope, response, options);
4658            }
4659            if(options.callback){
4660                options.callback.call(options.scope, options, false, response);
4661            }
4662        },
4663
4664        
4665        doFormUpload : function(o, ps, url){
4666            var id = Ext.id(),
4667                doc = document,
4668                frame = doc.createElement('iframe'),
4669                form = Ext.getDom(o.form),
4670                hiddens = [],
4671                hd,
4672                encoding = 'multipart/form-data',
4673                buf = {
4674                    target: form.target,
4675                    method: form.method,
4676                    encoding: form.encoding,
4677                    enctype: form.enctype,
4678                    action: form.action
4679                };
4680
4681            
4682            Ext.fly(frame).set({
4683                id: id,
4684                name: id,
4685                cls: 'x-hidden',
4686                src: Ext.SSL_SECURE_URL
4687            }); 
4688
4689            doc.body.appendChild(frame);
4690
4691            
4692            if(Ext.isIE){
4693               document.frames[id].name = id;
4694            }
4695
4696
4697            Ext.fly(form).set({
4698                target: id,
4699                method: POST,
4700                enctype: encoding,
4701                encoding: encoding,
4702                action: url || buf.action
4703            });
4704
4705            
4706            Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
4707                hd = doc.createElement('input');
4708                Ext.fly(hd).set({
4709                    type: 'hidden',
4710                    value: v,
4711                    name: k
4712                });
4713                form.appendChild(hd);
4714                hiddens.push(hd);
4715            });
4716
4717            function cb(){
4718                var me = this,
4719                    
4720                    r = {responseText : '',
4721                         responseXML : null,
4722                         argument : o.argument},
4723                    doc,
4724                    firstChild;
4725
4726                try{
4727                    doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
4728                    if(doc){
4729                        if(doc.body){
4730                            if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ 
4731                                r.responseText = firstChild.value;
4732                            }else{
4733                                r.responseText = doc.body.innerHTML;
4734                            }
4735                        }
4736                        
4737                        r.responseXML = doc.XMLDocument || doc;
4738                    }
4739                }
4740                catch(e) {}
4741
4742                Ext.EventManager.removeListener(frame, LOAD, cb, me);
4743
4744                me.fireEvent(REQUESTCOMPLETE, me, r, o);
4745
4746                function runCallback(fn, scope, args){
4747                    if(Ext.isFunction(fn)){
4748                        fn.apply(scope, args);
4749                    }
4750                }
4751
4752                runCallback(o.success, o.scope, [r, o]);
4753                runCallback(o.callback, o.scope, [o, true, r]);
4754
4755                if(!me.debugUploads){
4756                    setTimeout(function(){Ext.removeNode(frame);}, 100);
4757                }
4758            }
4759
4760            Ext.EventManager.on(frame, LOAD, cb, this);
4761            form.submit();
4762
4763            Ext.fly(form).set(buf);
4764            Ext.each(hiddens, function(h) {
4765                Ext.removeNode(h);
4766            });
4767        }
4768    });
4769})();
4770
4771
4772Ext.Ajax = new Ext.data.Connection({
4773    
4774    
4775    
4776    
4777    
4778    
4779
4780    
4781
4782    
4783    
4784    
4785    
4786    
4787    
4788
4789    
4790    autoAbort : false,
4791
4792    
4793    serializeForm : function(form){
4794        return Ext.lib.Ajax.serializeForm(form);
4795    }
4796});
4797
4798Ext.util.JSON = new (function(){
4799    var useHasOwn = !!{}.hasOwnProperty,
4800        isNative = function() {
4801            var useNative = null;
4802
4803            return function() {
4804                if (useNative === null) {
4805                    useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
4806                }
4807        
4808                return useNative;
4809            };
4810        }(),
4811        pad = function(n) {
4812            return n < 10 ? "0" + n : n;
4813        },
4814        doDecode = function(json){
4815            return json ? eval("(" + json + ")") : "";    
4816        },
4817        doEncode = function(o){
4818            if(!Ext.isDefined(o) || o === null){
4819                return "null";
4820            }else if(Ext.isArray(o)){
4821                return encodeArray(o);
4822            }else if(Ext.isDate(o)){
4823                return Ext.util.JSON.encodeDate(o);
4824            }else if(Ext.isString(o)){
4825                return encodeString(o);
4826            }else if(typeof o == "number"){
4827                
4828                return isFinite(o) ? String(o) : "null";
4829            }else if(Ext.isBoolean(o)){
4830                return String(o);
4831            }else {
4832                var a = ["{"], b, i, v;
4833                for (i in o) {
4834                    
4835                    if(!o.getElementsByTagName){
4836                        if(!useHasOwn || o.hasOwnProperty(i)) {
4837                            v = o[i];
4838                            switch (typeof v) {
4839                            case "undefined":
4840                            case "function":
4841                            case "unknown":
4842                                break;
4843                            default:
4844                                if(b){
4845                                    a.push(',');
4846                                }
4847                                a.push(doEncode(i), ":",
4848                                        v === null ? "null" : doEncode(v));
4849                                b = true;
4850                            }
4851                        }
4852                    }
4853                }
4854                a.push("}");
4855                return a.join("");
4856            }    
4857        },
4858        m = {
4859            "\b": '\\b',
4860            "\t": '\\t',
4861            "\n": '\\n',
4862            "\f": '\\f',
4863            "\r": '\\r',
4864            '"' : '\\"',
4865            "\\": '\\\\'
4866        },
4867        encodeString = function(s){
4868            if (/["\\\x00-\x1f]/.test(s)) {
4869                return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
4870                    var c = m[b];
4871                    if(c){
4872                        return c;
4873                    }
4874                    c = b.charCodeAt();
4875                    return "\\u00" +
4876                        Math.floor(c / 16).toString(16) +
4877                        (c % 16).toString(16);
4878                }) + '"';
4879            }
4880            return '"' + s + '"';
4881        },
4882        encodeArray = function(o){
4883            var a = ["["], b, i, l = o.length, v;
4884                for (i = 0; i < l; i += 1) {
4885                    v = o[i];
4886                    switch (typeof v) {
4887                        case "undefined":
4888                        case "function":
4889                        case "unknown":
4890                            break;
4891                        default:
4892                            if (b) {
4893                                a.push(',');
4894                            }
4895                            a.push(v === null ? "null" : Ext.util.JSON.encode(v));
4896                            b = true;
4897                    }
4898                }
4899                a.push("]");
4900                return a.join("");
4901        };
4902
4903    
4904    this.encodeDate = function(o){
4905        return '"' + o.getFullYear() + "-" +
4906                pad(o.getMonth() + 1) + "-" +
4907                pad(o.getDate()) + "T" +
4908                pad(o.getHours()) + ":" +
4909                pad(o.getMinutes()) + ":" +
4910                pad(o.getSeconds()) + '"';
4911    };
4912
4913    
4914    this.encode = function() {
4915        var ec;
4916        return function(o) {
4917            if (!ec) {
4918                
4919                ec = isNative() ? JSON.stringify : doEncode;
4920            }
4921            return ec(o);
4922        };
4923    }();
4924
4925
4926    
4927    this.decode = function() {
4928        var dc;
4929        return function(json) {
4930            if (!dc) {
4931                
4932                dc = isNative() ? JSON.parse : doDecode;
4933            }
4934            return dc(json);
4935        };
4936    }();
4937
4938})();
4939
4940Ext.encode = Ext.util.JSON.encode;
4941
4942Ext.decode = Ext.util.JSON.decode;
4943
4944Ext.EventManager = function(){
4945    var docReadyEvent,
4946        docReadyProcId,
4947        docReadyState = false,
4948        DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
4949        E = Ext.lib.Event,
4950        D = Ext.lib.Dom,
4951        DOC = document,
4952        WINDOW = window,
4953        DOMCONTENTLOADED = "DOMContentLoaded",
4954        COMPLETE = 'complete',
4955        propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
4956        
4957        specialElCache = [];
4958
4959     function getId(el){
4960        var id = false,
4961            i = 0,
4962            len = specialElCache.length,
4963            skip = false,
4964            o;
4965            
4966        if (el) {
4967            if (el.getElementById || el.navigator) {
4968                
4969                for(; i < len; ++i){
4970                    o = specialElCache[i];
4971                    if(o.el === el){
4972                        id = o.id;
4973                        break;
4974                    }
4975                }
4976                if(!id){
4977                    
4978                    id = Ext.id(el);
4979                    specialElCache.push({
4980                        id: id,
4981                        el: el
4982                    });
4983                    skip = true;
4984                }
4985            }else{
4986                id = Ext.id(el);
4987            }
4988            if(!Ext.elCache[id]){
4989                Ext.Element.addToCache(new Ext.Element(el), id);
4990                if(skip){
4991                    Ext.elCache[id].skipGC = true;
4992                }
4993            }
4994        }
4995        return id;
4996     }
4997
4998    
4999    function addListener(el, ename, fn, task, wrap, scope){
5000        el = Ext.getDom(el);
5001        var id = getId(el),
5002            es = Ext.elCache[id].events,
5003            wfn;
5004
5005        wfn = E.on(el, ename, wrap);
5006        es[ename] = es[ename] || [];
5007
5008        
5009        es[ename].push([fn, wrap, scope, wfn, task]);
5010
5011        
5012        
5013
5014        
5015        if(el.addEventListener && ename == "mousewheel"){
5016            var args = ["DOMMouseScroll", wrap, false];
5017            el.addEventListener.apply(el, args);
5018            Ext.EventManager.addListener(WINDOW, 'unload', function(){
5019                el.removeEventListener.apply(el, args);
5020            });
5021        }
5022
5023        
5024        if(el == DOC && ename == "mousedown"){
5025            Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
5026        }
5027    }
5028
5029    function doScrollChk(){
5030        
5031        if(window != top){
5032            return false;
5033        }
5034
5035        try{
5036            DOC.documentElement.doScroll('left');
5037        }catch(e){
5038             return false;
5039        }
5040
5041        fireDocReady();
5042        return true;
5043    }
5044    
5045    function checkReadyState(e){
5046
5047        if(Ext.isIE && doScrollChk()){
5048            return true;
5049        }
5050        if(DOC.readyState == COMPLETE){
5051            fireDocReady();
5052            return true;
5053        }
5054        docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
5055        return false;
5056    }
5057
5058    var styles;
5059    function checkStyleSheets(e){
5060        styles || (styles = Ext.query('style, link[rel=stylesheet]'));
5061        if(styles.length == DOC.styleSheets.length){
5062            fireDocReady();
5063            return true;
5064        }
5065        docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
5066        return false;
5067    }
5068
5069    function OperaDOMContentLoaded(e){
5070        DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
5071        checkStyleSheets();
5072    }
5073
5074    function fireDocReady(e){
5075        if(!docReadyState){
5076            docReadyState = true; 
5077
5078            if(docReadyProcId){
5079                clearTimeout(docReadyProcId);
5080            }
5081            if(DETECT_NATIVE) {
5082                DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
5083            }
5084            if(Ext.isIE && checkReadyState.bindIE){  
5085                DOC.detachEvent('onreadystatechange', checkReadyState);
5086            }
5087            E.un(WINDOW, "load", arguments.callee);
5088        }
5089        if(docReadyEvent && !Ext.isReady){
5090            Ext.isReady = true;
5091            docReadyEvent.fire();
5092            docReadyEvent.listeners = [];
5093        }
5094
5095    }
5096
5097    function initDocReady(){
5098        docReadyEvent || (docReadyEvent = new Ext.util.Event());
5099        if (DETECT_NATIVE) {
5100            DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
5101        }
5102        
5103        if (Ext.isIE){
5104            
5105            
5106            if(!checkReadyState()){
5107                checkReadyState.bindIE = true;
5108                DOC.attachEvent('onreadystatechange', checkReadyState);
5109            }
5110
5111        }else if(Ext.isOpera ){
5112            
5113
5114            
5115            (DOC.readyState == COMPLETE && checkStyleSheets()) ||
5116                DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
5117
5118        }else if (Ext.isWebKit){
5119            
5120            checkReadyState();
5121        }
5122        
5123        E.on(WINDOW, "load", fireDocReady);
5124    }
5125
5126    function createTargeted(h, o){
5127        return function(){
5128            var args = Ext.toArray(arguments);
5129            if(o.target == Ext.EventObject.setEvent(args[0]).target){
5130                h.apply(this, args);
5131            }
5132        };
5133    }
5134
5135    function createBuffered(h, o, task){
5136        return function(e){
5137            
5138            task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
5139        };
5140    }
5141
5142    function createSingle(h, el, ename, fn, scope){
5143        return function(e){
5144            Ext.EventManager.removeListener(el, ename, fn, scope);
5145            h(e);
5146        };
5147    }
5148
5149    function createDelayed(h, o, fn){
5150        return function(e){
5151            var task = new Ext.util.DelayedTask(h);
5152            if(!fn.tasks) {
5153                fn.tasks = [];
5154            }
5155            fn.tasks.push(task);
5156            task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
5157        };
5158    }
5159
5160    function listen(element, ename, opt, fn, scope){
5161        var o = (!opt || typeof opt == "boolean") ? {} : opt,
5162            el = Ext.getDom(element), task;
5163
5164        fn = fn || o.fn;
5165        scope = scope || o.scope;
5166
5167        if(!el){
5168            throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
5169        }
5170        function h(e){
5171            
5172            if(!Ext){
5173                return;
5174            }
5175            e = Ext.EventObject.setEvent(e);
5176            var t;
5177            if (o.delegate) {
5178                if(!(t = e.getTarget(o.delegate, el))){
5179                    return;
5180                }
5181            } else {
5182                t = e.target;
5183            }
5184            if (o.stopEvent) {
5185                e.stopEvent();
5186            }
5187            if (o.preventDefault) {
5188               e.preventDefault();
5189            }
5190            if (o.stopPropagation) {
5191                e.stopPropagation();
5192            }
5193            if (o.normalized === false) {
5194                e = e.browserEvent;
5195            }
5196
5197            fn.call(scope || el, e, t, o);
5198        }
5199        if(o.target){
5200            h = createTargeted(h, o);
5201        }
5202        if(o.delay){
5203            h = createDelayed(h, o, fn);
5204        }
5205        if(o.single){
5206            h = createSingle(h, el, ename, fn, scope);
5207        }
5208        if(o.buffer){
5209            task = new Ext.util.DelayedTask(h);
5210            h = createBuffered(h, o, task);
5211        }
5212
5213        addListener(el, ename, fn, task, h, scope);
5214        return h;
5215    }
5216
5217    var pub = {
5218        
5219        addListener : function(element, eventName, fn, scope, options){
5220            if(typeof eventName == 'object'){
5221                var o = eventName, e, val;
5222                for(e in o){
5223                    val = o[e];
5224                    if(!propRe.test(e)){
5225                        if(Ext.isFunction(val)){
5226                            
5227                            listen(element, e, o, val, o.scope);
5228                        }else{
5229                            
5230                            listen(element, e, val);
5231                        }
5232                    }
5233                }
5234            } else {
5235                listen(element, eventName, options, fn, scope);
5236            }
5237        },
5238
5239        
5240        removeListener : function(el, eventName, fn, scope){
5241            el = Ext.getDom(el);
5242            var id = getId(el),
5243                f = el && (Ext.elCache[id].events)[eventName] || [],
5244                wrap, i, l, k, len, fnc;
5245
5246            for (i = 0, len = f.length; i < len; i++) {
5247
5248                
5249                if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
5250                    if(fnc[4]) {
5251                        fnc[4].cancel();
5252                    }
5253                    k = fn.tasks && fn.tasks.length;
5254                    if(k) {
5255                        while(k--) {
5256                            fn.tasks[k].cancel();
5257                        }
5258                        delete fn.tasks;
5259                    }
5260                    wrap = fnc[1];
5261                    E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
5262
5263                    
5264                    if(wrap && el.addEventListener && eventName == "mousewheel"){
5265                        el.removeEventListener("DOMMouseScroll", wrap, false);
5266                    }
5267
5268                    
5269                    if(wrap && el == DOC && eventName == "mousedown"){
5270                        Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
5271                    }
5272
5273                    f.splice(i, 1);
5274                    if (f.length === 0) {
5275                        delete Ext.elCache[id].events[eventName];
5276                    }
5277                    for (k in Ext.elCache[id].events) {
5278                        return false;
5279                    }
5280                    Ext.elCache[id].events = {};
5281                    return false;
5282                }
5283            }
5284        },
5285
5286        
5287        removeAll : function(el){
5288            el = Ext.getDom(el);
5289            var id = getId(el),
5290                ec = Ext.elCache[id] || {},
5291                es = ec.events || {},
5292                f, i, len, ename, fn, k, wrap;
5293
5294            for(ename in es){
5295                if(es.hasOwnProperty(ename)){
5296                    f = es[ename];
5297                    
5298                    for (i = 0, len = f.length; i < len; i++) {
5299                        fn = f[i];
5300                        if(fn[4]) {
5301                            fn[4].cancel();
5302                        }
5303                        if(fn[0].tasks && (k = fn[0].tasks.length)) {
5304                            while(k--) {
5305                                fn[0].tasks[k].cancel();
5306                            }
5307                            delete fn.tasks;
5308                        }
5309                        wrap =  fn[1];
5310                        E.un(el, ename, E.extAdapter ? fn[3] : wrap);
5311
5312                        
5313                        if(el.addEventListener && wrap && ename == "mousewheel"){
5314                            el.removeEventListener("DOMMouseScroll", wrap, false);
5315                        }
5316
5317                        
5318                        if(wrap && el == DOC &&  ename == "mousedown"){
5319                            Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
5320                        }
5321                    }
5322                }
5323            }
5324            if (Ext.elCache[id]) {
5325                Ext.elCache[id].events = {};
5326            }
5327        },
5328
5329        getListeners : function(el, eventName) {
5330            el = Ext.getDom(el);
5331            var id = getId(el),
5332                ec = Ext.elCache[id] || {},
5333                es = ec.events || {},
5334                results = [];
5335            if (es && es[eventName]) {
5336                return es[eventName];
5337            } else {
5338                return null;
5339            }
5340        },
5341
5342        purgeElement : function(el, recurse, eventName) {
5343            el = Ext.getDom(el);
5344            var id = getId(el),
5345                ec = Ext.elCache[id] || {},
5346                es = ec.events || {},
5347                i, f, len;
5348            if (eventName) {
5349                if (es && es.hasOwnProperty(eventName)) {
5350                    f = es[eventName];
5351                    for (i = 0, len = f.length; i < len; i++) {
5352                        Ext.EventManager.removeListener(el, eventName, f[i][0]);
5353                    }
5354                }
5355            } else {
5356                Ext.EventManager.removeAll(el);
5357            }
5358            if (recurse && el && el.childNodes) {
5359                for (i = 0, len = el.childNodes.length; i < len; i++) {
5360                    Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
5361                }
5362            }
5363        },
5364
5365        _unload : function() {
5366            var el;
5367            for (el in Ext.elCache) {
5368                Ext.EventManager.removeAll(el);
5369            }
5370            delete Ext.elCache;
5371            delete Ext.Element._flyweights;
5372
5373            
5374            var c,
5375                conn,
5376                tid,
5377                ajax = Ext.lib.Ajax;
5378            (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
5379            for (tid in conn) {
5380                c = conn[tid];
5381                if (c) {
5382                    ajax.abort({conn: c, tId: tid});
5383                }
5384            }
5385        },
5386        
5387        onDocumentReady : function(fn, scope, options){
5388            if (Ext.isReady) { 
5389                docReadyEvent || (docReadyEvent = new Ext.util.Event());
5390                docReadyEvent.addListener(fn, scope, options);
5391                docReadyEvent.fire();
5392                docReadyEvent.listeners = [];
5393            } else {
5394                if (!docReadyEvent) {
5395                    initDocReady();
5396                }
5397                options = options || {};
5398                options.delay = options.delay || 1;
5399                docReadyEvent.addListener(fn, scope, options);
5400            }
5401        },
5402
5403        
5404        fireDocReady  : fireDocReady
5405    };
5406     
5407    pub.on = pub.addListener;
5408    
5409    pub.un = pub.removeListener;
5410
5411    pub.stoppedMouseDownEvent = new Ext.util.Event();
5412    return pub;
5413}();
5414
5415Ext.onReady = Ext.EventManager.onDocumentReady;
5416
5417
5418
5419(function(){
5420    var initExtCss = function() {
5421        
5422        var bd = document.body || document.getElementsByTagName('body')[0];
5423        if (!bd) {
5424            return false;
5425        }
5426
5427        var cls = [' ',
5428                Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : (Ext.isIE8 ? 'ext-ie8' : 'ext-ie9')))
5429                : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
5430                : Ext.isOpera ? "ext-opera"
5431                : Ext.isWebKit ? "ext-webkit" : ""];
5432
5433        if (Ext.isSafari) {
5434            cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
5435        } else if(Ext.isChrome) {
5436            cls.push("ext-chrome");
5437        }
5438
5439        if (Ext.isMac) {
5440            cls.push("ext-mac");
5441        }
5442        if (Ext.isLinux) {
5443            cls.push("ext-linux");
5444        }
5445
5446        
5447        if (Ext.isStrict || Ext.isBorderBox) {
5448            var p = bd.parentNode;
5449            if (p) {
5450                if (!Ext.isStrict) {
5451                    Ext.fly(p, '_internal').addClass('x-quirks');
5452                    if (Ext.isIE && !Ext.isStrict) {
5453                        Ext.isIEQuirks = true;
5454                    }
5455                }
5456                Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box');
5457            }
5458        }
5459        
5460        
5461        if (Ext.enableForcedBoxModel && !Ext.isIE) {
5462            Ext.isForcedBorderBox = true;
5463            cls.push("ext-forced-border-box");
5464        }
5465        
5466        Ext.fly(bd, '_internal').addClass(cls);
5467        return true;
5468    };
5469    
5470    if (!initExtCss()) {
5471        Ext.onReady(initExtCss);
5472    }
5473})();
5474
5475
5476(function(){
5477    var supports = Ext.apply(Ext.supports, {
5478        
5479        correctRightMargin: true,
5480        
5481        
5482        correctTransparentColor: true,
5483        
5484        
5485        cssFloat: true
5486    });
5487    
5488    var supportTests = function(){
5489            var div = document.createElement('div'),
5490                doc = document,
5491                view,
5492                last;
5493                
5494            div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
5495            doc.body.appendChild(div);
5496            last = div.lastChild;
5497            
5498            if((view = doc.defaultView)){
5499                if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
5500                    supports.correctRightMargin = false;
5501                }
5502                if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
5503                    supports.correctTransparentColor = false;
5504                }
5505            }
5506            supports.cssFloat = !!last.style.cssFloat;
5507            doc.body.removeChild(div);
5508    };
5509    
5510    if (Ext.isReady) {
5511        supportTests();    
5512    } else {
5513        Ext.onReady(supportTests);
5514    }
5515})();
5516
5517
5518
5519Ext.EventObject = function(){
5520    var E = Ext.lib.Event,
5521        clickRe = /(dbl)?click/,
5522        
5523        safariKeys = {
5524            3 : 13, 
5525            63234 : 37, 
5526            63235 : 39, 
5527            63232 : 38, 
5528            63233 : 40, 
5529            63276 : 33, 
5530            63277 : 34, 
5531            63272 : 46, 
5532            63273 : 36, 
5533            63275 : 35  
5534        },
5535        
5536        btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
5537
5538    Ext.EventObjectImpl = function(e){
5539        if(e){
5540            this.setEvent(e.browserEvent || e);
5541        }
5542    };
5543
5544    Ext.EventObjectImpl.prototype = {
5545           
5546        setEvent : function(e){
5547            var me = this;
5548            if(e == me || (e && e.browserEvent)){ 
5549                return e;
5550            }
5551            me.browserEvent = e;
5552            if(e){
5553                
5554                me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
5555                if(clickRe.test(e.type) && me.button == -1){
5556                    me.button = 0;
5557                }
5558                me.type = e.type;
5559                me.shiftKey = e.shiftKey;
5560                
5561                me.ctrlKey = e.ctrlKey || e.metaKey || false;
5562                me.altKey = e.altKey;
5563                
5564                me.keyCode = e.keyCode;
5565                me.charCode = e.charCode;
5566                
5567                me.target = E.getTarget(e);
5568                
5569                me.xy = E.getXY(e);
5570            }else{
5571                me.button = -1;
5572                me.shiftKey = false;
5573                me.ctrlKey = false;
5574                me.altKey = false;
5575                me.keyCode = 0;
5576                me.charCode = 0;
5577                me.target = null;
5578                me.xy = [0, 0];
5579            }
5580            return me;
5581        },
5582
5583        
5584        stopEvent : function(){
5585            var me = this;
5586            if(me.browserEvent){
5587                if(me.browserEvent.type == 'mousedown'){
5588                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
5589                }
5590                E.stopEvent(me.browserEvent);
5591            }
5592        },
5593
5594        
5595        preventDefault : function(){
5596            if(this.browserEvent){
5597                E.preventDefault(this.browserEvent);
5598            }
5599        },
5600
5601        
5602        stopPropagation : function(){
5603            var me = this;
5604            if(me.browserEvent){
5605                if(me.browserEvent.type == 'mousedown'){
5606                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
5607                }
5608                E.stopPropagation(me.browserEvent);
5609            }
5610        },
5611
5612        
5613        getCharCode : function(){
5614            return this.charCode || this.keyCode;
5615        },
5616
5617        
5618        getKey : function(){
5619            return this.normalizeKey(this.keyCode || this.charCode);
5620        },
5621
5622        
5623        normalizeKey: function(k){
5624            return Ext.isSafari ? (safariKeys[k] || k) : k;
5625        },
5626
5627        
5628        getPageX : function(){
5629            return this.xy[0];
5630        },
5631
5632        
5633        getPageY : function(){
5634            return this.xy[1];
5635        },
5636
5637        
5638        getXY : function(){
5639            return this.xy;
5640        },
5641
5642        
5643        getTarget : function(selector, maxDepth, returnEl){
5644            return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
5645        },
5646
5647        
5648        getRelatedTarget : function(){
5649            return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
5650        },
5651
5652        
5653        getWheelDelta : function(){
5654            var e = this.browserEvent;
5655            var delta = 0;
5656            if(e.wheelDelta){ 
5657                delta = e.wheelDelta/120;
5658            }else if(e.detail){ 
5659                delta = -e.detail/3;
5660            }
5661            return delta;
5662        },
5663
5664        
5665        within : function(el, related, allowEl){
5666            if(el){
5667                var t = this[related ? "getRelatedTarget" : "getTarget"]();
5668                return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
5669            }
5670            return false;
5671        }
5672     };
5673
5674    return new Ext.EventObjectImpl();
5675}();
5676Ext.Loader = Ext.apply({}, {
5677    
5678    load: function(fileList, callback, scope, preserveOrder) {
5679        var scope       = scope || this,
5680            head        = document.getElementsByTagName("head")[0],
5681            fragment    = document.createDocumentFragment(),
5682            numFiles    = fileList.length,
5683            loadedFiles = 0,
5684            me          = this;
5685        
5686        
5687        var loadFileIndex = function(index) {
5688            head.appendChild(
5689                me.buildScriptTag(fileList[index], onFileLoaded)
5690            );
5691        };
5692        
5693        
5694        var onFileLoaded = function() {
5695            loadedFiles ++;
5696            
5697            
5698            if (numFiles == loadedFiles && typeof callback == 'function') {
5699                callback.call(scope);
5700            } else {
5701                if (preserveOrder === true) {
5702                    loadFileIndex(loadedFiles);
5703                }
5704            }
5705        };
5706        
5707        if (preserveOrder === true) {
5708            loadFileIndex.call(this, 0);
5709        } else {
5710            
5711            Ext.each(fileList, function(file, index) {
5712                fragment.appendChild(
5713                    this.buildScriptTag(file, onFileLoaded)
5714                );  
5715            }, this);
5716            
5717            head.appendChild(fragment);
5718        }
5719    },
5720    
5721    
5722    buildScriptTag: function(filename, callback) {
5723        var script  = document.createElement('script');
5724        script.type = "text/javascript";
5725        script.src  = filename;
5726        
5727        
5728        if (script.readyState) {
5729            script.onreadystatechange = function() {
5730                if (script.readyState == "loaded" || script.readyState == "complete") {
5731                    script.onreadystatechange = null;
5732                    callback();
5733                }
5734            };
5735        } else {
5736            script.onload = callback;
5737        }    
5738        
5739        return script;
5740    }
5741});
5742
5743
5744Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
5745       "Ext.state", "Ext.layout.boxOverflow", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct", "Ext.slider");
5746    
5747
5748Ext.apply(Ext, function(){
5749    var E = Ext,
5750        idSeed = 0,
5751        scrollWidth = null;
5752
5753    return {
5754        
5755        emptyFn : function(){},
5756
5757        
5758        BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
5759                            'http:/' + '/www.extjs.com/s.gif' :
5760                            'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
5761
5762        extendX : function(supr, fn){
5763            return Ext.extend(supr, fn(supr.prototype));
5764        },
5765
5766        
5767        getDoc : function(){
5768            return Ext.get(document);
5769        },
5770
5771        
5772        num : function(v, defaultValue){
5773            v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
5774            return isNaN(v) ? defaultValue : v;
5775        },
5776
5777        
5778        value : function(v, defaultValue, allowBlank){
5779            return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
5780        },
5781
5782        
5783        escapeRe : function(s) {
5784            return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
5785        },
5786
5787        sequence : function(o, name, fn, scope){
5788            o[name] = o[name].createSequence(fn, scope);
5789        },
5790
5791        
5792        addBehaviors : function(o){
5793            if(!Ext.isReady){
5794                Ext.onReady(function(){
5795                    Ext.addBehaviors(o);
5796                });
5797            } else {
5798                var cache = {}, 
5799                    parts,
5800                    b,
5801                    s;
5802                for (b in o) {
5803                    if ((parts = b.split('@'))[1]) { 
5804                        s = parts[0];
5805                        if(!cache[s]){
5806                            cache[s] = Ext.select(s);
5807                        }
5808                        cache[s].on(parts[1], o[b]);
5809                    }
5810                }
5811                cache = null;
5812            }
5813        },
5814
5815        
5816        getScrollBarWidth: function(force){
5817            if(!Ext.isReady){
5818                return 0;
5819            }
5820
5821            if(force === true || scrollWidth === null){
5822                    
5823                var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
5824                    child = div.child('div', true);
5825                var w1 = child.offsetWidth;
5826                div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
5827                var w2 = child.offsetWidth;
5828                div.remove();
5829                
5830                scrollWidth = w1 - w2 + 2;
5831            }
5832            return scrollWidth;
5833        },
5834
5835
5836        
5837        combine : function(){
5838            var as = arguments, l = as.length, r = [];
5839            for(var i = 0; i < l; i++){
5840                var a = as[i];
5841                if(Ext.isArray(a)){
5842                    r = r.concat(a);
5843                }else if(a.length !== undefined && !a.substr){
5844                    r = r.concat(Array.prototype.slice.call(a, 0));
5845                }else{
5846                    r.push(a);
5847                }
5848            }
5849            return r;
5850        },
5851
5852        
5853        copyTo : function(dest, source, names){
5854            if(typeof names == 'string'){
5855                names = names.split(/[,;\s]/);
5856            }
5857            Ext.each(names, function(name){
5858                if(source.hasOwnProperty(name)){
5859                    dest[name] = source[name];
5860                }
5861            }, this);
5862            return dest;
5863        },
5864
5865        
5866        destroy : function(){
5867            Ext.each(arguments, function(arg){
5868                if(arg){
5869                    if(Ext.isArray(arg)){
5870                        this.destroy.apply(this, arg);
5871                    }else if(typeof arg.destroy == 'function'){
5872                        arg.destroy();
5873                    }else if(arg.dom){
5874                        arg.remove();
5875                    }
5876                }
5877            }, this);
5878        },
5879
5880        
5881        destroyMembers : function(o, arg1, arg2, etc){
5882            for(var i = 1, a = arguments, len = a.length; i < len; i++) {
5883                Ext.destroy(o[a[i]]);
5884                delete o[a[i]];
5885            }
5886        },
5887
5888        
5889        clean : function(arr){
5890            var ret = [];
5891            Ext.each(arr, function(v){
5892                if(!!v){
5893                    ret.push(v);
5894                }
5895            });
5896            return ret;
5897        },
5898
5899        
5900        unique : function(arr){
5901            var ret = [],
5902                collect = {};
5903
5904            Ext.each(arr, function(v) {
5905                if(!collect[v]){
5906                    ret.push(v);
5907                }
5908                collect[v] = true;
5909            });
5910            return ret;
5911        },
5912
5913        
5914        flatten : function(arr){
5915            var worker = [];
5916            function rFlatten(a) {
5917                Ext.each(a, function(v) {
5918                    if(Ext.isArray(v)){
5919                        rFlatten(v);
5920                    }else{
5921                        worker.push(v);
5922                    }
5923                });
5924                return worker;
5925            }
5926            return rFlatten(arr);
5927        },
5928
5929        
5930        min : function(arr, comp){
5931            var ret = arr[0];
5932            comp = comp || function(a,b){ return a < b ? -1 : 1; };
5933            Ext.each(arr, function(v) {
5934                ret = comp(ret, v) == -1 ? ret : v;
5935            });
5936            return ret;
5937        },
5938
5939        
5940        max : function(arr, comp){
5941            var ret = arr[0];
5942            comp = comp || function(a,b){ return a > b ? 1 : -1; };
5943            Ext.each(arr, function(v) {
5944                ret = comp(ret, v) == 1 ? ret : v;
5945            });
5946            return ret;
5947        },
5948
5949        
5950        mean : function(arr){
5951           return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
5952        },
5953
5954        
5955        sum : function(arr){
5956           var ret = 0;
5957           Ext.each(arr, function(v) {
5958               ret += v;
5959           });
5960           return ret;
5961        },
5962
5963        
5964        partition : function(arr, truth){
5965            var ret = [[],[]];
5966            Ext.each(arr, function(v, i, a) {
5967                ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
5968            });
5969            return ret;
5970        },
5971
5972        
5973        invoke : function(arr, methodName){
5974            var ret = [],
5975                args = Array.prototype.slice.call(arguments, 2);
5976            Ext.each(arr, function(v,i) {
5977                if (v && typeof v[methodName] == 'function') {
5978                    ret.push(v[methodName].apply(v, args));
5979                } else {
5980                    ret.push(undefined);
5981                }
5982            });
5983            return ret;
5984        },
5985
5986        
5987        pluck : function(arr, prop){
5988            var ret = [];
5989            Ext.each(arr, function(v) {
5990                ret.push( v[prop] );
5991            });
5992            return ret;
5993        },
5994
5995        
5996        zip : function(){
5997            var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
5998                arrs = parts[0],
5999                fn = parts[1][0],
6000                len = Ext.max(Ext.pluck(arrs, "length")),
6001                ret = [];
6002
6003            for (var i = 0; i < len; i++) {
6004                ret[i] = [];
6005                if(fn){
6006                    ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
6007                }else{
6008                    for (var j = 0, aLen = arrs.length; j < aLen; j++){
6009                        ret[i].push( arrs[j][i] );
6010                    }
6011                }
6012            }
6013            return ret;
6014        },
6015
6016        
6017        getCmp : function(id){
6018            return Ext.ComponentMgr.get(id);
6019        },
6020
6021        
6022        useShims: E.isIE6 || (E.isMac && E.isGecko2),
6023
6024        
6025        
6026        type : function(o){
6027            if(o === undefined || o === null){
6028                return false;
6029            }
6030            if(o.htmlElement){
6031                return 'element';
6032            }
6033            var t = typeof o;
6034            if(t == 'object' && o.nodeName) {
6035                switch(o.nodeType) {
6036                    case 1: return 'element';
6037                    case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
6038                }
6039            }
6040            if(t == 'object' || t == 'function') {
6041                switch(o.constructor) {
6042                    case Array: return 'array';
6043                    case RegExp: return 'regexp';
6044                    case Date: return 'date';
6045                }
6046                if(typeof o.length == 'number' && typeof o.item == 'function') {
6047                    return 'nodelist';
6048                }
6049            }
6050            return t;
6051        },
6052
6053        intercept : function(o, name, fn, scope){
6054            o[name] = o[name].createInterceptor(fn, scope);
6055        },
6056
6057        
6058        callback : function(cb, scope, args, delay){
6059            if(typeof cb == 'function'){
6060                if(delay){
6061                    cb.defer(delay, scope, args || []);
6062                }else{
6063                    cb.apply(scope, args || []);
6064                }
6065            }
6066        }
6067    };
6068}());
6069
6070
6071Ext.apply(Function.prototype, {
6072    
6073    createSequence : function(fcn, scope){
6074        var method = this;
6075        return (typeof fcn != 'function') ?
6076                this :
6077                function(){
6078                    var retval = method.apply(this || window, arguments);
6079                    fcn.apply(scope || this || window, arguments);
6080                    return retval;
6081                };
6082    }
6083});
6084
6085
6086
6087Ext.applyIf(String, {
6088
6089    
6090    escape : function(string) {
6091        return string.replace(/('|\\)/g, "\\$1");
6092    },
6093
6094    
6095    leftPad : function (val, size, ch) {
6096        var result = String(val);
6097        if(!ch) {
6098            ch = " ";
6099        }
6100        while (result.length < size) {
6101            result = ch + result;
6102        }
6103        return result;
6104    }
6105});
6106
6107
6108String.prototype.toggle = function(value, other){
6109    return this == value ? other : value;
6110};
6111
6112
6113String.prototype.trim = function(){
6114    var re = /^\s+|\s+$/g;
6115    return function(){ return this.replace(re, ""); };
6116}();
6117
6118
6119
6120Date.prototype.getElapsed = function(date) {
6121    return Math.abs((date || new Date()).getTime()-this.getTime());
6122};
6123
6124
6125
6126Ext.applyIf(Number.prototype, {
6127    
6128    constrain : function(min, max){
6129        return Math.min(Math.max(this, min), max);
6130    }
6131});
6132Ext.lib.Dom.getRegion = function(el) {
6133    return Ext.lib.Region.getRegion(el);
6134};	Ext.lib.Region = function(t, r, b, l) {
6135		var me = this;
6136        me.top = t;
6137        me[1] = t;
6138        me.right = r;
6139        me.bottom = b;
6140        me.left = l;
6141        me[0] = l;
6142    };
6143
6144    Ext.lib.Region.prototype = {
6145        contains : function(region) {
6146	        var me = this;
6147            return ( region.left >= me.left &&
6148                     region.right <= me.right &&
6149                     region.top >= me.top &&
6150                     region.bottom <= me.bottom );
6151
6152        },
6153
6154        getArea : function() {
6155	        var me = this;
6156            return ( (me.bottom - me.top) * (me.right - me.left) );
6157        },
6158
6159        intersect : function(region) {
6160            var me = this,
6161            	t = Math.max(me.top, region.top),
6162            	r = Math.min(me.right, region.right),
6163            	b = Math.min(me.bottom, region.bottom),
6164            	l = Math.max(me.left, region.left);
6165
6166            if (b >= t && r >= l) {
6167                return new Ext.lib.Region(t, r, b, l);
6168            }
6169        },
6170        
6171        union : function(region) {
6172	        var me = this,
6173            	t = Math.min(me.top, region.top),
6174            	r = Math.max(me.right, region.right),
6175            	b = Math.max(me.bottom, region.bottom),
6176            	l = Math.min(me.left, region.left);
6177
6178            return new Ext.lib.Region(t, r, b, l);
6179        },
6180
6181        constrainTo : function(r) {
6182	        var me = this;
6183            me.top = me.top.constrain(r.top, r.bottom);
6184            me.bottom = me.bottom.constrain(r.top, r.bottom);
6185            me.left = me.left.constrain(r.left, r.right);
6186            me.right = me.right.constrain(r.left, r.right);
6187            return me;
6188        },
6189
6190        adjust : function(t, l, b, r) {
6191	        var me = this;
6192            me.top += t;
6193            me.left += l;
6194            me.right += r;
6195            me.bottom += b;
6196            return me;
6197        }
6198    };
6199
6200    Ext.lib.Region.getRegion = function(el) {
6201        var p = Ext.lib.Dom.getXY(el),
6202        	t = p[1],
6203        	r = p[0] + el.offsetWidth,
6204        	b = p[1] + el.offsetHeight,
6205        	l = p[0];
6206
6207        return new Ext.lib.Region(t, r, b, l);
6208    };	Ext.lib.Point = function(x, y) {
6209        if (Ext.isArray(x)) {
6210            y = x[1];
6211            x = x[0];
6212        }
6213        var me = this;
6214        me.x = me.right = me.left = me[0] = x;
6215        me.y = me.top = me.bottom = me[1] = y;
6216    };
6217
6218    Ext.lib.Point.prototype = new Ext.lib.Region();
6219
6220Ext.apply(Ext.DomHelper,
6221function(){
6222    var pub,
6223        afterbegin = 'afterbegin',
6224        afterend = 'afterend',
6225        beforebegin = 'beforebegin',
6226        beforeend = 'beforeend',
6227        confRe = /tag|children|cn|html$/i;
6228
6229    
6230    function doInsert(el, o, returnElement, pos, sibling, append){
6231        el = Ext.getDom(el);
6232        var newNode;
6233        if (pub.useDom) {
6234            newNode = createDom(o, null);
6235            if (append) {
6236                el.appendChild(newNode);
6237            } else {
6238                (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
6239            }
6240        } else {
6241            newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
6242        }
6243        return returnElement ? Ext.get(newNode, true) : newNode;
6244    }
6245
6246    
6247    
6248    function createDom(o, parentNode){
6249        var el,
6250            doc = document,
6251            useSet,
6252            attr,
6253            val,
6254            cn;
6255
6256        if (Ext.isArray(o)) {                       
6257            el = doc.createDocumentFragment(); 
6258            for (var i = 0, l = o.length; i < l; i++) {
6259                createDom(o[i], el);
6260            }
6261        } else if (typeof o == 'string') {         
6262            el = doc.createTextNode(o);
6263        } else {
6264            el = doc.createElement( o.tag || 'div' );
6265            useSet = !!el.setAttribute; 
6266            for (var attr in o) {
6267                if(!confRe.test(attr)){
6268                    val = o[attr];
6269                    if(attr == 'cls'){
6270                        el.className = val;
6271                    }else{
6272                        if(useSet){
6273                            el.setAttribute(attr, val);
6274                        }else{
6275                            el[attr] = val;
6276                        }
6277                    }
6278                }
6279            }
6280            Ext.DomHelper.applyStyles(el, o.style);
6281
6282            if ((cn = o.children || o.cn)) {
6283                createDom(cn, el);
6284            } else if (o.html) {
6285                el.innerHTML = o.html;
6286            }
6287        }
6288        if(parentNode){
6289           parentNode.appendChild(el);
6290        }
6291        return el;
6292    }
6293
6294    pub = {
6295        
6296        createTemplate : function(o){
6297            var html = Ext.DomHelper.createHtml(o);
6298            return new Ext.Template(html);
6299        },
6300
6301        
6302        useDom : false,
6303
6304        
6305        insertBefore : function(el, o, returnElement){
6306            return doInsert(el, o, returnElement, beforebegin);
6307        },
6308
6309        
6310        insertAfter : function(el, o, returnElement){
6311            return doInsert(el, o, returnElement, afterend, 'nextSibling');
6312        },
6313
6314        
6315        insertFirst : function(el, o, returnElement){
6316            return doInsert(el, o, returnElement, afterbegin, 'firstChild');
6317        },
6318
6319        
6320        append: function(el, o, returnElement){
6321            return doInsert(el, o, returnElement, beforeend, '', true);
6322        },
6323
6324        
6325        createDom: createDom
6326    };
6327    return pub;
6328}());
6329
6330Ext.apply(Ext.Template.prototype, {
6331    
6332    disableFormats : false,
6333    
6334
6335    
6336    re : /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
6337    argsRe : /^\s*['"](.*)["']\s*$/,
6338    compileARe : /\\/g,
6339    compileBRe : /(\r\n|\n)/g,
6340    compileCRe : /'/g,
6341
6342    /**
6343     * Returns an HTML fragment of this template with the specified values applied.
6344     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
6345     * @return {String} The HTML fragment
6346     * @hide repeat doc
6347     */
6348    applyTemplate : function(values){
6349        var me = this,
6350            useF = me.disableFormats !== true,
6351            fm = Ext.util.Format,
6352            tpl = me;
6353
6354        if(me.compiled){
6355            return me.compiled(values);
6356        }
6357        function fn(m, name, format, args){
6358            if (format && useF) {
6359                if (format.substr(0, 5) == "this.") {
6360                    return tpl.call(format.substr(5), values[name], values);
6361                } else {
6362                    if (args) {
6363                        // quoted values are required for strings in compiled templates,
6364                        // but for non compiled we need to strip them
6365                        // quoted reversed for jsmin
6366                        var re = me.argsRe;
6367                        args = args.split(',');
6368                        for(var i = 0, len = args.length; i < len; i++){
6369                            args[i] = args[i].replace(re, "$1");
6370                        }
6371                        args = [values[name]].concat(args);
6372                    } else {
6373                        args = [values[name]];
6374                    }
6375                    return fm[format].apply(fm, args);
6376                }
6377            } else {
6378                return values[name] !== undefined ? values[name] : "";
6379            }
6380        }
6381        return me.html.replace(me.re, fn);
6382    },
6383
6384    /**
6385     * Compiles the template into an internal function, eliminating the RegEx overhead.
6386     * @return {Ext.Template} this
6387     * @hide repeat doc
6388     */
6389    compile : function(){
6390        var me = this,
6391            fm = Ext.util.Format,
6392            useF = me.disableFormats !== true,
6393            sep = Ext.isGecko ? "+" : ",",
6394            body;
6395
6396        function fn(m, name, format, args){
6397            if(format && useF){
6398                args = args ? ',' + args : "";
6399                if(format.substr(0, 5) != "this."){
6400                    format = "fm." + format + '(';
6401                }else{
6402                    format = 'this.call("'+ format.substr(5) + '", ';
6403                    args = ", values";
6404                }
6405            }else{
6406                args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
6407            }
6408            return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
6409        }
6410
6411        // branched to use + in gecko and [].join() in others
6412        if(Ext.isGecko){
6413            body = "this.compiled = function(values){ return '" +
6414                   me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
6415                    "';};";
6416        }else{
6417            body = ["this.compiled = function(values){ return ['"];
6418            body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
6419            body.push("'].join('');};");
6420            body = body.join('');
6421        }
6422        eval(body);
6423        return me;
6424    },
6425
6426    // private function used to call members
6427    call : function(fnName, value, allValues){
6428        return this[fnName](value, allValues);
6429    }
6430});
6431Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
6432/**
6433 * @class Ext.util.Functions
6434 * @singleton
6435 */
6436Ext.util.Functions = {
6437    /**
6438     * Creates an interceptor function. The passed function is called before the original one. If it returns false,
6439     * the original one is not called. The resulting function returns the results of the original function.
6440     * The passed function is called with the parameters of the original function. Example usage:
6441     * <pre><code>
6442var sayHi = function(name){
6443    alert('Hi, ' + name);
6444}
6445
6446sayHi('Fred'); // alerts "Hi, Fred"
6447
6448// create a new function that validates input without
6449// directly modifying the original function:
6450var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
6451    return name == 'Brian';
6452});
6453
6454sayHiToFriend('Fred');  // no alert
6455sayHiToFriend('Brian'); // alerts "Hi, Brian"
6456       </code></pre>
6457     * @param {Function} origFn The original function.
6458     * @param {Function} newFn The function to call before the original
6459     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
6460     * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
6461     * @return {Function} The new function
6462     */
6463    createInterceptor: function(origFn, newFn, scope) { 
6464        var method = origFn;
6465        if (!Ext.isFunction(newFn)) {
6466            return origFn;
6467        }
6468        else {
6469            return function() {
6470                var me = this,
6471                    args = arguments;
6472                newFn.target = me;
6473                newFn.method = origFn;
6474                return (newFn.apply(scope || me || window, args) !== false) ?
6475                        origFn.apply(me || window, args) :
6476                        null;
6477            };
6478        }
6479    },
6480
6481    /**
6482     * Creates a delegate (callback) that sets the scope to obj.
6483     * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
6484     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
6485     * callback points to obj. Example usage:
6486     * <pre><code>
6487var sayHi = function(name){
6488    // Note this use of "this.text" here.  This function expects to
6489    // execute within a scope that contains a text property.  In this
6490    // example, the "this" variable is pointing to the btn object that
6491    // was passed in createDelegate below.
6492    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
6493}
6494
6495var btn = new Ext.Button({
6496    text: 'Say Hi',
6497    renderTo: Ext.getBody()
6498});
6499
6500// This callback will execute in the scope of the
6501// button instance. Clicking the button alerts
6502// "Hi, Fred. You clicked the "Say Hi" button."
6503btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
6504       </code></pre>
6505     * @param {Function} fn The function to delegate.
6506     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6507     * <b>If omitted, defaults to the browser window.</b>
6508     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6509     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6510     * if a number the args are inserted at the specified position
6511     * @return {Function} The new function
6512     */
6513    createDelegate: function(fn, obj, args, appendArgs) {
6514        if (!Ext.isFunction(fn)) {
6515            return fn;
6516        }
6517        return function() {
6518            var callArgs = args || arguments;
6519            if (appendArgs === true) {
6520                callArgs = Array.prototype.slice.call(arguments, 0);
6521                callArgs = callArgs.concat(args);
6522            }
6523            else if (Ext.isNumber(appendArgs)) {
6524                callArgs = Array.prototype.slice.call(arguments, 0);
6525                // copy arguments first
6526                var applyArgs = [appendArgs, 0].concat(args);
6527                // create method call params
6528                Array.prototype.splice.apply(callArgs, applyArgs);
6529                // splice them in
6530            }
6531            return fn.apply(obj || window, callArgs);
6532        };
6533    },
6534
6535    /**
6536     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
6537     * <pre><code>
6538var sayHi = function(name){
6539    alert('Hi, ' + name);
6540}
6541
6542// executes immediately:
6543sayHi('Fred');
6544
6545// executes after 2 seconds:
6546Ext.defer(sayHi, 2000, this, ['Fred']);
6547
6548// this syntax is sometimes useful for deferring
6549// execution of an anonymous function:
6550Ext.defer(function(){
6551    alert('Anonymous');
6552}, 100);
6553       </code></pre>
6554     * @param {Function} fn The function to defer.
6555     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
6556     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6557     * <b>If omitted, defaults to the browser window.</b>
6558     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6559     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6560     * if a number the args are inserted at the specified position
6561     * @return {Number} The timeout id that can be used with clearTimeout
6562     */
6563    defer: function(fn, millis, obj, args, appendArgs) {
6564        fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
6565        if (millis > 0) {
6566            return setTimeout(fn, millis);
6567        }
6568        fn();
6569        return 0;
6570    },
6571
6572
6573    /**
6574     * Create a combined function call sequence of the original function + the passed function.
6575     * The resulting function returns the results of the original function.
6576     * The passed fcn is called with the parameters of the original function. Example usage:
6577     * 
6578
6579var sayHi = function(name){
6580    alert('Hi, ' + name);
6581}
6582
6583sayHi('Fred'); // alerts "Hi, Fred"
6584
6585var sayGoodbye = Ext.createSequence(sayHi, function(name){
6586    alert('Bye, ' + name);
6587});
6588
6589sayGoodbye('Fred'); // both alerts show
6590
6591     * @param {Function} origFn The original function.
6592     * @param {Function} newFn The function to sequence
6593     * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
6594     * If omitted, defaults to the scope in which the original function is called or the browser window.
6595     * @return {Function} The new function
6596     */
6597    createSequence: function(origFn, newFn, scope) {
6598        if (!Ext.isFunction(newFn)) {
6599            return origFn;
6600        }
6601        else {
6602            return function() {
6603                var retval = origFn.apply(this || window, arguments);
6604                newFn.apply(scope || this || window, arguments);
6605                return retval;
6606            };
6607        }
6608    }
6609};
6610
6611/**
6612 * Shorthand for {@link Ext.util.Functions#defer}   
6613 * @param {Function} fn The function to defer.
6614 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
6615 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6616 * <b>If omitted, defaults to the browser window.</b>
6617 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6618 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6619 * if a number the args are inserted at the specified position
6620 * @return {Number} The timeout id that can be used with clearTimeout
6621 * @member Ext
6622 * @method defer
6623 */
6624
6625Ext.defer = Ext.util.Functions.defer;
6626
6627/**
6628 * Shorthand for {@link Ext.util.Functions#createInterceptor}   
6629 * @param {Function} origFn The original function.
6630 * @param {Function} newFn The function to call before the original
6631 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
6632 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
6633 * @return {Function} The new function
6634 * @member Ext
6635 * @method defer
6636 */
6637
6638Ext.createInterceptor = Ext.util.Functions.createInterceptor;
6639
6640/**
6641 * Shorthand for {@link Ext.util.Functions#createSequence}
6642 * @param {Function} origFn The original function.
6643 * @param {Function} newFn The function to sequence
6644 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
6645 * If omitted, defaults to the scope in which the original function is called or the browser window.
6646 * @return {Function} The new function
6647 * @member Ext
6648 * @method defer
6649 */
6650
6651Ext.createSequence = Ext.util.Functions.createSequence;
6652
6653/**
6654 * Shorthand for {@link Ext.util.Functions#createDelegate}
6655 * @param {Function} fn The function to delegate.
6656 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6657 * <b>If omitted, defaults to the browser window.</b>
6658 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6659 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6660 * if a number the args are inserted at the specified position
6661 * @return {Function} The new function
6662 * @member Ext
6663 * @method defer
6664 */
6665Ext.createDelegate = Ext.util.Functions.createDelegate;
6666/**
6667 * @class Ext.util.Observable
6668 */
6669Ext.apply(Ext.util.Observable.prototype, function(){
6670    // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
6671    // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6672    // private
6673    function getMethodEvent(method){
6674        var e = (this.methodEvents = this.methodEvents ||
6675        {})[method], returnValue, v, cancel, obj = this;
6676
6677        if (!e) {
6678            this.methodEvents[method] = e = {};
6679            e.originalFn = this[method];
6680            e.methodName = method;
6681            e.before = [];
6682            e.after = [];
6683
6684            var makeCall = function(fn, scope, args){
6685                if((v = fn.apply(scope || obj, args)) !== undefined){
6686                    if (typeof v == 'object') {
6687                        if(v.returnValue !== undefined){
6688                            returnValue = v.returnValue;
6689                        }else{
6690                            returnValue = v;
6691                        }
6692                        cancel = !!v.cancel;
6693                    }
6694                    else
6695                        if (v === false) {
6696                            cancel = true;
6697                        }
6698                        else {
6699                            returnValue = v;
6700                        }
6701                }
6702            };
6703
6704            this[method] = function(){
6705                var args = Array.prototype.slice.call(arguments, 0),
6706                    b;
6707                returnValue = v = undefined;
6708                cancel = false;
6709
6710                for(var i = 0, len = e.before.length; i < len; i++){
6711                    b = e.before[i];
6712                    makeCall(b.fn, b.scope, args);
6713                    if (cancel) {
6714                        return returnValue;
6715                    }
6716                }
6717
6718                if((v = e.originalFn.apply(obj, args)) !== undefined){
6719                    returnValue = v;
6720                }
6721
6722                for(var i = 0, len = e.after.length; i < len; i++){
6723                    b = e.after[i];
6724                    makeCall(b.fn, b.scope, args);
6725                    if (cancel) {
6726                        return returnValue;
6727                    }
6728                }
6729                return returnValue;
6730            };
6731        }
6732        return e;
6733    }
6734
6735    return {
6736        // these are considered experimental
6737        // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6738        // adds an 'interceptor' called before the original method
6739        beforeMethod : function(method, fn, scope){
6740            getMethodEvent.call(this, method).before.push({
6741                fn: fn,
6742                scope: scope
6743            });
6744        },
6745
6746        // adds a 'sequence' called after the original method
6747        afterMethod : function(method, fn, scope){
6748            getMethodEvent.call(this, method).after.push({
6749                fn: fn,
6750                scope: scope
6751            });
6752        },
6753
6754        removeMethodListener: function(method, fn, scope){
6755            var e = this.getMethodEvent(method);
6756            for(var i = 0, len = e.before.length; i < len; i++){
6757                if(e.before[i].fn == fn && e.before[i].scope == scope){
6758                    e.before.splice(i, 1);
6759                    return;
6760                }
6761            }
6762            for(var i = 0, len = e.after.length; i < len; i++){
6763                if(e.after[i].fn == fn && e.after[i].scope == scope){
6764                    e.after.splice(i, 1);
6765                    return;
6766                }
6767            }
6768        },
6769
6770        /**
6771         * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
6772         * @param {Object} o The Observable whose events this object is to relay.
6773         * @param {Array} events Array of event names to relay.
6774         */
6775        relayEvents : function(o, events){
6776            var me = this;
6777            function createHandler(ename){
6778                return function(){
6779                    return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
6780                };
6781            }
6782            for(var i = 0, len = events.length; i < len; i++){
6783                var ename = events[i];
6784                me.events[ename] = me.events[ename] || true;
6785                o.on(ename, createHandler(ename), me);
6786            }
6787        },
6788
6789        /**
6790         * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
6791         * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
6792         * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
6793         * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
6794         * access the required target more quickly.</p>
6795         * <p>Example:</p><pre><code>
6796Ext.override(Ext.form.Field, {
6797    
6798    initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
6799        this.enableBubble('change');
6800    }),
6801
6802    
6803    getBubbleTarget : function() {
6804        if (!this.formPanel) {
6805            this.formPanel = this.findParentByType('form');
6806        }
6807        return this.formPanel;
6808    }
6809});
6810
6811var myForm = new Ext.formPanel({
6812    title: 'User Details',
6813    items: [{
6814        ...
6815    }],
6816    listeners: {
6817        change: function() {
6818            
6819            myForm.header.setStyle('color', 'red');
6820        }
6821    }
6822});
6823</code></pre>
6824         * @param {String/Array} events The event name to bubble, or an Array of event names.
6825         */
6826        enableBubble : function(events){
6827            var me = this;
6828            if(!Ext.isEmpty(events)){
6829                events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
6830                for(var i = 0, len = events.length; i < len; i++){
6831                    var ename = events[i];
6832                    ename = ename.toLowerCase();
6833                    var ce = me.events[ename] || true;
6834                    if (typeof ce == 'boolean') {
6835                        ce = new Ext.util.Event(me, ename);
6836                        me.events[ename] = ce;
6837                    }
6838                    ce.bubble = true;
6839                }
6840            }
6841        }
6842    };
6843}());
6844
6845
6846
6847Ext.util.Observable.capture = function(o, fn, scope){
6848    o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
6849};
6850
6851
6852
6853Ext.util.Observable.observeClass = function(c, listeners){
6854    if(c){
6855      if(!c.fireEvent){
6856          Ext.apply(c, new Ext.util.Observable());
6857          Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
6858      }
6859      if(typeof listeners == 'object'){
6860          c.on(listeners);
6861      }
6862      return c;
6863   }
6864};
6865
6866Ext.apply(Ext.EventManager, function(){
6867   var resizeEvent,
6868       resizeTask,
6869       textEvent,
6870       textSize,
6871       D = Ext.lib.Dom,
6872       propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
6873       unload = Ext.EventManager._unload,
6874       curWidth = 0,
6875       curHeight = 0,
6876       
6877       
6878       
6879       useKeydown = Ext.isWebKit ?
6880                   Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
6881                   !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
6882
6883   return {
6884       _unload: function(){
6885           Ext.EventManager.un(window, "resize", this.fireWindowResize, this);
6886           unload.call(Ext.EventManager);    
6887       },
6888       
6889       
6890       doResizeEvent: function(){
6891           var h = D.getViewHeight(),
6892               w = D.getViewWidth();
6893
6894            
6895            if(curHeight != h || curWidth != w){
6896               resizeEvent.fire(curWidth = w, curHeight = h);
6897            }
6898       },
6899
6900       
6901       onWindowResize : function(fn, scope, options){
6902           if(!resizeEvent){
6903               resizeEvent = new Ext.util.Event();
6904               resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
6905               Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
6906           }
6907           resizeEvent.addListener(fn, scope, options);
6908       },
6909
6910       
6911       fireWindowResize : function(){
6912           if(resizeEvent){
6913               resizeTask.delay(100);
6914           }
6915       },
6916
6917       
6918       onTextResize : function(fn, scope, options){
6919           if(!textEvent){
6920               textEvent = new Ext.util.Event();
6921               var textEl = new Ext.Element(document.createElement('div'));
6922               textEl.dom.className = 'x-text-resize';
6923               textEl.dom.innerHTML = 'X';
6924               textEl.appendTo(document.body);
6925               textSize = textEl.dom.offsetHeight;
6926               setInterval(function(){
6927                   if(textEl.dom.offsetHeight != textSize){
6928                       textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
6929                   }
6930               }, this.textResizeInterval);
6931           }
6932           textEvent.addListener(fn, scope, options);
6933       },
6934
6935       
6936       removeResizeListener : function(fn, scope){
6937           if(resizeEvent){
6938               resizeEvent.removeListener(fn, scope);
6939           }
6940       },
6941
6942       
6943       fireResize : function(){
6944           if(resizeEvent){
6945               resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
6946           }
6947       },
6948
6949        
6950       textResizeInterval : 50,
6951
6952       
6953       ieDeferSrc : false,
6954       
6955       
6956       getKeyEvent : function(){
6957           return useKeydown ? 'keydown' : 'keypress';
6958       },
6959
6960       
6961       
6962       useKeydown: useKeydown
6963   };
6964}());
6965
6966Ext.EventManager.on = Ext.EventManager.addListener;
6967
6968
6969Ext.apply(Ext.EventObjectImpl.prototype, {
6970   
6971   BACKSPACE: 8,
6972   
6973   TAB: 9,
6974   
6975   NUM_CENTER: 12,
6976   
6977   ENTER: 13,
6978   
6979   RETURN: 13,
6980   
6981   SHIFT: 16,
6982   
6983   CTRL: 17,
6984   CONTROL : 17, 
6985   
6986   ALT: 18,
6987   
6988   PAUSE: 19,
6989   
6990   CAPS_LOCK: 20,
6991   
6992   ESC: 27,
6993   
6994   SPACE: 32,
6995   
6996   PAGE_UP: 33,
6997   PAGEUP : 33, 
6998   
6999   PAGE_DOWN: 34,
7000   PAGEDOWN : 34, 
7001   
7002   END: 35,
7003   
7004   HOME: 36,
7005   
7006   LEFT: 37,
7007   
7008   UP: 38,
7009   
7010   RIGHT: 39,
7011   
7012   DOWN: 40,
7013   
7014   PRINT_SCREEN: 44,
7015   
7016   INSERT: 45,
7017   
7018   DELETE: 46,
7019   
7020   ZERO: 48,
7021   
7022   ONE: 49,
7023   
7024   TWO: 50,
7025   
7026   THREE: 51,
7027   
7028   FOUR: 52,
7029   
7030   FIVE: 53,
7031   
7032   SIX: 54,
7033   
7034   SEVEN: 55,
7035   
7036   EIGHT: 56,
7037   
7038   NINE: 57,
7039   
7040   A: 65,
7041   
7042   B: 66,
7043   
7044   C: 67,
7045   
7046   D: 68,
7047   
7048   E: 69,
7049   
7050   F: 70,
7051   
7052   G: 71,
7053   
7054   H: 72,
7055   
7056   I: 73,
7057   
7058   J: 74,
7059   
7060   K: 75,
7061   
7062   L: 76,
7063   
7064   M: 77,
7065   
7066   N: 78,
7067   
7068   O: 79,
7069   
7070   P: 80,
7071   
7072   Q: 81,
7073   
7074   R: 82,
7075   
7076   S: 83,
7077   
7078   T: 84,
7079   
7080   U: 85,
7081   
7082   V: 86,
7083   
7084   W: 87,
7085   
7086   X: 88,
7087   
7088   Y: 89,
7089   
7090   Z: 90,
7091   
7092   CONTEXT_MENU: 93,
7093   
7094   NUM_ZERO: 96,
7095   
7096   NUM_ONE: 97,
7097   
7098   NUM_TWO: 98,
7099   
7100   NUM_THREE: 99,
7101   
7102   NUM_FOUR: 100,
7103   
7104   NUM_FIVE: 101,
7105   
7106   NUM_SIX: 102,
7107   
7108   NUM_SEVEN: 103,
7109   
7110   NUM_EIGHT: 104,
7111   
7112   NUM_NINE: 105,
7113   
7114   NUM_MULTIPLY: 106,
7115   
7116   NUM_PLUS: 107,
7117   
7118   NUM_MINUS: 109,
7119   
7120   NUM_PERIOD: 110,
7121   
7122   NUM_DIVISION: 111,
7123   
7124   F1: 112,
7125   
7126   F2: 113,
7127   
7128   F3: 114,
7129   
7130   F4: 115,
7131   
7132   F5: 116,
7133   
7134   F6: 117,
7135   
7136   F7: 118,
7137   
7138   F8: 119,
7139   
7140   F9: 120,
7141   
7142   F10: 121,
7143   
7144   F11: 122,
7145   
7146   F12: 123,
7147
7148   
7149   isNavKeyPress : function(){
7150       var me = this,
7151           k = this.normalizeKey(me.keyCode);
7152       return (k >= 33 && k <= 40) ||  
7153       k == me.RETURN ||
7154       k == me.TAB ||
7155       k == me.ESC;
7156   },
7157
7158   isSpecialKey : function(){
7159       var k = this.normalizeKey(this.keyCode);
7160       return (this.type == 'keypress' && this.ctrlKey) ||
7161       this.isNavKeyPress() ||
7162       (k == this.BACKSPACE) || 
7163       (k >= 16 && k <= 20) || 
7164       (k >= 44 && k <= 46);   
7165   },
7166
7167   getPoint : function(){
7168       return new Ext.lib.Point(this.xy[0], this.xy[1]);
7169   },
7170
7171   
7172   hasModifier : function(){
7173       return ((this.ctrlKey || this.altKey) || this.shiftKey);
7174   }
7175});
7176Ext.Element.addMethods({
7177    
7178    swallowEvent : function(eventName, preventDefault) {
7179        var me = this;
7180        function fn(e) {
7181            e.stopPropagation();
7182            if (preventDefault) {
7183                e.preventDefault();
7184            }
7185        }
7186        
7187        if (Ext.isArray(eventName)) {
7188            Ext.each(eventName, function(e) {
7189                 me.on(e, fn);
7190            });
7191            return me;
7192        }
7193        me.on(eventName, fn);
7194        return me;
7195    },
7196
7197    
7198    relayEvent : function(eventName, observable) {
7199        this.on(eventName, function(e) {
7200            observable.fireEvent(eventName, e);
7201        });
7202    },
7203
7204    
7205    clean : function(forceReclean) {
7206        var me  = this,
7207            dom = me.dom,
7208            n   = dom.firstChild,
7209            ni  = -1;
7210
7211        if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
7212            return me;
7213        }
7214
7215        while (n) {
7216            var nx = n.nextSibling;
7217            if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
7218                dom.removeChild(n);
7219            } else {
7220                n.nodeIndex = ++ni;
7221            }
7222            n = nx;
7223        }
7224        
7225        Ext.Element.data(dom, 'isCleaned', true);
7226        return me;
7227    },
7228
7229    
7230    load : function() {
7231        var updateManager = this.getUpdater();
7232        updateManager.update.apply(updateManager, arguments);
7233        
7234        return this;
7235    },
7236
7237    
7238    getUpdater : function() {
7239        return this.updateManager || (this.updateManager = new Ext.Updater(this));
7240    },
7241
7242    
7243    update : function(html, loadScripts, callback) {
7244        if (!this.dom) {
7245            return this;
7246        }
7247        html = html || "";
7248
7249        if (loadScripts !== true) {
7250            this.dom.innerHTML = html;
7251            if (typeof callback == 'function') {
7252                callback();
7253            }
7254            return this;
7255        }
7256
7257        var id  = Ext.id(),
7258            dom = this.dom;
7259
7260        html += '<span id="' + id + '"></span>';
7261
7262        Ext.lib.Event.onAvailable(id, function() {
7263            var DOC    = document,
7264                hd     = DOC.getElementsByTagName("head")[0],
7265                re     = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
7266                srcRe  = /\ssrc=([\'\"])(.*?)\1/i,
7267                typeRe = /\stype=([\'\"])(.*?)\1/i,
7268                match,
7269                attrs,
7270                srcMatch,
7271                typeMatch,
7272                el,
7273                s;
7274
7275            while ((match = re.exec(html))) {
7276                attrs = match[1];
7277                srcMatch = attrs ? attrs.match(srcRe) : false;
7278                if (srcMatch && srcMatch[2]) {
7279                   s = DOC.createElement("script");
7280                   s.src = srcMatch[2];
7281                   typeMatch = attrs.match(typeRe);
7282                   if (typeMatch && typeMatch[2]) {
7283                       s.type = typeMatch[2];
7284                   }
7285                   hd.appendChild(s);
7286                } else if (match[2] && match[2].length > 0) {
7287                    if (window.execScript) {
7288                       window.execScript(match[2]);
7289                    } else {
7290                       window.eval(match[2]);
7291                    }
7292                }
7293            }
7294            
7295            el = DOC.getElementById(id);
7296            if (el) {
7297                Ext.removeNode(el);
7298            }
7299            
7300            if (typeof callback == 'function') {
7301                callback();
7302            }
7303        });
7304        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
7305        return this;
7306    },
7307
7308    
7309    removeAllListeners : function() {
7310        this.removeAnchor();
7311        Ext.EventManager.removeAll(this.dom);
7312        return this;
7313    },
7314
7315    
7316    createProxy : function(config, renderTo, matchBox) {
7317        config = (typeof config == 'object') ? config : {tag : "div", cls: config};
7318
7319        var me = this,
7320            proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
7321                               Ext.DomHelper.insertBefore(me.dom, config, true);
7322
7323        if (matchBox && me.setBox && me.getBox) { 
7324           proxy.setBox(me.getBox());
7325        }
7326        return proxy;
7327    }
7328});
7329
7330Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
7331
7332Ext.Element.addMethods({
7333    
7334    getAnchorXY : function(anchor, local, s){
7335        
7336        
7337		anchor = (anchor || "tl").toLowerCase();
7338        s = s || {};
7339        
7340        var me = this,        
7341        	vp = me.dom == document.body || me.dom == document,
7342        	w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
7343        	h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),         	        	
7344        	xy,       	
7345        	r = Math.round,
7346        	o = me.getXY(),
7347        	scroll = me.getScroll(),
7348        	extraX = vp ? scroll.left : !local ? o[0] : 0,
7349        	extraY = vp ? scroll.top : !local ? o[1] : 0,
7350        	hash = {
7351	        	c  : [r(w * 0.5), r(h * 0.5)],
7352	        	t  : [r(w * 0.5), 0],
7353	        	l  : [0, r(h * 0.5)],
7354	        	r  : [w, r(h * 0.5)],
7355	        	b  : [r(w * 0.5), h],
7356	        	tl : [0, 0],	
7357	        	bl : [0, h],
7358	        	br : [w, h],
7359	        	tr : [w, 0]
7360        	};
7361        
7362        xy = hash[anchor];	
7363        return [xy[0] + extraX, xy[1] + extraY]; 
7364    },
7365
7366    
7367    anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){        
7368	    var me = this,
7369            dom = me.dom,
7370            scroll = !Ext.isEmpty(monitorScroll),
7371            action = function(){
7372                Ext.fly(dom).alignTo(el, alignment, offsets, animate);
7373                Ext.callback(callback, Ext.fly(dom));
7374            },
7375            anchor = this.getAnchor();
7376            
7377        
7378        this.removeAnchor();
7379        Ext.apply(anchor, {
7380            fn: action,
7381            scroll: scroll
7382        });
7383
7384        Ext.EventManager.onWindowResize(action, null);
7385        
7386        if(scroll){
7387            Ext.EventManager.on(window, 'scroll', action, null,
7388                {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
7389        }
7390        action.call(me); 
7391        return me;
7392    },
7393    
7394    
7395    removeAnchor : function(){
7396        var me = this,
7397            anchor = this.getAnchor();
7398            
7399        if(anchor && anchor.fn){
7400            Ext.EventManager.removeResizeListener(anchor.fn);
7401            if(anchor.scroll){
7402                Ext.EventManager.un(window, 'scroll', anchor.fn);
7403            }
7404            delete anchor.fn;
7405        }
7406        return me;
7407    },
7408    
7409    
7410    getAnchor : function(){
7411        var data = Ext.Element.data,
7412            dom = this.dom;
7413            if (!dom) {
7414                return;
7415            }
7416            var anchor = data(dom, '_anchor');
7417            
7418        if(!anchor){
7419            anchor = data(dom, '_anchor', {});
7420        }
7421        return anchor;
7422    },
7423
7424    
7425    getAlignToXY : function(el, p, o){	    
7426        el = Ext.get(el);
7427        
7428        if(!el || !el.dom){
7429            throw "Element.alignToXY with an element that doesn't exist";
7430        }
7431        
7432        o = o || [0,0];
7433        p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       
7434                
7435        var me = this,
7436        	d = me.dom,
7437        	a1,
7438        	a2,
7439        	x,
7440        	y,
7441        	
7442        	w,
7443        	h,
7444        	r,
7445        	dw = Ext.lib.Dom.getViewWidth() -10, 
7446        	dh = Ext.lib.Dom.getViewHeight()-10, 
7447        	p1y,
7448        	p1x,        	
7449        	p2y,
7450        	p2x,
7451        	swapY,
7452        	swapX,
7453        	doc = document,
7454        	docElement = doc.documentElement,
7455        	docBody = doc.body,
7456        	scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
7457        	scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
7458        	c = false, 
7459        	p1 = "", 
7460        	p2 = "",
7461        	m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
7462        
7463        if(!m){
7464           throw "Element.alignTo with an invalid alignment " + p;
7465        }
7466        
7467        p1 = m[1]; 
7468        p2 = m[2]; 
7469        c = !!m[3];
7470
7471        
7472        
7473        a1 = me.getAnchorXY(p1, true);
7474        a2 = el.getAnchorXY(p2, false);
7475
7476        x = a2[0] - a1[0] + o[0];
7477        y = a2[1] - a1[1] + o[1];
7478
7479        if(c){    
7480	       w = me.getWidth();
7481           h = me.getHeight();
7482           r = el.getRegion();       
7483           
7484           
7485           
7486           p1y = p1.charAt(0);
7487           p1x = p1.charAt(p1.length-1);
7488           p2y = p2.charAt(0);
7489           p2x = p2.charAt(p2.length-1);
7490           swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
7491           swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));          
7492           
7493
7494           if (x + w > dw + scrollX) {
7495                x = swapX ? r.left-w : dw+scrollX-w;
7496           }
7497           if (x < scrollX) {
7498               x = swapX ? r.right : scrollX;
7499           }
7500           if (y + h > dh + scrollY) {
7501                y = swapY ? r.top-h : dh+scrollY-h;
7502            }
7503           if (y < scrollY){
7504               y = swapY ? r.bottom : scrollY;
7505           }
7506        }
7507        return [x,y];
7508    },
7509
7510    
7511    alignTo : function(element, position, offsets, animate){
7512	    var me = this;
7513        return me.setXY(me.getAlignToXY(element, position, offsets),
7514          		        me.preanim && !!animate ? me.preanim(arguments, 3) : false);
7515    },
7516    
7517    
7518    adjustForConstraints : function(xy, parent, offsets){
7519        return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
7520    },
7521
7522    
7523    getConstrainToXY : function(el, local, offsets, proposedXY){   
7524	    var os = {top:0, left:0, bottom:0, right: 0};
7525
7526        return function(el, local, offsets, proposedXY){
7527            el = Ext.get(el);
7528            offsets = offsets ? Ext.applyIf(offsets, os) : os;
7529
7530            var vw, vh, vx = 0, vy = 0;
7531            if(el.dom == document.body || el.dom == document){
7532                vw =Ext.lib.Dom.getViewWidth();
7533                vh = Ext.lib.Dom.getViewHeight();
7534            }else{
7535                vw = el.dom.clientWidth;
7536                vh = el.dom.clientHeight;
7537                if(!local){
7538                    var vxy = el.getXY();
7539                    vx = vxy[0];
7540                    vy = vxy[1];
7541                }
7542            }
7543
7544            var s = el.getScroll();
7545
7546            vx += offsets.left + s.left;
7547            vy += offsets.top + s.top;
7548
7549            vw -= offsets.right;
7550            vh -= offsets.bottom;
7551
7552            var vr = vx + vw,
7553                vb = vy + vh,
7554                xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
7555                x = xy[0], y = xy[1],
7556                offset = this.getConstrainOffset(),
7557                w = this.dom.offsetWidth + offset, 
7558                h = this.dom.offsetHeight + offset;
7559
7560            
7561            var moved = false;
7562
7563            
7564            if((x + w) > vr){
7565                x = vr - w;
7566                moved = true;
7567            }
7568            if((y + h) > vb){
7569                y = vb - h;
7570                moved = true;
7571            }
7572            
7573            if(x < vx){
7574                x = vx;
7575                moved = true;
7576            }
7577            if(y < vy){
7578                y = vy;
7579                moved = true;
7580            }
7581            return moved ? [x, y] : false;
7582        };
7583    }(),
7584	    
7585	    
7586	        
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640    
7641    getConstrainOffset : function(){
7642        return 0;
7643    },
7644    
7645    
7646    getCenterXY : function(){
7647        return this.getAlignToXY(document, 'c-c');
7648    },
7649
7650    
7651    center : function(centerIn){
7652        return this.alignTo(centerIn || document, 'c-c');        
7653    }    
7654});
7655
7656Ext.Element.addMethods({
7657    
7658    select : function(selector, unique){
7659        return Ext.Element.select(selector, unique, this.dom);
7660    }
7661});
7662Ext.apply(Ext.Element.prototype, function() {
7663	var GETDOM = Ext.getDom,
7664		GET = Ext.get,
7665		DH = Ext.DomHelper;
7666	
7667	return {	
7668		
7669	    insertSibling: function(el, where, returnDom){
7670	        var me = this,
7671	        	rt,
7672                isAfter = (where || 'before').toLowerCase() == 'after',
7673                insertEl;
7674	        	
7675	        if(Ext.isArray(el)){
7676                insertEl = me;
7677	            Ext.each(el, function(e) {
7678		            rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
7679                    if(isAfter){
7680                        insertEl = rt;
7681                    }
7682	            });
7683	            return rt;
7684	        }
7685	                
7686	        el = el || {};
7687	       	
7688            if(el.nodeType || el.dom){
7689                rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
7690                if (!returnDom) {
7691                    rt = GET(rt);
7692                }
7693            }else{
7694                if (isAfter && !me.dom.nextSibling) {
7695                    rt = DH.append(me.dom.parentNode, el, !returnDom);
7696                } else {                    
7697                    rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
7698                }
7699            }
7700	        return rt;
7701	    }
7702    };
7703}());
7704
7705
7706Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
7707
7708Ext.Element.addMethods(function(){
7709    var INTERNAL = "_internal",
7710        pxMatch = /(\d+\.?\d+)px/;
7711    return {
7712        
7713        applyStyles : function(style){
7714            Ext.DomHelper.applyStyles(this.dom, style);
7715            return this;
7716        },
7717
7718        
7719        getStyles : function(){
7720            var ret = {};
7721            Ext.each(arguments, function(v) {
7722               ret[v] = this.getStyle(v);
7723            },
7724            this);
7725            return ret;
7726        },
7727
7728        
7729        setOverflow : function(v){
7730            var dom = this.dom;
7731            if(v=='auto' && Ext.isMac && Ext.isGecko2){ 
7732                dom.style.overflow = 'hidden';
7733                (function(){dom.style.overflow = 'auto';}).defer(1);
7734            }else{
7735                dom.style.overflow = v;
7736            }
7737        },
7738
7739       
7740        boxWrap : function(cls){
7741            cls = cls || 'x-box';
7742            var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        
7743            Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
7744            return el;
7745        },
7746
7747        
7748        setSize : function(width, height, animate){
7749            var me = this;
7750            if(typeof width == 'object'){ 
7751                height = width.height;
7752                width = width.width;
7753            }
7754            width = me.adjustWidth(width);
7755            height = me.adjustHeight(height);
7756            if(!animate || !me.anim){
7757                me.dom.style.width = me.addUnits(width);
7758                me.dom.style.height = me.addUnits(height);
7759            }else{
7760                me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
7761            }
7762            return me;
7763        },
7764
7765        
7766        getComputedHeight : function(){
7767            var me = this,
7768                h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
7769            if(!h){
7770                h = parseFloat(me.getStyle('height')) || 0;
7771                if(!me.isBorderBox()){
7772                    h += me.getFrameWidth('tb');
7773                }
7774            }
7775            return h;
7776        },
7777
7778        
7779        getComputedWidth : function(){
7780            var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
7781            if(!w){
7782                w = parseFloat(this.getStyle('width')) || 0;
7783                if(!this.isBorderBox()){
7784                    w += this.getFrameWidth('lr');
7785                }
7786            }
7787            return w;
7788        },
7789
7790        
7791        getFrameWidth : function(sides, onlyContentBox){
7792            return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
7793        },
7794
7795        
7796        addClassOnOver : function(className){
7797            this.hover(
7798                function(){
7799                    Ext.fly(this, INTERNAL).addClass(className);
7800                },
7801                function(){
7802                    Ext.fly(this, INTERNAL).removeClass(className);
7803                }
7804            );
7805            return this;
7806        },
7807
7808        
7809        addClassOnFocus : function(className){
7810            this.on("focus", function(){
7811                Ext.fly(this, INTERNAL).addClass(className);
7812            }, this.dom);
7813            this.on("blur", function(){
7814                Ext.fly(this, INTERNAL).removeClass(className);
7815            }, this.dom);
7816            return this;
7817        },
7818
7819        
7820        addClassOnClick : function(className){
7821            var dom = this.dom;
7822            this.on("mousedown", function(){
7823                Ext.fly(dom, INTERNAL).addClass(className);
7824                var d = Ext.getDoc(),
7825                    fn = function(){
7826                        Ext.fly(dom, INTERNAL).removeClass(className);
7827                        d.removeListener("mouseup", fn);
7828                    };
7829                d.on("mouseup", fn);
7830            });
7831            return this;
7832        },
7833
7834        
7835
7836        getViewSize : function(){
7837            var doc = document,
7838                d = this.dom,
7839                isDoc = (d == doc || d == doc.body);
7840
7841            
7842            if (isDoc) {
7843                var extdom = Ext.lib.Dom;
7844                return {
7845                    width : extdom.getViewWidth(),
7846                    height : extdom.getViewHeight()
7847                };
7848
7849            
7850            } else {
7851                return {
7852                    width : d.clientWidth,
7853                    height : d.clientHeight
7854                };
7855            }
7856        },
7857
7858        
7859
7860        getStyleSize : function(){
7861            var me = this,
7862                w, h,
7863                doc = document,
7864                d = this.dom,
7865                isDoc = (d == doc || d == doc.body),
7866                s = d.style;
7867
7868            
7869            if (isDoc) {
7870                var extdom = Ext.lib.Dom;
7871                return {
7872                    width : extdom.getViewWidth(),
7873                    height : extdom.getViewHeight()
7874                };
7875            }
7876            
7877            if(s.width && s.width != 'auto'){
7878                w = parseFloat(s.width);
7879                if(me.isBorderBox()){
7880                   w -= me.getFrameWidth('lr');
7881                }
7882            }
7883            
7884            if(s.height && s.height != 'auto'){
7885                h = parseFloat(s.height);
7886                if(me.isBorderBox()){
7887                   h -= me.getFrameWidth('tb');
7888                }
7889            }
7890            
7891            return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
7892        },
7893
7894        
7895        getSize : function(contentSize){
7896            return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
7897        },
7898
7899        
7900        repaint : function(){
7901            var dom = this.dom;
7902            this.addClass("x-repaint");
7903            setTimeout(function(){
7904                Ext.fly(dom).removeClass("x-repaint");
7905            }, 1);
7906            return this;
7907        },
7908
7909        
7910        unselectable : function(){
7911            this.dom.unselectable = "on";
7912            return this.swallowEvent("selectstart", true).
7913                        applyStyles("-moz-user-select:none;-khtml-user-select:none;").
7914                        addClass("x-unselectable");
7915        },
7916
7917        
7918        getMargins : function(side){
7919            var me = this,
7920                key,
7921                hash = {t:"top", l:"left", r:"right", b: "bottom"},
7922                o = {};
7923
7924            if (!side) {
7925                for (key in me.margins){
7926                    o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
7927                }
7928                return o;
7929            } else {
7930                return me.addStyles.call(me, side, me.margins);
7931            }
7932        }
7933    };
7934}());
7935
7936Ext.Element.addMethods({
7937    
7938    setBox : function(box, adjust, animate){
7939        var me = this,
7940        	w = box.width, 
7941        	h = box.height;
7942        if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
7943           w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
7944           h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
7945        }
7946        me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
7947        return me;
7948    },
7949
7950    
7951	getBox : function(contentBox, local) {	    
7952	    var me = this,
7953        	xy,
7954        	left,
7955        	top,
7956        	getBorderWidth = me.getBorderWidth,
7957        	getPadding = me.getPadding, 
7958        	l,
7959        	r,
7960        	t,
7961        	b;
7962        if(!local){
7963            xy = me.getXY();
7964        }else{
7965            left = parseInt(me.getStyle("left"), 10) || 0;
7966            top = parseInt(me.getStyle("top"), 10) || 0;
7967            xy = [left, top];
7968        }
7969        var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
7970        if(!contentBox){
7971            bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
7972        }else{
7973            l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
7974            r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
7975            t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
7976            b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
7977            bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};
7978        }
7979        bx.right = bx.x + bx.width;
7980        bx.bottom = bx.y + bx.height;
7981        return bx;
7982	},
7983	
7984    
7985     move : function(direction, distance, animate){
7986        var me = this,        	
7987        	xy = me.getXY(),
7988        	x = xy[0],
7989        	y = xy[1],        	
7990        	left = [x - distance, y],
7991        	right = [x + distance, y],
7992        	top = [x, y - distance],
7993        	bottom = [x, y + distance],
7994	       	hash = {
7995	        	l :	left,
7996	        	left : left,
7997	        	r : right,
7998	        	right : right,
7999	        	t : top,
8000	        	top : top,
8001	        	up : top,
8002	        	b : bottom, 
8003	        	bottom : bottom,
8004	        	down : bottom	        		
8005	        };
8006        
8007 	    direction = direction.toLowerCase();    
8008 	    me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
8009    },
8010    
8011    
8012     setLeftTop : function(left, top){
8013	    var me = this,
8014	    	style = me.dom.style;
8015        style.left = me.addUnits(left);
8016        style.top = me.addUnits(top);
8017        return me;
8018    },
8019    
8020    
8021    getRegion : function(){
8022        return Ext.lib.Dom.getRegion(this.dom);
8023    },
8024    
8025    
8026    setBounds : function(x, y, width, height, animate){
8027	    var me = this;
8028        if (!animate || !me.anim) {
8029            me.setSize(width, height);
8030            me.setLocation(x, y);
8031        } else {
8032            me.anim({points: {to: [x, y]}, 
8033            		 width: {to: me.adjustWidth(width)}, 
8034            		 height: {to: me.adjustHeight(height)}},
8035                     me.preanim(arguments, 4), 
8036                     'motion');
8037        }
8038        return me;
8039    },
8040
8041    
8042    setRegion : function(region, animate) {
8043        return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
8044    }
8045});
8046Ext.Element.addMethods({
8047    
8048    scrollTo : function(side, value, animate) {
8049        
8050        var top = /top/i.test(side),
8051            me = this,
8052            dom = me.dom,
8053            prop;
8054        if (!animate || !me.anim) {
8055            
8056            prop = 'scroll' + (top ? 'Top' : 'Left');
8057            dom[prop] = value;
8058        }
8059        else {
8060            
8061            prop = 'scroll' + (top ? 'Left' : 'Top');
8062            me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
8063        }
8064        return me;
8065    },
8066    
8067    
8068    scrollIntoView : function(container, hscroll) {
8069        var c = Ext.getDom(container) || Ext.getBody().dom,
8070            el = this.dom,
8071            o = this.getOffsetsTo(c),
8072            l = o[0] + c.scrollLeft,
8073            t = o[1] + c.scrollTop,
8074            b = t + el.offsetHeight,
8075            r = l + el.offsetWidth,
8076            ch = c.clientHeight,
8077            ct = parseInt(c.scrollTop, 10),
8078            cl = parseInt(c.scrollLeft, 10),
8079            cb = ct + ch,
8080            cr = cl + c.clientWidth;
8081
8082        if (el.offsetHeight > ch || t < ct) {
8083            c.scrollTop = t;
8084        }
8085        else if (b > cb) {
8086            c.scrollTop = b-ch;
8087        }
8088        
8089        c.scrollTop = c.scrollTop;
8090
8091        if (hscroll !== false) {
8092            if (el.offsetWidth > c.clientWidth || l < cl) {
8093                c.scrollLeft = l;
8094            }
8095            else if (r > cr) {
8096                c.scrollLeft = r - c.clientWidth;
8097            }
8098            c.scrollLeft = c.scrollLeft;
8099        }
8100        return this;
8101    },
8102
8103    
8104    scrollChildIntoView : function(child, hscroll) {
8105        Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
8106    },
8107    
8108    
8109     scroll : function(direction, distance, animate) {
8110        if (!this.isScrollable()) {
8111            return false;
8112        }
8113        var el = this.dom,
8114            l = el.scrollLeft, t = el.scrollTop,
8115            w = el.scrollWidth, h = el.scrollHeight,
8116            cw = el.clientWidth, ch = el.clientHeight,
8117            scrolled = false, v,
8118            hash = {
8119                l: Math.min(l + distance, w-cw),
8120                r: v = Math.max(l - distance, 0),
8121                t: Math.max(t - distance, 0),
8122                b: Math.min(t + distance, h-ch)
8123            };
8124            hash.d = hash.b;
8125            hash.u = hash.t;
8126        
8127        direction = direction.substr(0, 1);
8128        if ((v = hash[direction]) > -1) {
8129            scrolled = true;
8130            this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
8131        }
8132        return scrolled;
8133    }
8134});
8135Ext.Element.addMethods(
8136    function() {
8137        var VISIBILITY      = "visibility",
8138            DISPLAY         = "display",
8139            HIDDEN          = "hidden",
8140            NONE            = "none",
8141            XMASKED         = "x-masked",
8142            XMASKEDRELATIVE = "x-masked-relative",
8143            data            = Ext.Element.data;
8144
8145        return {
8146            
8147            isVisible : function(deep) {
8148                var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
8149                    p   = this.dom.parentNode;
8150                
8151                if (deep !== true || !vis) {
8152                    return vis;
8153                }
8154                
8155                while (p && !(/^body/i.test(p.tagName))) {
8156                    if (!Ext.fly(p, '_isVisible').isVisible()) {
8157                        return false;
8158                    }
8159                    p = p.parentNode;
8160                }
8161                return true;
8162            },
8163
8164            
8165            isDisplayed : function() {
8166                return !this.isStyle(DISPLAY, NONE);
8167            },
8168
8169            
8170            enableDisplayMode : function(display) {
8171                this.setVisibilityMode(Ext.Element.DISPLAY);
8172                
8173                if (!Ext.isEmpty(display)) {
8174                    data(this.dom, 'originalDisplay', display);
8175                }
8176                
8177                return this;
8178            },
8179
8180            
8181            mask : function(msg, msgCls) {
8182                var me  = this,
8183                    dom = me.dom,
8184                    dh  = Ext.DomHelper,
8185                    EXTELMASKMSG = "ext-el-mask-msg",
8186                    el,
8187                    mask;
8188
8189                if (!/^body/i.test(dom.tagName) && me.getStyle('position') == 'static') {
8190                    me.addClass(XMASKEDRELATIVE);
8191                }
8192                if (el = data(dom, 'maskMsg')) {
8193                    el.remove();
8194                }
8195                if (el = data(dom, 'mask')) {
8196                    el.remove();
8197                }
8198
8199                mask = dh.append(dom, {cls : "ext-el-mask"}, true);
8200                data(dom, 'mask', mask);
8201
8202                me.addClass(XMASKED);
8203                mask.setDisplayed(true);
8204                
8205                if (typeof msg == 'string') {
8206                    var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
8207                    data(dom, 'maskMsg', mm);
8208                    mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
8209                    mm.dom.firstChild.innerHTML = msg;
8210                    mm.setDisplayed(true);
8211                    mm.center(me);
8212                }
8213                
8214                
8215                if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
8216                    mask.setSize(undefined, me.getHeight());
8217                }
8218                
8219                return mask;
8220            },
8221
8222            
8223            unmask : function() {
8224                var me      = this,
8225                    dom     = me.dom,
8226                    mask    = data(dom, 'mask'),
8227                    maskMsg = data(dom, 'maskMsg');
8228
8229                if (mask) {
8230                    if (maskMsg) {
8231                        maskMsg.remove();
8232                        data(dom, 'maskMsg', undefined);
8233                    }
8234                    
8235                    mask.remove();
8236                    data(dom, 'mask', undefined);
8237                    me.removeClass([XMASKED, XMASKEDRELATIVE]);
8238                }
8239            },
8240
8241            
8242            isMasked : function() {
8243                var m = data(this.dom, 'mask');
8244                return m && m.isVisible();
8245            },
8246
8247            
8248            createShim : function() {
8249                var el = document.createElement('iframe'),
8250                    shim;
8251                
8252                el.frameBorder = '0';
8253                el.className = 'ext-shim';
8254                el.src = Ext.SSL_SECURE_URL;
8255                shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
8256                shim.autoBoxAdjust = false;
8257                return shim;
8258            }
8259        };
8260    }()
8261);
8262Ext.Element.addMethods({
8263    
8264    addKeyListener : function(key, fn, scope){
8265        var config;
8266        if(typeof key != 'object' || Ext.isArray(key)){
8267            config = {
8268                key: key,
8269                fn: fn,
8270                scope: scope
8271            };
8272        }else{
8273            config = {
8274                key : key.key,
8275                shift : key.shift,
8276                ctrl : key.ctrl,
8277                alt : key.alt,
8278                fn: fn,
8279                scope: scope
8280            };
8281        }
8282        return new Ext.KeyMap(this, config);
8283    },
8284
8285    
8286    addKeyMap : function(config){
8287        return new Ext.KeyMap(this, config);
8288    }
8289});
8290
8291
8292
8293Ext.CompositeElementLite.importElementMethods();
8294Ext.apply(Ext.CompositeElementLite.prototype, {
8295    addElements : function(els, root){
8296        if(!els){
8297            return this;
8298        }
8299        if(typeof els == "string"){
8300            els = Ext.Element.selectorFunction(els, root);
8301        }
8302        var yels = this.elements;
8303        Ext.each(els, function(e) {
8304            yels.push(Ext.get(e));
8305        });
8306        return this;
8307    },
8308
8309    
8310    first : function(){
8311        return this.item(0);
8312    },
8313
8314    
8315    last : function(){
8316        return this.item(this.getCount()-1);
8317    },
8318
8319    
8320    contains : function(el){
8321        return this.indexOf(el) != -1;
8322    },
8323
8324    
8325    removeElement : function(keys, removeDom){
8326        var me = this,
8327            els = this.elements,
8328            el;
8329        Ext.each(keys, function(val){
8330            if ((el = (els[val] || els[val = me.indexOf(val)]))) {
8331                if(removeDom){
8332                    if(el.dom){
8333                        el.remove();
8334                    }else{
8335                        Ext.removeNode(el);
8336                    }
8337                }
8338                els.splice(val, 1);
8339            }
8340        });
8341        return this;
8342    }
8343});
8344
8345Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
8346    
8347    constructor : function(els, root){
8348        this.elements = [];
8349        this.add(els, root);
8350    },
8351    
8352    
8353    getElement : function(el){
8354        
8355        return el;
8356    },
8357    
8358    
8359    transformElement : function(el){
8360        return Ext.get(el);
8361    }
8362
8363    
8364
8365    
8366
8367    
8368});
8369
8370
8371Ext.Element.select = function(selector, unique, root){
8372    var els;
8373    if(typeof selector == "string"){
8374        els = Ext.Element.selectorFunction(selector, root);
8375    }else if(selector.length !== undefined){
8376        els = selector;
8377    }else{
8378        throw "Invalid selector";
8379    }
8380
8381    return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
8382};
8383
8384
8385Ext.select = Ext.Element.select;
8386Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
8387function() {
8388    var BEFOREUPDATE = "beforeupdate",
8389        UPDATE = "update",
8390        FAILURE = "failure";
8391
8392    
8393    function processSuccess(response){
8394        var me = this;
8395        me.transaction = null;
8396        if (response.argument.form && response.argument.reset) {
8397            try { 
8398                response.argument.form.reset();
8399            } catch(e){}
8400        }
8401        if (me.loadScripts) {
8402            me.renderer.render(me.el, response, me,
8403               updateComplete.createDelegate(me, [response]));
8404        } else {
8405            me.renderer.render(me.el, response, me);
8406            updateComplete.call(me, response);
8407        }
8408    }
8409
8410    
8411    function updateComplete(response, type, success){
8412        this.fireEvent(type || UPDATE, this.el, response);
8413        if(Ext.isFunction(response.argument.callback)){
8414            response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
8415        }
8416    }
8417
8418    
8419    function processFailure(response){
8420        updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
8421    }
8422
8423    return {
8424        constructor: function(el, forceNew){
8425            var me = this;
8426            el = Ext.get(el);
8427            if(!forceNew && el.updateManager){
8428                return el.updateManager;
8429            }
8430            
8431            me.el = el;
8432            
8433            me.defaultUrl = null;
8434
8435            me.addEvents(
8436                
8437                BEFOREUPDATE,
8438                
8439                UPDATE,
8440                
8441                FAILURE
8442            );
8443
8444            Ext.apply(me, Ext.Updater.defaults);
8445            
8446            
8447            
8448            
8449            
8450            
8451
8452            
8453            me.transaction = null;
8454            
8455            me.refreshDelegate = me.refresh.createDelegate(me);
8456            
8457            me.updateDelegate = me.update.createDelegate(me);
8458            
8459            me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
8460
8461            
8462            me.renderer = me.renderer || me.getDefaultRenderer();
8463
8464            Ext.Updater.superclass.constructor.call(me);
8465        },
8466
8467        
8468        setRenderer : function(renderer){
8469            this.renderer = renderer;
8470        },
8471
8472        
8473        getRenderer : function(){
8474           return this.renderer;
8475        },
8476
8477        
8478        getDefaultRenderer: function() {
8479            return new Ext.Updater.BasicRenderer();
8480        },
8481
8482        
8483        setDefaultUrl : function(defaultUrl){
8484            this.defaultUrl = defaultUrl;
8485        },
8486
8487        
8488        getEl : function(){
8489            return this.el;
8490        },
8491
8492        
8493        update : function(url, params, callback, discardUrl){
8494            var me = this,
8495                cfg,
8496                callerScope;
8497
8498            if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
8499                if(Ext.isObject(url)){ 
8500                    cfg = url;
8501                    url = cfg.url;
8502                    params = params || cfg.params;
8503                    callback = callback || cfg.callback;
8504                    discardUrl = discardUrl || cfg.discardUrl;
8505                    callerScope = cfg.scope;
8506                    if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
8507                    if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
8508                    if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
8509                    if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
8510                }
8511                me.showLoading();
8512
8513                if(!discardUrl){
8514                    me.defaultUrl = url;
8515                }
8516                if(Ext.isFunction(url)){
8517                    url = url.call(me);
8518                }
8519
8520                var o = Ext.apply({}, {
8521                    url : url,
8522                    params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
8523                    success: processSuccess,
8524                    failure: processFailure,
8525                    scope: me,
8526                    callback: undefined,
8527                    timeout: (me.timeout*1000),
8528                    disableCaching: me.disableCaching,
8529                    argument: {
8530                        "options": cfg,
8531                        "url": url,
8532                        "form": null,
8533                        "callback": callback,
8534                        "scope": callerScope || window,
8535                        "params": params
8536                    }
8537                }, cfg);
8538
8539                me.transaction = Ext.Ajax.request(o);
8540            }
8541        },
8542
8543        
8544        formUpdate : function(form, url, reset, callback){
8545            var me = this;
8546            if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
8547                if(Ext.isFunction(url)){
8548                    url = url.call(me);
8549                }
8550                form = Ext.getDom(form);
8551                me.transaction = Ext.Ajax.request({
8552                    form: form,
8553                    url:url,
8554                    success: processSuccess,
8555                    failure: processFailure,
8556                    scope: me,
8557                    timeout: (me.timeout*1000),
8558                    argument: {
8559                        "url": url,
8560                        "form": form,
8561                        "callback": callback,
8562                        "reset": reset
8563                    }
8564                });
8565                me.showLoading.defer(1, me);
8566            }
8567        },
8568
8569        
8570        startAutoRefresh : function(interval, url, params, callback, refreshNow){
8571            var me = this;
8572            if(refreshNow){
8573                me.update(url || me.defaultUrl, params, callback, true);
8574            }
8575            if(me.autoRefreshProcId){
8576                clearInterval(me.autoRefreshProcId);
8577            }
8578            me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
8579        },
8580
8581        
8582        stopAutoRefresh : function(){
8583            if(this.autoRefreshProcId){
8584                clearInterval(this.autoRefreshProcId);
8585                delete this.autoRefreshProcId;
8586            }
8587        },
8588
8589        
8590        isAutoRefreshing : function(){
8591           return !!this.autoRefreshProcId;
8592        },
8593
8594        
8595        showLoading : function(){
8596            if(this.showLoadIndicator){
8597                this.el.dom.innerHTML = this.indicatorText;
8598            }
8599        },
8600
8601        
8602        abort : function(){
8603            if(this.transaction){
8604                Ext.Ajax.abort(this.transaction);
8605            }
8606        },
8607
8608        
8609        isUpdating : function(){
8610            return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
8611        },
8612
8613        
8614        refresh : function(callback){
8615            if(this.defaultUrl){
8616                this.update(this.defaultUrl, null, callback, true);
8617            }
8618        }
8619    };
8620}());
8621
8622
8623Ext.Updater.defaults = {
8624   
8625    timeout : 30,
8626    
8627    disableCaching : false,
8628    
8629    showLoadIndicator : true,
8630    
8631    indicatorText : '<div class="loading-indicator">Loading...</div>',
8632     
8633    loadScripts : false,
8634    
8635    sslBlankUrl : Ext.SSL_SECURE_URL
8636};
8637
8638
8639
8640Ext.Updater.updateElement = function(el, url, params, options){
8641    var um = Ext.get(el).getUpdater();
8642    Ext.apply(um, options);
8643    um.update(url, params, options ? options.callback : null);
8644};
8645
8646
8647Ext.Updater.BasicRenderer = function(){};
8648
8649Ext.Updater.BasicRenderer.prototype = {
8650    
8651     render : function(el, response, updateManager, callback){
8652        el.update(response.responseText, updateManager.loadScripts, callback);
8653    }
8654};
8655
8656
8657
8658(function() {
8659
8660
8661Date.useStrict = false;
8662
8663
8664
8665
8666
8667function xf(format) {
8668    var args = Array.prototype.slice.call(arguments, 1);
8669    return format.replace(/\{(\d+)\}/g, function(m, i) {
8670        return args[i];
8671    });
8672}
8673
8674
8675
8676Date.formatCodeToRegex = function(character, currentGroup) {
8677    
8678    var p = Date.parseCodes[character];
8679
8680    if (p) {
8681      p = typeof p == 'function'? p() : p;
8682      Date.parseCodes[character] = p; 
8683    }
8684
8685    return p ? Ext.applyIf({
8686      c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
8687    }, p) : {
8688        g:0,
8689        c:null,
8690        s:Ext.escapeRe(character) 
8691    };
8692};
8693
8694
8695var $f = Date.formatCodeToRegex;
8696
8697Ext.apply(Date, {
8698    
8699    parseFunctions: {
8700        "M$": function(input, strict) {
8701            
8702            
8703            var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
8704            var r = (input || '').match(re);
8705            return r? new Date(((r[1] || '') + r[2]) * 1) : null;
8706        }
8707    },
8708    parseRegexes: [],
8709
8710    
8711    formatFunctions: {
8712        "M$": function() {
8713            
8714            return '\\/Date(' + this.getTime() + ')\\/';
8715        }
8716    },
8717
8718    y2kYear : 50,
8719
8720    
8721    MILLI : "ms",
8722
8723    
8724    SECOND : "s",
8725
8726    
8727    MINUTE : "mi",
8728
8729    
8730    HOUR : "h",
8731
8732    
8733    DAY : "d",
8734
8735    
8736    MONTH : "mo",
8737
8738    
8739    YEAR : "y",
8740
8741    
8742    defaults: {},
8743
8744    
8745    dayNames : [
8746        "Sunday",
8747        "Monday",
8748        "Tuesday",
8749        "Wednesday",
8750        "Thursday",
8751        "Friday",
8752        "Saturday"
8753    ],
8754
8755    
8756    monthNames : [
8757        "January",
8758        "February",
8759        "March",
8760        "April",
8761        "May",
8762        "June",
8763        "July",
8764        "August",
8765        "September",
8766        "October",
8767        "November",
8768        "December"
8769    ],
8770
8771    
8772    monthNumbers : {
8773        Jan:0,
8774        Feb:1,
8775        Mar:2,
8776        Apr:3,
8777        May:4,
8778        Jun:5,
8779        Jul:6,
8780        Aug:7,
8781        Sep:8,
8782        Oct:9,
8783        Nov:10,
8784        Dec:11
8785    },
8786
8787    
8788    getShortMonthName : function(month) {
8789        return Date.monthNames[month].substring(0, 3);
8790    },
8791
8792    
8793    getShortDayName : function(day) {
8794        return Date.dayNames[day].substring(0, 3);
8795    },
8796
8797    
8798    getMonthNumber : function(name) {
8799        
8800        return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
8801    },
8802    
8803    
8804    formatContainsHourInfo : (function(){
8805        var stripEscapeRe = /(\\.)/g,
8806            hourInfoRe = /([gGhHisucUOPZ]|M\$)/;
8807        return function(format){
8808            return hourInfoRe.test(format.replace(stripEscapeRe, ''));
8809        };
8810    })(),
8811
8812    
8813    formatCodes : {
8814        d: "String.leftPad(this.getDate(), 2, '0')",
8815        D: "Date.getShortDayName(this.getDay())", 
8816        j: "this.getDate()",
8817        l: "Date.dayNames[this.getDay()]",
8818        N: "(this.getDay() ? this.getDay() : 7)",
8819        S: "this.getSuffix()",
8820        w: "this.getDay()",
8821        z: "this.getDayOfYear()",
8822        W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
8823        F: "Date.monthNames[this.getMonth()]",
8824        m: "String.leftPad(this.getMonth() + 1, 2, '0')",
8825        M: "Date.getShortMonthName(this.getMonth())", 
8826        n: "(this.getMonth() + 1)",
8827        t: "this.getDaysInMonth()",
8828        L: "(this.isLeapYear() ? 1 : 0)",
8829        o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
8830        Y: "String.leftPad(this.getFullYear(), 4, '0')",
8831        y: "('' + this.getFullYear()).substring(2, 4)",
8832        a: "(this.getHours() < 12 ? 'am' : 'pm')",
8833        A: "(this.getHours() < 12 ? 'AM' : 'PM')",
8834        g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
8835        G: "this.getHours()",
8836        h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
8837        H: "String.leftPad(this.getHours(), 2, '0')",
8838        i: "String.leftPad(this.getMinutes(), 2, '0')",
8839        s: "String.leftPad(this.getSeconds(), 2, '0')",
8840        u: "String.leftPad(this.getMilliseconds(), 3, '0')",
8841        O: "this.getGMTOffset()",
8842        P: "this.getGMTOffset(true)",
8843        T: "this.getTimezone()",
8844        Z: "(this.getTimezoneOffset() * -60)",
8845
8846        c: function() { 
8847            for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
8848                var e = c.charAt(i);
8849                code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); 
8850            }
8851            return code.join(" + ");
8852        },
8853        
8854
8855        U: "Math.round(this.getTime() / 1000)"
8856    },
8857
8858    
8859    isValid : function(y, m, d, h, i, s, ms) {
8860        
8861        h = h || 0;
8862        i = i || 0;
8863        s = s || 0;
8864        ms = ms || 0;
8865
8866        
8867        var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);
8868
8869        return y == dt.getFullYear() &&
8870            m == dt.getMonth() + 1 &&
8871            d == dt.getDate() &&
8872            h == dt.getHours() &&
8873            i == dt.getMinutes() &&
8874            s == dt.getSeconds() &&
8875            ms == dt.getMilliseconds();
8876    },
8877
8878    
8879    parseDate : function(input, format, strict) {
8880        var p = Date.parseFunctions;
8881        if (p[format] == null) {
8882            Date.createParser(format);
8883        }
8884        return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
8885    },
8886
8887    
8888    getFormatCode : function(character) {
8889        var f = Date.formatCodes[character];
8890
8891        if (f) {
8892          f = typeof f == 'function'? f() : f;
8893          Date.formatCodes[character] = f; 
8894        }
8895
8896        
8897        return f || ("'" + String.escape(character) + "'");
8898    },
8899
8900    
8901    createFormat : function(format) {
8902        var code = [],
8903            special = false,
8904            ch = '';
8905
8906        for (var i = 0; i < format.length; ++i) {
8907            ch = format.charAt(i);
8908            if (!special && ch == "\\") {
8909                special = true;
8910            } else if (special) {
8911                special = false;
8912                code.push("'" + String.escape(ch) + "'");
8913            } else {
8914                code.push(Date.getFormatCode(ch));
8915            }
8916        }
8917        Date.formatFunctions[format] = new Function("return " + code.join('+'));
8918    },
8919
8920    
8921    createParser : function() {
8922        var code = [
8923            "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
8924                "def = Date.defaults,",
8925                "results = String(input).match(Date.parseRegexes[{0}]);", 
8926
8927            "if(results){",
8928                "{1}",
8929
8930                "if(u != null){", 
8931                    "v = new Date(u * 1000);", 
8932                "}else{",
8933                    
8934                    
8935                    
8936                    "dt = (new Date()).clearTime();",
8937
8938                    
8939                    "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
8940                    "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
8941                    "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
8942
8943                    
8944                    "h  = Ext.num(h, Ext.num(def.h, dt.getHours()));",
8945                    "i  = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
8946                    "s  = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
8947                    "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
8948
8949                    "if(z >= 0 && y >= 0){",
8950                        
8951                        
8952
8953                        
8954                        
8955                        "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8956
8957                        
8958                        "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
8959                    "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", 
8960                        "v = null;", 
8961                    "}else{",
8962                        
8963                        
8964                        "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8965                    "}",
8966                "}",
8967            "}",
8968
8969            "if(v){",
8970                
8971                "if(zz != null){",
8972                    
8973                    "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
8974                "}else if(o){",
8975                    
8976                    "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
8977                "}",
8978            "}",
8979
8980            "return v;"
8981        ].join('\n');
8982
8983        return function(format) {
8984            var regexNum = Date.parseRegexes.length,
8985                currentGroup = 1,
8986                calc = [],
8987                regex = [],
8988                special = false,
8989                ch = "",
8990                i = 0,
8991                obj,
8992                last;
8993
8994            for (; i < format.length; ++i) {
8995                ch = format.charAt(i);
8996                if (!special && ch == "\\") {
8997                    special = true;
8998                } else if (special) {
8999                    special = false;
9000                    regex.push(String.escape(ch));
9001                } else {
9002                    obj = $f(ch, currentGroup);
9003                    currentGroup += obj.g;
9004                    regex.push(obj.s);
9005                    if (obj.g && obj.c) {
9006                        if (obj.calcLast) {
9007                            last = obj.c;
9008                        } else {
9009                            calc.push(obj.c);
9010                        }
9011                    }
9012                }
9013            }
9014            
9015            if (last) {
9016                calc.push(last);
9017            }
9018
9019            Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
9020            Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
9021        };
9022    }(),
9023
9024    
9025    parseCodes : {
9026        
9027        d: {
9028            g:1,
9029            c:"d = parseInt(results[{0}], 10);\n",
9030            s:"(\\d{2})" 
9031        },
9032        j: {
9033            g:1,
9034            c:"d = parseInt(results[{0}], 10);\n",
9035            s:"(\\d{1,2})" 
9036        },
9037        D: function() {
9038            for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); 
9039            return {
9040                g:0,
9041                c:null,
9042                s:"(?:" + a.join("|") +")"
9043            };
9044        },
9045        l: function() {
9046            return {
9047                g:0,
9048                c:null,
9049                s:"(?:" + Date.dayNames.join("|") + ")"
9050            };
9051        },
9052        N: {
9053            g:0,
9054            c:null,
9055            s:"[1-7]" 
9056        },
9057        S: {
9058            g:0,
9059            c:null,
9060            s:"(?:st|nd|rd|th)"
9061        },
9062        w: {
9063            g:0,
9064            c:null,
9065            s:"[0-6]" 
9066        },
9067        z: {
9068            g:1,
9069            c:"z = parseInt(results[{0}], 10);\n",
9070            s:"(\\d{1,3})" 
9071        },
9072        W: {
9073            g:0,
9074            c:null,
9075            s:"(?:\\d{2})" 
9076        },
9077        F: function() {
9078            return {
9079                g:1,
9080                c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", 
9081                s:"(" + Date.monthNames.join("|") + ")"
9082            };
9083        },
9084        M: function() {
9085            for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); 
9086            return Ext.applyIf({
9087                s:"(" + a.join("|") + ")"
9088            }, $f("F"));
9089        },
9090        m: {
9091            g:1,
9092            c:"m = parseInt(results[{0}], 10) - 1;\n",
9093            s:"(\\d{2})" 
9094        },
9095        n: {
9096            g:1,
9097            c:"m = parseInt(results[{0}], 10) - 1;\n",
9098            s:"(\\d{1,2})" 
9099        },
9100        t: {
9101            g:0,
9102            c:null,
9103            s:"(?:\\d{2})" 
9104        },
9105        L: {
9106            g:0,
9107            c:null,
9108            s:"(?:1|0)"
9109        },
9110        o: function() {
9111            return $f("Y");
9112        },
9113        Y: {
9114            g:1,
9115            c:"y = parseInt(results[{0}], 10);\n",
9116            s:"(\\d{4})" 
9117        },
9118        y: {
9119            g:1,
9120            c:"var ty = parseInt(results[{0}], 10);\n"
9121                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", 
9122            s:"(\\d{1,2})"
9123        },
9124        
9125        a: function(){
9126            return $f("A");
9127        },
9128        A: {
9129            
9130            calcLast: true,
9131            g:1,
9132            c:"if (/(am)/i.test(results[{0}])) {\n"
9133                + "if (!h || h == 12) { h = 0; }\n"
9134                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
9135            s:"(AM|PM|am|pm)"
9136        },
9137        g: function() {
9138            return $f("G");
9139        },
9140        G: {
9141            g:1,
9142            c:"h = parseInt(results[{0}], 10);\n",
9143            s:"(\\d{1,2})" 
9144        },
9145        h: function() {
9146            return $f("H");
9147        },
9148        H: {
9149            g:1,
9150            c:"h = parseInt(results[{0}], 10);\n",
9151            s:"(\\d{2})" 
9152        },
9153        i: {
9154            g:1,
9155            c:"i = parseInt(results[{0}], 10);\n",
9156            s:"(\\d{2})" 
9157        },
9158        s: {
9159            g:1,
9160            c:"s = parseInt(results[{0}], 10);\n",
9161            s:"(\\d{2})" 
9162        },
9163        u: {
9164            g:1,
9165            c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
9166            s:"(\\d+)" 
9167        },
9168        O: {
9169            g:1,
9170            c:[
9171                "o = results[{0}];",
9172                "var sn = o.substring(0,1),", 
9173                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", 
9174                    "mn = o.substring(3,5) % 60;", 
9175                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
9176            ].join("\n"),
9177            s: "([+\-]\\d{4})" 
9178        },
9179        P: {
9180            g:1,
9181            c:[
9182                "o = results[{0}];",
9183                "var sn = o.substring(0,1),", 
9184                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", 
9185                    "mn = o.substring(4,6) % 60;", 
9186                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
9187            ].join("\n"),
9188            s: "([+\-]\\d{2}:\\d{2})" 
9189        },
9190        T: {
9191            g:0,
9192            c:null,
9193            s:"[A-Z]{1,4}" 
9194        },
9195        Z: {
9196            g:1,
9197            c:"zz = results[{0}] * 1;\n" 
9198                  + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
9199            s:"([+\-]?\\d{1,5})" 
9200        },
9201        c: function() {
9202            var calc = [],
9203                arr = [
9204                    $f("Y", 1), 
9205                    $f("m", 2), 
9206                    $f("d", 3), 
9207                    $f("h", 4), 
9208                    $f("i", 5), 
9209                    $f("s", 6), 
9210                    {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, 
9211                    {c:[ 
9212                        "if(results[8]) {", 
9213                            "if(results[8] == 'Z'){",
9214                                "zz = 0;", 
9215                            "}else if (results[8].indexOf(':') > -1){",
9216                                $f("P", 8).c, 
9217                            "}else{",
9218                                $f("O", 8).c, 
9219                            "}",
9220                        "}"
9221                    ].join('\n')}
9222                ];
9223
9224            for (var i = 0, l = arr.length; i < l; ++i) {
9225                calc.push(arr[i].c);
9226            }
9227
9228            return {
9229                g:1,
9230                c:calc.join(""),
9231                s:[
9232                    arr[0].s, 
9233                    "(?:", "-", arr[1].s, 
9234                        "(?:", "-", arr[2].s, 
9235                            "(?:",
9236                                "(?:T| )?", 
9237                                arr[3].s, ":", arr[4].s,  
9238                                "(?::", arr[5].s, ")?", 
9239                                "(?:(?:\\.|,)(\\d+))?", 
9240                                "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", 
9241                            ")?",
9242                        ")?",
9243                    ")?"
9244                ].join("")
9245            };
9246        },
9247        U: {
9248            g:1,
9249            c:"u = parseInt(results[{0}], 10);\n",
9250            s:"(-?\\d+)" 
9251        }
9252    }
9253});
9254
9255}());
9256
9257Ext.apply(Date.prototype, {
9258    
9259    dateFormat : function(format) {
9260        if (Date.formatFunctions[format] == null) {
9261            Date.createFormat(format);
9262        }
9263        return Date.formatFunctions[format].call(this);
9264    },
9265
9266    
9267    getTimezone : function() {
9268        
9269        
9270        
9271        
9272        
9273        
9274        
9275        
9276        
9277        
9278        
9279        
9280        return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
9281    },
9282
9283    
9284    getGMTOffset : function(colon) {
9285        return (this.getTimezoneOffset() > 0 ? "-" : "+")
9286            + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
9287            + (colon ? ":" : "")
9288            + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
9289    },
9290
9291    
9292    getDayOfYear: function() {
9293        var num = 0,
9294            d = this.clone(),
9295            m = this.getMonth(),
9296            i;
9297
9298        for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
9299            num += d.getDaysInMonth();
9300        }
9301        return num + this.getDate() - 1;
9302    },
9303
9304    
9305    getWeekOfYear : function() {
9306        
9307        var ms1d = 864e5, 
9308            ms7d = 7 * ms1d; 
9309
9310        return function() { 
9311            var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, 
9312                AWN = Math.floor(DC3 / 7), 
9313                Wyr = new Date(AWN * ms7d).getUTCFullYear();
9314
9315            return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
9316        };
9317    }(),
9318
9319    
9320    isLeapYear : function() {
9321        var year = this.getFullYear();
9322        return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
9323    },
9324
9325    
9326    getFirstDayOfMonth : function() {
9327        var day = (this.getDay() - (this.getDate() - 1)) % 7;
9328        return (day < 0) ? (day + 7) : day;
9329    },
9330
9331    
9332    getLastDayOfMonth : function() {
9333        return this.getLastDateOfMonth().getDay();
9334    },
9335
9336
9337    
9338    getFirstDateOfMonth : function() {
9339        return new Date(this.getFullYear(), this.getMonth(), 1);
9340    },
9341
9342    
9343    getLastDateOfMonth : function() {
9344        return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
9345    },
9346
9347    
9348    getDaysInMonth: function() {
9349        var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
9350
9351        return function() { 
9352            var m = this.getMonth();
9353
9354            return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
9355        };
9356    }(),
9357
9358    
9359    getSuffix : function() {
9360        switch (this.getDate()) {
9361            case 1:
9362            case 21:
9363            case 31:
9364                return "st";
9365            case 2:
9366            case 22:
9367                return "nd";
9368            case 3:
9369            case 23:
9370                return "rd";
9371            default:
9372                return "th";
9373        }
9374    },
9375
9376    
9377    clone : function() {
9378        return new Date(this.getTime());
9379    },
9380
9381    
9382    isDST : function() {
9383        
9384        
9385        return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
9386    },
9387
9388    
9389    clearTime : function(clone) {
9390        if (clone) {
9391            return this.clone().clearTime();
9392        }
9393
9394        
9395        var d = this.getDate();
9396
9397        
9398        this.setHours(0);
9399        this.setMinutes(0);
9400        this.setSeconds(0);
9401        this.setMilliseconds(0);
9402
9403        if (this.getDate() != d) { 
9404            
9405            
9406
9407            
9408            for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
9409
9410            this.setDate(d);
9411            this.setHours(c.getHours());
9412        }
9413
9414        return this;
9415    },
9416
9417    
9418    add : function(interval, value) {
9419        var d = this.clone();
9420        if (!interval || value === 0) return d;
9421
9422        switch(interval.toLowerCase()) {
9423            case Date.MILLI:
9424                d.setMilliseconds(this.getMilliseconds() + value);
9425                break;
9426            case Date.SECOND:
9427                d.setSeconds(this.getSeconds() + value);
9428                break;
9429            case Date.MINUTE:
9430                d.setMinutes(this.getMinutes() + value);
9431                break;
9432            case Date.HOUR:
9433                d.setHours(this.getHours() + value);
9434                break;
9435            case Date.DAY:
9436                d.setDate(this.getDate() + value);
9437                break;
9438            case Date.MONTH:
9439                var day = this.getDate();
9440                if (day > 28) {
9441                    day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
9442                }
9443                d.setDate(day);
9444                d.setMonth(this.getMonth() + value);
9445                break;
9446            case Date.YEAR:
9447                d.setFullYear(this.getFullYear() + value);
9448                break;
9449        }
9450        return d;
9451    },
9452
9453    
9454    between : function(start, end) {
9455        var t = this.getTime();
9456        return start.getTime() <= t && t <= end.getTime();
9457    }
9458});
9459
9460
9461
9462Date.prototype.format = Date.prototype.dateFormat;
9463
9464
9465
9466if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
9467    Ext.apply(Date.prototype, {
9468        _xMonth : Date.prototype.setMonth,
9469        _xDate  : Date.prototype.setDate,
9470
9471        
9472        
9473        setMonth : function(num) {
9474            if (num <= -1) {
9475                var n = Math.ceil(-num),
9476                    back_year = Math.ceil(n / 12),
9477                    month = (n % 12) ? 12 - n % 12 : 0;
9478
9479                this.setFullYear(this.getFullYear() - back_year);
9480
9481                return this._xMonth(month);
9482            } else {
9483                return this._xMonth(num);
9484            }
9485        },
9486
9487        
9488        
9489        
9490        setDate : function(d) {
9491            
9492            
9493            return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
9494        }
9495    });
9496}
9497
9498
9499
9500
9501
9502Ext.util.MixedCollection = function(allowFunctions, keyFn){
9503    this.items = [];
9504    this.map = {};
9505    this.keys = [];
9506    this.length = 0;
9507    this.addEvents(
9508        
9509        'clear',
9510        
9511        'add',
9512        
9513        'replace',
9514        
9515        'remove',
9516        'sort'
9517    );
9518    this.allowFunctions = allowFunctions === true;
9519    if(keyFn){
9520        this.getKey = keyFn;
9521    }
9522    Ext.util.MixedCollection.superclass.constructor.call(this);
9523};
9524
9525Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
9526
9527    
9528    allowFunctions : false,
9529
9530    
9531    add : function(key, o){
9532        if(arguments.length == 1){
9533            o = arguments[0];
9534            key = this.getKey(o);
9535        }
9536        if(typeof key != 'undefined' && key !== null){
9537            var old = this.map[key];
9538            if(typeof old != 'undefined'){
9539                return this.replace(key, o);
9540            }
9541            this.map[key] = o;
9542        }
9543        this.length++;
9544        this.items.push(o);
9545        this.keys.push(key);
9546        this.fireEvent('add', this.length-1, o, key);
9547        return o;
9548    },
9549
9550    
9551    getKey : function(o){
9552         return o.id;
9553    },
9554
9555    
9556    replace : function(key, o){
9557        if(arguments.length == 1){
9558            o = arguments[0];
9559            key = this.getKey(o);
9560        }
9561        var old = this.map[key];
9562        if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
9563             return this.add(key, o);
9564        }
9565        var index = this.indexOfKey(key);
9566        this.items[index] = o;
9567        this.map[key] = o;
9568        this.fireEvent('replace', key, old, o);
9569        return o;
9570    },
9571
9572    
9573    addAll : function(objs){
9574        if(arguments.length > 1 || Ext.isArray(objs)){
9575            var args = arguments.length > 1 ? arguments : objs;
9576            for(var i = 0, len = args.length; i < len; i++){
9577                this.add(args[i]);
9578            }
9579        }else{
9580            for(var key in objs){
9581                if(this.allowFunctions || typeof objs[key] != 'function'){
9582                    this.add(key, objs[key]);
9583                }
9584            }
9585        }
9586    },
9587
9588    
9589    each : function(fn, scope){
9590        var items = [].concat(this.items); 
9591        for(var i = 0, len = items.length; i < len; i++){
9592            if(fn.call(scope || items[i], items[i], i, len) === false){
9593                break;
9594            }
9595        }
9596    },
9597
9598    
9599    eachKey : function(fn, scope){
9600        for(var i = 0, len = this.keys.length; i < len; i++){
9601            fn.call(scope || window, this.keys[i], this.items[i], i, len);
9602        }
9603    },
9604
9605    
9606    find : function(fn, scope){
9607        for(var i = 0, len = this.items.length; i < len; i++){
9608            if(fn.call(scope || window, this.items[i], this.keys[i])){
9609                return this.items[i];
9610            }
9611        }
9612        return null;
9613    },
9614
9615    
9616    insert : function(index, key, o){
9617        if(arguments.length == 2){
9618            o = arguments[1];
9619            key = this.getKey(o);
9620        }
9621        if(this.containsKey(key)){
9622            this.suspendEvents();
9623            this.removeKey(key);
9624            this.resumeEvents();
9625        }
9626        if(index >= this.length){
9627            return this.add(key, o);
9628        }
9629        this.length++;
9630        this.items.splice(index, 0, o);
9631        if(typeof key != 'undefined' && key !== null){
9632            this.map[key] = o;
9633        }
9634        this.keys.splice(index, 0, key);
9635        this.fireEvent('add', index, o, key);
9636        return o;
9637    },
9638
9639    
9640    remove : function(o){
9641        return this.removeAt(this.indexOf(o));
9642    },
9643
9644    
9645    removeAt : function(index){
9646        if(index < this.length && index >= 0){
9647            this.length--;
9648            var o = this.items[index];
9649            this.items.splice(index, 1);
9650            var key = this.keys[index];
9651            if(typeof key != 'undefined'){
9652                delete this.map[key];
9653            }
9654            this.keys.splice(index, 1);
9655            this.fireEvent('remove', o, key);
9656            return o;
9657        }
9658        return false;
9659    },
9660
9661    
9662    removeKey : function(key){
9663        return this.removeAt(this.indexOfKey(key));
9664    },
9665
9666    
9667    getCount : function(){
9668        return this.length;
9669    },
9670
9671    
9672    indexOf : function(o){
9673        return this.items.indexOf(o);
9674    },
9675
9676    
9677    indexOfKey : function(key){
9678        return this.keys.indexOf(key);
9679    },
9680
9681    
9682    item : function(key){
9683        var mk = this.map[key],
9684            item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
9685        return typeof item != 'function' || this.allowFunctions ? item : null; 
9686    },
9687
9688    
9689    itemAt : function(index){
9690        return this.items[index];
9691    },
9692
9693    
9694    key : function(key){
9695        return this.map[key];
9696    },
9697
9698    
9699    contains : function(o){
9700        return this.indexOf(o) != -1;
9701    },
9702
9703    
9704    containsKey : function(key){
9705        return typeof this.map[key] != 'undefined';
9706    },
9707
9708    
9709    clear : function(){
9710        this.length = 0;
9711        this.items = [];
9712        this.keys = [];
9713        this.map = {};
9714        this.fireEvent('clear');
9715    },
9716
9717    
9718    first : function(){
9719        return this.items[0];
9720    },
9721
9722    
9723    last : function(){
9724        return this.items[this.length-1];
9725    },
9726
9727    
9728    _sort : function(property, dir, fn){
9729        var i, len,
9730            dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
9731
9732            
9733            c     = [],
9734            keys  = this.keys,
9735            items = this.items;
9736
9737        
9738        fn = fn || function(a, b) {
9739            return a - b;
9740        };
9741
9742        
9743        for(i = 0, len = items.length; i < len; i++){
9744            c[c.length] = {
9745                key  : keys[i],
9746                value: items[i],
9747                index: i
9748            };
9749        }
9750
9751        
9752        c.sort(function(a, b){
9753            var v = fn(a[property], b[property]) * dsc;
9754            if(v === 0){
9755                v = (a.index < b.index ? -1 : 1);
9756            }
9757            return v;
9758        });
9759
9760        
9761        for(i = 0, len = c.length; i < len; i++){
9762            items[i] = c[i].value;
9763            keys[i]  = c[i].key;
9764        }
9765
9766        this.fireEvent('sort', this);
9767    },
9768
9769    
9770    sort : function(dir, fn){
9771        this._sort('value', dir, fn);
9772    },
9773
9774    
9775    reorder: function(mapping) {
9776        this.suspendEvents();
9777
9778        var items = this.items,
9779            index = 0,
9780            length = items.length,
9781            order = [],
9782            remaining = [],
9783            oldIndex;
9784
9785        
9786        for (oldIndex in mapping) {
9787            order[mapping[oldIndex]] = items[oldIndex];
9788        }
9789
9790        for (index = 0; index < length; index++) {
9791            if (mapping[index] == undefined) {
9792                remaining.push(items[index]);
9793            }
9794        }
9795
9796        for (index = 0; index < length; index++) {
9797            if (order[index] == undefined) {
9798                order[index] = remaining.shift();
9799            }
9800        }
9801
9802        this.clear();
9803        this.addAll(order);
9804
9805        this.resumeEvents();
9806        this.fireEvent('sort', this);
9807    },
9808
9809    
9810    keySort : function(dir, fn){
9811        this._sort('key', dir, fn || function(a, b){
9812            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
9813            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
9814        });
9815    },
9816
9817    
9818    getRange : function(start, end){
9819        var items = this.items;
9820        if(items.length < 1){
9821            return [];
9822        }
9823        start = start || 0;
9824        end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
9825        var i, r = [];
9826        if(start <= end){
9827            for(i = start; i <= end; i++) {
9828                r[r.length] = items[i];
9829            }
9830        }else{
9831            for(i = start; i >= end; i--) {
9832                r[r.length] = items[i];
9833            }
9834        }
9835        return r;
9836    },
9837
9838    
9839    filter : function(property, value, anyMatch, caseSensitive){
9840        if(Ext.isEmpty(value, false)){
9841            return this.clone();
9842        }
9843        value = this.createValueMatcher(value, anyMatch, caseSensitive);
9844        return this.filterBy(function(o){
9845            return o && value.test(o[property]);
9846        });
9847    },
9848
9849    
9850    filterBy : function(fn, scope){
9851        var r = new Ext.util.MixedCollection();
9852        r.getKey = this.getKey;
9853        var k = this.keys, it = this.items;
9854        for(var i = 0, len = it.length; i < len; i++){
9855            if(fn.call(scope||this, it[i], k[i])){
9856                r.add(k[i], it[i]);
9857            }
9858        }
9859        return r;
9860    },
9861
9862    
9863    findIndex : function(property, value, start, anyMatch, caseSensitive){
9864        if(Ext.isEmpty(value, false)){
9865            return -1;
9866        }
9867        value = this.createValueMatcher(value, anyMatch, caseSensitive);
9868        return this.findIndexBy(function(o){
9869            return o && value.test(o[property]);
9870        }, null, start);
9871    },
9872
9873    
9874    findIndexBy : function(fn, scope, start){
9875        var k = this.keys, it = this.items;
9876        for(var i = (start||0), len = it.length; i < len; i++){
9877            if(fn.call(scope||this, it[i], k[i])){
9878                return i;
9879            }
9880        }
9881        return -1;
9882    },
9883
9884    
9885    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
9886        if (!value.exec) { 
9887            var er = Ext.escapeRe;
9888            value = String(value);
9889
9890            if (anyMatch === true) {
9891                value = er(value);
9892            } else {
9893                value = '^' + er(value);
9894                if (exactMatch === true) {
9895                    value += '$';
9896                }
9897            }
9898            value = new RegExp(value, caseSensitive ? '' : 'i');
9899         }
9900         return value;
9901    },
9902
9903    
9904    clone : function(){
9905        var r = new Ext.util.MixedCollection();
9906        var k = this.keys, it = this.items;
9907        for(var i = 0, len = it.length; i < len; i++){
9908            r.add(k[i], it[i]);
9909        }
9910        r.getKey = this.getKey;
9911        return r;
9912    }
9913});
9914
9915Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
9916
9917Ext.AbstractManager = Ext.extend(Object, {
9918    typeName: 'type',
9919    
9920    constructor: function(config) {
9921        Ext.apply(this, config || {});
9922        
9923        
9924        this.all = new Ext.util.MixedCollection();
9925        
9926        this.types = {};
9927    },
9928    
9929    
9930    get : function(id){
9931        return this.all.get(id);
9932    },
9933    
9934    
9935    register: function(item) {
9936        this.all.add(item);
9937    },
9938    
9939    
9940    unregister: function(item) {
9941        this.all.remove(item);        
9942    },
9943    
9944    
9945    registerType : function(type, cls){
9946        this.types[type] = cls;
9947        cls[this.typeName] = type;
9948    },
9949    
9950    
9951    isRegistered : function(type){
9952        return this.types[type] !== undefined;    
9953    },
9954    
9955    
9956    create: function(config, defaultType) {
9957        var type        = config[this.typeName] || config.type || defaultType,
9958            Constructor = this.types[type];
9959        
9960        if (Constructor == undefined) {
9961            throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
9962        }
9963        
9964        return new Constructor(config);
9965    },
9966    
9967    
9968    onAvailable : function(id, fn, scope){
9969        var all = this.all;
9970        
9971        all.on("add", function(index, o){
9972            if (o.id == id) {
9973                fn.call(scope || o, o);
9974                all.un("add", fn, scope);
9975            }
9976        });
9977    }
9978});
9979Ext.util.Format = function() {
9980    var trimRe         = /^\s+|\s+$/g,
9981        stripTagsRE    = /<\/?[^>]+>/gi,
9982        stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
9983        nl2brRe        = /\r?\n/g;
9984
9985    return {
9986        
9987        ellipsis : function(value, len, word) {
9988            if (value && value.length > len) {
9989                if (word) {
9990                    var vs    = value.substr(0, len - 2),
9991                        index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
9992                    if (index == -1 || index < (len - 15)) {
9993                        return value.substr(0, len - 3) + "...";
9994                    } else {
9995                        return vs.substr(0, index) + "...";
9996                    }
9997                } else {
9998                    return value.substr(0, len - 3) + "...";
9999                }
10000            }
10001            return value;
10002        },
10003
10004        
10005        undef : function(value) {
10006            return value !== undefined ? value : "";
10007        },
10008
10009        
10010        defaultValue : function(value, defaultValue) {
10011            return value !== undefined && value !== '' ? value : defaultValue;
10012        },
10013
10014        
10015        htmlEncode : function(value) {
10016            return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
10017        },
10018
10019        
10020        htmlDecode : function(value) {
10021            return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
10022        },
10023
10024        
10025        trim : function(value) {
10026            return String(value).replace(trimRe, "");
10027        },
10028
10029        
10030        substr : function(value, start, length) {
10031            return String(value).substr(start, length);
10032        },
10033
10034        
10035        lowercase : function(value) {
10036            return String(value).toLowerCase();
10037        },
10038
10039        
10040        uppercase : function(value) {
10041            return String(value).toUpperCase();
10042        },
10043
10044        
10045        capitalize : function(value) {
10046            return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
10047        },
10048
10049        
10050        call : function(value, fn) {
10051            if (arguments.length > 2) {
10052                var args = Array.prototype.slice.call(arguments, 2);
10053                args.unshift(value);
10054                return eval(fn).apply(window, args);
10055            } else {
10056                return eval(fn).call(window, value);
10057            }
10058        },
10059
10060        
10061        usMoney : function(v) {
10062            v = (Math.round((v-0)*100))/100;
10063            v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
10064            v = String(v);
10065            var ps = v.split('.'),
10066                whole = ps[0],
10067                sub = ps[1] ? '.'+ ps[1] : '.00',
10068                r = /(\d+)(\d{3})/;
10069            while (r.test(whole)) {
10070                whole = whole.replace(r, '$1' + ',' + '$2');
10071            }
10072            v = whole + sub;
10073            if (v.charAt(0) == '-') {
10074                return '-$' + v.substr(1);
10075            }
10076            return "$" +  v;
10077        },
10078
10079        
10080        date : function(v, format) {
10081            if (!v) {
10082                return "";
10083            }
10084            if (!Ext.isDate(v)) {
10085                v = new Date(Date.parse(v));
10086            }
10087            return v.dateFormat(format || "m/d/Y");
10088        },
10089
10090        
10091        dateRenderer : function(format) {
10092            return function(v) {
10093                return Ext.util.Format.date(v, format);
10094            };
10095        },
10096
10097        
10098        stripTags : function(v) {
10099            return !v ? v : String(v).replace(stripTagsRE, "");
10100        },
10101
10102        
10103        stripScripts : function(v) {
10104            return !v ? v : String(v).replace(stripScriptsRe, "");
10105        },
10106
10107        
10108        fileSize : function(size) {
10109            if (size < 1024) {
10110                return size + " bytes";
10111            } else if (size < 1048576) {
10112                return (Math.round(((size*10) / 1024))/10) + " KB";
10113            } else {
10114                return (Math.round(((size*10) / 1048576))/10) + " MB";
10115            }
10116        },
10117
10118        
10119        math : function(){
10120            var fns = {};
10121            
10122            return function(v, a){
10123                if (!fns[a]) {
10124                    fns[a] = new Function('v', 'return v ' + a + ';');
10125                }
10126                return fns[a](v);
10127            };
10128        }(),
10129
10130        
10131        round : function(value, precision) {
10132            var result = Number(value);
10133            if (typeof precision == 'number') {
10134                precision = Math.pow(10, precision);
10135                result = Math.round(value * precision) / precision;
10136            }
10137            return result;
10138        },
10139
10140        
10141        number: function(v, format) {
10142            if (!format) {
10143                return v;
10144            }
10145            v = Ext.num(v, NaN);
10146            if (isNaN(v)) {
10147                return '';
10148            }
10149            var comma = ',',
10150                dec   = '.',
10151                i18n  = false,
10152                neg   = v < 0;
10153
10154            v = Math.abs(v);
10155            if (format.substr(format.length - 2) == '/i') {
10156                format = format.substr(0, format.length - 2);
10157                i18n   = true;
10158                comma  = '.';
10159                dec    = ',';
10160            }
10161
10162            var hasComma = format.indexOf(comma) != -1,
10163                psplit   = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
10164
10165            if (1 < psplit.length) {
10166                v = v.toFixed(psplit[1].length);
10167            } else if(2 < psplit.length) {
10168                throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
10169            } else {
10170                v = v.toFixed(0);
10171            }
10172
10173            var fnum = v.toString();
10174
10175            psplit = fnum.split('.');
10176
10177            if (hasComma) {
10178                var cnum = psplit[0], 
10179                    parr = [], 
10180                    j    = cnum.length, 
10181                    m    = Math.floor(j / 3),
10182                    n    = cnum.length % 3 || 3,
10183                    i;
10184
10185                for (i = 0; i < j; i += n) {
10186                    if (i != 0) {
10187                        n = 3;
10188                    }
10189                    
10190                    parr[parr.length] = cnum.substr(i, n);
10191                    m -= 1;
10192                }
10193                fnum = parr.join(comma);
10194                if (psplit[1]) {
10195                    fnum += dec + psplit[1];
10196                }
10197            } else {
10198                if (psplit[1]) {
10199                    fnum = psplit[0] + dec + psplit[1];
10200                }
10201            }
10202
10203            return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
10204        },
10205
10206        
10207        numberRenderer : function(format) {
10208            return function(v) {
10209                return Ext.util.Format.number(v, format);
10210            };
10211        },
10212
10213        
10214        plural : function(v, s, p) {
10215            return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
10216        },
10217
10218        
10219        nl2br : function(v) {
10220            return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
10221        }
10222    };
10223}();
10224
10225Ext.XTemplate = function(){
10226    Ext.XTemplate.superclass.constructor.apply(this, arguments);
10227
10228    var me = this,
10229        s = me.html,
10230        re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
10231        nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
10232        ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
10233        execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
10234        m,
10235        id = 0,
10236        tpls = [],
10237        VALUES = 'values',
10238        PARENT = 'parent',
10239        XINDEX = 'xindex',
10240        XCOUNT = 'xcount',
10241        RETURN = 'return ',
10242        WITHVALUES = 'with(values){ ';
10243
10244    s = ['<tpl>', s, '</tpl>'].join('');
10245
10246    while((m = s.match(re))){
10247        var m2 = m[0].match(nameRe),
10248            m3 = m[0].match(ifRe),
10249            m4 = m[0].match(execRe),
10250            exp = null,
10251            fn = null,
10252            exec = null,
10253            name = m2 && m2[1] ? m2[1] : '';
10254
10255       if (m3) {
10256           exp = m3 && m3[1] ? m3[1] : null;
10257           if(exp){
10258               fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
10259           }
10260       }
10261       if (m4) {
10262           exp = m4 && m4[1] ? m4[1] : null;
10263           if(exp){
10264               exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
10265           }
10266       }
10267       if(name){
10268           switch(name){
10269               case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
10270               case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
10271               default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
10272           }
10273       }
10274       tpls.push({
10275            id: id,
10276            target: name,
10277            exec: exec,
10278            test: fn,
10279            body: m[1]||''
10280        });
10281       s = s.replace(m[0], '{xtpl'+ id + '}');
10282       ++id;
10283    }
10284    for(var i = tpls.length-1; i >= 0; --i){
10285        me.compileTpl(tpls[i]);
10286    }
10287    me.master = tpls[tpls.length-1];
10288    me.tpls = tpls;
10289};
10290Ext.extend(Ext.XTemplate, Ext.Template, {
10291    
10292    re : /\{([\w\-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
10293    
10294    codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
10295
10296    
10297    applySubTemplate : function(id, values, parent, xindex, xcount){
10298        var me = this,
10299            len,
10300            t = me.tpls[id],
10301            vs,
10302            buf = [];
10303        if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
10304            (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
10305            return '';
10306        }
10307        vs = t.target ? t.target.call(me, values, parent) : values;
10308        len = vs.length;
10309        parent = t.target ? values : parent;
10310        if(t.target && Ext.isArray(vs)){
10311            for(var i = 0, len = vs.length; i < len; i++){
10312                buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
10313            }
10314            return buf.join('');
10315        }
10316        return t.compiled.call(me, vs, parent, xindex, xcount);
10317    },
10318
10319    
10320    compileTpl : function(tpl){
10321        var fm = Ext.util.Format,
10322            useF = this.disableFormats !== true,
10323            sep = Ext.isGecko ? "+" : ",",
10324            body;
10325
10326        function fn(m, name, format, args, math){
10327            if(name.substr(0, 4) == 'xtpl'){
10328                return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
10329            }
10330            var v;
10331            if(name === '.'){
10332                v = 'values';
10333            }else if(name === '#'){
10334                v = 'xindex';
10335            }else if(name.indexOf('.') != -1){
10336                v = name;
10337            }else{
10338                v = "values['" + name + "']";
10339            }
10340            if(math){
10341                v = '(' + v + math + ')';
10342            }
10343            if (format && useF) {
10344                args = args ? ',' + args : "";
10345                if(format.substr(0, 5) != "this."){
10346                    format = "fm." + format + '(';
10347                }else{
10348                    format = 'this.call("'+ format.substr(5) + '", ';
10349                    args = ", values";
10350                }
10351            } else {
10352                args= ''; format = "("+v+" === undefined ? '' : ";
10353            }
10354            return "'"+ sep + format + v + args + ")"+sep+"'";
10355        }
10356
10357        function codeFn(m, code){
10358            
10359            return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
10360        }
10361
10362        
10363        if(Ext.isGecko){
10364            body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
10365                   tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
10366                    "';};";
10367        }else{
10368            body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
10369            body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
10370            body.push("'].join('');};");
10371            body = body.join('');
10372        }
10373        eval(body);
10374        return this;
10375    },
10376
10377    
10378    applyTemplate : function(values){
10379        return this.master.compiled.call(this, values, {}, 1, 1);
10380    },
10381
10382    
10383    compile : function(){return this;}
10384
10385    
10386    
10387    
10388
10389});
10390
10391Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
10392
10393
10394Ext.XTemplate.from = function(el){
10395    el = Ext.getDom(el);
10396    return new Ext.XTemplate(el.value || el.innerHTML);
10397};
10398
10399Ext.util.CSS = function(){
10400	var rules = null;
10401   	var doc = document;
10402
10403    var camelRe = /(-[a-z])/gi;
10404    var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
10405
10406   return {
10407   
10408   createStyleSheet : function(cssText, id){
10409       var ss;
10410       var head = doc.getElementsByTagName("head")[0];
10411       var rules = doc.createElement("style");
10412       rules.setAttribute("type", "text/css");
10413       if(id){
10414           rules.setAttribute("id", id);
10415       }
10416       if(Ext.isIE){
10417           head.appendChild(rules);
10418           ss = rules.styleSheet;
10419           ss.cssText = cssText;
10420       }else{
10421           try{
10422                rules.appendChild(doc.createTextNode(cssText));
10423           }catch(e){
10424               rules.cssText = cssText;
10425           }
10426           head.appendChild(rules);
10427           ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
10428       }
10429       this.cacheStyleSheet(ss);
10430       return ss;
10431   },
10432
10433   
10434   removeStyleSheet : function(id){
10435       var existing = doc.getElementById(id);
10436       if(existing){
10437           existing.parentNode.removeChild(existing);
10438       }
10439   },
10440
10441   
10442   swapStyleSheet : function(id, url){
10443       this.removeStyleSheet(id);
10444       var ss = doc.createElement("link");
10445       ss.setAttribute("rel", "stylesheet");
10446       ss.setAttribute("type", "text/css");
10447       ss.setAttribute("id", id);
10448       ss.setAttribute("href", url);
10449       doc.getElementsByTagName("head")[0].appendChild(ss);
10450   },
10451   
10452   
10453   refreshCache : function(){
10454       return this.getRules(true);
10455   },
10456
10457   
10458   cacheStyleSheet : function(ss){
10459       if(!rules){
10460           rules = {};
10461       }
10462       try{
10463           var ssRules = ss.cssRules || ss.rules;
10464           for(var j = ssRules.length-1; j >= 0; --j){
10465               rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
10466           }
10467       }catch(e){}
10468   },
10469   
10470   
10471   getRules : function(refreshCache){
10472   		if(rules === null || refreshCache){
10473   			rules = {};
10474   			var ds = doc.styleSheets;
10475   			for(var i =0, len = ds.length; i < len; i++){
10476   			    try{
10477    		        this.cacheStyleSheet(ds[i]);
10478    		    }catch(e){} 
10479	        }
10480   		}
10481   		return rules;
10482   	},
10483   	
10484   	
10485   getRule : function(selector, refreshCache){
10486   		var rs = this.getRules(refreshCache);
10487   		if(!Ext.isArray(selector)){
10488   		    return rs[selector.toLowerCase()];
10489   		}
10490   		for(var i = 0; i < selector.length; i++){
10491			if(rs[selector[i]]){
10492				return rs[selector[i].toLowerCase()];
10493			}
10494		}
10495		return null;
10496   	},
10497   	
10498   	
10499   	
10500   updateRule : function(selector, property, value){
10501   		if(!Ext.isArray(selector)){
10502   			var rule = this.getRule(selector);
10503   			if(rule){
10504   				rule.style[property.replace(camelRe, camelFn)] = value;
10505   				return true;
10506   			}
10507   		}else{
10508   			for(var i = 0; i < selector.length; i++){
10509   				if(this.updateRule(selector[i], property, value)){
10510   					return true;
10511   				}
10512   			}
10513   		}
10514   		return false;
10515   	}
10516   };	
10517}();
10518Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
10519    
10520    constructor : function(el, config){
10521        this.el = Ext.get(el);
10522        this.el.unselectable();
10523
10524        Ext.apply(this, config);
10525
10526        this.addEvents(
10527        
10528        "mousedown",
10529        
10530        "click",
10531        
10532        "mouseup"
10533        );
10534
10535        if(!this.disabled){
10536            this.disabled = true;
10537            this.enable();
10538        }
10539
10540        
10541        if(this.handler){
10542            this.on("click", this.handler,  this.scope || this);
10543        }
10544
10545        Ext.util.ClickRepeater.superclass.constructor.call(this);        
10546    },
10547    
10548    interval : 20,
10549    delay: 250,
10550    preventDefault : true,
10551    stopDefault : false,
10552    timer : 0,
10553
10554    
10555    enable: function(){
10556        if(this.disabled){
10557            this.el.on('mousedown', this.handleMouseDown, this);
10558            if (Ext.isIE){
10559                this.el.on('dblclick', this.handleDblClick, this);
10560            }
10561            if(this.preventDefault || this.stopDefault){
10562                this.el.on('click', this.eventOptions, this);
10563            }
10564        }
10565        this.disabled = false;
10566    },
10567
10568    
10569    disable: function( force){
10570        if(force || !this.disabled){
10571            clearTimeout(this.timer);
10572            if(this.pressClass){
10573                this.el.removeClass(this.pressClass);
10574            }
10575            Ext.getDoc().un('mouseup', this.handleMouseUp, this);
10576            this.el.removeAllListeners();
10577        }
10578        this.disabled = true;
10579    },
10580
10581    
10582    setDisabled: function(disabled){
10583        this[disabled ? 'disable' : 'enable']();
10584    },
10585
10586    eventOptions: function(e){
10587        if(this.preventDefault){
10588            e.preventDefault();
10589        }
10590        if(this.stopDefault){
10591            e.stopEvent();
10592        }
10593    },
10594
10595    
10596    destroy : function() {
10597        this.disable(true);
10598        Ext.destroy(this.el);
10599        this.purgeListeners();
10600    },
10601
10602    handleDblClick : function(e){
10603        clearTimeout(this.timer);
10604        this.el.blur();
10605
10606        this.fireEvent("mousedown", this, e);
10607        this.fireEvent("click", this, e);
10608    },
10609
10610    
10611    handleMouseDown : function(e){
10612        clearTimeout(this.timer);
10613        this.el.blur();
10614        if(this.pressClass){
10615            this.el.addClass(this.pressClass);
10616        }
10617        this.mousedownTime = new Date();
10618
10619        Ext.getDoc().on("mouseup", this.handleMouseUp, this);
10620        this.el.on("mouseout", this.handleMouseOut, this);
10621
10622        this.fireEvent("mousedown", this, e);
10623        this.fireEvent("click", this, e);
10624
10625        
10626        if (this.accelerate) {
10627            this.delay = 400;
10628        }
10629        this.timer = this.click.defer(this.delay || this.interval, this, [e]);
10630    },
10631
10632    
10633    click : function(e){
10634        this.fireEvent("click", this, e);
10635        this.timer = this.click.defer(this.accelerate ?
10636            this.easeOutExpo(this.mousedownTime.getElapsed(),
10637                400,
10638                -390,
10639                12000) :
10640            this.interval, this, [e]);
10641    },
10642
10643    easeOutExpo : function (t, b, c, d) {
10644        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10645    },
10646
10647    
10648    handleMouseOut : function(){
10649        clearTimeout(this.timer);
10650        if(this.pressClass){
10651            this.el.removeClass(this.pressClass);
10652        }
10653        this.el.on("mouseover", this.handleMouseReturn, this);
10654    },
10655
10656    
10657    handleMouseReturn : function(){
10658        this.el.un("mouseover", this.handleMouseReturn, this);
10659        if(this.pressClass){
10660            this.el.addClass(this.pressClass);
10661        }
10662        this.click();
10663    },
10664
10665    
10666    handleMouseUp : function(e){
10667        clearTimeout(this.timer);
10668        this.el.un("mouseover", this.handleMouseReturn, this);
10669        this.el.un("mouseout", this.handleMouseOut, this);
10670        Ext.getDoc().un("mouseup", this.handleMouseUp, this);
10671        this.el.removeClass(this.pressClass);
10672        this.fireEvent("mouseup", this, e);
10673    }
10674});
10675Ext.KeyNav = function(el, config){
10676    this.el = Ext.get(el);
10677    Ext.apply(this, config);
10678    if(!this.disabled){
10679        this.disabled = true;
10680        this.enable();
10681    }
10682};
10683
10684Ext.KeyNav.prototype = {
10685    
10686    disabled : false,
10687    
10688    defaultEventAction: "stopEvent",
10689    
10690    forceKeyDown : false,
10691
10692    
10693    relay : function(e){
10694        var k = e.getKey(),
10695            h = this.keyToHandler[k];
10696        if(h && this[h]){
10697            if(this.doRelay(e, this[h], h) !== true){
10698                e[this.defaultEventAction]();
10699            }
10700        }
10701    },
10702
10703    
10704    doRelay : function(e, h, hname){
10705        return h.call(this.scope || this, e, hname);
10706    },
10707
10708    
10709    enter : false,
10710    left : false,
10711    right : false,
10712    up : false,
10713    down : false,
10714    tab : false,
10715    esc : false,
10716    pageUp : false,
10717    pageDown : false,
10718    del : false,
10719    home : false,
10720    end : false,
10721    space : false,
10722
10723    
10724    keyToHandler : {
10725        37 : "left",
10726        39 : "right",
10727        38 : "up",
10728        40 : "down",
10729        33 : "pageUp",
10730        34 : "pageDown",
10731        46 : "del",
10732        36 : "home",
10733        35 : "end",
10734        13 : "enter",
10735        27 : "esc",
10736        9  : "tab",
10737        32 : "space"
10738    },
10739    
10740    stopKeyUp: function(e) {
10741        var k = e.getKey();
10742
10743        if (k >= 37 && k <= 40) {
10744            
10745            
10746            e.stopEvent();
10747        }
10748    },
10749    
10750    
10751    destroy: function(){
10752        this.disable();    
10753    },
10754
10755	
10756	enable: function() {
10757        if (this.disabled) {
10758            if (Ext.isSafari2) {
10759                
10760                this.el.on('keyup', this.stopKeyUp, this);
10761            }
10762
10763            this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10764            this.disabled = false;
10765        }
10766    },
10767
10768	
10769	disable: function() {
10770        if (!this.disabled) {
10771            if (Ext.isSafari2) {
10772                
10773                this.el.un('keyup', this.stopKeyUp, this);
10774            }
10775
10776            this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10777            this.disabled = true;
10778        }
10779    },
10780    
10781    
10782    setDisabled : function(disabled){
10783        this[disabled ? "disable" : "enable"]();
10784    },
10785    
10786    
10787    isKeydown: function(){
10788        return this.forceKeyDown || Ext.EventManager.useKeydown;
10789    }
10790};
10791
10792Ext.KeyMap = function(el, config, eventName){
10793    this.el  = Ext.get(el);
10794    this.eventName = eventName || "keydown";
10795    this.bindings = [];
10796    if(config){
10797        this.addBinding(config);
10798    }
10799    this.enable();
10800};
10801
10802Ext.KeyMap.prototype = {
10803    
10804    stopEvent : false,
10805
10806    
10807	addBinding : function(config){
10808        if(Ext.isArray(config)){
10809            Ext.each(config, function(c){
10810                this.addBinding(c);
10811            }, this);
10812            return;
10813        }
10814        var keyCode = config.key,
10815            fn = config.fn || config.handler,
10816            scope = config.scope;
10817
10818	if (config.stopEvent) {
10819	    this.stopEvent = config.stopEvent;    
10820	}	
10821
10822        if(typeof keyCode == "string"){
10823            var ks = [];
10824            var keyString = keyCode.toUpperCase();
10825            for(var j = 0, len = keyString.length; j < len; j++){
10826                ks.push(keyString.charCodeAt(j));
10827            }
10828            keyCode = ks;
10829        }
10830        var keyArray = Ext.isArray(keyCode);
10831        
10832        var handler = function(e){
10833            if(this.checkModifiers(config, e)){
10834                var k = e.getKey();
10835                if(keyArray){
10836                    for(var i = 0, len = keyCode.length; i < len; i++){
10837                        if(keyCode[i] == k){
10838                          if(this.stopEvent){
10839                              e.stopEvent();
10840                          }
10841                          fn.call(scope || window, k, e);
10842                          return;
10843                        }
10844                    }
10845                }else{
10846                    if(k == keyCode){
10847                        if(this.stopEvent){
10848                           e.stopEvent();
10849                        }
10850                        fn.call(scope || window, k, e);
10851                    }
10852                }
10853            }
10854        };
10855        this.bindings.push(handler);
10856	},
10857    
10858    
10859    checkModifiers: function(config, e){
10860        var val, key, keys = ['shift', 'ctrl', 'alt'];
10861        for (var i = 0, len = keys.length; i < len; ++i){
10862            key = keys[i];
10863            val = config[key];
10864            if(!(val === undefined || (val === e[key + 'Key']))){
10865                return false;
10866            }
10867        }
10868        return true;
10869    },
10870
10871    
10872    on : function(key, fn, scope){
10873        var keyCode, shift, ctrl, alt;
10874        if(typeof key == "object" && !Ext.isArray(key)){
10875            keyCode = key.key;
10876            shift = key.shift;
10877            ctrl = key.ctrl;
10878            alt = key.alt;
10879        }else{
10880            keyCode = key;
10881        }
10882        this.addBinding({
10883            key: keyCode,
10884            shift: shift,
10885            ctrl: ctrl,
10886            alt: alt,
10887            fn: fn,
10888            scope: scope
10889        });
10890    },
10891
10892    
10893    handleKeyDown : function(e){
10894	    if(this.enabled){ 
10895    	    var b = this.bindings;
10896    	    for(var i = 0, len = b.length; i < len; i++){
10897    	        b[i].call(this, e);
10898    	    }
10899	    }
10900	},
10901
10902	
10903	isEnabled : function(){
10904	    return this.enabled;
10905	},
10906
10907	
10908	enable: function(){
10909		if(!this.enabled){
10910		    this.el.on(this.eventName, this.handleKeyDown, this);
10911		    this.enabled = true;
10912		}
10913	},
10914
10915	
10916	disable: function(){
10917		if(this.enabled){
10918		    this.el.removeListener(this.eventName, this.handleKeyDown, this);
10919		    this.enabled = false;
10920		}
10921	},
10922    
10923    
10924    setDisabled : function(disabled){
10925        this[disabled ? "disable" : "enable"]();
10926    }
10927};
10928Ext.util.TextMetrics = function(){
10929    var shared;
10930    return {
10931        
10932        measure : function(el, text, fixedWidth){
10933            if(!shared){
10934                shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
10935            }
10936            shared.bind(el);
10937            shared.setFixedWidth(fixedWidth || 'auto');
10938            return shared.getSize(text);
10939        },
10940
10941        
10942        createInstance : function(el, fixedWidth){
10943            return Ext.util.TextMetrics.Instance(el, fixedWidth);
10944        }
10945    };
10946}();
10947
10948Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
10949    var ml = new Ext.Element(document.createElement('div'));
10950    document.body.appendChild(ml.dom);
10951    ml.position('absolute');
10952    ml.setLeftTop(-1000, -1000);
10953    ml.hide();
10954
10955    if(fixedWidth){
10956        ml.setWidth(fixedWidth);
10957    }
10958
10959    var instance = {
10960        
10961        getSize : function(text){
10962            ml.update(text);
10963            var s = ml.getSize();
10964            ml.update('');
10965            return s;
10966        },
10967
10968        
10969        bind : function(el){
10970            ml.setStyle(
10971                Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
10972            );
10973        },
10974
10975        
10976        setFixedWidth : function(width){
10977            ml.setWidth(width);
10978        },
10979
10980        
10981        getWidth : function(text){
10982            ml.dom.style.width = 'auto';
10983            return this.getSize(text).width;
10984        },
10985
10986        
10987        getHeight : function(text){
10988            return this.getSize(text).height;
10989        }
10990    };
10991
10992    instance.bind(bindTo);
10993
10994    return instance;
10995};
10996
10997Ext.Element.addMethods({
10998    
10999    getTextWidth : function(text, min, max){
11000        return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
11001    }
11002});
11003
11004Ext.util.Cookies = {
11005    
11006    set : function(name, value){
11007        var argv = arguments;
11008        var argc = arguments.length;
11009        var expires = (argc > 2) ? argv[2] : null;
11010        var path = (argc > 3) ? argv[3] : '/';
11011        var domain = (argc > 4) ? argv[4] : null;
11012        var secure = (argc > 5) ? argv[5] : false;
11013        document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
11014    },
11015
11016    
11017    get : function(name){
11018        var arg = name + "=";
11019        var alen = arg.length;
11020        var clen = document.cookie.length;
11021        var i = 0;
11022        var j = 0;
11023        while(i < clen){
11024            j = i + alen;
11025            if(document.cookie.substring(i, j) == arg){
11026                return Ext.util.Cookies.getCookieVal(j);
11027            }
11028            i = document.cookie.indexOf(" ", i) + 1;
11029            if(i === 0){
11030                break;
11031            }
11032        }
11033        return null;
11034    },
11035
11036    
11037    clear : function(name){
11038        if(Ext.util.Cookies.get(name)){
11039            document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
11040        }
11041    },
11042    
11043    getCookieVal : function(offset){
11044        var endstr = document.cookie.indexOf(";", offset);
11045        if(endstr == -1){
11046            endstr = document.cookie.length;
11047        }
11048        return unescape(document.cookie.substring(offset, endstr));
11049    }
11050};
11051Ext.handleError = function(e) {
11052    throw e;
11053};
11054
11055
11056Ext.Error = function(message) {
11057    
11058    this.message = (this.lang[message]) ? this.lang[message] : message;
11059};
11060
11061Ext.Error.prototype = new Error();
11062Ext.apply(Ext.Error.prototype, {
11063    
11064    lang: {},
11065
11066    name: 'Ext.Error',
11067    
11068    getName : function() {
11069        return this.name;
11070    },
11071    
11072    getMessage : function() {
11073        return this.message;
11074    },
11075    
11076    toJson : function() {
11077        return Ext.encode(this);
11078    }
11079});
11080
11081Ext.ComponentMgr = function(){
11082    var all = new Ext.util.MixedCollection();
11083    var types = {};
11084    var ptypes = {};
11085
11086    return {
11087        
11088        register : function(c){
11089            all.add(c);
11090        },
11091
11092        
11093        unregister : function(c){
11094            all.remove(c);
11095        },
11096
11097        
11098        get : function(id){
11099            return all.get(id);
11100        },
11101
11102        
11103        onAvailable : function(id, fn, scope){
11104            all.on("add", function(index, o){
11105                if(o.id == id){
11106                    fn.call(scope || o, o);
11107                    all.un("add", fn, scope);
11108                }
11109            });
11110        },
11111
11112        
11113        all : all,
11114        
11115        
11116        types : types,
11117        
11118        
11119        ptypes: ptypes,
11120        
11121        
11122        isRegistered : function(xtype){
11123            return types[xtype] !== undefined;    
11124        },
11125        
11126        
11127        isPluginRegistered : function(ptype){
11128            return ptypes[ptype] !== undefined;    
11129        },        
11130
11131        
11132        registerType : function(xtype, cls){
11133            types[xtype] = cls;
11134            cls.xtype = xtype;
11135        },
11136
11137        
11138        create : function(config, defaultType){
11139            return config.render ? config : new types[config.xtype || defaultType](config);
11140        },
11141
11142        
11143        registerPlugin : function(ptype, cls){
11144            ptypes[ptype] = cls;
11145            cls.ptype = ptype;
11146        },
11147
11148        
11149        createPlugin : function(config, defaultType){
11150            var PluginCls = ptypes[config.ptype || defaultType];
11151            if (PluginCls.init) {
11152                return PluginCls;                
11153            } else {
11154                return new PluginCls(config);
11155            }            
11156        }
11157    };
11158}();
11159
11160
11161Ext.reg = Ext.ComponentMgr.registerType; 
11162
11163Ext.preg = Ext.ComponentMgr.registerPlugin;
11164
11165Ext.create = Ext.ComponentMgr.create;
11166Ext.Component = function(config){
11167    config = config || {};
11168    if(config.initialConfig){
11169        if(config.isAction){           
11170            this.baseAction = config;
11171        }
11172        config = config.initialConfig; 
11173    }else if(config.tagName || config.dom || Ext.isString(config)){ 
11174        config = {applyTo: config, id: config.id || config};
11175    }
11176
11177    
11178    this.initialConfig = config;
11179
11180    Ext.apply(this, config);
11181    this.addEvents(
11182        
11183        'added',
11184        
11185        'disable',
11186        
11187        'enable',
11188        
11189        'beforeshow',
11190        
11191        'show',
11192        
11193        'beforehide',
11194        
11195        'hide',
11196        
11197        'removed',
11198        
11199        'beforerender',
11200        
11201        'render',
11202        
11203        'afterrender',
11204        
11205        'beforedestroy',
11206        
11207        'destroy',
11208        
11209        'beforestaterestore',
11210        
11211        'staterestore',
11212        
11213        'beforestatesave',
11214        
11215        'statesave'
11216    );
11217    this.getId();
11218    Ext.ComponentMgr.register(this);
11219    Ext.Component.superclass.constructor.call(this);
11220
11221    if(this.baseAction){
11222        this.baseAction.addComponent(this);
11223    }
11224
11225    this.initComponent();
11226
11227    if(this.plugins){
11228        if(Ext.isArray(this.plugins)){
11229            for(var i = 0, len = this.plugins.length; i < len; i++){
11230                this.plugins[i] = this.initPlugin(this.plugins[i]);
11231            }
11232        }else{
11233            this.plugins = this.initPlugin(this.plugins);
11234        }
11235    }
11236
11237    if(this.stateful !== false){
11238        this.initState();
11239    }
11240
11241    if(this.applyTo){
11242        this.applyToMarkup(this.applyTo);
11243        delete this.applyTo;
11244    }else if(this.renderTo){
11245        this.render(this.renderTo);
11246        delete this.renderTo;
11247    }
11248};
11249
11250
11251Ext.Component.AUTO_ID = 1000;
11252
11253Ext.extend(Ext.Component, Ext.util.Observable, {
11254    
11255    
11256    
11257    
11258    
11259    
11260    
11261
11262    
11263    
11264    
11265    
11266    
11267    
11268    
11269    
11270    
11271    disabled : false,
11272    
11273    hidden : false,
11274    
11275    
11276    
11277    
11278    
11279    
11280    
11281    autoEl : 'div',
11282
11283    
11284    disabledClass : 'x-item-disabled',
11285    
11286    allowDomMove : true,
11287    
11288    autoShow : false,
11289    
11290    hideMode : 'display',
11291    
11292    hideParent : false,
11293    
11294    
11295    
11296    
11297    
11298    rendered : false,
11299
11300    
11301    
11302
11303    
11304
11305    
11306    tplWriteMode : 'overwrite',
11307
11308    
11309    
11310    
11311    bubbleEvents: [],
11312
11313
11314    
11315    ctype : 'Ext.Component',
11316
11317    
11318    actionMode : 'el',
11319
11320    
11321    getActionEl : function(){
11322        return this[this.actionMode];
11323    },
11324
11325    initPlugin : function(p){
11326        if(p.ptype && !Ext.isFunction(p.init)){
11327            p = Ext.ComponentMgr.createPlugin(p);
11328        }else if(Ext.isString(p)){
11329            p = Ext.ComponentMgr.createPlugin({
11330                ptype: p
11331            });
11332        }
11333        p.init(this);
11334        return p;
11335    },
11336
11337    
11338    initComponent : function(){
11339        
11340        if(this.listeners){
11341            this.on(this.listeners);
11342            delete this.listeners;
11343        }
11344        this.enableBubble(this.bubbleEvents);
11345    },
11346
11347    
11348    render : function(container, position){
11349        if(!this.rendered && this.fireEvent('beforerender', this) !== false){
11350            if(!container && this.el){
11351                this.el = Ext.get(this.el);
11352                container = this.el.dom.parentNode;
11353                this.allowDomMove = false;
11354            }
11355            this.container = Ext.get(container);
11356            if(this.ctCls){
11357                this.container.addClass(this.ctCls);
11358            }
11359            this.rendered = true;
11360            if(position !== undefined){
11361                if(Ext.isNumber(position)){
11362                    position = this.container.dom.childNodes[position];
11363                }else{
11364                    position = Ext.getDom(position);
11365                }
11366            }
11367            this.onRender(this.container, position || null);
11368            if(this.autoShow){
11369                this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
11370            }
11371            if(this.cls){
11372                this.el.addClass(this.cls);
11373                delete this.cls;
11374            }
11375            if(this.style){
11376                this.el.applyStyles(this.style);
11377                delete this.style;
11378            }
11379            if(this.overCls){
11380                this.el.addClassOnOver(this.overCls);
11381            }
11382            this.fireEvent('render', this);
11383
11384
11385            
11386            
11387            var contentTarget = this.getContentTarget();
11388            if (this.html){
11389                contentTarget.update(Ext.DomHelper.markup(this.html));
11390                delete this.html;
11391            }
11392            if (this.contentEl){
11393                var ce = Ext.getDom(this.contentEl);
11394                Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
11395                contentTarget.appendChild(ce);
11396            }
11397            if (this.tpl) {
11398                if (!this.tpl.compile) {
11399                    this.tpl = new Ext.XTemplate(this.tpl);
11400                }
11401                if (this.data) {
11402                    this.tpl[this.tplWriteMode](contentTarget, this.data);
11403                    delete this.data;
11404                }
11405            }
11406            this.afterRender(this.container);
11407
11408
11409            if(this.hidden){
11410                
11411                this.doHide();
11412            }
11413            if(this.disabled){
11414                
11415                this.disable(true);
11416            }
11417
11418            if(this.stateful !== false){
11419                this.initStateEvents();
11420            }
11421            this.fireEvent('afterrender', this);
11422        }
11423        return this;
11424    },
11425
11426
11427    
11428    update: function(htmlOrData, loadScripts, cb) {
11429        var contentTarget = this.getContentTarget();
11430        if (this.tpl && typeof htmlOrData !== "string") {
11431            this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
11432        } else {
11433            var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
11434            contentTarget.update(html, loadScripts, cb);
11435        }
11436    },
11437
11438
11439    
11440    onAdded : function(container, pos) {
11441        this.ownerCt = container;
11442        this.initRef();
11443        this.fireEvent('added', this, container, pos);
11444    },
11445
11446    
11447    onRemoved : function() {
11448        this.removeRef();
11449        this.fireEvent('removed', this, this.ownerCt);
11450        delete this.ownerCt;
11451    },
11452
11453    
11454    initRef : function() {
11455        
11456        if(this.ref && !this.refOwner){
11457            var levels = this.ref.split('/'),
11458                last = levels.length,
11459                i = 0,
11460                t = this;
11461
11462            while(t && i < last){
11463                t = t.ownerCt;
11464                ++i;
11465            }
11466            if(t){
11467                t[this.refName = levels[--i]] = this;
11468                
11469                this.refOwner = t;
11470            }
11471        }
11472    },
11473
11474    removeRef : function() {
11475        if (this.refOwner && this.refName) {
11476            delete this.refOwner[this.refName];
11477            delete this.refOwner;
11478        }
11479    },
11480
11481    
11482    initState : function(){
11483        if(Ext.state.Manager){
11484            var id = this.getStateId();
11485            if(id){
11486                var state = Ext.state.Manager.get(id);
11487                if(state){
11488                    if(this.fireEvent('beforestaterestore', this, state) !== false){
11489                        this.applyState(Ext.apply({}, state));
11490                        this.fireEvent('staterestore', this, state);
11491                    }
11492                }
11493            }
11494        }
11495    },
11496
11497    
11498    getStateId : function(){
11499        return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
11500    },
11501
11502    
11503    initStateEvents : function(){
11504        if(this.stateEvents){
11505            for(var i = 0, e; e = this.stateEvents[i]; i++){
11506                this.on(e, this.saveState, this, {delay:100});
11507            }
11508        }
11509    },
11510
11511    
11512    applyState : function(state){
11513        if(state){
11514            Ext.apply(this, state);
11515        }
11516    },
11517
11518    
11519    getState : function(){
11520        return null;
11521    },
11522
11523    
11524    saveState : function(){
11525        if(Ext.state.Manager && this.stateful !== false){
11526            var id = this.getStateId();
11527            if(id){
11528                var state = this.getState();
11529                if(this.fireEvent('beforestatesave', this, state) !== false){
11530                    Ext.state.Manager.set(id, state);
11531                    this.fireEvent('statesave', this, state);
11532                }
11533            }
11534        }
11535    },
11536
11537    
11538    applyToMarkup : function(el){
11539        this.allowDomMove = false;
11540        this.el = Ext.get(el);
11541        this.render(this.el.dom.parentNode);
11542    },
11543
11544    
11545    addClass : function(cls){
11546        if(this.el){
11547            this.el.addClass(cls);
11548        }else{
11549            this.cls = this.cls ? this.cls + ' ' + cls : cls;
11550        }
11551        return this;
11552    },
11553
11554    
11555    removeClass : function(cls){
11556        if(this.el){
11557            this.el.removeClass(cls);
11558        }else if(this.cls){
11559            this.cls = this.cls.split(' ').remove(cls).join(' ');
11560        }
11561        return this;
11562    },
11563
11564    
11565    
11566    onRender : function(ct, position){
11567        if(!this.el && this.autoEl){
11568            if(Ext.isString(this.autoEl)){
11569                this.el = document.createElement(this.autoEl);
11570            }else{
11571                var div = document.createElement('div');
11572                Ext.DomHelper.overwrite(div, this.autoEl);
11573                this.el = div.firstChild;
11574            }
11575            if (!this.el.id) {
11576                this.el.id = this.getId();
11577            }
11578        }
11579        if(this.el){
11580            this.el = Ext.get(this.el);
11581            if(this.allowDomMove !== false){
11582                ct.dom.insertBefore(this.el.dom, position);
11583                if (div) {
11584                    Ext.removeNode(div);
11585                    div = null;
11586                }
11587            }
11588        }
11589    },
11590
11591    
11592    getAutoCreate : function(){
11593        var cfg = Ext.isObject(this.autoCreate) ?
11594                      this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
11595        if(this.id && !cfg.id){
11596            cfg.id = this.id;
11597        }
11598        return cfg;
11599    },
11600
11601    
11602    afterRender : Ext.emptyFn,
11603
11604    
11605    destroy : function(){
11606        if(!this.isDestroyed){
11607            if(this.fireEvent('beforedestroy', this) !== false){
11608                this.destroying = true;
11609                this.beforeDestroy();
11610                if(this.ownerCt && this.ownerCt.remove){
11611                    this.ownerCt.remove(this, false);
11612                }
11613                if(this.rendered){
11614                    this.el.remove();
11615                    if(this.actionMode == 'container' || this.removeMode == 'container'){
11616                        this.container.remove();
11617                    }
11618                }
11619                
11620                if(this.focusTask && this.focusTask.cancel){
11621                    this.focusTask.cancel();
11622                }
11623                this.onDestroy();
11624                Ext.ComponentMgr.unregister(this);
11625                this.fireEvent('destroy', this);
11626                this.purgeListeners();
11627                this.destroying = false;
11628                this.isDestroyed = true;
11629            }
11630        }
11631    },
11632
11633    deleteMembers : function(){
11634        var args = arguments;
11635        for(var i = 0, len = args.length; i < len; ++i){
11636            delete this[args[i]];
11637        }
11638    },
11639
11640    
11641    beforeDestroy : Ext.emptyFn,
11642
11643    
11644    onDestroy  : Ext.emptyFn,
11645
11646    
11647    getEl : function(){
11648        return this.el;
11649    },
11650
11651    
11652    getContentTarget : function(){
11653        return this.el;
11654    },
11655
11656    
11657    getId : function(){
11658        return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
11659    },
11660
11661    
11662    getItemId : function(){
11663        return this.itemId || this.getId();
11664    },
11665
11666    
11667    focus : function(selectText, delay){
11668        if(delay){
11669            this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
11670            this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
11671            return this;
11672        }
11673        if(this.rendered && !this.isDestroyed){
11674            this.el.focus();
11675            if(selectText === true){
11676                this.el.dom.select();
11677            }
11678        }
11679        return this;
11680    },
11681
11682    
11683    blur : function(){
11684        if(this.rendered){
11685            this.el.blur();
11686        }
11687        return this;
11688    },
11689
11690    
11691    disable : function( silent){
11692        if(this.rendered){
11693            this.onDisable();
11694        }
11695        this.disabled = true;
11696        if(silent !== true){
11697            this.fireEvent('disable', this);
11698        }
11699        return this;
11700    },
11701
11702    
11703    onDisable : function(){
11704        this.getActionEl().addClass(this.disabledClass);
11705        this.el.dom.disabled = true;
11706    },
11707
11708    
11709    enable : function(){
11710        if(this.rendered){
11711            this.onEnable();
11712        }
11713        this.disabled = false;
11714        this.fireEvent('enable', this);
11715        return this;
11716    },
11717
11718    
11719    onEnable : function(){
11720        this.getActionEl().removeClass(this.disabledClass);
11721        this.el.dom.disabled = false;
11722    },
11723
11724    
11725    setDisabled : function(disabled){
11726        return this[disabled ? 'disable' : 'enable']();
11727    },
11728
11729    
11730    show : function(){
11731        if(this.fireEvent('beforeshow', this) !== false){
11732            this.hidden = false;
11733            if(this.autoRender){
11734                this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
11735            }
11736            if(this.rendered){
11737                this.onShow();
11738            }
11739            this.fireEvent('show', this);
11740        }
11741        return this;
11742    },
11743
11744    
11745    onShow : function(){
11746        this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
11747    },
11748
11749    
11750    hide : function(){
11751        if(this.fireEvent('beforehide', this) !== false){
11752            this.doHide();
11753            this.fireEvent('hide', this);
11754        }
11755        return this;
11756    },
11757
11758    
11759    doHide: function(){
11760        this.hidden = true;
11761        if(this.rendered){
11762            this.onHide();
11763        }
11764    },
11765
11766    
11767    onHide : function(){
11768        this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
11769    },
11770
11771    
11772    getVisibilityEl : function(){
11773        return this.hideParent ? this.container : this.getActionEl();
11774    },
11775
11776    
11777    setVisible : function(visible){
11778        return this[visible ? 'show' : 'hide']();
11779    },
11780
11781    
11782    isVisible : function(){
11783        return this.rendered && this.getVisibilityEl().isVisible();
11784    },
11785
11786    
11787    cloneConfig : function(overrides){
11788        overrides = overrides || {};
11789        var id = overrides.id || Ext.id();
11790        var cfg = Ext.applyIf(overrides, this.initialConfig);
11791        cfg.id = id; 
11792        return new this.constructor(cfg);
11793    },
11794
11795    
11796    getXType : function(){
11797        return this.constructor.xtype;
11798    },
11799
11800    
11801    isXType : function(xtype, shallow){
11802        
11803        if (Ext.isFunction(xtype)){
11804            xtype = xtype.xtype; 
11805        }else if (Ext.isObject(xtype)){
11806            xtype = xtype.constructor.xtype; 
11807        }
11808
11809        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
11810    },
11811
11812    
11813    getXTypes : function(){
11814        var tc = this.constructor;
11815        if(!tc.xtypes){
11816            var c = [], sc = this;
11817            while(sc && sc.constructor.xtype){
11818                c.unshift(sc.constructor.xtype);
11819                sc = sc.constructor.superclass;
11820            }
11821            tc.xtypeChain = c;
11822            tc.xtypes = c.join('/');
11823        }
11824        return tc.xtypes;
11825    },
11826
11827    
11828    findParentBy : function(fn) {
11829        for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
11830        return p || null;
11831    },
11832
11833    
11834    findParentByType : function(xtype, shallow){
11835        return this.findParentBy(function(c){
11836            return c.isXType(xtype, shallow);
11837        });
11838    },
11839    
11840    
11841    bubble : function(fn, scope, args){
11842        var p = this;
11843        while(p){
11844            if(fn.apply(scope || p, args || [p]) === false){
11845                break;
11846            }
11847            p = p.ownerCt;
11848        }
11849        return this;
11850    },
11851
11852    
11853    getPositionEl : function(){
11854        return this.positionEl || this.el;
11855    },
11856
11857    
11858    purgeListeners : function(){
11859        Ext.Component.superclass.purgeListeners.call(this);
11860        if(this.mons){
11861            this.on('beforedestroy', this.clearMons, this, {single: true});
11862        }
11863    },
11864
11865    
11866    clearMons : function(){
11867        Ext.each(this.mons, function(m){
11868            m.item.un(m.ename, m.fn, m.scope);
11869        }, this);
11870        this.mons = [];
11871    },
11872
11873    
11874    createMons: function(){
11875        if(!this.mons){
11876            this.mons = [];
11877            this.on('beforedestroy', this.clearMons, this, {single: true});
11878        }
11879    },
11880
11881    
11882    mon : function(item, ename, fn, scope, opt){
11883        this.createMons();
11884        if(Ext.isObject(ename)){
11885            var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
11886
11887            var o = ename;
11888            for(var e in o){
11889                if(propRe.test(e)){
11890                    continue;
11891                }
11892                if(Ext.isFunction(o[e])){
11893                    
11894                    this.mons.push({
11895                        item: item, ename: e, fn: o[e], scope: o.scope
11896                    });
11897                    item.on(e, o[e], o.scope, o);
11898                }else{
11899                    
11900                    this.mons.push({
11901                        item: item, ename: e, fn: o[e], scope: o.scope
11902                    });
11903                    item.on(e, o[e]);
11904                }
11905            }
11906            return;
11907        }
11908
11909        this.mons.push({
11910            item: item, ename: ename, fn: fn, scope: scope
11911        });
11912        item.on(ename, fn, scope, opt);
11913    },
11914
11915    
11916    mun : function(item, ename, fn, scope){
11917        var found, mon;
11918        this.createMons();
11919        for(var i = 0, len = this.mons.length; i < len; ++i){
11920            mon = this.mons[i];
11921            if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
11922                this.mons.splice(i, 1);
11923                item.un(ename, fn, scope);
11924                found = true;
11925                break;
11926            }
11927        }
11928        return found;
11929    },
11930
11931    
11932    nextSibling : function(){
11933        if(this.ownerCt){
11934            var index = this.ownerCt.items.indexOf(this);
11935            if(index != -1 && index+1 < this.ownerCt.items.getCount()){
11936                return this.ownerCt.items.itemAt(index+1);
11937            }
11938        }
11939        return null;
11940    },
11941
11942    
11943    previousSibling : function(){
11944        if(this.ownerCt){
11945            var index = this.ownerCt.items.indexOf(this);
11946            if(index > 0){
11947                return this.ownerCt.items.itemAt(index-1);
11948            }
11949        }
11950        return null;
11951    },
11952
11953    
11954    getBubbleTarget : function(){
11955        return this.ownerCt;
11956    }
11957});
11958
11959Ext.reg('component', Ext.Component);
11960
11961Ext.Action = Ext.extend(Object, {
11962    
11963    
11964    
11965    
11966    
11967    
11968    
11969
11970    constructor : function(config){
11971        this.initialConfig = config;
11972        this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
11973        this.items = [];
11974    },
11975    
11976    
11977    isAction : true,
11978
11979    
11980    setText : function(text){
11981        this.initialConfig.text = text;
11982        this.callEach('setText', [text]);
11983    },
11984
11985    
11986    getText : function(){
11987        return this.initialConfig.text;
11988    },
11989
11990    
11991    setIconClass : function(cls){
11992        this.initialConfig.iconCls = cls;
11993        this.callEach('setIconClass', [cls]);
11994    },
11995
11996    
11997    getIconClass : function(){
11998        return this.initialConfig.iconCls;
11999    },
12000
12001    
12002    setDisabled : function(v){
12003        this.initialConfig.disabled = v;
12004        this.callEach('setDisabled', [v]);
12005    },
12006
12007    
12008    enable : function(){
12009        this.setDisabled(false);
12010    },
12011
12012    
12013    disable : function(){
12014        this.setDisabled(true);
12015    },
12016
12017    
12018    isDisabled : function(){
12019        return this.initialConfig.disabled;
12020    },
12021
12022    
12023    setHidden : function(v){
12024        this.initialConfig.hidden = v;
12025        this.callEach('setVisible', [!v]);
12026    },
12027
12028    
12029    show : function(){
12030        this.setHidden(false);
12031    },
12032
12033    
12034    hide : function(){
12035        this.setHidden(true);
12036    },
12037
12038    
12039    isHidden : function(){
12040        return this.initialConfig.hidden;
12041    },
12042
12043    
12044    setHandler : function(fn, scope){
12045        this.initialConfig.handler = fn;
12046        this.initialConfig.scope = scope;
12047        this.callEach('setHandler', [fn, scope]);
12048    },
12049
12050    
12051    each : function(fn, scope){
12052        Ext.each(this.items, fn, scope);
12053    },
12054
12055    
12056    callEach : function(fnName, args){
12057        var cs = this.items;
12058        for(var i = 0, len = cs.length; i < len; i++){
12059            cs[i][fnName].apply(cs[i], args);
12060        }
12061    },
12062
12063    
12064    addComponent : function(comp){
12065        this.items.push(comp);
12066        comp.on('destroy', this.removeComponent, this);
12067    },
12068
12069    
12070    removeComponent : function(comp){
12071        this.items.remove(comp);
12072    },
12073
12074    
12075    execute : function(){
12076        this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
12077    }
12078});
12079
12080(function(){
12081Ext.Layer = function(config, existingEl){
12082    config = config || {};
12083    var dh = Ext.DomHelper,
12084        cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
12085        
12086    if (existingEl) {
12087        this.dom = Ext.getDom(existingEl);
12088    }
12089    if(!this.dom){
12090        var o = config.dh || {tag: 'div', cls: 'x-layer'};
12091        this.dom = dh.append(pel, o);
12092    }
12093    if(config.cls){
12094        this.addClass(config.cls);
12095    }
12096    this.constrain = config.constrain !== false;
12097    this.setVisibilityMode(Ext.Element.VISIBILITY);
12098    if(config.id){
12099        this.id = this.dom.id = config.id;
12100    }else{
12101        this.id = Ext.id(this.dom);
12102    }
12103    this.zindex = config.zindex || this.getZIndex();
12104    this.position('absolute', this.zindex);
12105    if(config.shadow){
12106        this.shadowOffset = config.shadowOffset || 4;
12107        this.shadow = new Ext.Shadow({
12108            offset : this.shadowOffset,
12109            mode : config.shadow
12110        });
12111    }else{
12112        this.shadowOffset = 0;
12113    }
12114    this.useShim = config.shim !== false && Ext.useShims;
12115    this.useDisplay = config.useDisplay;
12116    this.hide();
12117};
12118
12119var supr = Ext.Element.prototype;
12120
12121
12122var shims = [];
12123
12124Ext.extend(Ext.Layer, Ext.Element, {
12125
12126    getZIndex : function(){
12127        return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
12128    },
12129
12130    getShim : function(){
12131        if(!this.useShim){
12132            return null;
12133        }
12134        if(this.shim){
12135            return this.shim;
12136        }
12137        var shim = shims.shift();
12138        if(!shim){
12139            shim = this.createShim();
12140            shim.enableDisplayMode('block');
12141            shim.dom.style.display = 'none';
12142            shim.dom.style.visibility = 'visible';
12143        }
12144        var pn = this.dom.parentNode;
12145        if(shim.dom.parentNode != pn){
12146            pn.insertBefore(shim.dom, this.dom);
12147        }
12148        shim.setStyle('z-index', this.getZIndex()-2);
12149        this.shim = shim;
12150        return shim;
12151    },
12152
12153    hideShim : function(){
12154        if(this.shim){
12155            this.shim.setDisplayed(false);
12156            shims.push(this.shim);
12157            delete this.shim;
12158        }
12159    },
12160
12161    disableShadow : function(){
12162        if(this.shadow){
12163            this.shadowDisabled = true;
12164            this.shadow.hide();
12165            this.lastShadowOffset = this.shadowOffset;
12166            this.shadowOffset = 0;
12167        }
12168    },
12169
12170    enableShadow : function(show){
12171        if(this.shadow){
12172            this.shadowDisabled = false;
12173            if(Ext.isDefined(this.lastShadowOffset)) {
12174                this.shadowOffset = this.lastShadowOffset;
12175                delete this.lastShadowOffset;
12176            }
12177            if(show){
12178                this.sync(true);
12179            }
12180        }
12181    },
12182
12183    
12184    
12185    
12186    sync : function(doShow){
12187        var shadow = this.shadow;
12188        if(!this.updating && this.isVisible() && (shadow || this.useShim)){
12189            var shim = this.getShim(),
12190                w = this.getWidth(),
12191                h = this.getHeight(),
12192                l = this.getLeft(true),
12193                t = this.getTop(true);
12194
12195            if(shadow && !this.shadowDisabled){
12196                if(doShow && !shadow.isVisible()){
12197                    shadow.show(this);
12198                }else{
12199                    shadow.realign(l, t, w, h);
12200                }
12201                if(shim){
12202                    if(doShow){
12203                       shim.show();
12204                    }
12205                    
12206                    var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
12207                        shadowSize = shadow.el.getSize();
12208                    shimStyle.left = (shadowAdj[0])+'px';
12209                    shimStyle.top = (shadowAdj[1])+'px';
12210                    shimStyle.width = (shadowSize.width)+'px';
12211                    shimStyle.height = (shadowSize.height)+'px';
12212                }
12213            }else if(shim){
12214                if(doShow){
12215                   shim.show();
12216                }
12217                shim.setSize(w, h);
12218                shim.setLeftTop(l, t);
12219            }
12220        }
12221    },
12222
12223    
12224    destroy : function(){
12225        this.hideShim();
12226        if(this.shadow){
12227            this.shadow.hide();
12228        }
12229        this.removeAllListeners();
12230        Ext.removeNode(this.dom);
12231        delete this.dom;
12232    },
12233
12234    remove : function(){
12235        this.destroy();
12236    },
12237
12238    
12239    beginUpdate : function(){
12240        this.updating = true;
12241    },
12242
12243    
12244    endUpdate : function(){
12245        this.updating = false;
12246        this.sync(true);
12247    },
12248
12249    
12250    hideUnders : function(negOffset){
12251        if(this.shadow){
12252            this.shadow.hide();
12253        }
12254        this.hideShim();
12255    },
12256
12257    
12258    constrainXY : function(){
12259        if(this.constrain){
12260            var vw = Ext.lib.Dom.getViewWidth(),
12261                vh = Ext.lib.Dom.getViewHeight();
12262            var s = Ext.getDoc().getScroll();
12263
12264            var xy = this.getXY();
12265            var x = xy[0], y = xy[1];
12266            var so = this.shadowOffset;
12267            var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
12268            
12269            var moved = false;
12270            
12271            if((x + w) > vw+s.left){
12272                x = vw - w - so;
12273                moved = true;
12274            }
12275            if((y + h) > vh+s.top){
12276                y = vh - h - so;
12277                moved = true;
12278            }
12279            
12280            if(x < s.left){
12281                x = s.left;
12282                moved = true;
12283            }
12284            if(y < s.top){
12285                y = s.top;
12286                moved = true;
12287            }
12288            if(moved){
12289                if(this.avoidY){
12290                    var ay = this.avoidY;
12291                    if(y <= ay && (y+h) >= ay){
12292                        y = ay-h-5;
12293                    }
12294                }
12295                xy = [x, y];
12296                this.storeXY(xy);
12297                supr.setXY.call(this, xy);
12298                this.sync();
12299            }
12300        }
12301        return this;
12302    },
12303    
12304    getConstrainOffset : function(){
12305        return this.shadowOffset;    
12306    },
12307
12308    isVisible : function(){
12309        return this.visible;
12310    },
12311
12312    
12313    showAction : function(){
12314        this.visible = true; 
12315        if(this.useDisplay === true){
12316            this.setDisplayed('');
12317        }else if(this.lastXY){
12318            supr.setXY.call(this, this.lastXY);
12319        }else if(this.lastLT){
12320            supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
12321        }
12322    },
12323
12324    
12325    hideAction : function(){
12326        this.visible = false;
12327        if(this.useDisplay === true){
12328            this.setDisplayed(false);
12329        }else{
12330            this.setLeftTop(-10000,-10000);
12331        }
12332    },
12333
12334    
12335    setVisible : function(v, a, d, c, e){
12336        if(v){
12337            this.showAction();
12338        }
12339        if(a && v){
12340            var cb = function(){
12341                this.sync(true);
12342                if(c){
12343                    c();
12344                }
12345            }.createDelegate(this);
12346            supr.setVisible.call(this, true, true, d, cb, e);
12347        }else{
12348            if(!v){
12349                this.hideUnders(true);
12350            }
12351            var cb = c;
12352            if(a){
12353                cb = function(){
12354                    this.hideAction();
12355                    if(c){
12356                        c();
12357                    }
12358                }.createDelegate(this);
12359            }
12360            supr.setVisible.call(this, v, a, d, cb, e);
12361            if(v){
12362                this.sync(true);
12363            }else if(!a){
12364                this.hideAction();
12365            }
12366        }
12367        return this;
12368    },
12369
12370    storeXY : function(xy){
12371        delete this.lastLT;
12372        this.lastXY = xy;
12373    },
12374
12375    storeLeftTop : function(left, top){
12376        delete this.lastXY;
12377        this.lastLT = [left, top];
12378    },
12379
12380    
12381    beforeFx : function(){
12382        this.beforeAction();
12383        return Ext.Layer.superclass.beforeFx.apply(this, arguments);
12384    },
12385
12386    
12387    afterFx : function(){
12388        Ext.Layer.superclass.afterFx.apply(this, arguments);
12389        this.sync(this.isVisible());
12390    },
12391
12392    
12393    beforeAction : function(){
12394        if(!this.updating && this.shadow){
12395            this.shadow.hide();
12396        }
12397    },
12398
12399    
12400    setLeft : function(left){
12401        this.storeLeftTop(left, this.getTop(true));
12402        supr.setLeft.apply(this, arguments);
12403        this.sync();
12404        return this;
12405    },
12406
12407    setTop : function(top){
12408        this.storeLeftTop(this.getLeft(true), top);
12409        supr.setTop.apply(this, arguments);
12410        this.sync();
12411        return this;
12412    },
12413
12414    setLeftTop : function(left, top){
12415        this.storeLeftTop(left, top);
12416        supr.setLeftTop.apply(this, arguments);
12417        this.sync();
12418        return this;
12419    },
12420
12421    setXY : function(xy, a, d, c, e){
12422        this.fixDisplay();
12423        this.beforeAction();
12424        this.storeXY(xy);
12425        var cb = this.createCB(c);
12426        supr.setXY.call(this, xy, a, d, cb, e);
12427        if(!a){
12428            cb();
12429        }
12430        return this;
12431    },
12432
12433    
12434    createCB : function(c){
12435        var el = this;
12436        return function(){
12437            el.constrainXY();
12438            el.sync(true);
12439            if(c){
12440                c();
12441            }
12442        };
12443    },
12444
12445    
12446    setX : function(x, a, d, c, e){
12447        this.setXY([x, this.getY()], a, d, c, e);
12448        return this;
12449    },
12450
12451    
12452    setY : function(y, a, d, c, e){
12453        this.setXY([this.getX(), y], a, d, c, e);
12454        return this;
12455    },
12456
12457    
12458    setSize : function(w, h, a, d, c, e){
12459        this.beforeAction();
12460        var cb = this.createCB(c);
12461        supr.setSize.call(this, w, h, a, d, cb, e);
12462        if(!a){
12463            cb();
12464        }
12465        return this;
12466    },
12467
12468    
12469    setWidth : function(w, a, d, c, e){
12470        this.beforeAction();
12471        var cb = this.createCB(c);
12472        supr.setWidth.call(this, w, a, d, cb, e);
12473        if(!a){
12474            cb();
12475        }
12476        return this;
12477    },
12478
12479    
12480    setHeight : function(h, a, d, c, e){
12481        this.beforeAction();
12482        var cb = this.createCB(c);
12483        supr.setHeight.call(this, h, a, d, cb, e);
12484        if(!a){
12485            cb();
12486        }
12487        return this;
12488    },
12489
12490    
12491    setBounds : function(x, y, w, h, a, d, c, e){
12492        this.beforeAction();
12493        var cb = this.createCB(c);
12494        if(!a){
12495            this.storeXY([x, y]);
12496            supr.setXY.call(this, [x, y]);
12497            supr.setSize.call(this, w, h, a, d, cb, e);
12498            cb();
12499        }else{
12500            supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
12501        }
12502        return this;
12503    },
12504
12505    
12506    setZIndex : function(zindex){
12507        this.zindex = zindex;
12508        this.setStyle('z-index', zindex + 2);
12509        if(this.shadow){
12510            this.shadow.setZIndex(zindex + 1);
12511        }
12512        if(this.shim){
12513            this.shim.setStyle('z-index', zindex);
12514        }
12515        return this;
12516    }
12517});
12518})();
12519
12520Ext.Shadow = function(config) {
12521    Ext.apply(this, config);
12522    if (typeof this.mode != "string") {
12523        this.mode = this.defaultMode;
12524    }
12525    var o = this.offset,
12526        a = {
12527            h: 0
12528        },
12529        rad = Math.floor(this.offset / 2);
12530    switch (this.mode.toLowerCase()) {
12531        
12532        case "drop":
12533            a.w = 0;
12534            a.l = a.t = o;
12535            a.t -= 1;
12536            if (Ext.isIE) {
12537                a.l -= this.offset + rad;
12538                a.t -= this.offset + rad;
12539                a.w -= rad;
12540                a.h -= rad;
12541                a.t += 1;
12542            }
12543        break;
12544        case "sides":
12545            a.w = (o * 2);
12546            a.l = -o;
12547            a.t = o - 1;
12548            if (Ext.isIE) {
12549                a.l -= (this.offset - rad);
12550                a.t -= this.offset + rad;
12551                a.l += 1;
12552                a.w -= (this.offset - rad) * 2;
12553                a.w -= rad + 1;
12554                a.h -= 1;
12555            }
12556        break;
12557        case "frame":
12558            a.w = a.h = (o * 2);
12559            a.l = a.t = -o;
12560            a.t += 1;
12561            a.h -= 2;
12562            if (Ext.isIE) {
12563                a.l -= (this.offset - rad);
12564                a.t -= (this.offset - rad);
12565                a.l += 1;
12566                a.w -= (this.offset + rad + 1);
12567                a.h -= (this.offset + rad);
12568                a.h += 1;
12569            }
12570        break;
12571    };
12572
12573    this.adjusts = a;
12574};
12575
12576Ext.Shadow.prototype = {
12577    
12578    
12579    offset: 4,
12580
12581    
12582    defaultMode: "drop",
12583
12584    
12585    show: function(target) {
12586        target = Ext.get(target);
12587        if (!this.el) {
12588            this.el = Ext.Shadow.Pool.pull();
12589            if (this.el.dom.nextSibling != target.dom) {
12590                this.el.insertBefore(target);
12591            }
12592        }
12593        this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
12594        if (Ext.isIE) {
12595            this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
12596        }
12597        this.realign(
12598        target.getLeft(true),
12599        target.getTop(true),
12600        target.getWidth(),
12601        target.getHeight()
12602        );
12603        this.el.dom.style.display = "block";
12604    },
12605
12606    
12607    isVisible: function() {
12608        return this.el ? true: false;
12609    },
12610
12611    
12612    realign: function(l, t, w, h) {
12613        if (!this.el) {
12614            return;
12615        }
12616        var a = this.adjusts,
12617            d = this.el.dom,
12618            s = d.style,
12619            iea = 0,
12620            sw = (w + a.w),
12621            sh = (h + a.h),
12622            sws = sw + "px",
12623            shs = sh + "px",
12624            cn,
12625            sww;
12626        s.left = (l + a.l) + "px";
12627        s.top = (t + a.t) + "px";
12628        if (s.width != sws || s.height != shs) {
12629            s.width = sws;
12630            s.height = shs;
12631            if (!Ext.isIE) {
12632                cn = d.childNodes;
12633                sww = Math.max(0, (sw - 12)) + "px";
12634                cn[0].childNodes[1].style.width = sww;
12635                cn[1].childNodes[1].style.width = sww;
12636                cn[2].childNodes[1].style.width = sww;
12637                cn[1].style.height = Math.max(0, (sh - 12)) + "px";
12638            }
12639        }
12640    },
12641
12642    
12643    hide: function() {
12644        if (this.el) {
12645            this.el.dom.style.display = "none";
12646            Ext.Shadow.Pool.push(this.el);
12647            delete this.el;
12648        }
12649    },
12650
12651    
12652    setZIndex: function(z) {
12653        this.zIndex = z;
12654        if (this.el) {
12655            this.el.setStyle("z-index", z);
12656        }
12657    }
12658};
12659
12660
12661Ext.Shadow.Pool = function() {
12662    var p = [],
12663        markup = Ext.isIE ?
12664            '<div class="x-ie-shadow"></div>':
12665            '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
12666    return {
12667        pull: function() {
12668            var sh = p.shift();
12669            if (!sh) {
12670                sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
12671                sh.autoBoxAdjust = false;
12672            }
12673            return sh;
12674        },
12675
12676        push: function(sh) {
12677            p.push(sh);
12678        }
12679    };
12680}();
12681Ext.BoxComponent = Ext.extend(Ext.Component, {
12682
12683    
12684    
12685    
12686    
12687    
12688    
12689    
12690    
12691    
12692    
12693    
12694    
12695    
12696    
12697    
12698    
12699    
12700    
12701    
12702    
12703    
12704    
12705    
12706
12707    
12708
12709    
12710    initComponent : function(){
12711        Ext.BoxComponent.superclass.initComponent.call(this);
12712        this.addEvents(
12713            
12714            'resize',
12715            
12716            'move'
12717        );
12718    },
12719
12720    
12721    boxReady : false,
12722    
12723    deferHeight: false,
12724
12725    
12726    setSize : function(w, h){
12727
12728        
12729        if(typeof w == 'object'){
12730            h = w.height;
12731            w = w.width;
12732        }
12733        if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
12734            w = this.boxMinWidth;
12735        }
12736        if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
12737            h = this.boxMinHeight;
12738        }
12739        if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
12740            w = this.boxMaxWidth;
12741        }
12742        if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
12743            h = this.boxMaxHeight;
12744        }
12745        
12746        if(!this.boxReady){
12747            this.width  = w;
12748            this.height = h;
12749            return this;
12750        }
12751
12752        
12753        if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
12754            return this;
12755        }
12756        this.lastSize = {width: w, height: h};
12757        var adj = this.adjustSize(w, h),
12758            aw = adj.width,
12759            ah = adj.height,
12760            rz;
12761        if(aw !== undefined || ah !== undefined){ 
12762            rz = this.getResizeEl();
12763            if(!this.deferHeight && aw !== undefined && ah !== undefined){
12764                rz.setSize(aw, ah);
12765            }else if(!this.deferHeight && ah !== undefined){
12766                rz.setHeight(ah);
12767            }else if(aw !== undefined){
12768                rz.setWidth(aw);
12769            }
12770            this.onResize(aw, ah, w, h);
12771            this.fireEvent('resize', this, aw, ah, w, h);
12772        }
12773        return this;
12774    },
12775
12776    
12777    setWidth : function(width){
12778        return this.setSize(width);
12779    },
12780
12781    
12782    setHeight : function(height){
12783        return this.setSize(undefined, height);
12784    },
12785
12786    
12787    getSize : function(){
12788        return this.getResizeEl().getSize();
12789    },
12790
12791    
12792    getWidth : function(){
12793        return this.getResizeEl().getWidth();
12794    },
12795
12796    
12797    getHeight : function(){
12798        return this.getResizeEl().getHeight();
12799    },
12800
12801    
12802    getOuterSize : function(){
12803        var el = this.getResizeEl();
12804        return {width: el.getWidth() + el.getMargins('lr'),
12805                height: el.getHeight() + el.getMargins('tb')};
12806    },
12807
12808    
12809    getPosition : function(local){
12810        var el = this.getPositionEl();
12811        if(local === true){
12812            return [el.getLeft(true), el.getTop(true)];
12813        }
12814        return this.xy || el.getXY();
12815    },
12816
12817    
12818    getBox : function(local){
12819        var pos = this.getPosition(local);
12820        var s = this.getSize();
12821        s.x = pos[0];
12822        s.y = pos[1];
12823        return s;
12824    },
12825
12826    
12827    updateBox : function(box){
12828        this.setSize(box.width, box.height);
12829        this.setPagePosition(box.x, box.y);
12830        return this;
12831    },
12832
12833    
12834    getResizeEl : function(){
12835        return this.resizeEl || this.el;
12836    },
12837
12838    
12839    setAutoScroll : function(scroll){
12840        if(this.rendered){
12841            this.getContentTarget().setOverflow(scroll ? 'auto' : '');
12842        }
12843        this.autoScroll = scroll;
12844        return this;
12845    },
12846
12847    
12848    setPosition : function(x, y){
12849        if(x && typeof x[1] == 'number'){
12850            y = x[1];
12851            x = x[0];
12852        }
12853        this.x = x;
12854        this.y = y;
12855        if(!this.boxReady){
12856            return this;
12857        }
12858        var adj = this.adjustPosition(x, y);
12859        var ax = adj.x, ay = adj.y;
12860
12861        var el = this.getPositionEl();
12862        if(ax !== undefined || ay !== undefined){
12863            if(ax !== undefined && ay !== undefined){
12864                el.setLeftTop(ax, ay);
12865            }else if(ax !== undefined){
12866                el.setLeft(ax);
12867            }else if(ay !== undefined){
12868                el.setTop(ay);
12869            }
12870            this.onPosition(ax, ay);
12871            this.fireEvent('move', this, ax, ay);
12872        }
12873        return this;
12874    },
12875
12876    
12877    setPagePosition : function(x, y){
12878        if(x && typeof x[1] == 'number'){
12879            y = x[1];
12880            x = x[0];
12881        }
12882        this.pageX = x;
12883        this.pageY = y;
12884        if(!this.boxReady){
12885            return;
12886        }
12887        if(x === undefined || y === undefined){ 
12888            return;
12889        }
12890        var p = this.getPositionEl().translatePoints(x, y);
12891        this.setPosition(p.left, p.top);
12892        return this;
12893    },
12894
12895    
12896    afterRender : function(){
12897        Ext.BoxComponent.superclass.afterRender.call(this);
12898        if(this.resizeEl){
12899            this.resizeEl = Ext.get(this.resizeEl);
12900        }
12901        if(this.positionEl){
12902            this.positionEl = Ext.get(this.positionEl);
12903        }
12904        this.boxReady = true;
12905        Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
12906        this.setSize(this.width, this.height);
12907        if(this.x || this.y){
12908            this.setPosition(this.x, this.y);
12909        }else if(this.pageX || this.pageY){
12910            this.setPagePosition(this.pageX, this.pageY);
12911        }
12912    },
12913
12914    
12915    syncSize : function(){
12916        delete this.lastSize;
12917        this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
12918        return this;
12919    },
12920
12921    
12922    onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
12923    },
12924
12925    
12926    onPosition : function(x, y){
12927
12928    },
12929
12930    
12931    adjustSize : function(w, h){
12932        if(this.autoWidth){
12933            w = 'auto';
12934        }
12935        if(this.autoHeight){
12936            h = 'auto';
12937        }
12938        return {width : w, height: h};
12939    },
12940
12941    
12942    adjustPosition : function(x, y){
12943        return {x : x, y: y};
12944    }
12945});
12946Ext.reg('box', Ext.BoxComponent);
12947
12948
12949
12950Ext.Spacer = Ext.extend(Ext.BoxComponent, {
12951    autoEl:'div'
12952});
12953Ext.reg('spacer', Ext.Spacer);
12954Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
12955
12956    
12957    this.el = Ext.get(dragElement, true);
12958    this.el.dom.unselectable = "on";
12959    
12960    this.resizingEl = Ext.get(resizingElement, true);
12961
12962    
12963    this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
12964
12965    
12966    
12967    this.minSize = 0;
12968
12969    
12970    this.maxSize = 2000;
12971
12972    
12973    this.animate = false;
12974
12975    
12976    this.useShim = false;
12977
12978    
12979    this.shim = null;
12980
12981    if(!existingProxy){
12982        
12983        this.proxy = Ext.SplitBar.createProxy(this.orientation);
12984    }else{
12985        this.proxy = Ext.get(existingProxy).dom;
12986    }
12987    
12988    this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
12989
12990    
12991    this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
12992
12993    
12994    this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
12995
12996    
12997    this.dragSpecs = {};
12998
12999    
13000    this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
13001    this.adapter.init(this);
13002
13003    if(this.orientation == Ext.SplitBar.HORIZONTAL){
13004        
13005        this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
13006        this.el.addClass("x-splitbar-h");
13007    }else{
13008        
13009        this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
13010        this.el.addClass("x-splitbar-v");
13011    }
13012
13013    this.addEvents(
13014        
13015        "resize",
13016        
13017        "moved",
13018        
13019        "beforeresize",
13020
13021        "beforeapply"
13022    );
13023
13024    Ext.SplitBar.superclass.constructor.call(this);
13025};
13026
13027Ext.extend(Ext.SplitBar, Ext.util.Observable, {
13028    onStartProxyDrag : function(x, y){
13029        this.fireEvent("beforeresize", this);
13030        this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
13031        this.overlay.unselectable();
13032        this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
13033        this.overlay.show();
13034        Ext.get(this.proxy).setDisplayed("block");
13035        var size = this.adapter.getElementSize(this);
13036        this.activeMinSize = this.getMinimumSize();
13037        this.activeMaxSize = this.getMaximumSize();
13038        var c1 = size - this.activeMinSize;
13039        var c2 = Math.max(this.activeMaxSize - size, 0);
13040        if(this.orientation == Ext.SplitBar.HORIZONTAL){
13041            this.dd.resetConstraints();
13042            this.dd.setXConstraint(
13043                this.placement == Ext.SplitBar.LEFT ? c1 : c2,
13044                this.placement == Ext.SplitBar.LEFT ? c2 : c1,
13045                this.tickSize
13046            );
13047            this.dd.setYConstraint(0, 0);
13048        }else{
13049            this.dd.resetConstraints();
13050            this.dd.setXConstraint(0, 0);
13051            this.dd.setYConstraint(
13052                this.placement == Ext.SplitBar.TOP ? c1 : c2,
13053                this.placement == Ext.SplitBar.TOP ? c2 : c1,
13054                this.tickSize
13055            );
13056         }
13057        this.dragSpecs.startSize = size;
13058        this.dragSpecs.startPoint = [x, y];
13059        Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
13060    },
13061
13062    
13063    onEndProxyDrag : function(e){
13064        Ext.get(this.proxy).setDisplayed(false);
13065        var endPoint = Ext.lib.Event.getXY(e);
13066        if(this.overlay){
13067            Ext.destroy(this.overlay);
13068            delete this.overlay;
13069        }
13070        var newSize;
13071        if(this.orientation == Ext.SplitBar.HORIZONTAL){
13072            newSize = this.dragSpecs.startSize +
13073                (this.placement == Ext.SplitBar.LEFT ?
13074                    endPoint[0] - this.dragSpecs.startPoint[0] :
13075                    this.dragSpecs.startPoint[0] - endPoint[0]
13076                );
13077        }else{
13078            newSize = this.dragSpecs.startSize +
13079                (this.placement == Ext.SplitBar.TOP ?
13080                    endPoint[1] - this.dragSpecs.startPoint[1] :
13081                    this.dragSpecs.startPoint[1] - endPoint[1]
13082                );
13083        }
13084        newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
13085        if(newSize != this.dragSpecs.startSize){
13086            if(this.fireEvent('beforeapply', this, newSize) !== false){
13087                this.adapter.setElementSize(this, newSize);
13088                this.fireEvent("moved", this, newSize);
13089                this.fireEvent("resize", this, newSize);
13090            }
13091        }
13092    },
13093
13094    
13095    getAdapter : function(){
13096        return this.adapter;
13097    },
13098
13099    
13100    setAdapter : function(adapter){
13101        this.adapter = adapter;
13102        this.adapter.init(this);
13103    },
13104
13105    
13106    getMinimumSize : function(){
13107        return this.minSize;
13108    },
13109
13110    
13111    setMinimumSize : function(minSize){
13112        this.minSize = minSize;
13113    },
13114
13115    
13116    getMaximumSize : function(){
13117        return this.maxSize;
13118    },
13119
13120    
13121    setMaximumSize : function(maxSize){
13122        this.maxSize = maxSize;
13123    },
13124
13125    
13126    setCurrentSize : function(size){
13127        var oldAnimate = this.animate;
13128        this.animate = false;
13129        this.adapter.setElementSize(this, size);
13130        this.animate = oldAnimate;
13131    },
13132
13133    
13134    destroy : function(removeEl){
13135        Ext.destroy(this.shim, Ext.get(this.proxy));
13136        this.dd.unreg();
13137        if(removeEl){
13138            this.el.remove();
13139        }
13140        this.purgeListeners();
13141    }
13142});
13143
13144
13145Ext.SplitBar.createProxy = function(dir){
13146    var proxy = new Ext.Element(document.createElement("div"));
13147    document.body.appendChild(proxy.dom);
13148    proxy.unselectable();
13149    var cls = 'x-splitbar-proxy';
13150    proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
13151    return proxy.dom;
13152};
13153
13154
13155Ext.SplitBar.BasicLayoutAdapter = function(){
13156};
13157
13158Ext.SplitBar.BasicLayoutAdapter.prototype = {
13159    
13160    init : function(s){
13161
13162    },
13163    
13164     getElementSize : function(s){
13165        if(s.orientation == Ext.SplitBar.HORIZONTAL){
13166            return s.resizingEl.getWidth();
13167        }else{
13168            return s.resizingEl.getHeight();
13169        }
13170    },
13171
13172    
13173    setElementSize : function(s, newSize, onComplete){
13174        if(s.orientation == Ext.SplitBar.HORIZONTAL){
13175            if(!s.animate){
13176                s.resizingEl.setWidth(newSize);
13177                if(onComplete){
13178                    onComplete(s, newSize);
13179                }
13180            }else{
13181                s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
13182            }
13183        }else{
13184
13185            if(!s.animate){
13186                s.resizingEl.setHeight(newSize);
13187                if(onComplete){
13188                    onComplete(s, newSize);
13189                }
13190            }else{
13191                s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
13192            }
13193        }
13194    }
13195};
13196
13197
13198Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
13199    this.basic = new Ext.SplitBar.BasicLayoutAdapter();
13200    this.container = Ext.get(container);
13201};
13202
13203Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
13204    init : function(s){
13205        this.basic.init(s);
13206    },
13207
13208    getElementSize : function(s){
13209        return this.basic.getElementSize(s);
13210    },
13211
13212    setElementSize : function(s, newSize, onComplete){
13213        this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
13214    },
13215
13216    moveSplitter : function(s){
13217        var yes = Ext.SplitBar;
13218        switch(s.placement){
13219            case yes.LEFT:
13220                s.el.setX(s.resizingEl.getRight());
13221                break;
13222            case yes.RIGHT:
13223                s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
13224                break;
13225            case yes.TOP:
13226                s.el.setY(s.resizingEl.getBottom());
13227                break;
13228            case yes.BOTTOM:
13229                s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
13230                break;
13231        }
13232    }
13233};
13234
13235
13236Ext.SplitBar.VERTICAL = 1;
13237
13238
13239Ext.SplitBar.HORIZONTAL = 2;
13240
13241
13242Ext.SplitBar.LEFT = 1;
13243
13244
13245Ext.SplitBar.RIGHT = 2;
13246
13247
13248Ext.SplitBar.TOP = 3;
13249
13250
13251Ext.SplitBar.BOTTOM = 4;
13252
13253Ext.Container = Ext.extend(Ext.BoxComponent, {
13254    
13255    
13256    
13257    
13258    bufferResize: 50,
13259
13260    
13261    
13262    
13263
13264
13265    
13266    autoDestroy : true,
13267
13268    
13269    forceLayout: false,
13270
13271    
13272    
13273    defaultType : 'panel',
13274
13275    
13276    resizeEvent: 'resize',
13277
13278    
13279    bubbleEvents: ['add', 'remove'],
13280
13281    
13282    initComponent : function(){
13283        Ext.Container.superclass.initComponent.call(this);
13284
13285        this.addEvents(
13286            
13287            'afterlayout',
13288            
13289            'beforeadd',
13290            
13291            'beforeremove',
13292            
13293            'add',
13294            
13295            'remove'
13296        );
13297
13298        
13299        var items = this.items;
13300        if(items){
13301            delete this.items;
13302            this.add(items);
13303        }
13304    },
13305
13306    
13307    initItems : function(){
13308        if(!this.items){
13309            this.items = new Ext.util.MixedCollection(false, this.getComponentId);
13310            this.getLayout(); 
13311        }
13312    },
13313
13314    
13315    setLayout : function(layout){
13316        if(this.layout && this.layout != layout){
13317            this.layout.setContainer(null);
13318        }
13319        this.layout = layout;
13320        this.initItems();
13321        layout.setContainer(this);
13322    },
13323
13324    afterRender: function(){
13325        
13326        
13327        Ext.Container.superclass.afterRender.call(this);
13328        if(!this.layout){
13329            this.layout = 'auto';
13330        }
13331        if(Ext.isObject(this.layout) && !this.layout.layout){
13332            this.layoutConfig = this.layout;
13333            this.layout = this.layoutConfig.type;
13334        }
13335        if(Ext.isString(this.layout)){
13336            this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
13337        }
13338        this.setLayout(this.layout);
13339
13340        
13341        if(this.activeItem !== undefined && this.layout.setActiveItem){
13342            var item = this.activeItem;
13343            delete this.activeItem;
13344            this.layout.setActiveItem(item);
13345        }
13346
13347        
13348        if(!this.ownerCt){
13349            this.doLayout(false, true);
13350        }
13351
13352        
13353        
13354        if(this.monitorResize === true){
13355            Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
13356        }
13357    },
13358
13359    
13360    getLayoutTarget : function(){
13361        return this.el;
13362    },
13363
13364    
13365    getComponentId : function(comp){
13366        return comp.getItemId();
13367    },
13368
13369    
13370    add : function(comp){
13371        this.initItems();
13372        var args = arguments.length > 1;
13373        if(args || Ext.isArray(comp)){
13374            var result = [];
13375            Ext.each(args ? arguments : comp, function(c){
13376                result.push(this.add(c));
13377            }, this);
13378            return result;
13379        }
13380        var c = this.lookupComponent(this.applyDefaults(comp));
13381        var index = this.items.length;
13382        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
13383            this.items.add(c);
13384            
13385            c.onAdded(this, index);
13386            this.onAdd(c);
13387            this.fireEvent('add', this, c, index);
13388        }
13389        return c;
13390    },
13391
13392    onAdd : function(c){
13393        
13394    },
13395
13396    
13397    onAdded : function(container, pos) {
13398        
13399        this.ownerCt = container;
13400        this.initRef();
13401        
13402        this.cascade(function(c){
13403            c.initRef();
13404        });
13405        this.fireEvent('added', this, container, pos);
13406    },
13407
13408    
13409    insert : function(index, comp) {
13410        var args   = arguments,
13411            length = args.length,
13412            result = [],
13413            i, c;
13414        
13415        this.initItems();
13416        
13417        if (length > 2) {
13418            for (i = length - 1; i >= 1; --i) {
13419                result.push(this.insert(index, args[i]));
13420            }
13421            return result;
13422        }
13423        
13424        c = this.lookupComponent(this.applyDefaults(comp));
13425        index = Math.min(index, this.items.length);
13426        
13427        if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
13428            if (c.ownerCt == this) {
13429                this.items.remove(c);
13430            }
13431            this.items.insert(index, c);
13432            c.onAdded(this, index);
13433            this.onAdd(c);
13434            this.fireEvent('add', this, c, index);
13435        }
13436        
13437        return c;
13438    },
13439
13440    
13441    applyDefaults : function(c){
13442        var d = this.defaults;
13443        if(d){
13444            if(Ext.isFunction(d)){
13445                d = d.call(this, c);
13446            }
13447            if(Ext.isString(c)){
13448                c = Ext.ComponentMgr.get(c);
13449                Ext.apply(c, d);
13450            }else if(!c.events){
13451                Ext.applyIf(c.isAction ? c.initialConfig : c, d);
13452            }else{
13453                Ext.apply(c, d);
13454            }
13455        }
13456        return c;
13457    },
13458
13459    
13460    onBeforeAdd : function(item){
13461        if(item.ownerCt){
13462            item.ownerCt.remove(item, false);
13463        }
13464        if(this.hideBorders === true){
13465            item.border = (item.border === true);
13466        }
13467    },
13468
13469    
13470    remove : function(comp, autoDestroy){
13471        this.initItems();
13472        var c = this.getComponent(comp);
13473        if(c && this.fireEvent('beforeremove', this, c) !== false){
13474            this.doRemove(c, autoDestroy);
13475            this.fireEvent('remove', this, c);
13476        }
13477        return c;
13478    },
13479
13480    onRemove: function(c){
13481        
13482    },
13483
13484    
13485    doRemove: function(c, autoDestroy){
13486        var l = this.layout,
13487            hasLayout = l && this.rendered;
13488
13489        if(hasLayout){
13490            l.onRemove(c);
13491        }
13492        this.items.remove(c);
13493        c.onRemoved();
13494        this.onRemove(c);
13495        if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
13496            c.destroy();
13497        }
13498        if(hasLayout){
13499            l.afterRemove(c);
13500        }
13501    },
13502
13503    
13504    removeAll: function(autoDestroy){
13505        this.initItems();
13506        var item, rem = [], items = [];
13507        this.items.each(function(i){
13508            rem.push(i);
13509        });
13510        for (var i = 0, len = rem.length; i < len; ++i){
13511            item = rem[i];
13512            this.remove(item, autoDestroy);
13513            if(item.ownerCt !== this){
13514                items.push(item);
13515            }
13516        }
13517        return items;
13518    },
13519
13520    
13521    getComponent : function(comp){
13522        if(Ext.isObject(comp)){
13523            comp = comp.getItemId();
13524        }
13525        return this.items.get(comp);
13526    },
13527
13528    
13529    lookupComponent : function(comp){
13530        if(Ext.isString(comp)){
13531            return Ext.ComponentMgr.get(comp);
13532        }else if(!comp.events){
13533            return this.createComponent(comp);
13534        }
13535        return comp;
13536    },
13537
13538    
13539    createComponent : function(config, defaultType){
13540        if (config.render) {
13541            return config;
13542        }
13543        
13544        
13545        var c = Ext.create(Ext.apply({
13546            ownerCt: this
13547        }, config), defaultType || this.defaultType);
13548        delete c.initialConfig.ownerCt;
13549        delete c.ownerCt;
13550        return c;
13551    },
13552
13553    
13554    canLayout : function() {
13555        var el = this.getVisibilityEl();
13556        return el && el.dom && !el.isStyle("display", "none");
13557    },
13558
13559    
13560
13561    doLayout : function(shallow, force){
13562        var rendered = this.rendered,
13563            forceLayout = force || this.forceLayout;
13564
13565        if(this.collapsed || !this.canLayout()){
13566            this.deferLayout = this.deferLayout || !shallow;
13567            if(!forceLayout){
13568                return;
13569            }
13570            shallow = shallow && !this.deferLayout;
13571        } else {
13572            delete this.deferLayout;
13573        }
13574        if(rendered && this.layout){
13575            this.layout.layout();
13576        }
13577        if(shallow !== true && this.items){
13578            var cs = this.items.items;
13579            for(var i = 0, len = cs.length; i < len; i++){
13580                var c = cs[i];
13581                if(c.doLayout){
13582                    c.doLayout(false, forceLayout);
13583                }
13584            }
13585        }
13586        if(rendered){
13587            this.onLayout(shallow, forceLayout);
13588        }
13589        
13590        this.hasLayout = true;
13591        delete this.forceLayout;
13592    },
13593
13594    onLayout : Ext.emptyFn,
13595
13596    
13597    shouldBufferLayout: function(){
13598        
13599        var hl = this.hasLayout;
13600        if(this.ownerCt){
13601            
13602            return hl ? !this.hasLayoutPending() : false;
13603        }
13604        
13605        return hl;
13606    },
13607
13608    
13609    hasLayoutPending: function(){
13610        
13611        var pending = false;
13612        this.ownerCt.bubble(function(c){
13613            if(c.layoutPending){
13614                pending = true;
13615                return false;
13616            }
13617        });
13618        return pending;
13619    },
13620
13621    onShow : function(){
13622        
13623        Ext.Container.superclass.onShow.call(this);
13624        
13625        if(Ext.isDefined(this.deferLayout)){
13626            delete this.deferLayout;
13627            this.doLayout(true);
13628        }
13629    },
13630
13631    
13632    getLayout : function(){
13633        if(!this.layout){
13634            var layout = new Ext.layout.AutoLayout(this.layoutConfig);
13635            this.setLayout(layout);
13636        }
13637        return this.layout;
13638    },
13639
13640    
13641    beforeDestroy : function(){
13642        var c;
13643        if(this.items){
13644            while(c = this.items.first()){
13645                this.doRemove(c, true);
13646            }
13647        }
13648        if(this.monitorResize){
13649            Ext.EventManager.removeResizeListener(this.doLayout, this);
13650        }
13651        Ext.destroy(this.layout);
13652        Ext.Container.superclass.beforeDestroy.call(this);
13653    },
13654
13655    
13656    cascade : function(fn, scope, args){
13657        if(fn.apply(scope || this, args || [this]) !== false){
13658            if(this.items){
13659                var cs = this.items.items;
13660                for(var i = 0, len = cs.length; i < len; i++){
13661                    if(cs[i].cascade){
13662                        cs[i].cascade(fn, scope, args);
13663                    }else{
13664                        fn.apply(scope || cs[i], args || [cs[i]]);
13665                    }
13666                }
13667            }
13668        }
13669        return this;
13670    },
13671
13672    
13673    findById : function(id){
13674        var m = null, 
13675            ct = this;
13676        this.cascade(function(c){
13677            if(ct != c && c.id === id){
13678                m = c;
13679                return false;
13680            }
13681        });
13682        return m;
13683    },
13684
13685    
13686    findByType : function(xtype, shallow){
13687        return this.findBy(function(c){
13688            return c.isXType(xtype, shallow);
13689        });
13690    },
13691
13692    
13693    find : function(prop, value){
13694        return this.findBy(function(c){
13695            return c[prop] === value;
13696        });
13697    },
13698
13699    
13700    findBy : function(fn, scope){
13701        var m = [], ct = this;
13702        this.cascade(function(c){
13703            if(ct != c && fn.call(scope || c, c, ct) === true){
13704                m.push(c);
13705            }
13706        });
13707        return m;
13708    },
13709
13710    
13711    get : function(key){
13712        return this.getComponent(key);
13713    }
13714});
13715
13716Ext.Container.LAYOUTS = {};
13717Ext.reg('container', Ext.Container);
13718
13719Ext.layout.ContainerLayout = Ext.extend(Object, {
13720    
13721    
13722
13723    
13724
13725    
13726    monitorResize:false,
13727    
13728    activeItem : null,
13729
13730    constructor : function(config){
13731        this.id = Ext.id(null, 'ext-layout-');
13732        Ext.apply(this, config);
13733    },
13734
13735    type: 'container',
13736
13737    
13738    IEMeasureHack : function(target, viewFlag) {
13739        var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
13740        for (i = 0 ; i < tLen ; i++) {
13741            c = tChildren[i];
13742            e = Ext.get(c);
13743            if (e) {
13744                d[i] = e.getStyle('display');
13745                e.setStyle({display: 'none'});
13746            }
13747        }
13748        ret = target ? target.getViewSize(viewFlag) : {};
13749        for (i = 0 ; i < tLen ; i++) {
13750            c = tChildren[i];
13751            e = Ext.get(c);
13752            if (e) {
13753                e.setStyle({display: d[i]});
13754            }
13755        }
13756        return ret;
13757    },
13758
13759    
13760    getLayoutTargetSize : Ext.EmptyFn,
13761
13762    
13763    layout : function(){
13764        var ct = this.container, target = ct.getLayoutTarget();
13765        if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
13766            target.addClass(this.targetCls);
13767        }
13768        this.onLayout(ct, target);
13769        ct.fireEvent('afterlayout', ct, this);
13770    },
13771
13772    
13773    onLayout : function(ct, target){
13774        this.renderAll(ct, target);
13775    },
13776
13777    
13778    isValidParent : function(c, target){
13779        return target && c.getPositionEl().dom.parentNode == (target.dom || target);
13780    },
13781
13782    
13783    renderAll : function(ct, target){
13784        var items = ct.items.items, i, c, len = items.length;
13785        for(i = 0; i < len; i++) {
13786            c = items[i];
13787            if(c && (!c.rendered || !this.isValidParent(c, target))){
13788                this.renderItem(c, i, target);
13789            }
13790        }
13791    },
13792
13793    
13794    renderItem : function(c, position, target){
13795        if (c) {
13796            if (!c.rendered) {
13797                c.render(target, position);
13798                this.configureItem(c);
13799            } else if (!this.isValidParent(c, target)) {
13800                if (Ext.isNumber(position)) {
13801                    position = target.dom.childNodes[position];
13802                }
13803                
13804                target.dom.insertBefore(c.getPositionEl().dom, position || null);
13805                c.container = target;
13806                this.configureItem(c);
13807            }
13808        }
13809    },
13810
13811    
13812    
13813    getRenderedItems: function(ct){
13814        var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
13815        for (i = 0; i < len; i++) {
13816            if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
13817                items.push(c);
13818            }
13819        };
13820        return items;
13821    },
13822
13823    
13824    configureItem: function(c){
13825        if (this.extraCls) {
13826            var t = c.getPositionEl ? c.getPositionEl() : c;
13827            t.addClass(this.extraCls);
13828        }
13829        
13830        
13831        if (c.doLayout && this.forceLayout) {
13832            c.doLayout();
13833        }
13834        if (this.renderHidden && c != this.activeItem) {
13835            c.hide();
13836        }
13837    },
13838
13839    onRemove: function(c){
13840        if(this.activeItem == c){
13841            delete this.activeItem;
13842        }
13843        if(c.rendered && this.extraCls){
13844            var t = c.getPositionEl ? c.getPositionEl() : c;
13845            t.removeClass(this.extraCls);
13846        }
13847    },
13848
13849    afterRemove: function(c){
13850        if(c.removeRestore){
13851            c.removeMode = 'container';
13852            delete c.removeRestore;
13853        }
13854    },
13855
13856    
13857    onResize: function(){
13858        var ct = this.container,
13859            b;
13860        if(ct.collapsed){
13861            return;
13862        }
13863        if(b = ct.bufferResize && ct.shouldBufferLayout()){
13864            if(!this.resizeTask){
13865                this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
13866                this.resizeBuffer = Ext.isNumber(b) ? b : 50;
13867            }
13868            ct.layoutPending = true;
13869            this.resizeTask.delay(this.resizeBuffer);
13870        }else{
13871            this.runLayout();
13872        }
13873    },
13874
13875    runLayout: function(){
13876        var ct = this.container;
13877        this.layout();
13878        ct.onLayout();
13879        delete ct.layoutPending;
13880    },
13881
13882    
13883    setContainer : function(ct){
13884        
13885        if(this.monitorResize && ct != this.container){
13886            var old = this.container;
13887            if(old){
13888                old.un(old.resizeEvent, this.onResize, this);
13889            }
13890            if(ct){
13891                ct.on(ct.resizeEvent, this.onResize, this);
13892            }
13893        }
13894        this.container = ct;
13895    },
13896
13897    
13898    parseMargins : function(v){
13899        if (Ext.isNumber(v)) {
13900            v = v.toString();
13901        }
13902        var ms  = v.split(' '),
13903            len = ms.length;
13904            
13905        if (len == 1) {
13906            ms[1] = ms[2] = ms[3] = ms[0];
13907        } else if(len == 2) {
13908            ms[2] = ms[0];
13909            ms[3] = ms[1];
13910        } else if(len == 3) {
13911            ms[3] = ms[1];
13912        }
13913        
13914        return {
13915            top   :parseInt(ms[0], 10) || 0,
13916            right :parseInt(ms[1], 10) || 0,
13917            bottom:parseInt(ms[2], 10) || 0,
13918            left  :parseInt(ms[3], 10) || 0
13919        };
13920    },
13921
13922    
13923    fieldTpl: (function() {
13924        var t = new Ext.Template(
13925            '<div class="x-form-item {itemCls}" tabIndex="-1">',
13926                '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
13927                '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
13928                '</div><div class="{clearCls}"></div>',
13929            '</div>'
13930        );
13931        t.disableFormats = true;
13932        return t.compile();
13933    })(),
13934
13935    
13936    destroy : function(){
13937        
13938        if(this.resizeTask && this.resizeTask.cancel){
13939            this.resizeTask.cancel();
13940        }
13941        if(this.container) {
13942            this.container.un(this.container.resizeEvent, this.onResize, this);
13943        }
13944        if(!Ext.isEmpty(this.targetCls)){
13945            var target = this.container.getLayoutTarget();
13946            if(target){
13947                target.removeClass(this.targetCls);
13948            }
13949        }
13950    }
13951});
13952Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
13953    type: 'auto',
13954
13955    monitorResize: true,
13956
13957    onLayout : function(ct, target){
13958        Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
13959        var cs = this.getRenderedItems(ct), len = cs.length, i, c;
13960        for(i = 0; i < len; i++){
13961            c = cs[i];
13962            if (c.doLayout){
13963                
13964                c.doLayout(true);
13965            }
13966        }
13967    }
13968});
13969
13970Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
13971
13972Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
13973    
13974    monitorResize:true,
13975
13976    type: 'fit',
13977
13978    getLayoutTargetSize : function() {
13979        var target = this.container.getLayoutTarget();
13980        if (!target) {
13981            return {};
13982        }
13983        
13984        return target.getStyleSize();
13985    },
13986
13987    
13988    onLayout : function(ct, target){
13989        Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
13990        if(!ct.collapsed){
13991            this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
13992        }
13993    },
13994
13995    
13996    setItemSize : function(item, size){
13997        if(item && size.height > 0){ 
13998            item.setSize(size);
13999        }
14000    }
14001});
14002Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
14003Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
14004    
14005    deferredRender : false,
14006
14007    
14008    layoutOnCardChange : false,
14009
14010    
14011    
14012    renderHidden : true,
14013
14014    type: 'card',
14015
14016    
14017    setActiveItem : function(item){
14018        var ai = this.activeItem,
14019            ct = this.container;
14020        item = ct.getComponent(item);
14021
14022        
14023        if(item && ai != item){
14024
14025            
14026            if(ai){
14027                ai.hide();
14028                if (ai.hidden !== true) {
14029                    return false;
14030                }
14031                ai.fireEvent('deactivate', ai);
14032            }
14033
14034            var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
14035
14036            
14037            this.activeItem = item;
14038
14039            
14040            
14041            delete item.deferLayout;
14042
14043            
14044            item.show();
14045
14046            this.layout();
14047
14048            if(layout){
14049                item.doLayout();
14050            }
14051            item.fireEvent('activate', item);
14052        }
14053    },
14054
14055    
14056    renderAll : function(ct, target){
14057        if(this.deferredRender){
14058            this.renderItem(this.activeItem, undefined, target);
14059        }else{
14060            Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
14061        }
14062    }
14063});
14064Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
14065
14066Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
14067    
14068
14069    
14070    monitorResize : true,
14071
14072    type : 'anchor',
14073
14074    
14075    defaultAnchor : '100%',
14076
14077    parseAnchorRE : /^(r|right|b|bottom)$/i,
14078
14079
14080    getLayoutTargetSize : function() {
14081        var target = this.container.getLayoutTarget(), ret = {};
14082        if (target) {
14083            ret = target.getViewSize();
14084
14085            
14086            
14087            
14088            if (Ext.isIE && Ext.isStrict && ret.width == 0){
14089                ret =  target.getStyleSize();
14090            }
14091            ret.width -= target.getPadding('lr');
14092            ret.height -= target.getPadding('tb');
14093        }
14094        return ret;
14095    },
14096
14097    
14098    onLayout : function(container, target) {
14099        Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);
14100
14101        var size = this.getLayoutTargetSize(),
14102            containerWidth = size.width,
14103            containerHeight = size.height,
14104            overflow = target.getStyle('overflow'),
14105            components = this.getRenderedItems(container),
14106            len = components.length,
14107            boxes = [],
14108            box,
14109            anchorWidth,
14110            anchorHeight,
14111            component,
14112            anchorSpec,
14113            calcWidth,
14114            calcHeight,
14115            anchorsArray,
14116            totalHeight = 0,
14117            i,
14118            el;
14119
14120        if(containerWidth < 20 && containerHeight < 20){
14121            return;
14122        }
14123
14124        
14125        if(container.anchorSize) {
14126            if(typeof container.anchorSize == 'number') {
14127                anchorWidth = container.anchorSize;
14128            } else {
14129                anchorWidth = container.anchorSize.width;
14130                anchorHeight = container.anchorSize.height;
14131            }
14132        } else {
14133            anchorWidth = container.initialConfig.width;
14134            anchorHeight = container.initialConfig.height;
14135        }
14136
14137        for(i = 0; i < len; i++) {
14138            component = components[i];
14139            el = component.getPositionEl();
14140
14141            
14142            if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
14143                component.anchor = this.defaultAnchor;
14144            }
14145
14146            if(component.anchor) {
14147                anchorSpec = component.anchorSpec;
14148                
14149                if(!anchorSpec){
14150                    anchorsArray = component.anchor.split(' ');
14151                    component.anchorSpec = anchorSpec = {
14152                        right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
14153                        bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
14154                    };
14155                }
14156                calcWidth = anchorSpec.right ? this.adjustWidthAnchor(
14156anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
14157                calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;
14158
14159                if(calcWidth || calcHeight) {
14160                    boxes.push({
14161                        component: component,
14162                        width: calcWidth || undefined,
14163                        height: calcHeight || undefined
14164                    });
14165                }
14166            }
14167        }
14168        for (i = 0, len = boxes.length; i < len; i++) {
14169            box = boxes[i];
14170            box.component.setSize(box.width, box.height);
14171        }
14172
14173        if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
14174            var newTargetSize = this.getLayoutTargetSize();
14175            if (newTargetSize.width != size.width || newTargetSize.height != size.height){
14176                this.adjustmentPass = true;
14177                this.onLayout(container, target);
14178            }
14179        }
14180
14181        delete this.adjustmentPass;
14182    },
14183
14184    
14185    parseAnchor : function(a, start, cstart) {
14186        if (a && a != 'none') {
14187            var last;
14188            
14189            if (this.parseAnchorRE.test(a)) {
14190                var diff = cstart - start;
14191                return function(v){
14192                    if(v !== last){
14193                        last = v;
14194                        return v - diff;
14195                    }
14196                };
14197            
14198            } else if(a.indexOf('%') != -1) {
14199                var ratio = parseFloat(a.replace('%', ''))*.01;
14200                return function(v){
14201                    if(v !== last){
14202                        last = v;
14203                        return Math.floor(v*ratio);
14204                    }
14205                };
14206            
14207            } else {
14208                a = parseInt(a, 10);
14209                if (!isNaN(a)) {
14210                    return function(v) {
14211                        if (v !== last) {
14212                            last = v;
14213                            return v + a;
14214                        }
14215                    };
14216                }
14217            }
14218        }
14219        return false;
14220    },
14221
14222    
14223    adjustWidthAnchor : function(value, comp){
14224        return value;
14225    },
14226
14227    
14228    adjustHeightAnchor : function(value, comp){
14229        return value;
14230    }
14231
14232    
14233});
14234Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
14235
14236Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
14237    
14238    monitorResize:true,
14239
14240    type: 'column',
14241
14242    extraCls: 'x-column',
14243
14244    scrollOffset : 0,
14245
14246    
14247
14248    targetCls: 'x-column-layout-ct',
14249
14250    isValidParent : function(c, target){
14251        return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
14252    },
14253
14254    getLayoutTargetSize : function() {
14255        var target = this.container.getLayoutTarget(), ret;
14256        if (target) {
14257            ret = target.getViewSize();
14258
14259            
14260            
14261            
14262            if (Ext.isIE && Ext.isStrict && ret.width == 0){
14263                ret =  target.getStyleSize();
14264            }
14265
14266            ret.width -= target.getPadding('lr');
14267            ret.height -= target.getPadding('tb');
14268        }
14269        return ret;
14270    },
14271
14272    renderAll : function(ct, target) {
14273        if(!this.innerCt){
14274            
14275            
14276            this.innerCt = target.createChild({cls:'x-column-inner'});
14277            this.innerCt.createChild({cls:'x-clear'});
14278        }
14279        Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
14280    },
14281
14282    
14283    onLayout : function(ct, target){
14284        var cs = ct.items.items,
14285            len = cs.length,
14286            c,
14287            i,
14288            m,
14289            margins = [];
14290
14291        this.renderAll(ct, target);
14292
14293        var size = this.getLayoutTargetSize();
14294
14295        if(size.width < 1 && size.height < 1){ 
14296            return;
14297        }
14298
14299        var w = size.width - this.scrollOffset,
14300            h = size.height,
14301            pw = w;
14302
14303        this.innerCt.setWidth(w);
14304
14305        
14306        
14307
14308        for(i = 0; i < len; i++){
14309            c = cs[i];
14310            m = c.getPositionEl().getMargins('lr');
14311            margins[i] = m;
14312            if(!c.columnWidth){
14313                pw -= (c.getWidth() + m);
14314            }
14315        }
14316
14317        pw = pw < 0 ? 0 : pw;
14318
14319        for(i = 0; i < len; i++){
14320            c = cs[i];
14321            m = margins[i];
14322            if(c.columnWidth){
14323                c.setSize(Math.floor(c.columnWidth * pw) - m);
14324            }
14325        }
14326
14327        
14328        
14329        if (Ext.isIE) {
14330            if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
14331                var ts = this.getLayoutTargetSize();
14332                if (ts.width != size.width){
14333                    this.adjustmentPass = true;
14334                    this.onLayout(ct, target);
14335                }
14336            }
14337        }
14338        delete this.adjustmentPass;
14339    }
14340
14341    
14342});
14343
14344Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
14345
14346Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
14347    
14348    monitorResize:true,
14349    
14350    rendered : false,
14351
14352    type: 'border',
14353
14354    targetCls: 'x-border-layout-ct',
14355
14356    getLayoutTargetSize : function() {
14357        var target = this.container.getLayoutTarget();
14358        return target ? target.getViewSize() : {};
14359    },
14360
14361    
14362    onLayout : function(ct, target){
14363        var collapsed, i, c, pos, items = ct.items.items, len = items.length;
14364        if(!this.rendered){
14365            collapsed = [];
14366            for(i = 0; i < len; i++) {
14367                c = items[i];
14368                pos = c.region;
14369                if(c.collapsed){
14370                    collapsed.push(c);
14371                }
14372                c.collapsed = false;
14373                if(!c.rendered){
14374                    c.render(target, i);
14375                    c.getPositionEl().addClass('x-border-panel');
14376                }
14377                this[pos] = pos != 'center' && c.split ?
14378                    new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
14379                    new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
14380                this[pos].render(target, c);
14381            }
14382            this.rendered = true;
14383        }
14384
14385        var size = this.getLayoutTargetSize();
14386        if(size.width < 20 || size.height < 20){ 
14387            if(collapsed){
14388                this.restoreCollapsed = collapsed;
14389            }
14390            return;
14391        }else if(this.restoreCollapsed){
14392            collapsed = this.restoreCollapsed;
14393            delete this.restoreCollapsed;
14394        }
14395
14396        var w = size.width, h = size.height,
14397            centerW = w, centerH = h, centerY = 0, centerX = 0,
14398            n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
14399            b, m, totalWidth, totalHeight;
14400        if(!c && Ext.layout.BorderLayout.WARN !== false){
14401            throw 'No center region defined in BorderLayout ' + ct.id;
14402        }
14403
14404        if(n && n.isVisible()){
14405            b = n.getSize();
14406            m = n.getMargins();
14407            b.width = w - (m.left+m.right);
14408            b.x = m.left;
14409            b.y = m.top;
14410            centerY = b.height + b.y + m.bottom;
14411            centerH -= centerY;
14412            n.applyLayout(b);
14413        }
14414        if(s && s.isVisible()){
14415            b = s.getSize();
14416            m = s.getMargins();
14417            b.width = w - (m.left+m.right);
14418            b.x = m.left;
14419            totalHeight = (b.height + m.top + m.bottom);
14420            b.y = h - totalHeight + m.top;
14421            centerH -= totalHeight;
14422            s.applyLayout(b);
14423        }
14424        if(west && west.isVisible()){
14425            b = west.getSize();
14426            m = west.getMargins();
14427            b.height = centerH - (m.top+m.bottom);
14428            b.x = m.left;
14429            b.y = centerY + m.top;
14430            totalWidth = (b.width + m.left + m.right);
14431            centerX += totalWidth;
14432            centerW -= totalWidth;
14433            west.applyLayout(b);
14434        }
14435        if(e && e.isVisible()){
14436            b = e.getSize();
14437            m = e.getMargins();
14438            b.height = centerH - (m.top+m.bottom);
14439            totalWidth = (b.width + m.left + m.right);
14440            b.x = w - totalWidth + m.left;
14441            b.y = centerY + m.top;
14442            centerW -= totalWidth;
14443            e.applyLayout(b);
14444        }
14445        if(c){
14446            m = c.getMargins();
14447            var centerBox = {
14448                x: centerX + m.left,
14449                y: centerY + m.top,
14450                width: centerW - (m.left+m.right),
14451                height: centerH - (m.top+m.bottom)
14452            };
14453            c.applyLayout(centerBox);
14454        }
14455        if(collapsed){
14456            for(i = 0, len = collapsed.length; i < len; i++){
14457                collapsed[i].collapse(false);
14458            }
14459        }
14460        if(Ext.isIE && Ext.isStrict){ 
14461            target.repaint();
14462        }
14463        
14464        if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
14465            var ts = this.getLayoutTargetSize();
14466            if (ts.width != size.width || ts.height != size.height){
14467                this.adjustmentPass = true;
14468                this.onLayout(ct, target);
14469            }
14470        }
14471        delete this.adjustmentPass;
14472    },
14473
14474    destroy: function() {
14475        var r = ['north', 'south', 'east', 'west'], i, region;
14476        for (i = 0; i < r.length; i++) {
14477            region = this[r[i]];
14478            if(region){
14479                if(region.destroy){
14480                    region.destroy();
14481                }else if (region.split){
14482                    region.split.destroy(true);
14483                }
14484            }
14485        }
14486        Ext.layout.BorderLayout.superclass.destroy.call(this);
14487    }
14488
14489    
14490});
14491
14492
14493Ext.layout.BorderLayout.Region = function(layout, config, pos){
14494    Ext.apply(this, config);
14495    this.layout = layout;
14496    this.position = pos;
14497    this.state = {};
14498    if(typeof this.margins == 'string'){
14499        this.margins = this.layout.parseMargins(this.margins);
14500    }
14501    this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
14502    if(this.collapsible){
14503        if(typeof this.cmargins == 'string'){
14504            this.cmargins = this.layout.parseMargins(this.cmargins);
14505        }
14506        if(this.collapseMode == 'mini' && !this.cmargins){
14507            this.cmargins = {left:0,top:0,right:0,bottom:0};
14508        }else{
14509            this.cmargins = Ext.applyIf(this.cmargins || {},
14510                pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
14511        }
14512    }
14513};
14514
14515Ext.layout.BorderLayout.Region.prototype = {
14516    
14517    
14518    
14519    
14520    
14521    
14522    collapsible : false,
14523    
14524    split:false,
14525    
14526    floatable: true,
14527    
14528    minWidth:50,
14529    
14530    minHeight:50,
14531
14532    
14533    defaultMargins : {left:0,top:0,right:0,bottom:0},
14534    
14535    defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
14536    
14537    defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
14538    floatingZIndex: 100,
14539
14540    
14541    isCollapsed : false,
14542
14543    
14544    
14545    
14546
14547    
14548    render : function(ct, p){
14549        this.panel = p;
14550        p.el.enableDisplayMode();
14551        this.targetEl = ct;
14552        this.el = p.el;
14553
14554        var gs = p.getState, ps = this.position;
14555        p.getState = function(){
14556            return Ext.apply(gs.call(p) || {}, this.state);
14557        }.createDelegate(this);
14558
14559        if(ps != 'center'){
14560            p.allowQueuedExpand = false;
14561            p.on({
14562                beforecollapse: this.beforeCollapse,
14563                collapse: this.onCollapse,
14564                beforeexpand: this.beforeExpand,
14565                expand: this.onExpand,
14566                hide: this.onHide,
14567                show: this.onShow,
14568                scope: this
14569            });
14570            if(this.collapsible || this.floatable){
14571                p.collapseEl = 'el';
14572                p.slideAnchor = this.getSlideAnchor();
14573            }
14574            if(p.tools && p.tools.toggle){
14575                p.tools.toggle.addClass('x-tool-collapse-'+ps);
14576                p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
14577            }
14578        }
14579    },
14580
14581    
14582    getCollapsedEl : function(){
14583        if(!this.collapsedEl){
14584            if(!this.toolTemplate){
14585                var tt = new Ext.Template(
14586                     '<div class="x-tool x-tool-{id}">&#160;</div>'
14587                );
14588                tt.disableFormats = true;
14589                tt.compile();
14590                Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
14591            }
14592            this.collapsedEl = this.targetEl.createChild({
14593                cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
14594                id: this.panel.id + '-xcollapsed'
14595            });
14596            this.collapsedEl.enableDisplayMode('block');
14597
14598            if(this.collapseMode == 'mini'){
14599                this.collapsedEl.addClass('x-layout-cmini-'+this.position);
14600                this.miniCollapsedEl = this.collapsedEl.createChild({
14601                    cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
14602                });
14603                this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
14604                this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14605                this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14606            }else {
14607                if(this.collapsible !== false && !this.hideCollapseTool) {
14608                    var t = this.expandToolEl = this.toolTemplate.append(
14609                            this.collapsedEl.dom,
14610                            {id:'expand-'+this.position}, true);
14611                    t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14612                    t.on('click', this.onExpandClick, this, {stopEvent:true});
14613                }
14614                if(this.floatable !== false || this.titleCollapse){
14615                   this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14616                   this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
14617                }
14618            }
14619        }
14620        return this.collapsedEl;
14621    },
14622
14623    
14624    onExpandClick : function(e){
14625        if(this.isSlid){
14626            this.panel.expand(false);
14627        }else{
14628            this.panel.expand();
14629        }
14630    },
14631
14632    
14633    onCollapseClick : function(e){
14634        this.panel.collapse();
14635    },
14636
14637    
14638    beforeCollapse : function(p, animate){
14639        this.lastAnim = animate;
14640        if(this.splitEl){
14641            this.splitEl.hide();
14642        }
14643        this.getCollapsedEl().show();
14644        var el = this.panel.getEl();
14645        this.originalZIndex = el.getStyle('z-index');
14646        el.setStyle('z-index', 100);
14647        this.isCollapsed = true;
14648        this.layout.layout();
14649    },
14650
14651    
14652    onCollapse : function(animate){
14653        this.panel.el.setStyle('z-index', 1);
14654        if(this.lastAnim === false || this.panel.animCollapse === false){
14655            this.getCollapsedEl().dom.style.visibility = 'visible';
14656        }else{
14657            this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14658        }
14659        this.state.collapsed = true;
14660        this.panel.saveState();
14661    },
14662
14663    
14664    beforeExpand : function(animate){
14665        if(this.isSlid){
14666            this.afterSlideIn();
14667        }
14668        var c = this.getCollapsedEl();
14669        this.el.show();
14670        if(this.position == 'east' || this.position == 'west'){
14671            this.panel.setSize(undefined, c.getHeight());
14672        }else{
14673            this.panel.setSize(c.getWidth(), undefined);
14674        }
14675        c.hide();
14676        c.dom.style.visibility = 'hidden';
14677        this.panel.el.setStyle('z-index', this.floatingZIndex);
14678    },
14679
14680    
14681    onExpand : function(){
14682        this.isCollapsed = false;
14683        if(this.splitEl){
14684            this.splitEl.show();
14685        }
14686        this.layout.layout();
14687        this.panel.el.setStyle('z-index', this.originalZIndex);
14688        this.state.collapsed = false;
14689        this.panel.saveState();
14690    },
14691
14692    
14693    collapseClick : function(e){
14694        if(this.isSlid){
14695           e.stopPropagation();
14696           this.slideIn();
14697        }else{
14698           e.stopPropagation();
14699           this.slideOut();
14700        }
14701    },
14702
14703    
14704    onHide : function(){
14705        if(this.isCollapsed){
14706            this.getCollapsedEl().hide();
14707        }else if(this.splitEl){
14708            this.splitEl.hide();
14709        }
14710    },
14711
14712    
14713    onShow : function(){
14714        if(this.isCollapsed){
14715            this.getCollapsedEl().show();
14716        }else if(this.splitEl){
14717            this.splitEl.show();
14718        }
14719    },
14720
14721    
14722    isVisible : function(){
14723        return !this.panel.hidden;
14724    },
14725
14726    
14727    getMargins : function(){
14728        return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14729    },
14730
14731    
14732    getSize : function(){
14733        return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14734    },
14735
14736    
14737    setPanel : function(panel){
14738        this.panel = panel;
14739    },
14740
14741    
14742    getMinWidth: function(){
14743        return this.minWidth;
14744    },
14745
14746    
14747    getMinHeight: function(){
14748        return this.minHeight;
14749    },
14750
14751    
14752    applyLayoutCollapsed : function(box){
14753        var ce = this.getCollapsedEl();
14754        ce.setLeftTop(box.x, box.y);
14755        ce.setSize(box.width, box.height);
14756    },
14757
14758    
14759    applyLayout : function(box){
14760        if(this.isCollapsed){
14761            this.applyLayoutCollapsed(box);
14762        }else{
14763            this.panel.setPosition(box.x, box.y);
14764            this.panel.setSize(box.width, box.height);
14765        }
14766    },
14767
14768    
14769    beforeSlide: function(){
14770        this.panel.beforeEffect();
14771    },
14772
14773    
14774    afterSlide : function(){
14775        this.panel.afterEffect();
14776    },
14777
14778    
14779    initAutoHide : function(){
14780        if(this.autoHide !== false){
14781            if(!this.autoHideHd){
14782                this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
14783                this.autoHideHd = {
14784                    "mouseout": function(e){
14785                        if(!e.within(this.el, true)){
14786                            this.autoHideSlideTask.delay(500);
14787                        }
14788                    },
14789                    "mouseover" : function(e){
14790                        this.autoHideSlideTask.cancel();
14791                    },
14792                    scope : this
14793                };
14794            }
14795            this.el.on(this.autoHideHd);
14796            this.collapsedEl.on(this.autoHideHd);
14797        }
14798    },
14799
14800    
14801    clearAutoHide : function(){
14802        if(this.autoHide !== false){
14803            this.el.un("mouseout", this.autoHideHd.mouseout);
14804            this.el.un("mouseover", this.autoHideHd.mouseover);
14805            this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
14806            this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
14807        }
14808    },
14809
14810    
14811    clearMonitor : function(){
14812        Ext.getDoc().un("click", this.slideInIf, this);
14813    },
14814
14815    
14816    slideOut : function(){
14817        if(this.isSlid || this.el.hasActiveFx()){
14818            return;
14819        }
14820        this.isSlid = true;
14821        var ts = this.panel.tools, dh, pc;
14822        if(ts && ts.toggle){
14823            ts.toggle.hide();
14824        }
14825        this.el.show();
14826
14827        
14828        pc = this.panel.collapsed;
14829        this.panel.collapsed = false;
14830
14831        if(this.position == 'east' || this.position == 'west'){
14832            
14833            dh = this.panel.deferHeight;
14834            this.panel.deferHeight = false;
14835
14836            this.panel.setSize(undefined, this.collapsedEl.getHeight());
14837
14838            
14839            this.panel.deferHeight = dh;
14840        }else{
14841            this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14842        }
14843
14844        
14845        this.panel.collapsed = pc;
14846
14847        this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14848        this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14849        this.el.setStyle("z-index", this.floatingZIndex+2);
14850        this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
14851        if(this.animFloat !== false){
14852            this.beforeSlide();
14853            this.el.slideIn(this.getSlideAnchor(), {
14854                callback: function(){
14855                    this.afterSlide();
14856                    this.initAutoHide();
14857                    Ext.getDoc().on("click", this.slideInIf, this);
14858                },
14859                scope: this,
14860                block: true
14861            });
14862        }else{
14863            this.initAutoHide();
14864             Ext.getDoc().on("click", this.slideInIf, this);
14865        }
14866    },
14867
14868    
14869    afterSlideIn : function(){
14870        this.clearAutoHide();
14871        this.isSlid = false;
14872        this.clearMonitor();
14873        this.el.setStyle("z-index", "");
14874        this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
14875        this.el.dom.style.left = this.restoreLT[0];
14876        this.el.dom.style.top = this.restoreLT[1];
14877
14878        var ts = this.panel.tools;
14879        if(ts && ts.toggle){
14880            ts.toggle.show();
14881        }
14882    },
14883
14884    
14885    slideIn : function(cb){
14886        if(!this.isSlid || this.el.hasActiveFx()){
14887            Ext.callback(cb);
14888            return;
14889        }
14890        this.isSlid = false;
14891        if(this.animFloat !== false){
14892            this.beforeSlide();
14893            this.el.slideOut(this.getSlideAnchor(), {
14894                callback: function(){
14895                    this.el.hide();
14896                    this.afterSlide();
14897                    this.afterSlideIn();
14898                    Ext.callback(cb);
14899                },
14900                scope: this,
14901                block: true
14902            });
14903        }else{
14904            this.el.hide();
14905            this.afterSlideIn();
14906        }
14907    },
14908
14909    
14910    slideInIf : function(e){
14911        if(!e.within(this.el)){
14912            this.slideIn();
14913        }
14914    },
14915
14916    
14917    anchors : {
14918        "west" : "left",
14919        "east" : "right",
14920        "north" : "top",
14921        "south" : "bottom"
14922    },
14923
14924    
14925    sanchors : {
14926        "west" : "l",
14927        "east" : "r",
14928        "north" : "t",
14929        "south" : "b"
14930    },
14931
14932    
14933    canchors : {
14934        "west" : "tl-tr",
14935        "east" : "tr-tl",
14936        "north" : "tl-bl",
14937        "south" : "bl-tl"
14938    },
14939
14940    
14941    getAnchor : function(){
14942        return this.anchors[this.position];
14943    },
14944
14945    
14946    getCollapseAnchor : function(){
14947        return this.canchors[this.position];
14948    },
14949
14950    
14951    getSlideAnchor : function(){
14952        return this.sanchors[this.position];
14953    },
14954
14955    
14956    getAlignAdj : function(){
14957        var cm = this.cmargins;
14958        switch(this.position){
14959            case "west":
14960                return [0, 0];
14961            break;
14962            case "east":
14963                return [0, 0];
14964            break;
14965            case "north":
14966                return [0, 0];
14967            break;
14968            case "south":
14969                return [0, 0];
14970            break;
14971        }
14972    },
14973
14974    
14975    getExpandAdj : function(){
14976        var c = this.collapsedEl, cm = this.cmargins;
14977        switch(this.position){
14978            case "west":
14979                return [-(cm.right+c.getWidth()+cm.left), 0];
14980            break;
14981            case "east":
14982                return [cm.right+c.getWidth()+cm.left, 0];
14983            break;
14984            case "north":
14985                return [0, -(cm.top+cm.bottom+c.getHeight())];
14986            break;
14987            case "south":
14988                return [0, cm.top+cm.bottom+c.getHeight()];
14989            break;
14990        }
14991    },
14992
14993    destroy : function(){
14994        if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
14995            this.autoHideSlideTask.cancel();
14996        }
14997        Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
14998    }
14999};
15000
15001
15002Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
15003    Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
15004    
15005    this.applyLayout = this.applyFns[pos];
15006};
15007
15008Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
15009    
15010    
15011    splitTip : "Drag to resize.",
15012    
15013    collapsibleSplitTip : "Drag to resize. Double click to hide.",
15014    
15015    useSplitTips : false,
15016
15017    
15018    splitSettings : {
15019        north : {
15020            orientation: Ext.SplitBar.VERTICAL,
15021            placement: Ext.SplitBar.TOP,
15022            maxFn : 'getVMaxSize',
15023            minProp: 'minHeight',
15024            maxProp: 'maxHeight'
15025        },
15026        south : {
15027            orientation: Ext.SplitBar.VERTICAL,
15028            placement: Ext.SplitBar.BOTTOM,
15029            maxFn : 'getVMaxSize',
15030            minProp: 'minHeight',
15031            maxProp: 'maxHeight'
15032        },
15033        east : {
15034            orientation: Ext.SplitBar.HORIZONTAL,
15035            placement: Ext.SplitBar.RIGHT,
15036            maxFn : 'getHMaxSize',
15037            minProp: 'minWidth',
15038            maxProp: 'maxWidth'
15039        },
15040        west : {
15041            orientation: Ext.SplitBar.HORIZONTAL,
15042            placement: Ext.SplitBar.LEFT,
15043            maxFn : 'getHMaxSize',
15044            minProp: 'minWidth',
15045            maxProp: 'maxWidth'
15046        }
15047    },
15048
15049    
15050    applyFns : {
15051        west : function(box){
15052            if(this.isCollapsed){
15053                return this.applyLayoutCollapsed(box);
15054            }
15055            var sd = this.splitEl.dom, s = sd.style;
15056            this.panel.setPosition(box.x, box.y);
15057            var sw = sd.offsetWidth;
15058            s.left = (box.x+box.width-sw)+'px';
15059            s.top = (box.y)+'px';
15060            s.height = Math.max(0, box.height)+'px';
15061            this.panel.setSize(box.width-sw, box.height);
15062        },
15063        east : function(box){
15064            if(this.isCollapsed){
15065                return this.applyLayoutCollapsed(box);
15066            }
15067            var sd = this.splitEl.dom, s = sd.style;
15068            var sw = sd.offsetWidth;
15069            this.panel.setPosition(box.x+sw, box.y);
15070            s.left = (box.x)+'px';
15071            s.top = (box.y)+'px';
15072            s.height = Math.max(0, box.height)+'px';
15073            this.panel.setSize(box.width-sw, box.height);
15074        },
15075        north : function(box){
15076            if(this.isCollapsed){
15077                return this.applyLayoutCollapsed(box);
15078            }
15079            var sd = this.splitEl.dom, s = sd.style;
15080            var sh = sd.offsetHeight;
15081            this.panel.setPosition(box.x, box.y);
15082            s.left = (box.x)+'px';
15083            s.top = (box.y+box.height-sh)+'px';
15084            s.width = Math.max(0, box.width)+'px';
15085            this.panel.setSize(box.width, box.height-sh);
15086        },
15087        south : function(box){
15088            if(this.isCollapsed){
15089                return this.applyLayoutCollapsed(box);
15090            }
15091            var sd = this.splitEl.dom, s = sd.style;
15092            var sh = sd.offsetHeight;
15093            this.panel.setPosition(box.x, box.y+sh);
15094            s.left = (box.x)+'px';
15095            s.top = (box.y)+'px';
15096            s.width = Math.max(0, box.width)+'px';
15097            this.panel.setSize(box.width, box.height-sh);
15098        }
15099    },
15100
15101    
15102    render : function(ct, p){
15103        Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
15104
15105        var ps = this.position;
15106
15107        this.splitEl = ct.createChild({
15108            cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
15109            id: this.panel.id + '-xsplit'
15110        });
15111
15112        if(this.collapseMode == 'mini'){
15113            this.miniSplitEl = this.splitEl.createChild({
15114                cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
15115            });
15116            this.miniSplitEl.addClassOnOver('x-layout-mini-over');
15117            this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
15118        }
15119
15120        var s = this.splitSettings[ps];
15121
15122        this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
15123        this.split.tickSize = this.tickSize;
15124        this.split.placement = s.placement;
15125        this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
15126        this.split.minSize = this.minSize || this[s.minProp];
15127        this.split.on("beforeapply", this.onSplitMove, this);
15128        this.split.useShim = this.useShim === true;
15129        this.maxSize = this.maxSize || this[s.maxProp];
15130
15131        if(p.hidden){
15132            this.splitEl.hide();
15133        }
15134
15135        if(this.useSplitTips){
15136            this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
15137        }
15138        if(this.collapsible){
15139            this.splitEl.on("dblclick", this.onCollapseClick,  this);
15140        }
15141    },
15142
15143    
15144    getSize : function(){
15145        if(this.isCollapsed){
15146            return this.collapsedEl.getSize();
15147        }
15148        var s = this.panel.getSize();
15149        if(this.position == 'north' || this.position == 'south'){
15150            s.height += this.splitEl.dom.offsetHeight;
15151        }else{
15152            s.width += this.splitEl.dom.offsetWidth;
15153        }
15154        return s;
15155    },
15156
15157    
15158    getHMaxSize : function(){
15159         var cmax = this.maxSize || 10000;
15160         var center = this.layout.center;
15161         return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
15162    },
15163
15164    
15165    getVMaxSize : function(){
15166        var cmax = this.maxSize || 10000;
15167        var center = this.layout.center;
15168        return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
15169    },
15170
15171    
15172    onSplitMove : function(split, newSize){
15173        var s = this.panel.getSize();
15174        this.lastSplitSize = newSize;
15175        if(this.position == 'north' || this.position == 'south'){
15176            this.panel.setSize(s.width, newSize);
15177            this.state.height = newSize;
15178        }else{
15179            this.panel.setSize(newSize, s.height);
15180            this.state.width = newSize;
15181        }
15182        this.layout.layout();
15183        this.panel.saveState();
15184        return false;
15185    },
15186
15187    
15188    getSplitBar : function(){
15189        return this.split;
15190    },
15191
15192    
15193    destroy : function() {
15194        Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
15195        Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
15196    }
15197});
15198
15199Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
15200
15201Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
15202
15203    
15204    labelSeparator : ':',
15205
15206    
15207
15208    
15209    trackLabels: true,
15210
15211    type: 'form',
15212
15213    onRemove: function(c){
15214        Ext.layout.FormLayout.superclass.onRemove.call(this, c);
15215        if(this.trackLabels){
15216            c.un('show', this.onFieldShow, this);
15217            c.un('hide', this.onFieldHide, this);
15218        }
15219        
15220        var el = c.getPositionEl(),
15221            ct = c.getItemCt && c.getItemCt();
15222        if (c.rendered && ct) {
15223            if (el && el.dom) {
15224                el.insertAfter(ct);
15225            }
15226            Ext.destroy(ct);
15227            Ext.destroyMembers(c, 'label', 'itemCt');
15228            if (c.customItemCt) {
15229                Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
15230            }
15231        }
15232    },
15233
15234    
15235    setContainer : function(ct){
15236        Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
15237        if(ct.labelAlign){
15238            ct.addClass('x-form-label-'+ct.labelAlign);
15239        }
15240
15241        if(ct.hideLabels){
15242            Ext.apply(this, {
15243                labelStyle: 'display:none',
15244                elementStyle: 'padding-left:0;',
15245                labelAdjust: 0
15246            });
15247        }else{
15248            this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
15249            ct.labelWidth = ct.labelWidth || 100;
15250            if(Ext.isNumber(ct.labelWidth)){
15251                var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
15252                Ext.apply(this, {
15253                    labelAdjust: ct.labelWidth + pad,
15254                    labelStyle: 'width:' + ct.labelWidth + 'px;',
15255                    elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
15256                });
15257            }
15258            if(ct.labelAlign == 'top'){
15259                Ext.apply(this, {
15260                    labelStyle: 'width:auto;',
15261                    labelAdjust: 0,
15262                    elementStyle: 'padding-left:0;'
15263                });
15264            }
15265        }
15266    },
15267
15268    
15269    isHide: function(c){
15270        return c.hideLabel || this.container.hideLabels;
15271    },
15272
15273    onFieldShow: function(c){
15274        c.getItemCt().removeClass('x-hide-' + c.hideMode);
15275
15276        
15277        if (c.isComposite) {
15278            c.doLayout();
15279        }
15280    },
15281
15282    onFieldHide: function(c){
15283        c.getItemCt().addClass('x-hide-' + c.hideMode);
15284    },
15285
15286    
15287    getLabelStyle: function(s){
15288        var ls = '', items = [this.labelStyle, s];
15289        for (var i = 0, len = items.length; i < len; ++i){
15290            if (items[i]){
15291                ls += items[i];
15292                if (ls.substr(-1, 1) != ';'){
15293                    ls += ';';
15294                }
15295            }
15296        }
15297        return ls;
15298    },
15299
15300    
15301
15302    
15303    renderItem : function(c, position, target){
15304        if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
15305            var args = this.getTemplateArgs(c);
15306            if(Ext.isNumber(position)){
15307                position = target.dom.childNodes[position] || null;
15308            }
15309            if(position){
15310                c.itemCt = this.fieldTpl.insertBefore(position, args, true);
15311            }else{
15312                c.itemCt = this.fieldTpl.append(target, args, true);
15313            }
15314            if(!c.getItemCt){
15315                
15316                
15317                Ext.apply(c, {
15318                    getItemCt: function(){
15319                        return c.itemCt;
15320                    },
15321                    customItemCt: true
15322                });
15323            }
15324            c.label = c.getItemCt().child('label.x-form-item-label');
15325            if(!c.rendered){
15326                c.render('x-form-el-' + c.id);
15327            }else if(!this.isValidParent(c, target)){
15328                Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
15329            }
15330            if(this.trackLabels){
15331                if(c.hidden){
15332                    this.onFieldHide(c);
15333                }
15334                c.on({
15335                    scope: this,
15336                    show: this.onFieldShow,
15337                    hide: this.onFieldHide
15338                });
15339            }
15340            this.configureItem(c);
15341        }else {
15342            Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
15343        }
15344    },
15345
15346    
15347    getTemplateArgs: function(field) {
15348        var noLabelSep = !field.fieldLabel || field.hideLabel,
15349            itemCls = (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : '');
15350
15351        
15352        if (Ext.isIE9 && Ext.isIEQuirks && field instanceof Ext.form.TextField) {
15353            itemCls += ' x-input-wrapper';
15354        }
15355
15356        return {
15357            id            : field.id,
15358            label         : field.fieldLabel,
15359            itemCls       : itemCls,
15360            clearCls      : field.clearCls || 'x-form-clear-left',
15361            labelStyle    : this.getLabelStyle(field.labelStyle),
15362            elementStyle  : this.elementStyle || '',
15363            labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
15364        };
15365    },
15366
15367    
15368    adjustWidthAnchor: function(value, c){
15369        if(c.label && !this.isHide(c) && (this.container.labelAlign != 'to
15369p')){
15370            var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
15371            return value - this.labelAdjust + (adjust ? -3 : 0);
15372        }
15373        return value;
15374    },
15375
15376    adjustHeightAnchor : function(value, c){
15377        if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
15378            return value - c.label.getHeight();
15379        }
15380        return value;
15381    },
15382
15383    
15384    isValidParent : function(c, target){
15385        return target && this.container.getEl().contains(c.getPositionEl());
15386    }
15387
15388    
15389});
15390
15391Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
15392
15393Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
15394    
15395    fill : true,
15396    
15397    autoWidth : true,
15398    
15399    titleCollapse : true,
15400    
15401    hideCollapseTool : false,
15402    
15403    collapseFirst : false,
15404    
15405    animate : false,
15406    
15407    sequence : false,
15408    
15409    activeOnTop : false,
15410
15411    type: 'accordion',
15412
15413    renderItem : function(c){
15414        if(this.animate === false){
15415            c.animCollapse = false;
15416        }
15417        c.collapsible = true;
15418        if(this.autoWidth){
15419            c.autoWidth = true;
15420        }
15421        if(this.titleCollapse){
15422            c.titleCollapse = true;
15423        }
15424        if(this.hideCollapseTool){
15425            c.hideCollapseTool = true;
15426        }
15427        if(this.collapseFirst !== undefined){
15428            c.collapseFirst = this.collapseFirst;
15429        }
15430        if(!this.activeItem && !c.collapsed){
15431            this.setActiveItem(c, true);
15432        }else if(this.activeItem && this.activeItem != c){
15433            c.collapsed = true;
15434        }
15435        Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
15436        c.header.addClass('x-accordion-hd');
15437        c.on('beforeexpand', this.beforeExpand, this);
15438    },
15439
15440    onRemove: function(c){
15441        Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
15442        if(c.rendered){
15443            c.header.removeClass('x-accordion-hd');
15444        }
15445        c.un('beforeexpand', this.beforeExpand, this);
15446    },
15447
15448    
15449    beforeExpand : function(p, anim){
15450        var ai = this.activeItem;
15451        if(ai){
15452            if(this.sequence){
15453                delete this.activeItem;
15454                if (!ai.collapsed){
15455                    ai.collapse({callback:function(){
15456                        p.expand(anim || true);
15457                    }, scope: this});
15458                    return false;
15459                }
15460            }else{
15461                ai.collapse(this.animate);
15462            }
15463        }
15464        this.setActive(p);
15465        if(this.activeOnTop){
15466            p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
15467        }
15468        
15469        this.layout();
15470    },
15471
15472    
15473    setItemSize : function(item, size){
15474        if(this.fill && item){
15475            var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
15476            
15477            for (i = 0; i < len; i++) {
15478                if((p = ct[i]) != item && !p.hidden){
15479                    hh += p.header.getHeight();
15480                }
15481            };
15482            
15483            size.height -= hh;
15484            
15485            
15486            item.setSize(size);
15487        }
15488    },
15489
15490    
15491    setActiveItem : function(item){
15492        this.setActive(item, true);
15493    },
15494
15495    
15496    setActive : function(item, expand){
15497        var ai = this.activeItem;
15498        item = this.container.getComponent(item);
15499        if(ai != item){
15500            if(item.rendered && item.collapsed && expand){
15501                item.expand();
15502            }else{
15503                if(ai){
15504                   ai.fireEvent('deactivate', ai);
15505                }
15506                this.activeItem = item;
15507                item.fireEvent('activate', item);
15508            }
15509        }
15510    }
15511});
15512Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
15513
15514
15515Ext.layout.Accordion = Ext.layout.AccordionLayout;
15516Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
15517    
15518
15519    
15520    monitorResize:false,
15521
15522    type: 'table',
15523
15524    targetCls: 'x-table-layout-ct',
15525
15526    
15527    tableAttrs:null,
15528
15529    
15530    setContainer : function(ct){
15531        Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
15532
15533        this.currentRow = 0;
15534        this.currentColumn = 0;
15535        this.cells = [];
15536    },
15537    
15538    
15539    onLayout : function(ct, target){
15540        var cs = ct.items.items, len = cs.length, c, i;
15541
15542        if(!this.table){
15543            target.addClass('x-table-layout-ct');
15544
15545            this.table = target.createChild(
15546                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
15547        }
15548        this.renderAll(ct, target);
15549    },
15550
15551    
15552    getRow : function(index){
15553        var row = this.table.tBodies[0].childNodes[index];
15554        if(!row){
15555            row = document.createElement('tr');
15556            this.table.tBodies[0].appendChild(row);
15557        }
15558        return row;
15559    },
15560
15561    
15562    getNextCell : function(c){
15563        var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
15564        var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
15565        for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
15566            if(!this.cells[rowIndex]){
15567                this.cells[rowIndex] = [];
15568            }
15569            for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
15570                this.cells[rowIndex][colIndex] = true;
15571            }
15572        }
15573        var td = document.createElement('td');
15574        if(c.cellId){
15575            td.id = c.cellId;
15576        }
15577        var cls = 'x-table-layout-cell';
15578        if(c.cellCls){
15579            cls += ' ' + c.cellCls;
15580        }
15581        td.className = cls;
15582        if(c.colspan){
15583            td.colSpan = c.colspan;
15584        }
15585        if(c.rowspan){
15586            td.rowSpan = c.rowspan;
15587        }
15588        this.getRow(curRow).appendChild(td);
15589        return td;
15590    },
15591
15592    
15593    getNextNonSpan: function(colIndex, rowIndex){
15594        var cols = this.columns;
15595        while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
15596            if(cols && colIndex >= cols){
15597                rowIndex++;
15598                colIndex = 0;
15599            }else{
15600                colIndex++;
15601            }
15602        }
15603        return [colIndex, rowIndex];
15604    },
15605
15606    
15607    renderItem : function(c, position, target){
15608        
15609        if(!this.table){
15610            this.table = target.createChild(
15611                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
15612        }
15613        if(c && !c.rendered){
15614            c.render(this.getNextCell(c));
15615            this.configureItem(c);
15616        }else if(c && !this.isValidParent(c, target)){
15617            var container = this.getNextCell(c);
15618            container.insertBefore(c.getPositionEl().dom, null);
15619            c.container = Ext.get(container);
15620            this.configureItem(c);
15621        }
15622    },
15623
15624    
15625    isValidParent : function(c, target){
15626        return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
15627    },
15628    
15629    destroy: function(){
15630        delete this.table;
15631        Ext.layout.TableLayout.superclass.destroy.call(this);
15632    }
15633
15634    
15635});
15636
15637Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15638Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
15639
15640    extraCls: 'x-abs-layout-item',
15641
15642    type: 'absolute',
15643
15644    onLayout : function(ct, target){
15645        target.position();
15646        this.paddingLeft = target.getPadding('l');
15647        this.paddingTop = target.getPadding('t');
15648        Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
15649    },
15650
15651    
15652    adjustWidthAnchor : function(value, comp){
15653        return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
15654    },
15655
15656    
15657    adjustHeightAnchor : function(value, comp){
15658        return  value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
15659    }
15660    
15661});
15662Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15663
15664Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
15665    
15666    defaultMargins : {left:0,top:0,right:0,bottom:0},
15667    
15668    padding : '0',
15669    
15670    pack : 'start',
15671
15672    
15673    monitorResize : true,
15674    type: 'box',
15675    scrollOffset : 0,
15676    extraCls : 'x-box-item',
15677    targetCls : 'x-box-layout-ct',
15678    innerCls : 'x-box-inner',
15679
15680    constructor : function(config){
15681        Ext.layout.BoxLayout.superclass.constructor.call(this, config);
15682
15683        if (Ext.isString(this.defaultMargins)) {
15684            this.defaultMargins = this.parseMargins(this.defaultMargins);
15685        }
15686        
15687        var handler = this.overflowHandler;
15688        
15689        if (typeof handler == 'string') {
15690            handler = {
15691                type: handler
15692            };
15693        }
15694        
15695        var handlerType = 'none';
15696        if (handler && handler.type != undefined) {
15697            handlerType = handler.type;
15698        }
15699        
15700        var constructor = Ext.layout.boxOverflow[handlerType];
15701        if (constructor[this.type]) {
15702            constructor = constructor[this.type];
15703        }
15704        
15705        this.overflowHandler = new constructor(this, handler);
15706    },
15707
15708    
15709    onLayout: function(container, target) {
15710        Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
15711
15712        var tSize = this.getLayoutTargetSize(),
15713            items = this.getVisibleItems(container),
15714            calcs = this.calculateChildBoxes(items, tSize),
15715            boxes = calcs.boxes,
15716            meta  = calcs.meta;
15717        
15718        
15719        if (tSize.width > 0) {
15720            var handler = this.overflowHandler,
15721                method  = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';
15722            
15723            var results = handler[method](calcs, tSize);
15724            
15725            if (results) {
15726                if (results.targetSize) {
15727                    tSize = results.targetSize;
15728                }
15729                
15730                if (results.recalculate) {
15731                    items = this.getVisibleItems(container);
15732                    calcs = this.calculateChildBoxes(items, tSize);
15733                    boxes = calcs.boxes;
15734                }
15735            }
15736        }
15737        
15738        
15739        this.layoutTargetLastSize = tSize;
15740        
15741        
15742        this.childBoxCache = calcs;
15743        
15744        this.updateInnerCtSize(tSize, calcs);
15745        this.updateChildBoxes(boxes);
15746
15747        
15748        this.handleTargetOverflow(tSize, container, target);
15749    },
15750
15751    
15752    updateChildBoxes: function(boxes) {
15753        for (var i = 0, length = boxes.length; i < length; i++) {
15754            var box  = boxes[i],
15755                comp = box.component;
15756            
15757            if (box.dirtySize) {
15758                comp.setSize(box.width, box.height);
15759            }
15760            
15761            if (isNaN(box.left) || isNaN(box.top)) {
15762                continue;
15763            }
15764            
15765            comp.setPosition(box.left, box.top);
15766        }
15767    },
15768
15769    
15770    updateInnerCtSize: function(tSize, calcs) {
15771        var align   = this.align,
15772            padding = this.padding,
15773            width   = tSize.width,
15774            height  = tSize.height;
15775        
15776        if (this.type == 'hbox') {
15777            var innerCtWidth  = width,
15778                innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;
15779
15780            if (align == 'stretch') {
15781                innerCtHeight = height;
15782            } else if (align == 'middle') {
15783                innerCtHeight = Math.max(height, innerCtHeight);
15784            }
15785        } else {
15786            var innerCtHeight = height,
15787                innerCtWidth  = calcs.meta.maxWidth + padding.left + padding.right;
15788
15789            if (align == 'stretch') {
15790                innerCtWidth = width;
15791            } else if (align == 'center') {
15792                innerCtWidth = Math.max(width, innerCtWidth);
15793            }
15794        }
15795
15796        this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
15797    },
15798
15799    
15800    handleTargetOverflow: function(previousTargetSize, container, target) {
15801        var overflow = target.getStyle('overflow');
15802
15803        if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
15804            var newTargetSize = this.getLayoutTargetSize();
15805            if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
15806                this.adjustmentPass = true;
15807                this.onLayout(container, target);
15808            }
15809        }
15810
15811        delete this.adjustmentPass;
15812    },
15813
15814    
15815    isValidParent : function(c, target) {
15816        return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
15817    },
15818
15819    
15820    getVisibleItems: function(ct) {
15821        var ct  = ct || this.container,
15822            t   = ct.getLayoutTarget(),
15823            cti = ct.items.items,
15824            len = cti.length,
15825
15826            i, c, items = [];
15827
15828        for (i = 0; i < len; i++) {
15829            if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true  && c.collapsed !== true && c.shouldLayout !== false){
15830                items.push(c);
15831            }
15832        }
15833
15834        return items;
15835    },
15836
15837    
15838    renderAll : function(ct, target) {
15839        if (!this.innerCt) {
15840            
15841            this.innerCt = target.createChild({cls:this.innerCls});
15842            this.padding = this.parseMargins(this.padding);
15843        }
15844        Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
15845    },
15846
15847    getLayoutTargetSize : function() {
15848        var target = this.container.getLayoutTarget(), ret;
15849        
15850        if (target) {
15851            ret = target.getViewSize();
15852
15853            
15854            
15855            
15856            if (Ext.isIE && Ext.isStrict && ret.width == 0){
15857                ret =  target.getStyleSize();
15858            }
15859
15860            ret.width  -= target.getPadding('lr');
15861            ret.height -= target.getPadding('tb');
15862        }
15863        
15864        return ret;
15865    },
15866
15867    
15868    renderItem : function(c) {
15869        if(Ext.isString(c.margins)){
15870            c.margins = this.parseMargins(c.margins);
15871        }else if(!c.margins){
15872            c.margins = this.defaultMargins;
15873        }
15874        Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
15875    },
15876    
15877    
15878    destroy: function() {
15879        Ext.destroy(this.overflowHandler);
15880        
15881        Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
15882    }
15883});
15884
15885
15886
15887Ext.layout.boxOverflow.None = Ext.extend(Object, {
15888    constructor: function(layout, config) {
15889        this.layout = layout;
15890        
15891        Ext.apply(this, config || {});
15892    },
15893    
15894    handleOverflow: Ext.emptyFn,
15895    
15896    clearOverflow: Ext.emptyFn
15897});
15898
15899
15900Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;
15901
15902Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {
15903    
15904    afterCls: 'x-strip-right',
15905    
15906    
15907    noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
15908    
15909    constructor: function(layout) {
15910        Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);
15911        
15912        
15913        this.menuItems = [];
15914    },
15915    
15916    
15917    createInnerElements: function() {
15918        if (!this.afterCt) {
15919            this.afterCt  = this.layout.innerCt.insertSibling({cls: this.afterCls},  'before');
15920        }
15921    },
15922    
15923    
15924    clearOverflow: function(calculations, targetSize) {
15925        var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
15926            items    = this.menuItems;
15927        
15928        this.hideTrigger();
15929        
15930        for (var index = 0, length = items.length; index < length; index++) {
15931            items.pop().component.show();
15932        }
15933        
15934        return {
15935            targetSize: {
15936                height: targetSize.height,
15937                width : newWidth
15938            }
15939        };
15940    },
15941    
15942    
15943    showTrigger: function() {
15944        this.createMenu();
15945        this.menuTrigger.show();
15946    },
15947    
15948    
15949    hideTrigger: function() {
15950        if (this.menuTrigger != undefined) {
15951            this.menuTrigger.hide();
15952        }
15953    },
15954    
15955    
15956    beforeMenuShow: function(menu) {
15957        var items = this.menuItems,
15958            len   = items.length,
15959            item,
15960            prev;
15961
15962        var needsSep = function(group, item){
15963            return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
15964        };
15965        
15966        this.clearMenu();
15967        menu.removeAll();
15968        
15969        for (var i = 0; i < len; i++) {
15970            item = items[i].component;
15971            
15972            if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
15973                menu.add('-');
15974            }
15975            
15976            this.addComponentToMenu(menu, item);
15977            prev = item;
15978        }
15979
15980        
15981        if (menu.items.length < 1) {
15982            menu.add(this.noItemsMenuText);
15983        }
15984    },
15985    
15986    
15987    createMenuConfig : function(component, hideOnClick){
15988        var config = Ext.apply({}, component.initialConfig),
15989            group  = component.toggleGroup;
15990
15991        Ext.copyTo(config, component, [
15992            'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
15993        ]);
15994
15995        Ext.apply(config, {
15996            text       : component.overflowText || component.text,
15997            hideOnClick: hideOnClick
15998        });
15999
16000        if (group || component.enableToggle) {
16001            Ext.apply(config, {
16002                group  : group,
16003                checked: component.pressed,
16004                listeners: {
16005                    checkchange: function(item, checked){
16006                        component.toggle(checked);
16007                    }
16008                }
16009            });
16010        }
16011
16012        delete config.ownerCt;
16013        delete config.xtype;
16014        delete config.id;
16015
16016        return config;
16017    },
16018
16019    
16020    addComponentToMenu : function(menu, component) {
16021        if (component instanceof Ext.Toolbar.Separator) {
16022            menu.add('-');
16023
16024        } else if (Ext.isFunction(component.isXType)) {
16025            if (component.isXType('splitbutton')) {
16026                menu.add(this.createMenuConfig(component, true));
16027
16028            } else if (component.isXType('button')) {
16029                menu.add(this.createMenuConfig(component, !component.menu));
16030
16031            } else if (component.isXType('buttongroup')) {
16032                component.items.each(function(item){
16033                     this.addComponentToMenu(menu, item);
16034                }, this);
16035            }
16036        }
16037    },
16038    
16039    
16040    clearMenu : function(){
16041        var menu = this.moreMenu;
16042        if (menu && menu.items) {
16043            menu.items.each(function(item){
16044                delete item.menu;
16045            });
16046        }
16047    },
16048    
16049    
16050    createMenu: function() {
16051        if (!this.menuTrigger) {
16052            this.createInnerElements();
16053            
16054            
16055            this.menu = new Ext.menu.Menu({
16056                ownerCt : this.layout.container,
16057                listeners: {
16058                    scope: this,
16059                    beforeshow: this.beforeMenuShow
16060                }
16061            });
16062
16063            
16064            this.menuTrigger = new Ext.Button({
16065                iconCls : 'x-toolbar-more-icon',
16066                cls     : 'x-toolbar-more',
16067                menu    : this.menu,
16068                renderTo: this.afterCt
16069            });
16070        }
16071    },
16072    
16073    
16074    destroy: function() {
16075        Ext.destroy(this.menu, this.menuTrigger);
16076    }
16077});
16078
16079Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;
16080
16081
16082
16083Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {
16084    
16085    constructor: function() {
16086        Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);
16087        
16088        var me = this,
16089            layout = me.layout,
16090            origFunction = layout.calculateChildBoxes;
16091        
16092        layout.calculateChildBoxes = function(visibleItems, targetSize) {
16093            var calcs = origFunction.apply(layout, arguments),
16094                meta  = calcs.meta,
16095                items = me.menuItems;
16096            
16097            
16098            
16099            var hiddenWidth = 0;
16100            for (var index = 0, length = items.length; index < length; index++) {
16101                hiddenWidth += items[index].width;
16102            }
16103            
16104            meta.minimumWidth += hiddenWidth;
16105            meta.tooNarrow = meta.minimumWidth > targetSize.width;
16106            
16107            return calcs;
16108        };        
16109    },
16110    
16111    handleOverflow: function(calculations, targetSize) {
16112        this.showTrigger();
16113        
16114        var newWidth    = targetSize.width - this.afterCt.getWidth(),
16115            boxes       = calculations.boxes,
16116            usedWidth   = 0,
16117            recalculate = false;
16118        
16119        
16120        for (var index = 0, length = boxes.length; index < length; index++) {
16121            usedWidth += boxes[index].width;
16122        }
16123        
16124        var spareWidth = newWidth - usedWidth,
16125            showCount  = 0;
16126        
16127        
16128        for (var index = 0, length = this.menuItems.length; index < length; index++) {
16129            var hidden = this.menuItems[index],
16130                comp   = hidden.component,
16131                width  = hidden.width;
16132            
16133            if (width < spareWidth) {
16134                comp.show();
16135                
16136                spareWidth -= width;
16137                showCount ++;
16138                recalculate = true;
16139            } else {
16140                break;
16141            }
16142        }
16143                
16144        if (recalculate) {
16145            this.menuItems = this.menuItems.slice(showCount);
16146        } else {
16147            for (var i = boxes.length - 1; i >= 0; i--) {
16148                var item  = boxes[i].component,
16149                    right = boxes[i].left + boxes[i].width;
16150
16151                if (right >= newWidth) {
16152                    this.menuItems.unshift({
16153                        component: item,
16154                        width    : boxes[i].width
16155                    });
16156
16157                    item.hide();
16158                } else {
16159                    break;
16160                }
16161            }
16162        }
16163        
16164        if (this.menuItems.length == 0) {
16165            this.hideTrigger();
16166        }
16167        
16168        return {
16169            targetSize: {
16170                height: targetSize.height,
16171                width : newWidth
16172            },
16173            recalculate: recalculate
16174        };
16175    }
16176});
16177
16178Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
16179Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
16180    
16181    animateScroll: true,
16182    
16183    
16184    scrollIncrement: 100,
16185    
16186    
16187    wheelIncrement: 3,
16188    
16189    
16190    scrollRepeatInterval: 400,
16191    
16192    
16193    scrollDuration: 0.4,
16194    
16195    
16196    beforeCls: 'x-strip-left',
16197    
16198    
16199    afterCls: 'x-strip-right',
16200    
16201    
16202    scrollerCls: 'x-strip-scroller',
16203    
16204    
16205    beforeScrollerCls: 'x-strip-scroller-left',
16206    
16207    
16208    afterScrollerCls: 'x-strip-scroller-right',
16209    
16210    
16211    createWheelListener: function() {
16212        this.layout.innerCt.on({
16213            scope     : this,
16214            mousewheel: function(e) {
16215                e.stopEvent();
16216
16217                this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
16218            }
16219        });
16220    },
16221    
16222    
16223    handleOverflow: function(calculations, targetSize) {
16224        this.createInnerElements();
16225        this.showScrollers();
16226    },
16227    
16228    
16229    clearOverflow: function() {
16230        this.hideScrollers();
16231    },
16232    
16233    
16234    showScrollers: function() {
16235        this.createScrollers();
16236        
16237        this.beforeScroller.show();
16238        this.afterScroller.show();
16239        
16240        this.updateScrollButtons();
16241    },
16242    
16243    
16244    hideScrollers: function() {
16245        if (this.beforeScroller != undefined) {
16246            this.beforeScroller.hide();
16247            this.afterScroller.hide();          
16248        }
16249    },
16250    
16251    
16252    createScrollers: function() {
16253        if (!this.beforeScroller && !this.afterScroller) {
16254            var before = this.beforeCt.createChild({
16255                cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
16256            });
16257            
16258            var after = this.afterCt.createChild({
16259                cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
16260            });
16261            
16262            before.addClassOnOver(this.beforeScrollerCls + '-hover');
16263            after.addClassOnOver(this.afterScrollerCls + '-hover');
16264            
16265            before.setVisibilityMode(Ext.Element.DISPLAY);
16266            after.setVisibilityMode(Ext.Element.DISPLAY);
16267            
16268            this.beforeRepeater = new Ext.util.ClickRepeater(before, {
16269                interval: this.scrollRepeatInterval,
16270                handler : this.scrollLeft,
16271                scope   : this
16272            });
16273            
16274            this.afterRepeater = new Ext.util.ClickRepeater(after, {
16275                interval: this.scrollRepeatInterval,
16276                handler : this.scrollRight,
16277                scope   : this
16278            });
16279            
16280            
16281            this.beforeScroller = before;
16282            
16283            
16284            this.afterScroller = after;
16285        }
16286    },
16287    
16288    
16289    destroy: function() {
16290        Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
16291    },
16292    
16293    
16294    scrollBy: function(delta, animate) {
16295        this.scrollTo(this.getScrollPosition() + delta, animate);
16296    },
16297    
16298    
16299    getItem: function(item) {
16300        if (Ext.isString(item)) {
16301            item = Ext.getCmp(item);
16302        } else if (Ext.isNumber(item)) {
16303            item = this.items[item];
16304        }
16305        
16306        return item;
16307    },
16308    
16309    
16310    getScrollAnim: function() {
16311        return {
16312            duration: this.scrollDuration, 
16313            callback: this.updateScrollButtons, 
16314            scope   : this
16315        };
16316    },
16317    
16318    
16319    updateScrollButtons: function() {
16320        if (this.beforeScroller == undefined || this.afterScroller == undefined) {
16321            return;
16322        }
16323        
16324        var beforeMeth = this.atExtremeBefore()  ? 'addClass' : 'removeClass',
16325            afterMeth  = this.atExtremeAfter() ? 'addClass' : 'removeClass',
16326            beforeCls  = this.beforeScrollerCls + '-disabled',
16327            afterCls   = this.afterScrollerCls  + '-disabled';
16328        
16329        this.beforeScroller[beforeMeth](beforeCls);
16330        this.afterScroller[afterMeth](afterCls);
16331        this.scrolling = false;
16332    },
16333    
16334    
16335    atExtremeBefore: function() {
16336        return this.getScrollPosition() === 0;
16337    },
16338    
16339    
16340    scrollLeft: function(animate) {
16341        this.scrollBy(-this.scrollIncrement, animate);
16342    },
16343    
16344    
16345    scrollRight: function(animate) {
16346        this.scrollBy(this.scrollIncrement, animate);
16347    },
16348    
16349    
16350    scrollToItem: function(item, animate) {
16351        item = this.getItem(item);
16352        
16353        if (item != undefined) {
16354            var visibility = this.getItemVisibility(item);
16355            
16356            if (!visibility.fullyVisible) {
16357                var box  = item.getBox(true, true),
16358                    newX = box.x;
16359                    
16360                if (visibility.hiddenRight) {
16361                    newX -= (this.layout.innerCt.getWidth() - box.width);
16362                }
16363                
16364                this.scrollTo(newX, animate);
16365            }
16366        }
16367    },
16368    
16369    
16370    getItemVisibility: function(item) {
16371        var box         = this.getItem(item).getBox(true, true),
16372            itemLeft    = box.x,
16373            itemRight   = box.x + box.width,
16374            scrollLeft  = this.getScrollPosition(),
16375            scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
16376        
16377        return {
16378            hiddenLeft  : itemLeft < scrollLeft,
16379            hiddenRight : itemRight > scrollRight,
16380            fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
16381        };
16382    }
16383});
16384
16385Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
16386
16387
16388
16389Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
16390    scrollIncrement: 75,
16391    wheelIncrement : 2,
16392    
16393    handleOverflow: function(calculations, targetSize) {
16394        Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
16395        
16396        return {
16397            targetSize: {
16398                height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
16399                width : targetSize.width
16400            }
16401        };
16402    },
16403    
16404    
16405    createInnerElements: function() {
16406        var target = this.layout.innerCt;
16407        
16408        
16409        
16410        if (!this.beforeCt) {
16411            this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
16412            this.afterCt  = target.insertSibling({cls: this.afterCls},  'after');
16413
16414            this.createWheelListener();
16415        }
16416    },
16417    
16418    
16419    scrollTo: function(position, animate) {
16420        var oldPosition = this.getScrollPosition(),
16421            newPosition = position.constrain(0, this.getMaxScrollBottom());
16422        
16423        if (newPosition != oldPosition && !this.scrolling) {
16424            if (animate == undefined) {
16425                animate = this.animateScroll;
16426            }
16427            
16428            this.layout.innerCt.scrollTo('top', newPosition, animate ? this.get
16428ScrollAnim() : false);
16429            
16430            if (animate) {
16431                this.scrolling = true;
16432            } else {
16433                this.scrolling = false;
16434                this.updateScrollButtons();
16435            }
16436        }
16437    },
16438    
16439    
16440    getScrollPosition: function(){
16441        return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
16442    },
16443    
16444    
16445    getMaxScrollBottom: function() {
16446        return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
16447    },
16448    
16449    
16450    atExtremeAfter: function() {
16451        return this.getScrollPosition() >= this.getMaxScrollBottom();
16452    }
16453});
16454
16455Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
16456
16457
16458
16459Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
16460    handleOverflow: function(calculations, targetSize) {
16461        Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
16462        
16463        return {
16464            targetSize: {
16465                height: targetSize.height,
16466                width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
16467            }
16468        };
16469    },
16470    
16471    
16472    createInnerElements: function() {
16473        var target = this.layout.innerCt;
16474        
16475        
16476        
16477        if (!this.beforeCt) {
16478            this.afterCt  = target.insertSibling({cls: this.afterCls},  'before');
16479            this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
16480            
16481            this.createWheelListener();
16482        }
16483    },
16484    
16485    
16486    scrollTo: function(position, animate) {
16487        var oldPosition = this.getScrollPosition(),
16488            newPosition = position.constrain(0, this.getMaxScrollRight());
16489        
16490        if (newPosition != oldPosition && !this.scrolling) {
16491            if (animate == undefined) {
16492                animate = this.animateScroll;
16493            }
16494            
16495            this.layout.innerCt.scrollTo('left', newPosition, animate ? this.get
16495ScrollAnim() : false);
16496            
16497            if (animate) {
16498                this.scrolling = true;
16499            } else {
16500                this.scrolling = false;
16501                this.updateScrollButtons();
16502            }
16503        }
16504    },
16505    
16506    
16507    getScrollPosition: function(){
16508        return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
16509    },
16510    
16511    
16512    getMaxScrollRight: function() {
16513        return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
16514    },
16515    
16516    
16517    atExtremeAfter: function() {
16518        return this.getScrollPosition() >= this.getMaxScrollRight();
16519    }
16520});
16521
16522Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
16523Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
16524    
16525    align: 'top', 
16526
16527    type : 'hbox',
16528
16529    
16530    
16531
16532    
16533    calculateChildBoxes: function(visibleItems, targetSize) {
16534        var visibleCount = visibleItems.length,
16535
16536            padding      = this.padding,
16537            topOffset    = padding.top,
16538            leftOffset   = padding.left,
16539            paddingVert  = topOffset  + padding.bottom,
16540            paddingHoriz = leftOffset + padding.right,
16541
16542            width        = targetSize.width - this.scrollOffset,
16543            height       = targetSize.height,
16544            availHeight  = Math.max(0, height - paddingVert),
16545
16546            isStart      = this.pack == 'start',
16547            isCenter     = this.pack == 'center',
16548            isEnd        = this.pack == 'end',
16549
16550            nonFlexWidth = 0,
16551            maxHeight    = 0,
16552            totalFlex    = 0,
16553            desiredWidth = 0,
16554            minimumWidth = 0,
16555
16556            
16557            boxes        = [],
16558
16559            
16560            child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, 
16561            horizMargins, vertMargins, stretchHeight;
16562
16563        
16564        for (i = 0; i < visibleCount; i++) {
16565            child       = visibleItems[i];
16566            childHeight = child.height;
16567            childWidth  = child.width;
16568            canLayout   = !child.hasLayout && typeof child.doLayout == 'function';
16569
16570            
16571            if (typeof childWidth != 'number') {
16572
16573                
16574                if (child.flex && !childWidth) {
16575                    totalFlex += child.flex;
16576
16577                
16578                } else {
16579                    
16580                    
16581                    if (!childWidth && canLayout) {
16582                        child.doLayout();
16583                    }
16584
16585                    childSize   = child.getSize();
16586                    childWidth  = childSize.width;
16587                    childHeight = childSize.height;
16588                }
16589            }
16590
16591            childMargins = child.margins;
16592            horizMargins = childMargins.left + childMargins.right;
16593
16594            nonFlexWidth += horizMargins + (childWidth || 0);
16595            desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
16596            minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
16597
16598            
16599            if (typeof childHeight != 'number') {
16600                if (canLayout) {
16601                    child.doLayout();
16602                }
16603                childHeight = child.getHeight();
16604            }
16605
16606            maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
16607
16608            
16609            boxes.push({
16610                component: child,
16611                height   : childHeight || undefined,
16612                width    : childWidth  || undefined
16613            });
16614        }
16615                
16616        var shortfall = desiredWidth - width,
16617            tooNarrow = minimumWidth > width;
16618            
16619        
16620        var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
16621        
16622        if (tooNarrow) {
16623            for (i = 0; i < visibleCount; i++) {
16624                boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
16625            }
16626        } else {
16627            
16628            
16629            if (shortfall > 0) {
16630                var minWidths = [];
16631                
16632                
16633                for (var index = 0, length = visibleCount; index < length; index++) {
16634                    var item     = visibleItems[index],
16635                        minWidth = item.minWidth || 0;
16636
16637                    
16638                    
16639                    if (item.flex) {
16640                        boxes[index].width = minWidth;
16641                    } else {
16642                        minWidths.push({
16643                            minWidth : minWidth,
16644                            available: boxes[index].width - minWidth,
16645                            index    : index
16646                        });
16647                    }
16648                }
16649                
16650                
16651                minWidths.sort(function(a, b) {
16652                    return a.available > b.available ? 1 : -1;
16653                });
16654                
16655                
16656                for (var i = 0, length = minWidths.length; i < length; i++) {
16657                    var itemIndex = minWidths[i].index;
16658                    
16659                    if (itemIndex == undefined) {
16660                        continue;
16661                    }
16662                        
16663                    var item      = visibleItems[itemIndex],
16664                        box       = boxes[itemIndex],
16665                        oldWidth  = box.width,
16666                        minWidth  = item.minWidth,
16667                        newWidth  = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
16668                        reduction = oldWidth - newWidth;
16669                    
16670                    boxes[itemIndex].width = newWidth;
16671                    shortfall -= reduction;                    
16672                }
16673            } else {
16674                
16675                var remainingWidth = availableWidth,
16676                    remainingFlex  = totalFlex;
16677
16678                
16679                for (i = 0; i < visibleCount; i++) {
16680                    child = visibleItems[i];
16681                    calcs = boxes[i];
16682
16683                    childMargins = child.margins;
16684                    vertMargins  = childMargins.top + childMargins.bottom;
16685
16686                    if (isStart && child.flex && !child.width) {
16687                        flexedWidth     = Math.ceil((child.flex / remainingFlex) * remainingWidth);
16688                        remainingWidth -= flexedWidth;
16689                        remainingFlex  -= child.flex;
16690
16691                        calcs.width = flexedWidth;
16692                        calcs.dirtySize = true;
16693                    }
16694                }
16695            }
16696        }
16697        
16698        if (isCenter) {
16699            leftOffset += availableWidth / 2;
16700        } else if (isEnd) {
16701            leftOffset += availableWidth;
16702        }
16703        
16704        
16705        for (i = 0; i < visibleCount; i++) {
16706            child = visibleItems[i];
16707            calcs = boxes[i];
16708            
16709            childMargins = child.margins;
16710            leftOffset  += childMargins.left;
16711            vertMargins  = childMargins.top + childMargins.bottom;
16712            
16713            calcs.left = leftOffset;
16714            calcs.top  = topOffset + childMargins.top;
16715
16716            switch (this.align) {
16717                case 'stretch':
16718                    stretchHeight = availHeight - vertMargins;
16719                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16720                    calcs.dirtySize = true;
16721                    break;
16722                case 'stretchmax':
16723                    stretchHeight = maxHeight - vertMargins;
16724                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16725                    calcs.dirtySize = true;
16726                    break;
16727                case 'middle':
16728                    var diff = availHeight - calcs.height - vertMargins;
16729                    if (diff > 0) {
16730                        calcs.top = topOffset + vertMargins + (diff / 2);
16731                    }
16732            }
16733            
16734            leftOffset += calcs.width + childMargins.right;
16735        }
16736
16737        return {
16738            boxes: boxes,
16739            meta : {
16740                maxHeight   : maxHeight,
16741                nonFlexWidth: nonFlexWidth,
16742                desiredWidth: desiredWidth,
16743                minimumWidth: minimumWidth,
16744                shortfall   : desiredWidth - width,
16745                tooNarrow   : tooNarrow
16746            }
16747        };
16748    }
16749});
16750
16751Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
16752Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
16753    
16754    align : 'left', 
16755    type: 'vbox',
16756
16757    
16758
16759    
16760
16761    
16762    calculateChildBoxes: function(visibleItems, targetSize) {
16763        var visibleCount = visibleItems.length,
16764
16765            padding      = this.padding,
16766            topOffset    = padding.top,
16767            leftOffset   = padding.left,
16768            paddingVert  = topOffset  + padding.bottom,
16769            paddingHoriz = leftOffset + padding.right,
16770
16771            width        = targetSize.width - this.scrollOffset,
16772            height       = targetSize.height,
16773            availWidth   = Math.max(0, width - paddingHoriz),
16774
16775            isStart      = this.pack == 'start',
16776            isCenter     = this.pack == 'center',
16777            isEnd        = this.pack == 'end',
16778
16779            nonFlexHeight= 0,
16780            maxWidth     = 0,
16781            totalFlex    = 0,
16782            desiredHeight= 0,
16783            minimumHeight= 0,
16784
16785            
16786            boxes        = [],
16787            
16788            
16789            child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, 
16790            horizMargins, vertMargins, stretchWidth, length;
16791
16792        
16793        for (i = 0; i < visibleCount; i++) {
16794            child = visibleItems[i];
16795            childHeight = child.height;
16796            childWidth  = child.width;
16797            canLayout   = !child.hasLayout && typeof child.doLayout == 'function';
16798
16799            
16800            if (typeof childHeight != 'number') {
16801
16802                
16803                if (child.flex && !childHeight) {
16804                    totalFlex += child.flex;
16805
16806                
16807                } else {
16808                    
16809                    
16810                    if (!childHeight && canLayout) {
16811                        child.doLayout();
16812                    }
16813
16814                    childSize = child.getSize();
16815                    childWidth = childSize.width;
16816                    childHeight = childSize.height;
16817                }
16818            }
16819            
16820            childMargins = child.margins;
16821            vertMargins  = childMargins.top + childMargins.bottom;
16822
16823            nonFlexHeight += vertMargins + (childHeight || 0);
16824            desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
16825            minimumHeight += vertMargins + (child.minHeight || childHeight || 0);
16826
16827            
16828            if (typeof childWidth != 'number') {
16829                if (canLayout) {
16830                    child.doLayout();
16831                }
16832                childWidth = child.getWidth();
16833            }
16834
16835            maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
16836
16837            
16838            boxes.push({
16839                component: child,
16840                height   : childHeight || undefined,
16841                width    : childWidth || undefined
16842            });
16843        }
16844                
16845        var shortfall = desiredHeight - height,
16846            tooNarrow = minimumHeight > height;
16847
16848        
16849        var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
16850        
16851        if (tooNarrow) {
16852            for (i = 0, length = visibleCount; i < length; i++) {
16853                boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
16854            }
16855        } else {
16856            
16857            
16858            if (shortfall > 0) {
16859                var minHeights = [];
16860
16861                
16862                for (var index = 0, length = visibleCount; index < length; index++) {
16863                    var item      = visibleItems[index],
16864                        minHeight = item.minHeight || 0;
16865
16866                    
16867                    
16868                    if (item.flex) {
16869                        boxes[index].height = minHeight;
16870                    } else {
16871                        minHeights.push({
16872                            minHeight: minHeight, 
16873                            available: boxes[index].height - minHeight,
16874                            index    : index
16875                        });
16876                    }
16877                }
16878
16879                
16880                minHeights.sort(function(a, b) {
16881                    return a.available > b.available ? 1 : -1;
16882                });
16883
16884                
16885                for (var i = 0, length = minHeights.length; i < length; i++) {
16886                    var itemIndex = minHeights[i].index;
16887
16888                    if (itemIndex == undefined) {
16889                        continue;
16890                    }
16891
16892                    var item      = visibleItems[itemIndex],
16893                        box       = boxes[itemIndex],
16894                        oldHeight  = box.height,
16895                        minHeight  = item.minHeight,
16896                        newHeight  = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
16897                        reduction = oldHeight - newHeight;
16898
16899                    boxes[itemIndex].height = newHeight;
16900                    shortfall -= reduction;
16901                }
16902            } else {
16903                
16904                var remainingHeight = availableHeight,
16905                    remainingFlex   = totalFlex;
16906                
16907                
16908                for (i = 0; i < visibleCount; i++) {
16909                    child = visibleItems[i];
16910                    calcs = boxes[i];
16911
16912                    childMargins = child.margins;
16913                    horizMargins = childMargins.left + childMargins.right;
16914
16915                    if (isStart && child.flex && !child.height) {
16916                        flexedHeight     = Math.ceil((child.flex / remainingFlex) * remainingHeight);
16917                        remainingHeight -= flexedHeight;
16918                        remainingFlex   -= child.flex;
16919
16920                        calcs.height = flexedHeight;
16921                        calcs.dirtySize = true;
16922                    }
16923                }
16924            }
16925        }
16926
16927        if (isCenter) {
16928            topOffset += availableHeight / 2;
16929        } else if (isEnd) {
16930            topOffset += availableHeight;
16931        }
16932
16933        
16934        for (i = 0; i < visibleCount; i++) {
16935            child = visibleItems[i];
16936            calcs = boxes[i];
16937
16938            childMargins = child.margins;
16939            topOffset   += childMargins.top;
16940            horizMargins = childMargins.left + childMargins.right;
16941            
16942
16943            calcs.left = leftOffset + childMargins.left;
16944            calcs.top  = topOffset;
16945            
16946            switch (this.align) {
16947                case 'stretch':
16948                    stretchWidth = availWidth - horizMargins;
16949                    calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16950                    calcs.dirtySize = true;
16951                    break;
16952                case 'stretchmax':
16953                    stretchWidth = maxWidth - horizMargins;
16954                    calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16955                    calcs.dirtySize = true;
16956                    break;
16957                case 'center':
16958                    var diff = availWidth - calcs.width - horizMargins;
16959                    if (diff > 0) {
16960                        calcs.left = leftOffset + horizMargins + (diff / 2);
16961                    }
16962            }
16963
16964            topOffset += calcs.height + childMargins.bottom;
16965        }
16966        
16967        return {
16968            boxes: boxes,
16969            meta : {
16970                maxWidth     : maxWidth,
16971                nonFlexHeight: nonFlexHeight,
16972                desiredHeight: desiredHeight,
16973                minimumHeight: minimumHeight,
16974                shortfall    : desiredHeight - height,
16975                tooNarrow    : tooNarrow
16976            }
16977        };
16978    }
16979});
16980
16981Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
16982
16983Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
16984    monitorResize : true,
16985
16986    type: 'toolbar',
16987
16988    
16989    triggerWidth: 18,
16990
16991    
16992    noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
16993
16994    
16995    lastOverflow: false,
16996
16997    
16998    tableHTML: [
16999        '<table cellspacing="0" class="x-toolbar-ct">',
17000            '<tbody>',
17001                '<tr>',
17002                    '<td class="x-toolbar-left" align="{0}">',
17003                        '<table cellspacing="0">',
17004                            '<tbody>',
17005                                '<tr class="x-toolbar-left-row"></tr>',
17006                            '</tbody>',
17007                        '</table>',
17008                    '</td>',
17009                    '<td class="x-toolbar-right" align="right">',
17010                        '<table cellspacing="0" class="x-toolbar-right-ct">',
17011                            '<tbody>',
17012                                '<tr>',
17013                                    '<td>',
17014                                        '<table cellspacing="0">',
17015                                            '<tbody>',
17016                                                '<tr class="x-toolbar-right-row"></tr>',
17017                                            '</tbody>',
17018                                        '</table>',
17019                                    '</td>',
17020                                    '<td>',
17021                                        '<table cellspacing="0">',
17022                                            '<tbody>',
17023                                                '<tr class="x-toolbar-extras-row"></tr>',
17024                                            '</tbody>',
17025                                        '</table>',
17026                                    '</td>',
17027                                '</tr>',
17028                            '</tbody>',
17029                        '</table>',
17030                    '</td>',
17031                '</tr>',
17032            '</tbody>',
17033        '</table>'
17034    ].join(""),
17035
17036    
17037    onLayout : function(ct, target) {
17038        
17039        if (!this.leftTr) {
17040            var align = ct.buttonAlign == 'center' ? 'center' : 'left';
17041
17042            target.addClass('x-toolbar-layout-ct');
17043            target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
17044
17045            this.leftTr   = target.child('tr.x-toolbar-left-row', true);
17046            this.rightTr  = target.child('tr.x-toolbar-right-row', true);
17047            this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
17048
17049            if (this.hiddenItem == undefined) {
17050                
17051                this.hiddenItems = [];
17052            }
17053        }
17054
17055        var side     = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
17056            items    = ct.items.items,
17057            position = 0;
17058
17059        
17060        for (var i = 0, len = items.length, c; i < len; i++, position++) {
17061            c = items[i];
17062
17063            if (c.isFill) {
17064                side   = this.rightTr;
17065                position = -1;
17066            } else if (!c.rendered) {
17067                c.render(this.insertCell(c, side, position));
17068                this.configureItem(c);
17069            } else {
17070                if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
17071                    var td = this.insertCell(c, side, position);
17072                    td.appendChild(c.getPositionEl().dom);
17073                    c.container = Ext.get(td);
17074                }
17075            }
17076        }
17077
17078        
17079        this.cleanup(this.leftTr);
17080        this.cleanup(this.rightTr);
17081        this.cleanup(this.extrasTr);
17082        this.fitToSize(target);
17083    },
17084
17085    
17086    cleanup : function(el) {
17087        var cn = el.childNodes, i, c;
17088
17089        for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
17090            if (!c.firstChild) {
17091                el.removeChild(c);
17092            }
17093        }
17094    },
17095
17096    
17097    insertCell : function(c, target, position) {
17098        var td = document.createElement('td');
17099        td.className = 'x-toolbar-cell';
17100
17101        target.insertBefore(td, target.childNodes[position] || null);
17102
17103        return td;
17104    },
17105
17106    
17107    hideItem : function(item) {
17108        this.hiddenItems.push(item);
17109
17110        item.xtbHidden = true;
17111        item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
17112        item.hide();
17113    },
17114
17115    
17116    unhideItem : function(item) {
17117        item.show();
17118        item.xtbHidden = false;
17119        this.hiddenItems.remove(item);
17120    },
17121
17122    
17123    getItemWidth : function(c) {
17124        return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
17125    },
17126
17127    
17128    fitToSize : function(target) {
17129        if (this.container.enableOverflow === false) {
17130            return;
17131        }
17132
17133        var width       = target.dom.clientWidth,
17134            tableWidth  = target.dom.firstChild.offsetWidth,
17135            clipWidth   = width - this.triggerWidth,
17136            lastWidth   = this.lastWidth || 0,
17137
17138            hiddenItems = this.hiddenItems,
17139            hasHiddens  = hiddenItems.length != 0,
17140            isLarger    = width >= lastWidth;
17141
17142        this.lastWidth  = width;
17143
17144        if (tableWidth > width || (hasHiddens && isLarger)) {
17145            var items     = this.container.items.items,
17146                len       = items.length,
17147                loopWidth = 0,
17148                item;
17149
17150            for (var i = 0; i < len; i++) {
17151                item = items[i];
17152
17153                if (!item.isFill) {
17154                    loopWidth += this.getItemWidth(item);
17155                    if (loopWidth > clipWidth) {
17156                        if (!(item.hidden || item.xtbHidden)) {
17157                            this.hideItem(item);
17158                        }
17159                    } else if (item.xtbHidden) {
17160                        this.unhideItem(item);
17161                    }
17162                }
17163            }
17164        }
17165
17166        
17167        hasHiddens = hiddenItems.length != 0;
17168
17169        if (hasHiddens) {
17170            this.initMore();
17171
17172            if (!this.lastOverflow) {
17173                this.container.fireEvent('overflowchange', this.container, true);
17174                this.lastOverflow = true;
17175            }
17176        } else if (this.more) {
17177            this.clearMenu();
17178            this.more.destroy();
17179            delete this.more;
17180
17181            if (this.lastOverflow) {
17182                this.container.fireEvent('overflowchange', this.container, false);
17183                this.lastOverflow = false;
17184            }
17185        }
17186    },
17187
17188    
17189    createMenuConfig : function(component, hideOnClick){
17190        var config = Ext.apply({}, component.initialConfig),
17191            group  = component.toggleGroup;
17192
17193        Ext.copyTo(config, component, [
17194            'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
17195        ]);
17196
17197        Ext.apply(config, {
17198            text       : component.overflowText || component.text,
17199            hideOnClick: hideOnClick
17200        });
17201
17202        if (group || component.enableToggle) {
17203            Ext.apply(config, {
17204                group  : group,
17205                checked: component.pressed,
17206                listeners: {
17207                    checkchange: function(item, checked){
17208                        component.toggle(checked);
17209                    }
17210                }
17211            });
17212        }
17213
17214        delete config.ownerCt;
17215        delete config.xtype;
17216        delete config.id;
17217
17218        return config;
17219    },
17220
17221    
17222    addComponentToMenu : function(menu, component) {
17223        if (component instanceof Ext.Toolbar.Separator) {
17224            menu.add('-');
17225
17226        } else if (Ext.isFunction(component.isXType)) {
17227            if (component.isXType('splitbutton')) {
17228                menu.add(this.createMenuConfig(component, true));
17229
17230            } else if (component.isXType('button')) {
17231                menu.add(this.createMenuConfig(component, !component.menu));
17232
17233            } else if (component.isXType('buttongroup')) {
17234                component.items.each(function(item){
17235                     this.addComponentToMenu(menu, item);
17236                }, this);
17237            }
17238        }
17239    },
17240
17241    
17242    clearMenu : function(){
17243        var menu = this.moreMenu;
17244        if (menu && menu.items) {
17245            menu.items.each(function(item){
17246                delete item.menu;
17247            });
17248        }
17249    },
17250
17251    
17252    beforeMoreShow : function(menu) {
17253        var items = this.container.items.items,
17254            len   = items.length,
17255            item,
17256            prev;
17257
17258        var needsSep = function(group, item){
17259            return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
17260        };
17261
17262        this.clearMenu();
17263        menu.removeAll();
17264        for (var i = 0; i < len; i++) {
17265            item = items[i];
17266            if (item.xtbHidden) {
17267                if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
17268                    menu.add('-');
17269                }
17270                this.addComponentToMenu(menu, item);
17271                prev = item;
17272            }
17273        }
17274
17275        
17276        if (menu.items.length < 1) {
17277            menu.add(this.noItemsMenuText);
17278        }
17279    },
17280
17281    
17282    initMore : function(){
17283        if (!this.more) {
17284            
17285            this.moreMenu = new Ext.menu.Menu({
17286                ownerCt : this.container,
17287                listeners: {
17288                    beforeshow: this.beforeMoreShow,
17289                    scope: this
17290                }
17291            });
17292
17293            
17294            this.more = new Ext.Button({
17295                iconCls: 'x-toolbar-more-icon',
17296                cls    : 'x-toolbar-more',
17297                menu   : this.moreMenu,
17298                ownerCt: this.container
17299            });
17300
17301            var td = this.insertCell(this.more, this.extrasTr, 100);
17302            this.more.render(td);
17303        }
17304    },
17305
17306    destroy : function(){
17307        Ext.destroy(this.more, this.moreMenu);
17308        delete this.leftTr;
17309        delete this.rightTr;
17310        delete this.extrasTr;
17311        Ext.layout.ToolbarLayout.superclass.destroy.call(this);
17312    }
17313});
17314
17315Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
17316
17317 Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
17318    monitorResize : true,
17319
17320    type: 'menu',
17321
17322    setContainer : function(ct){
17323        this.monitorResize = !ct.floating;
17324        
17325        
17326        ct.on('autosize', this.doAutoSize, this);
17327        Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
17328    },
17329
17330    renderItem : function(c, position, target){
17331        if (!this.itemTpl) {
17332            this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
17333                '<li id="{itemId}" class="{itemCls}">',
17334                    '<tpl if="needsIcon">',
17335                        '<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
17336                    '</tpl>',
17337                '</li>'
17338            );
17339        }
17340
17341        if(c && !c.rendered){
17342            if(Ext.isNumber(position)){
17343                position = target.dom.childNodes[position];
17344            }
17345            var a = this.getItemArgs(c);
17346
17347
17348            c.render(c.positionEl = position ?
17349                this.itemTpl.insertBefore(position, a, true) :
17350                this.itemTpl.append(target, a, true));
17351
17352
17353            c.positionEl.menuItemId = c.getItemId();
17354
17355
17356
17357            if (!a.isMenuItem && a.needsIcon) {
17358                c.positionEl.addClass('x-menu-list-item-indent');
17359            }
17360            this.configureItem(c);
17361        }else if(c && !this.isValidParent(c, target)){
17362            if(Ext.isNumber(position)){
17363                position = target.dom.childNodes[position];
17364            }
17365            target.dom.insertBefore(c.getActionEl().dom, position || null);
17366        }
17367    },
17368
17369    getItemArgs : function(c) {
17370        var isMenuItem = c instanceof Ext.menu.Item,
17371            canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);
17372
17373        return {
17374            isMenuItem: isMenuItem,
17375            needsIcon: canHaveIcon && (c.icon || c.iconCls),
17376            icon: c.icon || Ext.BLANK_IMAGE_URL,
17377            iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
17378            itemId: 'x-menu-el-' + c.id,
17379            itemCls: 'x-menu-list-item ',
17380            altText: c.altText || ''
17381        };
17382    },
17383
17384    
17385    isValidParent : function(c, target) {
17386        return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
17387    },
17388
17389    onLayout : function(ct, target){
17390        Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
17391        this.doAutoSize();
17392    },
17393
17394    doAutoSize : function(){
17395        var ct = this.container, w = ct.width;
17396        if(ct.floating){
17397            if(w){
17398                ct.setWidth(w);
17399            }else if(Ext.isIE){
17400                ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8 || Ext.isIE9) ? 'auto' : ct.minWidth);
17401                var el = ct.getEl(), t = el.dom.offsetWidth; 
17402                ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
17403            }
17404        }
17405    }
17406});
17407Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
17408
17409Ext.Viewport = Ext.extend(Ext.Container, {
17410    
17411    
17412    
17413    
17414    
17415    
17416    
17417    
17418    
17419    
17420    
17421    
17422
17423    initComponent : function() {
17424        Ext.Viewport.superclass.initComponent.call(this);
17425        document.getElementsByTagName('html')[0].className += ' x-viewport';
17426        this.el = Ext.getBody();
17427        this.el.setHeight = Ext.emptyFn;
17428        this.el.setWidth = Ext.emptyFn;
17429        this.el.setSize = Ext.emptyFn;
17430        this.el.dom.scroll = 'no';
17431        this.allowDomMove = false;
17432        this.autoWidth = true;
17433        this.autoHeight = true;
17434        Ext.EventManager.onWindowResize(this.fireResize, this);
17435        this.renderTo = this.el;
17436    },
17437
17438    fireResize : function(w, h){
17439        this.fireEvent('resize', this, w, h, w, h);
17440    }
17441});
17442Ext.reg('viewport', Ext.Viewport);
17443
17444Ext.Panel = Ext.extend(Ext.Container, {
17445    
17446    
17447    
17448    
17449    
17450    
17451    
17452    
17453    
17454    
17455    
17456    
17457    
17458    
17459    
17460    
17461    
17462    
17463    
17464    
17465    
17466    
17467    
17468    
17469    
17470    
17471    
17472    
17473    
17474    
17475    
17476    
17477
17478    
17479    
17480    
17481    
17482    
17483    
17484    
17485    
17486
17487
17488    
17489    baseCls : 'x-panel',
17490    
17491    collapsedCls : 'x-panel-collapsed',
17492    
17493    maskDisabled : true,
17494    
17495    animCollapse : Ext.enableFx,
17496    
17497    headerAsText : true,
17498    
17499    buttonAlign : 'right',
17500    
17501    collapsed : false,
17502    
17503    collapseFirst : true,
17504    
17505    minButtonWidth : 75,
17506    
17507    
17508    elements : 'body',
17509    
17510    preventBodyReset : false,
17511
17512    
17513    padding: undefined,
17514
17515    
17516    resizeEvent: 'bodyresize',
17517
17518    
17519    
17520    
17521    toolTarget : 'header',
17522    collapseEl : 'bwrap',
17523    slideAnchor : 't',
17524    disabledClass : '',
17525
17526    
17527    deferHeight : true,
17528    
17529    expandDefaults: {
17530        duration : 0.25
17531    },
17532    
17533    collapseDefaults : {
17534        duration : 0.25
17535    },
17536
17537    
17538    initComponent : function(){
17539        Ext.Panel.superclass.initComponent.call(this);
17540
17541        this.addEvents(
17542            
17543            'bodyresize',
17544            
17545            'titlechange',
17546            
17547            'iconchange',
17548            
17549            'collapse',
17550            
17551            'expand',
17552            
17553            'beforecollapse',
17554            
17555            'beforeexpand',
17556            
17557            'beforeclose',
17558            
17559            'close',
17560            
17561            'activate',
17562            
17563            'deactivate'
17564        );
17565
17566        if(this.unstyled){
17567            this.baseCls = 'x-plain';
17568        }
17569
17570
17571        this.toolbars = [];
17572        
17573        if(this.tbar){
17574            this.elements += ',tbar';
17575            this.topToolbar = this.createToolbar(this.tbar);
17576            this.tbar = null;
17577
17578        }
17579        if(this.bbar){
17580            this.elements += ',bbar';
17581            this.bottomToolbar = this.createToolbar(this.bbar);
17582            this.bbar = null;
17583        }
17584
17585        if(this.header === true){
17586            this.elements += ',header';
17587            this.header = null;
17588        }else if(this.headerCfg || (this.title && this.header !== false)){
17589            this.elements += ',header';
17590        }
17591
17592        if(this.footerCfg || this.footer === true){
17593            this.elements += ',footer';
17594            this.footer = null;
17595        }
17596
17597        if(this.buttons){
17598            this.fbar = this.buttons;
17599            this.buttons = null;
17600        }
17601        if(this.fbar){
17602            this.createFbar(this.fbar);
17603        }
17604        if(this.autoLoad){
17605            this.on('render', this.doAutoLoad, this, {delay:10});
17606        }
17607    },
17608
17609    
17610    createFbar : function(fbar){
17611        var min = this.minButtonWidth;
17612        this.elements += ',footer';
17613        this.fbar = this.createToolbar(fbar, {
17614            buttonAlign: this.buttonAlign,
17615            toolbarCls: 'x-panel-fbar',
17616            enableOverflow: false,
17617            defaults: function(c){
17618                return {
17619                    minWidth: c.minWidth || min
17620                };
17621            }
17622        });
17623        
17624        
17625        
17626        this.fbar.items.each(function(c){
17627            c.minWidth = c.minWidth || this.minButtonWidth;
17628        }, this);
17629        this.buttons = this.fbar.items.items;
17630    },
17631
17632    
17633    createToolbar: function(tb, options){
17634        var result;
17635        
17636        if(Ext.isArray(tb)){
17637            tb = {
17638                items: tb
17639            };
17640        }
17641        result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
17642        this.toolbars.push(result);
17643        return result;
17644    },
17645
17646    
17647    createElement : function(name, pnode){
17648        if(this[name]){
17649            pnode.appendChild(this[name].dom);
17650            return;
17651        }
17652
17653        if(name === 'bwrap' || this.elements.indexOf(name) != -1){
17654            if(this[name+'Cfg']){
17655                this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
17656            }else{
17657                var el = document.createElement('div');
17658                el.className = this[name+'Cls'];
17659                this[name] = Ext.get(pnode.appendChild(el));
17660            }
17661            if(this[name+'CssClass']){
17662                this[name].addClass(this[name+'CssClass']);
17663            }
17664            if(this[name+'Style']){
17665                this[name].applyStyles(this[name+'Style']);
17666            }
17667        }
17668    },
17669
17670    
17671    onRender : function(ct, position){
17672        Ext.Panel.superclass.onRender.call(this, ct, position);
17673        this.createClasses();
17674
17675        var el = this.el,
17676            d = el.dom,
17677            bw,
17678            ts;
17679
17680
17681        if(this.collapsible && !this.hideCollapseTool){
17682            this.tools = this.tools ? this.tools.slice(0) : [];
17683            this.tools[this.collapseFirst?'unshift':'push']({
17684                id: 'toggle',
17685                handler : this.toggleCollapse,
17686                scope: this
17687            });
17688        }
17689
17690        if(this.tools){
17691            ts = this.tools;
17692            this.elements += (this.header !== false) ? ',header' : '';
17693        }
17694        this.tools = {};
17695
17696        el.addClass(this.baseCls);
17697        if(d.firstChild){ 
17698            this.header = el.down('.'+this.headerCls);
17699            this.bwrap = el.down('.'+this.bwrapCls);
17700            var cp = this.bwrap ? this.bwrap : el;
17701            this.tbar = cp.down('.'+this.tbarCls);
17702            this.body = cp.down('.'+this.bodyCls);
17703            this.bbar = cp.down('.'+this.bbarCls);
17704            this.footer = cp.down('.'+this.footerCls);
17705            this.fromMarkup = true;
17706        }
17707        if (this.preventBodyReset === true) {
17708            el.addClass('x-panel-reset');
17709        }
17710        if(this.cls){
17711            el.addClass(this.cls);
17712        }
17713
17714        if(this.buttons){
17715            this.elements += ',footer';
17716        }
17717
17718        
17719
17720        
17721        if(this.frame){
17722            el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
17723
17724            this.createElement('header', d.firstChild.firstChild.firstChild);
17725            this.createElement('bwrap', d);
17726
17727            
17728            bw = this.bwrap.dom;
17729            var ml = d.childNodes[1], bl = d.childNodes[2];
17730            bw.appendChild(ml);
17731            bw.appendChild(bl);
17732
17733            var mc = bw.firstChild.firstChild.firstChild;
17734            this.createElement('tbar', mc);
17735            this.createElement('body', mc);
17736            this.createElement('bbar', mc);
17737            this.createElement('footer', bw.lastChild.firstChild.firstChild);
17738
17739            if(!this.footer){
17740                this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
17741            }
17742            
17743            this.ft = Ext.get(this.bwrap.dom.lastChild);
17744            this.mc = Ext.get(mc);
17745        }else{
17746            this.createElement('header', d);
17747            this.createElement('bwrap', d);
17748
17749            
17750            bw = this.bwrap.dom;
17751            this.createElement('tbar', bw);
17752            this.createElement('body', bw);
17753            this.createElement('bbar', bw);
17754            this.createElement('footer', bw);
17755
17756            if(!this.header){
17757                this.body.addClass(this.bodyCls + '-noheader');
17758                if(this.tbar){
17759                    this.tbar.addClass(this.tbarCls + '-noheader');
17760                }
17761            }
17762        }
17763
17764        if(Ext.isDefined(this.padding)){
17765            this.body.setStyle('padding', this.body.addUnits(this.padding));
17766        }
17767
17768        if(this.border === false){
17769            this.el.addClass(this.baseCls + '-noborder');
17770            this.body.addClass(this.bodyCls + '-noborder');
17771            if(this.header){
17772                this.header.addClass(this.headerCls + '-noborder');
17773            }
17774            if(this.footer){
17775                this.footer.addClass(this.footerCls + '-noborder');
17776            }
17777            if(this.tbar){
17778                this.tbar.addClass(this.tbarCls + '-noborder');
17779            }
17780            if(this.bbar){
17781                this.bbar.addClass(this.bbarCls + '-noborder');
17782            }
17783        }
17784
17785        if(this.bodyBorder === false){
17786           this.body.addClass(this.bodyCls + '-noborder');
17787        }
17788
17789        this.bwrap.enableDisplayMode('block');
17790
17791        if(this.header){
17792            this.header.unselectable();
17793
17794            
17795            if(this.headerAsText){
17796                this.header.dom.innerHTML =
17797                    '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
17798
17799                if(this.iconCls){
17800                    this.setIconClass(this.iconCls);
17801                }
17802            }
17803        }
17804
17805        if(this.floating){
17806            this.makeFloating(this.floating);
17807        }
17808
17809        if(this.collapsible && this.titleCollapse && this.header){
17810            this.mon(this.header, 'click', this.toggleCollapse, this);
17811            this.header.setStyle('cursor', 'pointer');
17812        }
17813        if(ts){
17814            this.addTool.apply(this, ts);
17815        }
17816
17817        
17818        if(this.fbar){
17819            this.footer.addClass('x-panel-btns');
17820            this.fbar.ownerCt = this;
17821            this.fbar.render(this.footer);
17822            this.footer.createChild({cls:'x-clear'});
17823        }
17824        if(this.tbar && this.topToolbar){
17825            this.topToolbar.ownerCt = this;
17826            this.topToolbar.render(this.tbar);
17827        }
17828        if(this.bbar && this.bottomToolbar){
17829            this.bottomToolbar.ownerCt = this;
17830            this.bottomToolbar.render(this.bbar);
17831        }
17832    },
17833
17834    
17835    setIconClass : function(cls){
17836        var old = this.iconCls;
17837        this.iconCls = cls;
17838        if(this.rendered && this.header){
17839            if(this.frame){
17840                this.header.addClass('x-panel-icon');
17841                this.header.replaceClass(old, this.iconCls);
17842            }else{
17843                var hd = this.header,
17844                    img = hd.child('img.x-panel-inline-icon');
17845                if(img){
17846                    Ext.fly(img).replaceClass(old, this.iconCls);
17847                }else{
17848                    var hdspan = hd.child('span.' + this.headerTextCls);
17849                    if (hdspan) {
17850                        Ext.DomHelper.insertBefore(hdspan.dom, {
17851                            tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
17852                        });
17853                    }
17854                 }
17855            }
17856        }
17857        this.fireEvent('iconchange', this, cls, old);
17858    },
17859
17860    
17861    makeFloating : function(cfg){
17862        this.floating = true;
17863        this.el = new Ext.Layer(Ext.apply({}, cfg, {
17864            shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
17865            shadowOffset: this.shadowOffset,
17866            constrain:false,
17867            shim: this.shim === false ? false : undefined
17868        }), this.el);
17869    },
17870
17871    
17872    getTopToolbar : function(){
17873        return this.topToolbar;
17874    },
17875
17876    
17877    getBottomToolbar : function(){
17878        return this.bottomToolbar;
17879    },
17880
17881    
17882    getFooterToolbar : function() {
17883        return this.fbar;
17884    },
17885
17886    
17887    addButton : function(config, handler, scope){
17888        if(!this.fbar){
17889            this.createFbar([]);
17890        }
17891        if(handler){
17892            if(Ext.isString(config)){
17893                config = {text: config};
17894            }
17895            config = Ext.apply({
17896                handler: handler,
17897                scope: scope
17898            }, config);
17899        }
17900        return this.fbar.add(config);
17901    },
17902
17903    
17904    addTool : function(){
17905        if(!this.rendered){
17906            if(!this.tools){
17907                this.tools = [];
17908            }
17909            Ext.each(arguments, function(arg){
17910                this.tools.push(arg);
17911            }, this);
17912            return;
17913        }
17914         
17915        if(!this[this.toolTarget]){
17916            return;
17917        }
17918        if(!this.toolTemplate){
17919            
17920            var tt = new Ext.Template(
17921                 '<div class="x-tool x-tool-{id}">&#160;</div>'
17922            );
17923            tt.disableFormats = true;
17924            tt.compile();
17925            Ext.Panel.prototype.toolTemplate = tt;
17926        }
17927        for(var i = 0, a = arguments, len = a.length; i < len; i++) {
17928            var tc = a[i];
17929            if(!this.tools[tc.id]){
17930                var overCls = 'x-tool-'+tc.id+'-over';
17931                var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
17932                this.tools[tc.id] = t;
17933                t.enableDisplayMode('block');
17934                this.mon(t, 'click',  this.createToolHandler(t, tc, overCls, this));
17935                if(tc.on){
17936                    this.mon(t, tc.on);
17937                }
17938                if(tc.hidden){
17939                    t.hide();
17940                }
17941                if(tc.qtip){
17942                    if(Ext.isObject(tc.qtip)){
17943                        Ext.QuickTips.register(Ext.apply({
17944                              target: t.id
17945                        }, tc.qtip));
17946                    } else {
17947                        t.dom.qtip = tc.qtip;
17948                    }
17949                }
17950                t.addClassOnOver(overCls);
17951            }
17952        }
17953    },
17954
17955    onLayout : function(shallow, force){
17956        Ext.Panel.superclass.onLayout.apply(this, arguments);
17957        if(this.hasLayout && this.toolbars.length > 0){
17958            Ext.each(this.toolbars, function(tb){
17959                tb.doLayout(undefined, force);
17960            });
17961            this.syncHeight();
17962        }
17963    },
17964
17965    syncHeight : function(){
17966        var h = this.toolbarHeight,
17967                bd = this.body,
17968                lsh = this.lastSize.height,
17969                sz;
17970
17971        if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
17972            return;
17973        }
17974
17975
17976        if(h != this.getToolbarHeight()){
17977            h = Math.max(0, lsh - this.getFrameHeight());
17978            bd.setHeight(h);
17979            sz = bd.getSize();
17980            this.toolbarHeight = this.getToolbarHeight();
17981            this.onBodyResize(sz.width, sz.height);
17982        }
17983    },
17984
17985    
17986    onShow : function(){
17987        if(this.floating){
17988            return this.el.show();
17989        }
17990        Ext.Panel.superclass.onShow.call(this);
17991    },
17992
17993    
17994    onHide : function(){
17995        if(this.floating){
17996            return this.el.hide();
17997        }
17998        Ext.Panel.superclass.onHide.call(this);
17999    },
18000
18001    
18002    createToolHandler : function(t, tc, overCls, panel){
18003        return function(e){
18004            t.removeClass(overCls);
18005            if(tc.stopEvent !== false){
18006                e.stopEvent();
18007            }
18008            if(tc.handler){
18009                tc.handler.call(tc.scope || t, e, t, panel, tc);
18010            }
18011        };
18012    },
18013
18014    
18015    afterRender : function(){
18016        if(this.floating && !this.hidden){
18017            this.el.show();
18018        }
18019        if(this.title){
18020            this.setTitle(this.title);
18021        }
18022        Ext.Panel.superclass.afterRender.call(this); 
18023        if (this.collapsed) {
18024            this.collapsed = false;
18025            this.collapse(false);
18026        }
18027        this.initEvents();
18028    },
18029
18030    
18031    getKeyMap : function(){
18032        if(!this.keyMap){
18033            this.keyMap = new Ext.KeyMap(this.el, this.keys);
18034        }
18035        return this.keyMap;
18036    },
18037
18038    
18039    initEvents : function(){
18040        if(this.keys){
18041            this.getKeyMap();
18042        }
18043        if(this.draggable){
18044            this.initDraggable();
18045        }
18046        if(this.toolbars.length > 0){
18047            Ext.each(this.toolbars, function(tb){
18048                tb.doLayout();
18049                tb.on({
18050                    scope: this,
18051                    afterlayout: this.syncHeight,
18052                    remove: this.syncHeight
18053                });
18054            }, this);
18055            this.syncHeight();
18056        }
18057
18058    },
18059
18060    
18061    initDraggable : function(){
18062        
18063        this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
18064    },
18065
18066    
18067    beforeEffect : function(anim){
18068        if(this.floating){
18069            this.el.beforeAction();
18070        }
18071        if(anim !== false){
18072            this.el.addClass('x-panel-animated');
18073        }
18074    },
18075
18076    
18077    afterEffect : function(anim){
18078        this.syncShadow();
18079        this.el.removeClass('x-panel-animated');
18080    },
18081
18082    
18083    createEffect : function(a, cb, scope){
18084        var o = {
18085            scope:scope,
18086            block:true
18087        };
18088        if(a === true){
18089            o.callback = cb;
18090            return o;
18091        }else if(!a.callback){
18092            o.callback = cb;
18093        }else { 
18094            o.callback = function(){
18095                cb.call(scope);
18096                Ext.callback(a.callback, a.scope);
18097            };
18098        }
18099        return Ext.applyIf(o, a);
18100    },
18101
18102    
18103    collapse : function(animate){
18104        if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
18105            return;
18106        }
18107        var doAnim = animate === true || (animate !== false && this.animCollapse);
18108        this.beforeEffect(doAnim);
18109        this.onCollapse(doAnim, animate);
18110        return this;
18111    },
18112
18113    
18114    onCollapse : function(doAnim, animArg){
18115        if(doAnim){
18116            this[this.collapseEl].slideOut(this.slideAnchor,
18117                    Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
18118                        this.collapseDefaults));
18119        }else{
18120            this[this.collapseEl].hide(this.hideMode);
18121            this.afterCollapse(false);
18122        }
18123    },
18124
18125    
18126    afterCollapse : function(anim){
18127        this.collapsed = true;
18128        this.el.addClass(this.collapsedCls);
18129        if(anim !== false){
18130            this[this.collapseEl].hide(this.hideMode);
18131        }
18132        this.afterEffect(anim);
18133
18134        
18135        this.cascade(function(c) {
18136            if (c.lastSize) {
18137                c.lastSize = { width: undefined, height: undefined };
18138            }
18139        });
18140        this.fireEvent('collapse', this);
18141    },
18142
18143    
18144    expand : function(animate){
18145        if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
18146            return;
18147        }
18148        var doAnim = animate === true || (animate !== false && this.animCollapse);
18149        this.el.removeClass(this.collapsedCls);
18150        this.beforeEffect(doAnim);
18151        this.onExpand(doAnim, animate);
18152        return this;
18153    },
18154
18155    
18156    onExpand : function(doAnim, animArg){
18157        if(doAnim){
18158            this[this.collapseEl].slideIn(this.slideAnchor,
18159                    Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
18160                        this.expandDefaults));
18161        }else{
18162            this[this.collapseEl].show(this.hideMode);
18163            this.afterExpand(false);
18164        }
18165    },
18166
18167    
18168    afterExpand : function(anim){
18169        this.collapsed = false;
18170        if(anim !== false){
18171            this[this.collapseEl].show(this.hideMode);
18172        }
18173        this.afterEffect(anim);
18174        if (this.deferLayout) {
18175            delete this.deferLayout;
18176            this.doLayout(true);
18177        }
18178        this.fireEvent('expand', this);
18179    },
18180
18181    
18182    toggleCollapse : function(animate){
18183        this[this.collapsed ? 'expand' : 'collapse'](animate);
18184        return this;
18185    },
18186
18187    
18188    onDisable : function(){
18189        if(this.rendered && this.maskDisabled){
18190            this.el.mask();
18191        }
18192        Ext.Panel.superclass.onDisable.call(this);
18193    },
18194
18195    
18196    onEnable : function(){
18197        if(this.rendered && this.maskDisabled){
18198            this.el.unmask();
18199        }
18200        Ext.Panel.superclass.onEnable.call(this);
18201    },
18202
18203    
18204    onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
18205        var w = adjWidth,
18206            h = adjHeight;
18207
18208        if(Ext.isDefined(w) || Ext.isDefined(h)){
18209            if(!this.collapsed){
18210                
18211                
18212                
18213
18214                if(Ext.isNumber(w)){
18215                    this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
18216                } else if (w == 'auto') {
18217                    w = this.body.setWidth('auto').dom.offsetWidth;
18218                } else {
18219                    w = this.body.dom.offsetWidth;
18220                }
18221
18222                if(this.tbar){
18223                    this.tbar.setWidth(w);
18224                    if(this.topToolbar){
18225                        this.topToolbar.setSize(w);
18226                    }
18227                }
18228                if(this.bbar){
18229                    this.bbar.setWidth(w);
18230                    if(this.bottomToolbar){
18231                        this.bottomToolbar.setSize(w);
18232                        
18233                        if (Ext.isIE) {
18234                            this.bbar.setStyle('position', 'static');
18235                            this.bbar.setStyle('position', '');
18236                        }
18237                    }
18238                }
18239                if(this.footer){
18240                    this.footer.setWidth(w);
18241                    if(this.fbar){
18242                        this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
18243                    }
18244                }
18245
18246                
18247                if(Ext.isNumber(h)){
18248                    h = Math.max(0, h - this.getFrameHeight());
18249                    
18250                    this.body.setHeight(h);
18251                }else if(h == 'auto'){
18252                    this.body.setHeight(h);
18253                }
18254
18255                if(this.disabled && this.el._mask){
18256                    this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
18257                }
18258            }else{
18259                
18260                this.queuedBodySize = {width: w, height: h};
18261                if(!this.queuedExpand && this.allowQueuedExpand !== false){
18262                    this.queuedExpand = true;
18263                    this.on('expand', function(){
18264                        delete this.queuedExpand;
18265                        this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
18266                    }, this, {single:true});
18267                }
18268            }
18269            this.onBodyResize(w, h);
18270        }
18271        this.syncShadow();
18272        Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
18273
18274    },
18275
18276    
18277    onBodyResize: function(w, h){
18278        this.fireEvent('bodyresize', this, w, h);
18279    },
18280
18281    
18282    getToolbarHeight: function(){
18283        var h = 0;
18284        if(this.rendered){
18285            Ext.each(this.toolbars, function(tb){
18286                h += tb.getHeight();
18287            }, this);
18288        }
18289        return h;
18290    },
18291
18292    
18293    adjustBodyHeight : function(h){
18294        return h;
18295    },
18296
18297    
18298    adjustBodyWidth : function(w){
18299        return w;
18300    },
18301
18302    
18303    onPosition : function(){
18304        this.syncShadow();
18305    },
18306
18307    
18308    getFrameWidth : function(){
18309        var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
18310
18311        if(this.frame){
18312            var l = this.bwrap.dom.firstChild;
18313            w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
18314            w += this.mc.getFrameWidth('lr');
18315        }
18316        return w;
18317    },
18318
18319    
18320    getFrameHeight : function() {
18321        var h  = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
18322        h += (this.tbar ? this.tbar.getHeight() : 0) +
18323             (this.bbar ? this.bbar.getHeight() : 0);
18324
18325        if(this.frame){
18326            h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
18327        }else{
18328            h += (this.header ? this.header.getHeight() : 0) +
18329                (this.footer ? this.footer.getHeight() : 0);
18330        }
18331        return h;
18332    },
18333
18334    
18335    getInnerWidth : function(){
18336        return this.getSize().width - this.getFrameWidth();
18337    },
18338
18339    
18340    getInnerHeight : function(){
18341        return this.body.getHeight();
18342        
18343    },
18344
18345    
18346    syncShadow : function(){
18347        if(this.floating){
18348            this.el.sync(true);
18349        }
18350    },
18351
18352    
18353    getLayoutTarget : function(){
18354        return this.body;
18355    },
18356
18357    
18358    getContentTarget : function(){
18359        return this.body;
18360    },
18361
18362    
18363    setTitle : function(title, iconCls){
18364        this.title = title;
18365        if(this.header && this.headerAsText){
18366            this.header.child('span').update(title);
18367        }
18368        if(iconCls){
18369            this.setIconClass(iconCls);
18370        }
18371        this.fireEvent('titlechange', this, title);
18372        return this;
18373    },
18374
18375    
18376    getUpdater : function(){
18377        return this.body.getUpdater();
18378    },
18379
18380     
18381    load : function(){
18382        var um = this.body.getUpdater();
18383        um.update.apply(um, arguments);
18384        return this;
18385    },
18386
18387    
18388    beforeDestroy : function(){
18389        Ext.Panel.superclass.beforeDestroy.call(this);
18390        if(this.header){
18391            this.header.removeAllListeners();
18392        }
18393        if(this.tools){
18394            for(var k in this.tools){
18395                Ext.destroy(this.tools[k]);
18396            }
18397        }
18398        if(this.toolbars.length > 0){
18399            Ext.each(this.toolbars, function(tb){
18400                tb.un('afterlayout', this.syncHeight, this);
18401                tb.un('remove', this.syncHeight, this);
18402            }, this);
18403        }
18404        if(Ext.isArray(this.buttons)){
18405            while(this.buttons.length) {
18406                Ext.destroy(this.buttons[0]);
18407            }
18408        }
18409        if(this.rendered){
18410            Ext.destroy(
18411                this.ft,
18412                this.header,
18413                this.footer,
18414                this.tbar,
18415                this.bbar,
18416                this.body,
18417                this.mc,
18418                this.bwrap,
18419                this.dd
18420            );
18421            if (this.fbar) {
18422                Ext.destroy(
18423                    this.fbar,
18424                    this.fbar.el
18425                );
18426            }
18427        }
18428        Ext.destroy(this.toolbars);
18429    },
18430
18431    
18432    createClasses : function(){
18433        this.headerCls = this.baseCls + '-header';
18434        this.headerTextCls = this.baseCls + '-header-text';
18435        this.bwrapCls = this.baseCls + '-bwrap';
18436        this.tbarCls = this.baseCls + '-tbar';
18437        this.bodyCls = this.baseCls + '-body';
18438        this.bbarCls = this.baseCls + '-bbar';
18439        this.footerCls = this.baseCls + '-footer';
18440    },
18441
18442    
18443    createGhost : function(cls, useShim, appendTo){
18444        var el = document.createElement('div');
18445        el.className = 'x-panel-ghost ' + (cls ? cls : '');
18446        if(this.header){
18447            el.appendChild(this.el.dom.firstChild.cloneNode(true));
18448        }
18449        Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
18450        el.style.width = this.el.dom.offsetWidth + 'px';;
18451        if(!appendTo){
18452            this.container.dom.appendChild(el);
18453        }else{
18454            Ext.getDom(appendTo).appendChild(el);
18455        }
18456        if(useShim !== false && this.el.useShim !== false){
18457            var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
18458            layer.show();
18459            return layer;
18460        }else{
18461            return new Ext.Element(el);
18462        }
18463    },
18464
18465    
18466    doAutoLoad : function(){
18467        var u = this.body.getUpdater();
18468        if(this.renderer){
18469            u.setRenderer(this.renderer);
18470        }
18471        u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
18472    },
18473
18474    
18475    getTool : function(id) {
18476        return this.tools[id];
18477    }
18478
18479
18480});
18481Ext.reg('panel', Ext.Panel);
18482
18483Ext.Editor = function(field, config){
18484    if(field.field){
18485        this.field = Ext.create(field.field, 'textfield');
18486        config = Ext.apply({}, field); 
18487        delete config.field;
18488    }else{
18489        this.field = field;
18490    }
18491    Ext.Editor.superclass.constructor.call(this, config);
18492};
18493
18494Ext.extend(Ext.Editor, Ext.Component, {
18495    
18496    
18497    allowBlur: true,
18498    
18499    
18500    
18501    
18502    
18503    value : "",
18504    
18505    alignment: "c-c?",
18506    
18507    offsets: [0, 0],
18508    
18509    shadow : "frame",
18510    
18511    constrain : false,
18512    
18513    swallowKeys : true,
18514    
18515    completeOnEnter : true,
18516    
18517    cancelOnEsc : true,
18518    
18519    updateEl : false,
18520
18521    initComponent : function(){
18522        Ext.Editor.superclass.initComponent.call(this);
18523        this.addEvents(
18524            
18525            "beforestartedit",
18526            
18527            "startedit",
18528            
18529            "beforecomplete",
18530            
18531            "complete",
18532            
18533            "canceledit",
18534            
18535            "specialkey"
18536        );
18537    },
18538
18539    
18540    onRender : function(ct, position){
18541        this.el = new Ext.Layer({
18542            shadow: this.shadow,
18543            cls: "x-editor",
18544            parentEl : ct,
18545            shim : this.shim,
18546            shadowOffset: this.shadowOffset || 4,
18547            id: this.id,
18548            constrain: this.constrain
18549        });
18550        if(this.zIndex){
18551            this.el.setZIndex(this.zIndex);
18552        }
18553        this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
18554        if(this.field.msgTarget != 'title'){
18555            this.field.msgTarget = 'qtip';
18556        }
18557        this.field.inEditor = true;
18558        this.mon(this.field, {
18559            scope: this,
18560            blur: this.onBlur,
18561            specialkey: this.onSpecialKey
18562        });
18563        if(this.field.grow){
18564            this.mon(this.field, "autosize", this.el.sync,  this.el, {delay:1});
18565        }
18566        this.field.render(this.el).show();
18567        this.field.getEl().dom.name = '';
18568        if(this.swallowKeys){
18569            this.field.el.swallowEvent([
18570                'keypress', 
18571                'keydown'   
18572            ]);
18573        }
18574    },
18575
18576    
18577    onSpecialKey : function(field, e){
18578        var key = e.getKey(),
18579            complete = this.completeOnEnter && key == e.ENTER,
18580            cancel = this.cancelOnEsc && key == e.ESC;
18581        if(complete || cancel){
18582            e.stopEvent();
18583            if(complete){
18584                this.completeEdit();
18585            }else{
18586                this.cancelEdit();
18587            }
18588            if(field.triggerBlur){
18589                field.triggerBlur();
18590            }
18591        }
18592        this.fireEvent('specialkey', field, e);
18593    },
18594
18595    
18596    startEdit : function(el, value){
18597        if(this.editing){
18598            this.completeEdit();
18599        }
18600        this.boundEl = Ext.get(el);
18601        var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
18602        if(!this.rendered){
18603            this.render(this.parentEl || document.body);
18604        }
18605        if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
18606            this.startValue = v;
18607            this.field.reset();
18608            this.field.setValue(v);
18609            this.realign(true);
18610            this.editing = true;
18611            this.show();
18612        }
18613    },
18614
18615    
18616    doAutoSize : function(){
18617        if(this.autoSize){
18618            var sz = this.boundEl.getSize(),
18619                fs = this.field.getSize();
18620
18621            switch(this.autoSize){
18622                case "width":
18623                    this.setSize(sz.width, fs.height);
18624                    break;
18625                case "height":
18626                    this.setSize(fs.width, sz.height);
18627                    break;
18628                case "none":
18629                    this.setSize(fs.width, fs.height);
18630                    break;
18631                default:
18632                    this.setSize(sz.width, sz.height);
18633            }
18634        }
18635    },
18636
18637    
18638    setSize : function(w, h){
18639        delete this.field.lastSize;
18640        this.field.setSize(w, h);
18641        if(this.el){
18642            
18643            if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
18644                
18645                this.el.setSize(w, h);
18646            }
18647            this.el.sync();
18648        }
18649    },
18650
18651    
18652    realign : function(autoSize){
18653        if(autoSize === true){
18654            this.doAutoSize();
18655        }
18656        this.el.alignTo(this.boundEl, this.alignment, this.offsets);
18657    },
18658
18659    
18660    completeEdit : function(remainVisible){
18661        if(!this.editing){
18662            return;
18663        }
18664        
18665        if (this.field.assertValue) {
18666            this.field.assertValue();
18667        }
18668        var v = this.getValue();
18669        if(!this.field.isValid()){
18670            if(this.revertInvalid !== false){
18671                this.cancelEdit(remainVisible);
18672            }
18673            return;
18674        }
18675        if(String(v) === String(this.startValue) && this.ignoreNoChange){
18676            this.hideEdit(remainVisible);
18677            return;
18678        }
18679        if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
18680            v = this.getValue();
18681            if(this.updateEl && this.boundEl){
18682                this.boundEl.update(v);
18683            }
18684            this.hideEdit(remainVisible);
18685            this.fireEvent("complete", this, v, this.startValue);
18686        }
18687    },
18688
18689    
18690    onShow : function(){
18691        this.el.show();
18692        if(this.hideEl !== false){
18693            this.boundEl.hide();
18694        }
18695        this.field.show().focus(false, true);
18696        this.fireEvent("startedit", this.boundEl, this.startValue);
18697    },
18698
18699    
18700    cancelEdit : function(remainVisible){
18701        if(this.editing){
18702            var v = this.getValue();
18703            this.setValue(this.startValue);
18704            this.hideEdit(remainVisible);
18705            this.fireEvent("canceledit", this, v, this.startValue);
18706        }
18707    },
18708
18709    
18710    hideEdit: function(remainVisible){
18711        if(remainVisible !== true){
18712            this.editing = false;
18713            this.hide();
18714        }
18715    },
18716
18717    
18718    onBlur : function(){
18719        
18720        if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
18721            this.completeEdit();
18722        }
18723    },
18724
18725    
18726    onHide : function(){
18727        if(this.editing){
18728            this.completeEdit();
18729            return;
18730        }
18731        this.field.blur();
18732        if(this.field.collapse){
18733            this.field.collapse();
18734        }
18735        this.el.hide();
18736        if(this.hideEl !== false){
18737            this.boundEl.show();
18738        }
18739    },
18740
18741    
18742    setValue : function(v){
18743        this.field.setValue(v);
18744    },
18745
18746    
18747    getValue : function(){
18748        return this.field.getValue();
18749    },
18750
18751    beforeDestroy : function(){
18752        Ext.destroyMembers(this, 'field');
18753
18754        delete this.parentEl;
18755        delete this.boundEl;
18756    }
18757});
18758Ext.reg('editor', Ext.Editor);
18759
18760Ext.ColorPalette = Ext.extend(Ext.Component, {
18761	
18762    
18763    itemCls : 'x-color-palette',
18764    
18765    value : null,
18766    
18767    clickEvent :'click',
18768    
18769    ctype : 'Ext.ColorPalette',
18770
18771    
18772    allowReselect : false,
18773
18774    
18775    colors : [
18776        '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
18777        '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
18778        'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
18779        'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
18780        'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
18781    ],
18782
18783    
18784    
18785    
18786    
18787    initComponent : function(){
18788        Ext.ColorPalette.superclass.initComponent.call(this);
18789        this.addEvents(
18790            
18791            'select'
18792        );
18793
18794        if(this.handler){
18795            this.on('select', this.handler, this.scope, true);
18796        }    
18797    },
18798
18799    
18800    onRender : function(container, position){
18801        this.autoEl = {
18802            tag: 'div',
18803            cls: this.itemCls
18804        };
18805        Ext.ColorPalette.superclass.onRender.call(this, container, position);
18806        var t = this.tpl || new Ext.XTemplate(
18807            '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'
18808        );
18809        t.overwrite(this.el, this.colors);
18810        this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
18811        if(this.clickEvent != 'click'){
18812        	this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
18813        }
18814    },
18815
18816    
18817    afterRender : function(){
18818        Ext.ColorPalette.superclass.afterRender.call(this);
18819        if(this.value){
18820            var s = this.value;
18821            this.value = null;
18822            this.select(s, true);
18823        }
18824    },
18825
18826    
18827    handleClick : function(e, t){
18828        e.preventDefault();
18829        if(!this.disabled){
18830            var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
18831            this.select(c.toUpperCase());
18832        }
18833    },
18834
18835    
18836    select : function(color, suppressEvent){
18837        color = color.replace('#', '');
18838        if(color != this.value || this.allowReselect){
18839            var el = this.el;
18840            if(this.value){
18841                el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
18842            }
18843            el.child('a.color-'+color).addClass('x-color-palette-sel');
18844            this.value = color;
18845            if(suppressEvent !== true){
18846                this.fireEvent('select', this, color);
18847            }
18848        }
18849    }
18850
18851    
18852});
18853Ext.reg('colorpalette', Ext.ColorPalette);
18854Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
18855    
18856    todayText : 'Today',
18857    
18858    okText : '&#160;
18858OK&#160;',
18859    
18860    cancelText : 'Cancel',
18861    
18862    
18863    
18864    todayTip : '{0} (Spacebar)',
18865    
18866    minText : 'This date is before the minimum date',
18867    
18868    maxText : 'This date is after the maximum date',
18869    
18870    format : 'm/d/y',
18871    
18872    disabledDaysText : 'Disabled',
18873    
18874    disabledDatesText : 'Disabled',
18875    
18876    monthNames : Date.monthNames,
18877    
18878    dayNames : Date.dayNames,
18879    
18880    nextText : 'Next Month (Control+Right)',
18881    
18882    prevText : 'Previous Month (Control+Left)',
18883    
18884    monthYearText : 'Choose a month (Control+Up/Down to move years)',
18885    
18886    startDay : 0,
18887    
18888    showToday : true,
18889    
18890    
18891    
18892    
18893    
18894
18895    
18896    
18897    focusOnSelect: true,
18898
18899    
18900    
18901    initHour: 12, 
18902
18903    
18904    initComponent : function(){
18905        Ext.DatePicker.superclass.initComponent.call(this);
18906
18907        this.value = this.value ?
18908                 this.value.clearTime(true) : new Date().clearTime();
18909
18910        this.addEvents(
18911            
18912            'select'
18913        );
18914
18915        if(this.handler){
18916            this.on('select', this.handler,  this.scope || this);
18917        }
18918
18919        this.initDisabledDays();
18920    },
18921
18922    
18923    initDisabledDays : function(){
18924        if(!this.disabledDatesRE && this.disabledDates){
18925            var dd = this.disabledDates,
18926                len = dd.length - 1,
18927                re = '(?:';
18928
18929            Ext.each(dd, function(d, i){
18930                re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
18931                if(i != len){
18932                    re += '|';
18933                }
18934            }, this);
18935            this.disabledDatesRE = new RegExp(re + ')');
18936        }
18937    },
18938
18939    
18940    setDisabledDates : function(dd){
18941        if(Ext.isArray(dd)){
18942            this.disabledDates = dd;
18943            this.disabledDatesRE = null;
18944        }else{
18945            this.disabledDatesRE = dd;
18946        }
18947        this.initDisabledDays();
18948        this.update(this.value, true);
18949    },
18950
18951    
18952    setDisabledDays : function(dd){
18953        this.disabledDays = dd;
18954        this.update(this.value, true);
18955    },
18956
18957    
18958    setMinDate : function(dt){
18959        this.minDate = dt;
18960        this.update(this.value, true);
18961    },
18962
18963    
18964    setMaxDate : function(dt){
18965        this.maxDate = dt;
18966        this.update(this.value, true);
18967    },
18968
18969    
18970    setValue : function(value){
18971        this.value = value.clearTime(true);
18972        this.update(this.value);
18973    },
18974
18975    
18976    getValue : function(){
18977        return this.value;
18978    },
18979
18980    
18981    focus : function(){
18982        this.update(this.activeDate);
18983    },
18984
18985    
18986    onEnable: function(initial){
18987        Ext.DatePicker.superclass.onEnable.call(this);
18988        this.doDisabled(false);
18989        this.update(initial ? this.value : this.activeDate);
18990        if(Ext.isIE){
18991            this.el.repaint();
18992        }
18993
18994    },
18995
18996    
18997    onDisable : function(){
18998        Ext.DatePicker.superclass.onDisable.call(this);
18999        this.doDisabled(true);
19000        if(Ext.isIE && !Ext.isIE8){
19001            
19002             Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
19003                 Ext.fly(el).repaint();
19004             });
19005        }
19006    },
19007
19008    
19009    doDisabled : function(disabled){
19010        this.keyNav.setDisabled(disabled);
19011        this.prevRepeater.setDisabled(disabled);
19012        this.nextRepeater.setDisabled(disabled);
19013        if(this.showToday){
19014            this.todayKeyListener.setDisabled(disabled);
19015            this.todayBtn.setDisabled(disabled);
19016        }
19017    },
19018
19019    
19020    onRender : function(container, position){
19021        var m = [
19022             '<table cellspacing="0">',
19023                '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',
19024                '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
19025                dn = this.dayNames,
19026                i;
19027        for(i = 0; i < 7; i++){
19028            var d = this.startDay+i;
19029            if(d > 6){
19030                d = d-7;
19031            }
19032            m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
19033        }
19034        m[m.length] = '</tr></thead><tbody><tr>';
19035        for(i = 0; i < 42; i++) {
19036            if(i % 7 === 0 && i !== 0){
19037                m[m.length] = '</tr><tr>';
19038            }
19039            m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
19040        }
19041        m.push('</tr></tbody></table></td></tr>',
19042                this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
19043                '</table><div class="x-date-mp"></div>');
19044
19045        var el = document.createElement('div');
19046        el.className = 'x-date-picker';
19047        el.innerHTML = m.join('');
19048
19049        container.dom.insertBefore(el, position);
19050
19051        this.el = Ext.get(el);
19052        this.eventEl = Ext.get(el.firstChild);
19053
19054        this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
19055            handler: this.showPrevMonth,
19056            scope: this,
19057            preventDefault:true,
19058            stopDefault:true
19059        });
19060
19061        this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
19062            handler: this.showNextMonth,
19063            scope: this,
19064            preventDefault:true,
19065            stopDefault:true
19066        });
19067
19068        this.monthPicker = this.el.down('div.x-date-mp');
19069        this.monthPicker.enableDisplayMode('block');
19070
19071        this.keyNav = new Ext.KeyNav(this.eventEl, {
19072            'left' : function(e){
19073                if(e.ctrlKey){
19074                    this.showPrevMonth();
19075                }else{
19076                    this.update(this.activeDate.add('d', -1));
19077                }
19078            },
19079
19080            'right' : function(e){
19081                if(e.ctrlKey){
19082                    this.showNextMonth();
19083                }else{
19084                    this.update(this.activeDate.add('d', 1));
19085                }
19086            },
19087
19088            'up' : function(e){
19089                if(e.ctrlKey){
19090                    this.showNextYear();
19091                }else{
19092                    this.update(this.activeDate.add('d', -7));
19093                }
19094            },
19095
19096            'down' : function(e){
19097                if(e.ctrlKey){
19098                    this.showPrevYear();
19099                }else{
19100                    this.update(this.activeDate.add('d', 7));
19101                }
19102            },
19103
19104            'pageUp' : function(e){
19105                this.showNextMonth();
19106            },
19107
19108            'pageDown' : function(e){
19109                this.showPrevMonth();
19110            },
19111
19112            'enter' : function(e){
19113                e.stopPropagation();
19114                return true;
19115            },
19116
19117            scope : this
19118        });
19119
19120        this.el.unselectable();
19121
19122        this.cells = this.el.select('table.x-date-inner tbody td');
19123        this.textNodes = this.el.query('table.x-date-inner tbody span');
19124
19125        this.mbtn = new Ext.Button({
19126            text: '&#160;',
19127            tooltip: this.monthYearText,
19128            renderTo: this.el.child('td.x-date-middle', true)
19129        });
19130        this.mbtn.el.child('em').addClass('x-btn-arrow');
19131
19132        if(this.showToday){
19133            this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);
19134            var today = (new Date()).dateFormat(this.format);
19135            this.todayBtn = new Ext.Button({
19136                renderTo: this.el.child('td.x-date-bottom', true),
19137                text: String.format(this.todayText, today),
19138                tooltip: String.format(this.todayTip, today),
19139                handler: this.selectToday,
19140                scope: this
19141            });
19142        }
19143        this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
19144        this.mon(this.eventEl, 'click', this.handleDateClick,  this, {delegate: 'a.x-date-date'});
19145        this.mon(this.mbtn, 'click', this.showMonthPicker, this);
19146        this.onEnable(true);
19147    },
19148
19149    
19150    createMonthPicker : function(){
19151        if(!this.monthPicker.dom.firstChild){
19152            var buf = ['<table border="0" cellspacing="0">'];
19153            for(var i = 0; i < 6; i++){
19154                buf.push(
19155                    '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
19156                    '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
19157                    i === 0 ?
19158                    '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
19159                    '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
19160                );
19161            }
19162            buf.push(
19163                '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
19164                    this.okText,
19165                    '</button><button type="button" class="x-date-mp-cancel">',
19166                    this.cancelText,
19167                    '</button></td></tr>',
19168                '</table>'
19169            );
19170            this.monthPicker.update(buf.join(''));
19171
19172            this.mon(this.monthPicker, 'click', this.onMonthClick, this);
19173            this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
19174
19175            this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
19176            this.mpYears = this.monthPicker.select('td.x-date-mp-year');
19177
19178            this.mpMonths.each(function(m, a, i){
19179                i += 1;
19180                if((i%2) === 0){
19181                    m.dom.xmonth = 5 + Math.round(i * 0.5);
19182                }else{
19183                    m.dom.xmonth = Math.round((i-1) * 0.5);
19184                }
19185            });
19186        }
19187    },
19188
19189    
19190    showMonthPicker : function(){
19191        if(!this.disabled){
19192            this.createMonthPicker();
19193            var size = this.el.getSize();
19194            this.monthPicker.setSize(size);
19195            this.monthPicker.child('table').setSize(size);
19196
19197            this.mpSelMonth = (this.activeDate || this.value).getMonth();
19198            this.updateMPMonth(this.mpSelMonth);
19199            this.mpSelYear = (this.activeDate || this.value).getFullYear();
19200            this.updateMPYear(this.mpSelYear);
19201
19202            this.monthPicker.slideIn('t', {duration:0.2});
19203        }
19204    },
19205
19206    
19207    updateMPYear : function(y){
19208        this.mpyear = y;
19209        var ys = this.mpYears.elements;
19210        for(var i = 1; i <= 10; i++){
19211            var td = ys[i-1], y2;
19212            if((i%2) === 0){
19213                y2 = y + Math.round(i * 0.5);
19214                td.firstChild.innerHTML = y2;
19215                td.xyear = y2;
19216            }else{
19217                y2 = y - (5-Math.round(i * 0.5));
19218                td.firstChild.innerHTML = y2;
19219                td.xyear = y2;
19220            }
19221            this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
19222        }
19223    },
19224
19225    
19226    updateMPMonth : function(sm){
19227        this.mpMonths.each(function(m, a, i){
19228            m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
19229        });
19230    },
19231
19232    
19233    selectMPMonth : function(m){
19234
19235    },
19236
19237    
19238    onMonthClick : function(e, t){
19239        e.stopEvent();
19240        var el = new Ext.Element(t), pn;
19241        if(el.is('button.x-date-mp-cancel')){
19242            this.hideMonthPicker();
19243        }
19244        else if(el.is('button.x-date-mp-ok')){
19245            var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
19246            if(d.getMonth() != this.mpSelMonth){
19247                
19248                d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
19249            }
19250            this.update(d);
19251            this.hideMonthPicker();
19252        }
19253        else if((pn = el.up('td.x-date-mp-month', 2))){
19254            this.mpMonths.removeClass('x-date-mp-sel');
19255            pn.addClass('x-date-mp-sel');
19256            this.mpSelMonth = pn.dom.xmonth;
19257        }
19258        else if((pn = el.up('td.x-date-mp-year', 2))){
19259            this.mpYears.removeClass('x-date-mp-sel');
19260            pn.addClass('x-date-mp-sel');
19261            this.mpSelYear = pn.dom.xyear;
19262        }
19263        else if(el.is('a.x-date-mp-prev')){
19264            this.updateMPYear(this.mpyear-10);
19265        }
19266        else if(el.is('a.x-date-mp-next')){
19267            this.updateMPYear(this.mpyear+10);
19268        }
19269    },
19270
19271    
19272    onMonthDblClick : function(e, t){
19273        e.stopEvent();
19274        var el = new Ext.Element(t), pn;
19275        if((pn = el.up('td.x-date-mp-month', 2))){
19276            this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
19277            this.hideMonthPicker();
19278        }
19279        else if((pn = el.up('td.x-date-mp-year', 2))){
19280            this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
19281            this.hideMonthPicker();
19282        }
19283    },
19284
19285    
19286    hideMonthPicker : function(disableAnim){
19287        if(this.monthPicker){
19288            if(disableAnim === true){
19289                this.monthPicker.hide();
19290            }else{
19291                this.monthPicker.slideOut('t', {duration:0.2});
19292            }
19293        }
19294    },
19295
19296    
19297    showPrevMonth : function(e){
19298        this.update(this.activeDate.add('mo', -1));
19299    },
19300
19301    
19302    showNextMonth : function(e){
19303        this.update(this.activeDate.add('mo', 1));
19304    },
19305
19306    
19307    showPrevYear : function(){
19308        this.update(this.activeDate.add('y', -1));
19309    },
19310
19311    
19312    showNextYear : function(){
19313        this.update(this.activeDate.add('y', 1));
19314    },
19315
19316    
19317    handleMouseWheel : function(e){
19318        e.stopEvent();
19319        if(!this.disabled){
19320            var delta = e.getWheelDelta();
19321            if(delta > 0){
19322                this.showPrevMonth();
19323            } else if(delta < 0){
19324                this.showNextMonth();
19325            }
19326        }
19327    },
19328
19329    
19330    handleDateClick : function(e, t){
19331        e.stopEvent();
19332        if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
19333            this.cancelFocus = this.focusOnSelect === false;
19334            this.setValue(new Date(t.dateValue));
19335            delete this.cancelFocus;
19336            this.fireEvent('select', this, this.value);
19337        }
19338    },
19339
19340    
19341    selectToday : function(){
19342        if(this.todayBtn && !this.todayBtn.disabled){
19343            this.setValue(new Date().clearTime());
19344            this.fireEvent('select', this, this.value);
19345        }
19346    },
19347
19348    
19349    update : function(date, forceRefresh){
19350        if(this.rendered){
19351            var vd = this.activeDate, vis = this.isVisible();
19352            this.activeDate = date;
19353            if(!forceRefresh && vd && this.el){
19354                var t = date.getTime();
19355                if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
19356                    this.cells.removeClass('x-date-selected');
19357                    this.cells.each(function(c){
19358                       if(c.dom.firstChild.dateValue == t){
19359                           c.addClass('x-date-selected');
19360                           if(vis && !this.cancelFocus){
19361                               Ext.fly(c.dom.firstChild).focus(50);
19362                           }
19363                           return false;
19364                       }
19365                    }, this);
19366                    return;
19367                }
19368            }
19369            var days = date.getDaysInMonth(),
19370                firstOfMonth = date.getFirstDateOfMonth(),
19371                startingPos = firstOfMonth.getDay()-this.startDay;
19372
19373            if(startingPos < 0){
19374                startingPos += 7;
19375            }
19376            days += startingPos;
19377
19378            var pm = date.add('mo', -1),
19379                prevStart = pm.getDaysInMonth()-startingPos,
19380                cells = this.cells.elements,
19381                textEls = this.textNodes,
19382                
19383                d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
19384                today = new Date().clearTime().getTime(),
19385                sel = date.clearTime(true).getTime(),
19386                min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
19387                max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
19388                ddMatch = this.disabledDatesRE,
19389                ddText = this.disabledDatesText,
19390                ddays = this.disabledDays ? this.disabledDays.join('') : false,
19391                ddaysText = this.disabledDaysText,
19392                format = this.format;
19393
19394            if(this.showToday){
19395                var td = new Date().clearTime(),
19396                    disable = (td < min || td > max ||
19397                    (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
19398                    (ddays && ddays.indexOf(td.getDay()) != -1));
19399
19400                if(!this.disabled){
19401                    this.todayBtn.setDisabled(disable);
19402                    this.todayKeyListener[disable ? 'disable' : 'enable']();
19403                }
19404            }
19405
19406            var setCellClass = function(cal, cell){
19407                cell.title = '';
19408                var t = d.clearTime(true).getTime();
19409                cell.firstChild.dateValue = t;
19410                if(t == today){
19411                    cell.className += ' x-date-today';
19412                    cell.title = cal.todayText;
19413                }
19414                if(t == sel){
19415                    cell.className += ' x-date-selected';
19416                    if(vis){
19417                        Ext.fly(cell.firstChild).focus(50);
19418                    }
19419                }
19420                
19421                if(t < min) {
19422                    cell.className = ' x-date-disabled';
19423                    cell.title = cal.minText;
19424                    return;
19425                }
19426                if(t > max) {
19427                    cell.className = ' x-date-disabled';
19428                    cell.title = cal.maxText;
19429                    return;
19430                }
19431                if(ddays){
19432                    if(ddays.indexOf(d.getDay()) != -1){
19433                        cell.title = ddaysText;
19434                        cell.className = ' x-date-disabled';
19435                    }
19436                }
19437                if(ddMatch && format){
19438                    var fvalue = d.dateFormat(format);
19439                    if(ddMatch.test(fvalue)){
19440                        cell.title = ddText.replace('%0', fvalue);
19441                        cell.className = ' x-date-disabled';
19442                    }
19443                }
19444            };
19445
19446            var i = 0;
19447            for(; i < startingPos; i++) {
19448                textEls[i].innerHTML = (++prevStart);
19449                d.setDate(d.getDate()+1);
19450                cells[i].className = 'x-date-prevday';
19451                setCellClass(this, cells[i]);
19452            }
19453            for(; i < days; i++){
19454                var intDay = i - startingPos + 1;
19455                textEls[i].innerHTML = (intDay);
19456                d.setDate(d.getDate()+1);
19457                cells[i].className = 'x-date-active';
19458                setCellClass(this, cells[i]);
19459            }
19460            var extraDays = 0;
19461            for(; i < 42; i++) {
19462                 textEls[i].innerHTML = (++extraDays);
19463                 d.setDate(d.getDate()+1);
19464                 cells[i].className = 'x-date-nextday';
19465                 setCellClass(this, cells[i]);
19466            }
19467
19468            this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
19469
19470            if(!this.internalRender){
19471                var main = this.el.dom.firstChild,
19472                    w = main.offsetWidth;
19473                this.el.setWidth(w + this.el.getBorderWidth('lr'));
19474                Ext.fly(main).setWidth(w);
19475                this.internalRender = true;
19476                
19477                
19478                
19479                if(Ext.isOpera && !this.secondPass){
19480                    main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
19481                    this.secondPass = true;
19482                    this.update.defer(10, this, [date]);
19483                }
19484            }
19485        }
19486    },
19487
19488    
19489    beforeDestroy : function() {
19490        if(this.rendered){
19491            Ext.destroy(
19492                this.keyNav,
19493                this.monthPicker,
19494                this.eventEl,
19495                this.mbtn,
19496                this.nextRepeater,
19497                this.prevRepeater,
19498                this.cells.el,
19499                this.todayBtn
19500            );
19501            delete this.textNodes;
19502            delete this.cells.elements;
19503        }
19504    }
19505
19506    
19507});
19508
19509Ext.reg('datepicker', Ext.DatePicker);
19510
19511Ext.LoadMask = function(el, config){
19512    this.el = Ext.get(el);
19513    Ext.apply(this, config);
19514    if(this.store){
19515        this.store.on({
19516            scope: this,
19517            beforeload: this.onBeforeLoad,
19518            load: this.onLoad,
19519            exception: this.onLoad
19520        });
19521        this.removeMask = Ext.value(this.removeMask, false);
19522    }else{
19523        var um = this.el.getUpdater();
19524        um.showLoadIndicator = false; 
19525        um.on({
19526            scope: this,
19527            beforeupdate: this.onBeforeLoad,
19528            update: this.onLoad,
19529            failure: this.onLoad
19530        });
19531        this.removeMask = Ext.value(this.removeMask, true);
19532    }
19533};
19534
19535Ext.LoadMask.prototype = {
19536    
19537    
19538    
19539    msg : 'Loading...',
19540    
19541    msgCls : 'x-mask-loading',
19542
19543    
19544    disabled: false,
19545
19546    
19547    disable : function(){
19548       this.disabled = true;
19549    },
19550
19551    
19552    enable : function(){
19553        this.disabled = false;
19554    },
19555
19556    
19557    onLoad : function(){
19558        this.el.unmask(this.removeMask);
19559    },
19560
19561    
19562    onBeforeLoad : function(){
19563        if(!this.disabled){
19564            this.el.mask(this.msg, this.msgCls);
19565        }
19566    },
19567
19568    
19569    show: function(){
19570        this.onBeforeLoad();
19571    },
19572
19573    
19574    hide: function(){
19575        this.onLoad();
19576    },
19577
19578    
19579    destroy : function(){
19580        if(this.store){
19581            this.store.un('beforeload', this.onBeforeLoad, this);
19582            this.store.un('load', this.onLoad, this);
19583            this.store.un('exception', this.onLoad, this);
19584        }else{
19585            var um = this.el.getUpdater();
19586            um.un('beforeupdate', this.onBeforeLoad, this);
19587            um.un('update', this.onLoad, this);
19588            um.un('failure', this.onLoad, this);
19589        }
19590    }
19591};
19592Ext.slider.Thumb = Ext.extend(Object, {
19593    
19594    
19595    dragging: false,
19596
19597    
19598    constructor: function(config) {
19599        
19600        Ext.apply(this, config || {}, {
19601            cls: 'x-slider-thumb',
19602
19603            
19604            constrain: false
19605        });
19606
19607        Ext.slider.Thumb.superclass.constructor.call(this, config);
19608
19609        if (this.slider.vertical) {
19610            Ext.apply(this, Ext.slider.Thumb.Vertical);
19611        }
19612    },
19613
19614    
19615    render: function() {
19616        this.el = this.slider.innerEl.insertFirst({cls: this.cls});
19617
19618        this.initEvents();
19619    },
19620
19621    
19622    enable: function() {
19623        this.disabled = false;
19624        this.el.removeClass(this.slider.disabledClass);
19625    },
19626
19627    
19628    disable: function() {
19629        this.disabled = true;
19630        this.el.addClass(this.slider.disabledClass);
19631    },
19632
19633    
19634    initEvents: function() {
19635        var el = this.el;
19636
19637        el.addClassOnOver('x-slider-thumb-over');
19638
19639        this.tracker = new Ext.dd.DragTracker({
19640            onBeforeStart: this.onBeforeDragStart.createDelegate(this),
19641            onStart      : this.onDragStart.createDelegate(this),
19642            onDrag       : this.onDrag.createDelegate(this),
19643            onEnd        : this.onDragEnd.createDelegate(this),
19644            tolerance    : 3,
19645            autoStart    : 300
19646        });
19647
19648        this.tracker.initEl(el);
19649    },
19650
19651    
19652    onBeforeDragStart : function(e) {
19653        if (this.disabled) {
19654            return false;
19655        } else {
19656            this.slider.promoteThumb(this);
19657            return true;
19658        }
19659    },
19660
19661    
19662    onDragStart: function(e){
19663        this.el.addClass('x-slider-thumb-drag');
19664        this.dragging = true;
19665        this.dragStartValue = this.value;
19666
19667        this.slider.fireEvent('dragstart', this.slider, e, this);
19668    },
19669
19670    
19671    onDrag: function(e) {
19672        var slider   = this.slider,
19673            index    = this.index,
19674            newValue = this.getNewValue();
19675
19676        if (this.constrain) {
19677            var above = slider.thumbs[index + 1],
19678                below = slider.thumbs[index - 1];
19679
19680            if (below != undefined && newValue <= below.value) newValue = below.value;
19681            if (above != undefined && newValue >= above.value) newValue = above.value;
19682        }
19683
19684        slider.setValue(index, newValue, false);
19685        slider.fireEvent('drag', slider, e, this);
19686    },
19687
19688    getNewValue: function() {
19689        var slider   = this.slider,
19690            pos      = slider.innerEl.translatePoints(this.tracker.getXY());
19691
19692        return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
19693    },
19694
19695    
19696    onDragEnd: function(e) {
19697        var slider = this.slider,
19698            value  = this.value;
19699
19700        this.el.removeClass('x-slider-thumb-drag');
19701
19702        this.dragging = false;
19703        slider.fireEvent('dragend', slider, e);
19704
19705        if (this.dragStartValue != value) {
19706            slider.fireEvent('changecomplete', slider, value, this);
19707        }
19708    },
19709    
19710    
19711    destroy: function(){
19712        Ext.destroyMembers(this, 'tracker', 'el');
19713    }
19714});
19715
19716
19717Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
19718    
19719    
19720    vertical: false,
19721    
19722    minValue: 0,
19723    
19724    maxValue: 100,
19725    
19726    decimalPrecision: 0,
19727    
19728    keyIncrement: 1,
19729    
19730    increment: 0,
19731
19732    
19733    clickRange: [5,15],
19734
19735    
19736    clickToChange : true,
19737    
19738    animate: true,
19739    
19740    constrainThumbs: true,
19741
19742    
19743    topThumbZIndex: 10000,
19744
19745    
19746    initComponent : function(){
19747        if(!Ext.isDefined(this.value)){
19748            this.value = this.minValue;
19749        }
19750
19751        
19752        this.thumbs = [];
19753
19754        Ext.slider.MultiSlider.superclass.initComponent.call(this);
19755
19756        this.keyIncrement = Math.max(this.increment, this.keyIncrement);
19757        this.addEvents(
19758            
19759            'beforechange',
19760
19761            
19762            'change',
19763
19764            
19765            'changecomplete',
19766
19767            
19768            'dragstart',
19769
19770            
19771            'drag',
19772
19773            
19774            'dragend'
19775        );
19776
19777        
19778        if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
19779
19780        var values = this.values;
19781
19782        for (var i=0; i < values.length; i++) {
19783            this.addThumb(values[i]);
19784        }
19785
19786        if(this.vertical){
19787            Ext.apply(this, Ext.slider.Vertical);
19788        }
19789    },
19790
19791    
19792    addThumb: function(value) {
19793        var thumb = new Ext.slider.Thumb({
19794            value    : value,
19795            slider   : this,
19796            index    : this.thumbs.length,
19797            constrain: this.constrainThumbs
19798        });
19799        this.thumbs.push(thumb);
19800
19801        
19802        if (this.rendered) thumb.render();
19803    },
19804
19805    
19806    promoteThumb: function(topThumb) {
19807        var thumbs = this.thumbs,
19808            zIndex, thumb;
19809
19810        for (var i = 0, j = thumbs.length; i < j; i++) {
19811            thumb = thumbs[i];
19812
19813            if (thumb == topThumb) {
19814                zIndex = this.topThumbZIndex;
19815            } else {
19816                zIndex = '';
19817            }
19818
19819            thumb.el.setStyle('zIndex', zIndex);
19820        }
19821    },
19822
19823    
19824    onRender : function() {
19825        this.autoEl = {
19826            cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
19827            cn : {
19828                cls: 'x-slider-end',
19829                cn : {
19830                    cls:'x-slider-inner',
19831                    cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
19832                }
19833            }
19834        };
19835
19836        Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
19837
19838        this.endEl   = this.el.first();
19839        this.innerEl = this.endEl.first();
19840        this.focusEl = this.innerEl.child('.x-slider-focus');
19841
19842        
19843        for (var i=0; i < this.thumbs.length; i++) {
19844            this.thumbs[i].render();
19845        }
19846
19847        
19848        var thumb      = this.innerEl.child('.x-slider-thumb');
19849        this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
19850
19851        this.initEvents();
19852    },
19853
19854    
19855    initEvents : function(){
19856        this.mon(this.el, {
19857            scope    : this,
19858            mousedown: this.onMouseDown,
19859            keydown  : this.onKeyDown
19860        });
19861
19862        this.focusEl.swallowEvent("click", true);
19863    },
19864
19865    
19866    onMouseDown : function(e){
19867        if(this.disabled){
19868            return;
19869        }
19870
19871        
19872        var thumbClicked = false;
19873        for (var i=0; i < this.thumbs.length; i++) {
19874            thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
19875        }
19876
19877        if (this.clickToChange && !thumbClicked) {
19878            var local = this.innerEl.translatePoints(e.getXY());
19879            this.onClickChange(local);
19880        }
19881        this.focus();
19882    },
19883
19884    
19885    onClickChange : function(local) {
19886        if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
19887            
19888            var thumb = this.getNearest(local, 'left'),
19889                index = thumb.index;
19890
19891            this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
19892        }
19893    },
19894
19895    
19896    getNearest: function(local, prop) {
19897        var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
19898            clickValue = this.reverseValue(localValue),
19899            nearestDistance = (this.maxValue - this.minValue) + 5, 
19900            index = 0,
19901            nearest = null;
19902
19903        for (var i=0; i < this.thumbs.length; i++) {
19904            var thumb = this.thumbs[i],
19905                value = thumb.value,
19906                dist  = Math.abs(value - clickValue);
19907
19908            if (Math.abs(dist <= nearestDistance)) {
19909                nearest = thumb;
19910                index = i;
19911                nearestDistance = dist;
19912            }
19913        }
19914        return nearest;
19915    },
19916
19917    
19918    onKeyDown : function(e){
19919        
19920        if(this.disabled || this.thumbs.length !== 1){
19921            e.preventDefault();
19922            return;
19923        }
19924        var k = e.getKey(),
19925            val;
19926        switch(k){
19927            case e.UP:
19928            case e.RIGHT:
19929                e.stopEvent();
19930                val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
19931                this.setValue(0, val, undefined, true);
19932            break;
19933            case e.DOWN:
19934            case e.LEFT:
19935                e.stopEvent();
19936                val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
19937                this.setValue(0, val, undefined, true);
19938            break;
19939            default:
19940                e.preventDefault();
19941        }
19942    },
19943
19944    
19945    doSnap : function(value){
19946        if (!(this.increment && value)) {
19947            return value;
19948        }
19949        var newValue = value,
19950            inc = this.increment,
19951            m = value % inc;
19952        if (m != 0) {
19953            newValue -= m;
19954            if (m * 2 >= inc) {
19955                newValue += inc;
19956            } else if (m * 2 < -inc) {
19957                newValue -= inc;
19958            }
19959        }
19960        return newValue.constrain(this.minValue,  this.maxValue);
19961    },
19962
19963    
19964    afterRender : function(){
19965        Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
19966
19967        for (var i=0; i < this.thumbs.length; i++) {
19968            var thumb = this.thumbs[i];
19969
19970            if (thumb.value !== undefined) {
19971                var v = this.normalizeValue(thumb.value);
19972
19973                if (v !== thumb.value) {
19974                    
19975                    this.setValue(i, v, false);
19976                } else {
19977                    this.moveThumb(i, this.translateValue(v), false);
19978                }
19979            }
19980        };
19981    },
19982
19983    
19984    getRatio : function(){
19985        var w = this.innerEl.getWidth(),
19986            v = this.maxValue - this.minValue;
19987        return v == 0 ? w : (w/v);
19988    },
19989
19990    
19991    normalizeValue : function(v){
19992        v = this.doSnap(v);
19993        v = Ext.util.Format.round(v, this.decimalPrecision);
19994        v = v.constrain(this.minValue, this.maxValue);
19995        return v;
19996    },
19997
19998    
19999    setMinValue : function(val){
20000        this.minValue = val;
20001        var i = 0,
20002            thumbs = this.thumbs,
20003            len = thumbs.length,
20004            t;
20005            
20006        for(; i < len; ++i){
20007            t = thumbs[i];
20008            t.value = t.value < val ? val : t.value;
20009        }
20010        this.syncThumb();
20011    },
20012
20013    
20014    setMaxValue : function(val){
20015        this.maxValue = val;
20016        var i = 0,
20017            thumbs = this.thumbs,
20018            len = thumbs.length,
20019            t;
20020            
20021        for(; i < len; ++i){
20022            t = thumbs[i];
20023            t.value = t.value > val ? val : t.value;
20024        }
20025        this.syncThumb();
20026    },
20027
20028    
20029    setValue : function(index, v, animate, changeComplete) {
20030        var thumb = this.thumbs[index],
20031            el    = thumb.el;
20032
20033        v = this.normalizeValue(v);
20034
20035        if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
20036            thumb.value = v;
20037            if(this.rendered){
20038                this.moveThumb(index, this.translateValue(v), animate !== false);
20039                this.fireEvent('change', this, v, thumb);
20040                if(changeComplete){
20041                    this.fireEvent('changecomplete', this, v, thumb);
20042                }
20043            }
20044        }
20045    },
20046
20047    
20048    translateValue : function(v) {
20049        var ratio = this.getRatio();
20050        return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
20051    },
20052
20053    
20054    reverseValue : function(pos){
20055        var ratio = this.getRatio();
20056        return (pos + (this.minValue * ratio)) / ratio;
20057    },
20058
20059    
20060    moveThumb: function(index, v, animate){
20061        var thumb = this.thumbs[index].el;
20062
20063        if(!animate || this.animate === false){
20064            thumb.setLeft(v);
20065        }else{
20066            thumb.shift({left: v, stopFx: true, duration:.35});
20067        }
20068    },
20069
20070    
20071    focus : function(){
20072        this.focusEl.focus(10);
20073    },
20074
20075    
20076    onResize : function(w, h){
20077        var thumbs = this.thumbs,
20078            len = thumbs.length,
20079            i = 0;
20080            
20081        
20082        for(; i < len; ++i){
20083            thumbs[i].el.stopFx();    
20084        }
20085        
20086        if(Ext.isNumber(w)){
20087            this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
20088        }
20089        this.syncThumb();
20090        Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
20091    },
20092
20093    
20094    onDisable: function(){
20095        Ext.slider.MultiSlider.superclass.onDisable.call(this);
20096
20097        for (var i=0; i < this.thumbs.length; i++) {
20098            var thumb = this.thumbs[i],
20099                el    = thumb.el;
20100
20101            thumb.disable();
20102
20103            if(Ext.isIE){
20104                
20105                
20106                var xy = el.getXY();
20107                el.hide();
20108
20109                this.innerEl.addClass(this.disabledClass).dom.disabled = true;
20110
20111                if (!this.thumbHolder) {
20112                    this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
20113                }
20114
20115                this.thumbHolder.show().setXY(xy);
20116            }
20117        }
20118    },
20119
20120    
20121    onEnable: function(){
20122        Ext.slider.MultiSlider.superclass.onEnable.call(this);
20123
20124        for (var i=0; i < this.thumbs.length; i++) {
20125            var thumb = this.thumbs[i],
20126                el    = thumb.el;
20127
20128            thumb.enable();
20129
20130            if (Ext.isIE) {
20131                this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
20132
20133                if (this.thumbHolder) this.thumbHolder.hide();
20134
20135                el.show();
20136                this.syncThumb();
20137            }
20138        }
20139    },
20140
20141    
20142    syncThumb : function() {
20143        if (this.rendered) {
20144            for (var i=0; i < this.thumbs.length; i++) {
20145                this.moveThumb(i, this.translateValue(this.thumbs[i].value));
20146            }
20147        }
20148    },
20149
20150    
20151    getValue : function(index) {
20152        return this.thumbs[index].value;
20153    },
20154
20155    
20156    getValues: function() {
20157        var values = [];
20158
20159        for (var i=0; i < this.thumbs.length; i++) {
20160            values.push(this.thumbs[i].value);
20161        }
20162
20163        return values;
20164    },
20165
20166    
20167    beforeDestroy : function(){
20168        var thumbs = this.thumbs;
20169        for(var i = 0, len = thumbs.length; i < len; ++i){
20170            thumbs[i].destroy();
20171            thumbs[i] = null;
20172        }
20173        Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
20174        Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
20175    }
20176});
20177
20178Ext.reg('multislider', Ext.slider.MultiSlider);
20179
20180
20181Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
20182    constructor: function(config) {
20183      config = config || {};
20184
20185      Ext.applyIf(config, {
20186          values: [config.value || 0]
20187      });
20188
20189      Ext.slider.SingleSlider.superclass.constructor.call(this, config);
20190    },
20191
20192    
20193    getValue: function() {
20194        
20195        return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
20196    },
20197
20198    
20199    setValue: function(value, animate) {
20200        var args = Ext.toArray(arguments),
20201            len  = args.length;
20202
20203        
20204        
20205        
20206        if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
20207            args.unshift(0);
20208        }
20209
20210        return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
20211    },
20212
20213    
20214    syncThumb : function() {
20215        return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
20216    },
20217    
20218    
20219    getNearest : function(){
20220        
20221        return this.thumbs[0];    
20222    }
20223});
20224
20225
20226Ext.Slider = Ext.slider.SingleSlider;
20227
20228Ext.reg('slider', Ext.slider.SingleSlider);
20229
20230
20231Ext.slider.Vertical = {
20232    onResize : function(w, h){
20233        this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
20234        this.syncThumb();
20235    },
20236
20237    getRatio : function(){
20238        var h = this.innerEl.getHeight(),
20239            v = this.maxValue - this.minValue;
20240        return h/v;
20241    },
20242
20243    moveThumb: function(index, v, animate) {
20244        var thumb = this.thumbs[index],
20245            el    = thumb.el;
20246
20247        if (!animate || this.animate === false) {
20248            el.setBottom(v);
20249        } else {
20250            el.shift({bottom: v, stopFx: true, duration:.35});
20251        }
20252    },
20253
20254    onClickChange : function(local) {
20255        if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
20256            var thumb = this.getNearest(local, 'top'),
20257                index = thumb.index,
20258                value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
20259
20260            this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
20261        }
20262    }
20263};
20264
20265
20266Ext.slider.Thumb.Vertical = {
20267    getNewValue: function() {
20268        var slider   = this.slider,
20269            innerEl  = slider.innerEl,
20270            pos      = innerEl.translatePoints(this.tracker.getXY()),
20271            bottom   = innerEl.getHeight() - pos.top;
20272
20273        return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
20274    }
20275};
20276
20277Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
20278   
20279    baseCls : 'x-progress',
20280    
20281    
20282    animate : false,
20283
20284    
20285    waitTimer : null,
20286
20287    
20288    initComponent : function(){
20289        Ext.ProgressBar.superclass.initComponent.call(this);
20290        this.addEvents(
20291            
20292            "update"
20293        );
20294    },
20295
20296    
20297    onRender : function(ct, position){
20298        var tpl = new Ext.Template(
20299            '<div class="{cls}-wrap">',
20300                '<div class="{cls}-inner">',
20301                    '<div class="{cls}-bar">',
20302                        '<div class="{cls}-text">',
20303                            '<div>&#160;</div>',
20304                        '</div>',
20305                    '</div>',
20306                    '<div class="{cls}-text {cls}-text-back">',
20307                        '<div>&#160;</div>',
20308                    '</div>',
20309                '</div>',
20310            '</div>'
20311        );
20312
20313        this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
20314            : tpl.append(ct, {cls: this.baseCls}, true);
20315                
20316        if(this.id){
20317            this.el.dom.id = this.id;
20318        }
20319        var inner = this.el.dom.firstChild;
20320        this.progressBar = Ext.get(inner.firstChild);
20321
20322        if(this.textEl){
20323            
20324            this.textEl = Ext.get(this.textEl);
20325            delete this.textTopEl;
20326        }else{
20327            
20328            this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
20329            var textBackEl = Ext.get(inner.childNodes[1]);
20330            this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
20331            this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
20332            this.textEl.setWidth(inner.offsetWidth);
20333        }
20334        this.progressBar.setHeight(inner.offsetHeight);
20335    },
20336    
20337    
20338    afterRender : function(){
20339        Ext.ProgressBar.superclass.afterRender.call(this);
20340        if(this.value){
20341            this.updateProgress(this.value, this.text);
20342        }else{
20343            this.updateText(this.text);
20344        }
20345    },
20346
20347    
20348    updateProgress : function(value, text, animate){
20349        this.value = value || 0;
20350        if(text){
20351            this.updateText(text);
20352        }
20353        if(this.rendered && !this.isDestroyed){
20354            var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
20355            this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
20356            if(this.textTopEl){
20357                
20358                this.textTopEl.removeClass('x-hidden').setWidth(w);
20359            }
20360        }
20361        this.fireEvent('update', this, value, text);
20362        return this;
20363    },
20364
20365    
20366    wait : function(o){
20367        if(!this.waitTimer){
20368            var scope = this;
20369            o = o || {};
20370            this.updateText(o.text);
20371            this.waitTimer = Ext.TaskMgr.start({
20372                run: function(i){
20373                    var inc = o.increment || 10;
20374                    i -= 1;
20375                    this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
20376                },
20377                interval: o.interval || 1000,
20378                duration: o.duration,
20379                onStop: function(){
20380                    if(o.fn){
20381                        o.fn.apply(o.scope || this);
20382                    }
20383                    this.reset();
20384                },
20385                scope: scope
20386            });
20387        }
20388        return this;
20389    },
20390
20391    
20392    isWaiting : function(){
20393        return this.waitTimer !== null;
20394    },
20395
20396    
20397    updateText : function(text){
20398        this.text = text || '&#160;';
20399        if(this.rendered){
20400            this.textEl.update(this.text);
20401        }
20402        return this;
20403    },
20404    
20405    
20406    syncProgressBar : function(){
20407        if(this.value){
20408            this.updateProgress(this.value, this.text);
20409        }
20410        return this;
20411    },
20412
20413    
20414    setSize : function(w, h){
20415        Ext.ProgressBar.superclass.setSize.call(this, w, h);
20416        if(this.textTopEl){
20417            var inner = this.el.dom.firstChild;
20418            this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
20419        }
20420        this.syncProgressBar();
20421        return this;
20422    },
20423
20424    
20425    reset : function(hide){
20426        this.updateProgress(0);
20427        if(this.textTopEl){
20428            this.textTopEl.addClass('x-hidden');
20429        }
20430        this.clearTimer();
20431        if(hide === true){
20432            this.hide();
20433        }
20434        return this;
20435    },
20436    
20437    
20438    clearTimer : function(){
20439        if(this.waitTimer){
20440            this.waitTimer.onStop = null; 
20441            Ext.TaskMgr.stop(this.waitTimer);
20442            this.waitTimer = null;
20443        }
20444    },
20445    
20446    onDestroy: function(){
20447        this.clearTimer();
20448        if(this.rendered){
20449            if(this.textEl.isComposite){
20450                this.textEl.clear();
20451            }
20452            Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
20453        }
20454        Ext.ProgressBar.superclass.onDestroy.call(this);
20455    }
20456});
20457Ext.reg('progress', Ext.ProgressBar);
20458
20459(function() {
20460
20461var Event=Ext.EventManager;
20462var Dom=Ext.lib.Dom;
20463
20464
20465Ext.dd.DragDrop = function(id, sGroup, config) {
20466    if(id) {
20467        this.init(id, sGroup, config);
20468    }
20469};
20470
20471Ext.dd.DragDrop.prototype = {
20472
20473    
20474
20475    
20476    id: null,
20477
20478    
20479    config: null,
20480
20481    
20482    dragElId: null,
20483
20484    
20485    handleElId: null,
20486
20487    
20488    invalidHandleTypes: null,
20489
20490    
20491    invalidHandleIds: null,
20492
20493    
20494    invalidHandleClasses: null,
20495
20496    
20497    startPageX: 0,
20498
20499    
20500    startPageY: 0,
20501
20502    
20503    groups: null,
20504
20505    
20506    locked: false,
20507
20508    
20509    lock: function() {
20510        this.locked = true;
20511    },
20512
20513    
20514    moveOnly: false,
20515
20516    
20517    unlock: function() {
20518        this.locked = false;
20519    },
20520
20521    
20522    isTarget: true,
20523
20524    
20525    padding: null,
20526
20527    
20528    _domRef: null,
20529
20530    
20531    __ygDragDrop: true,
20532
20533    
20534    constrainX: false,
20535
20536    
20537    constrainY: false,
20538
20539    
20540    minX: 0,
20541
20542    
20543    maxX: 0,
20544
20545    
20546    minY: 0,
20547
20548    
20549    maxY: 0,
20550
20551    
20552    maintainOffset: false,
20553
20554    
20555    xTicks: null,
20556
20557    
20558    yTicks: null,
20559
20560    
20561    primaryButtonOnly: true,
20562
20563    
20564    available: false,
20565
20566    
20567    hasOuterHandles: false,
20568
20569    
20570    b4StartDrag: function(x, y) { },
20571
20572    
20573    startDrag: function(x, y) {  },
20574
20575    
20576    b4Drag: function(e) { },
20577
20578    
20579    onDrag: function(e) {  },
20580
20581    
20582    onDragEnter: function(e, id) {  },
20583
20584    
20585    b4DragOver: function(e) { },
20586
20587    
20588    onDragOver: function(e, id) {  },
20589
20590    
20591    b4DragOut: function(e) { },
20592
20593    
20594    onDragOut: function(e, id) {  },
20595
20596    
20597    b4DragDrop: function(e) { },
20598
20599    
20600    onDragDrop: function(e, id) {  },
20601
20602    
20603    onInvalidDrop: function(e) {  },
20604
20605    
20606    b4EndDrag: function(e) { },
20607
20608    
20609    endDrag: function(e) {  },
20610
20611    
20612    b4MouseDown: function(e) {  },
20613
20614    
20615    onMouseDown: function(e) {  },
20616
20617    
20618    onMouseUp: function(e) {  },
20619
20620    
20621    onAvailable: function () {
20622    },
20623
20624    
20625    defaultPadding : {left:0, right:0, top:0, bottom:0},
20626
20627    
20628    constrainTo : function(constrainTo, pad, inContent){
20629        if(Ext.isNumber(pad)){
20630            pad = {left: pad, right:pad, top:pad, bottom:pad};
20631        }
20632        pad = pad || this.defaultPadding;
20633        var b = Ext.get(this.getEl()).getBox(),
20634            ce = Ext.get(constrainTo),
20635            s = ce.getScroll(),
20636            c, 
20637            cd = ce.dom;
20638        if(cd == document.body){
20639            c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
20640        }else{
20641            var xy = ce.getXY();
20642            c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
20643        }
20644
20645
20646        var topSpace = b.y - c.y,
20647            leftSpace = b.x - c.x;
20648
20649        this.resetConstraints();
20650        this.setXConstraint(leftSpace - (pad.left||0), 
20651                c.width - leftSpace - b.width - (pad.right||0), 
20652				this.xTickSize
20653        );
20654        this.setYConstraint(topSpace - (pad.top||0), 
20655                c.height - topSpace - b.height - (pad.bottom||0), 
20656				this.yTickSize
20657        );
20658    },
20659
20660    
20661    getEl: function() {
20662        if (!this._domRef) {
20663            this._domRef = Ext.getDom(this.id);
20664        }
20665
20666        return this._domRef;
20667    },
20668
20669    
20670    getDragEl: function() {
20671        return Ext.getDom(this.dragElId);
20672    },
20673
20674    
20675    init: function(id, sGroup, config) {
20676        this.initTarget(id, sGroup, config);
20677        Event.on(this.id, "mousedown", this.handleMouseDown, this);
20678        
20679    },
20680
20681    
20682    initTarget: function(id, sGroup, config) {
20683
20684        
20685        this.config = config || {};
20686
20687        
20688        this.DDM = Ext.dd.DDM;
20689        
20690        this.groups = {};
20691
20692        
20693        
20694        if (typeof id !== "string") {
20695            id = Ext.id(id);
20696        }
20697
20698        
20699        this.id = id;
20700
20701        
20702        this.addToGroup((sGroup) ? sGroup : "default");
20703
20704        
20705        
20706        this.handleElId = id;
20707
20708        
20709        this.setDragElId(id);
20710
20711        
20712        this.invalidHandleTypes = { A: "A" };
20713        this.invalidHandleIds = {};
20714        this.invalidHandleClasses = [];
20715
20716        this.applyConfig();
20717
20718        this.handleOnAvailable();
20719    },
20720
20721    
20722    applyConfig: function() {
20723
20724        
20725        
20726        this.padding           = this.config.padding || [0, 0, 0, 0];
20727        this.isTarget          = (this.config.isTarget !== false);
20728        this.maintainOffset    = (this.config.maintainOffset);
20729        this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
20730
20731    },
20732
20733    
20734    handleOnAvailable: function() {
20735        this.available = true;
20736        this.resetConstraints();
20737        this.onAvailable();
20738    },
20739
20740     
20741    setPadding: function(iTop, iRight, iBot, iLeft) {
20742        
20743        if (!iRight && 0 !== iRight) {
20744            this.padding = [iTop, iTop, iTop, iTop];
20745        } else if (!iBot && 0 !== iBot) {
20746            this.padding = [iTop, iRight, iTop, iRight];
20747        } else {
20748            this.padding = [iTop, iRight, iBot, iLeft];
20749        }
20750    },
20751
20752    
20753    setInitPosition: function(diffX, diffY) {
20754        var el = this.getEl();
20755
20756        if (!this.DDM.verifyEl(el)) {
20757            return;
20758        }
20759
20760        var dx = diffX || 0;
20761        var dy = diffY || 0;
20762
20763        var p = Dom.getXY( el );
20764
20765        this.initPageX = p[0] - dx;
20766        this.initPageY = p[1] - dy;
20767
20768        this.lastPageX = p[0];
20769        this.lastPageY = p[1];
20770
20771        this.setStartPosition(p);
20772    },
20773
20774    
20775    setStartPosition: function(pos) {
20776        var p = pos || Dom.getXY( this.getEl() );
20777        this.deltaSetXY = null;
20778
20779        this.startPageX = p[0];
20780        this.startPageY = p[1];
20781    },
20782
20783    
20784    addToGroup: function(sGroup) {
20785        this.groups[sGroup] = true;
20786        this.DDM.regDragDrop(this, sGroup);
20787    },
20788
20789    
20790    removeFromGroup: function(sGroup) {
20791        if (this.groups[sGroup]) {
20792            delete this.groups[sGroup];
20793        }
20794
20795        this.DDM.removeDDFromGroup(this, sGroup);
20796    },
20797
20798    
20799    setDragElId: function(id) {
20800        this.dragElId = id;
20801    },
20802
20803    
20804    setHandleElId: function(id) {
20805        if (typeof id !== "string") {
20806            id = Ext.id(id);
20807        }
20808        this.handleElId = id;
20809        this.DDM.regHandle(this.id, id);
20810    },
20811
20812    
20813    setOuterHandleElId: function(id) {
20814        if (typeof id !== "string") {
20815            id = Ext.id(id);
20816        }
20817        Event.on(id, "mousedown",
20818                this.handleMouseDown, this);
20819        this.setHandleElId(id);
20820
20821        this.hasOuterHandles = true;
20822    },
20823
20824    
20825    unreg: function() {
20826        Event.un(this.id, "mousedown",
20827                this.handleMouseDown);
20828        this._domRef = null;
20829        this.DDM._remove(this);
20830    },
20831
20832    destroy : function(){
20833        this.unreg();
20834    },
20835
20836    
20837    isLocked: function() {
20838        return (this.DDM.isLocked() || this.locked);
20839    },
20840
20841    
20842    handleMouseDown: function(e, oDD){
20843        if (this.primaryButtonOnly && e.button != 0) {
20844            return;
20845        }
20846
20847        if (this.isLocked()) {
20848            return;
20849        }
20850
20851        this.DDM.refreshCache(this.groups);
20852
20853        var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
20854        if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {
20855        } else {
20856            if (this.clickValidator(e)) {
20857
20858                
20859                this.setStartPosition();
20860
20861                this.b4MouseDown(e);
20862                this.onMouseDown(e);
20863
20864                this.DDM.handleMouseDown(e, this);
20865
20866                this.DDM.stopEvent(e);
20867            } else {
20868
20869
20870            }
20871        }
20872    },
20873
20874    clickValidator: function(e) {
20875        var target = e.getTarget();
20876        return ( this.isValidHandleChild(target) &&
20877                    (this.id == this.handleElId ||
20878                        this.DDM.handleWasClicked(target, this.id)) );
20879    },
20880
20881    
20882    addInvalidHandleType: function(tagName) {
20883        var type = tagName.toUpperCase();
20884        this.invalidHandleTypes[type] = type;
20885    },
20886
20887    
20888    addInvalidHandleId: function(id) {
20889        if (typeof id !== "string") {
20890            id = Ext.id(id);
20891        }
20892        this.invalidHandleIds[id] = id;
20893    },
20894
20895    
20896    addInvalidHandleClass: function(cssClass) {
20897        this.invalidHandleClasses.push(cssClass);
20898    },
20899
20900    
20901    removeInvalidHandleType: function(tagName) {
20902        var type = tagName.toUpperCase();
20903        
20904        delete this.invalidHandleTypes[type];
20905    },
20906
20907    
20908    removeInvalidHandleId: function(id) {
20909        if (typeof id !== "string") {
20910            id = Ext.id(id);
20911        }
20912        delete this.invalidHandleIds[id];
20913    },
20914
20915    
20916    removeInvalidHandleClass: function(cssClass) {
20917        for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
20918            if (this.invalidHandleClasses[i] == cssClass) {
20919                delete this.invalidHandleClasses[i];
20920            }
20921        }
20922    },
20923
20924    
20925    isValidHandleChild: function(node) {
20926
20927        var valid = true;
20928        
20929        var nodeName;
20930        try {
20931            nodeName = node.nodeName.toUpperCase();
20932        } catch(e) {
20933            nodeName = node.nodeName;
20934        }
20935        valid = valid && !this.invalidHandleTypes[nodeName];
20936        valid = valid && !this.invalidHandleIds[node.id];
20937
20938        for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
20939            valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
20940        }
20941
20942
20943        return valid;
20944
20945    },
20946
20947    
20948    setXTicks: function(iStartX, iTickSize) {
20949        this.xTicks = [];
20950        this.xTickSize = iTickSize;
20951
20952        var tickMap = {};
20953
20954        for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
20955            if (!tickMap[i]) {
20956                this.xTicks[this.xTicks.length] = i;
20957                tickMap[i] = true;
20958            }
20959        }
20960
20961        for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
20962            if (!tickMap[i]) {
20963                this.xTicks[this.xTicks.length] = i;
20964                tickMap[i] = true;
20965            }
20966        }
20967
20968        this.xTicks.sort(this.DDM.numericSort) ;
20969    },
20970
20971    
20972    setYTicks: function(iStartY, iTickSize) {
20973        this.yTicks = [];
20974        this.yTickSize = iTickSize;
20975
20976        var tickMap = {};
20977
20978        for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
20979            if (!tickMap[i]) {
20980                this.yTicks[this.yTicks.length] = i;
20981                tickMap[i] = true;
20982            }
20983        }
20984
20985        for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
20986            if (!tickMap[i]) {
20987                this.yTicks[this.yTicks.length] = i;
20988                tickMap[i] = true;
20989            }
20990        }
20991
20992        this.yTicks.sort(this.DDM.numericSort) ;
20993    },
20994
20995    
20996    setXConstraint: function(iLeft, iRight, iTickSize) {
20997        this.leftConstraint = iLeft;
20998        this.rightConstraint = iRight;
20999
21000        this.minX = this.initPageX - iLeft;
21001        this.maxX = this.initPageX + iRight;
21002        if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
21003
21004        this.constrainX = true;
21005    },
21006
21007    
21008    clearConstraints: function() {
21009        this.constrainX = false;
21010        this.constrainY = false;
21011        this.clearTicks();
21012    },
21013
21014    
21015    clearTicks: function() {
21016        this.xTicks = null;
21017        this.yTicks = null;
21018        this.xTickSize = 0;
21019        this.yTickSize = 0;
21020    },
21021
21022    
21023    setYConstraint: function(iUp, iDown, iTickSize) {
21024        this.topConstraint = iUp;
21025        this.bottomConstraint = iDown;
21026
21027        this.minY = this.initPageY - iUp;
21028        this.maxY = this.initPageY + iDown;
21029        if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
21030
21031        this.constrainY = true;
21032
21033    },
21034
21035    
21036    resetConstraints: function() {
21037        
21038        if (this.initPageX || this.initPageX === 0) {
21039            
21040            var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
21041            var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
21042
21043            this.setInitPosition(dx, dy);
21044
21045        
21046        } else {
21047            this.setInitPosition();
21048        }
21049
21050        if (this.constrainX) {
21051            this.setXConstraint( this.leftConstraint,
21052                                 this.rightConstraint,
21053                                 this.xTickSize        );
21054        }
21055
21056        if (this.constrainY) {
21057            this.setYConstraint( this.topConstraint,
21058                                 this.bottomConstraint,
21059                                 this.yTickSize         );
21060        }
21061    },
21062
21063    
21064    getTick: function(val, tickArray) {
21065        if (!tickArray) {
21066            
21067            
21068            return val;
21069        } else if (tickArray[0] >= val) {
21070            
21071            
21072            return tickArray[0];
21073        } else {
21074            for (var i=0, len=tickArray.length; i<len; ++i) {
21075                var next = i + 1;
21076                if (tickArray[next] && tickArray[next] >= val) {
21077                    var diff1 = val - tickArray[i];
21078                    var diff2 = tickArray[next] - val;
21079                    return (diff2 > diff1) ? tickArray[i] : tickArray[next];
21080                }
21081            }
21082
21083            
21084            
21085            return tickArray[tickArray.length - 1];
21086        }
21087    },
21088
21089    
21090    toString: function() {
21091        return ("DragDrop " + this.id);
21092    }
21093
21094};
21095
21096}
21096)();
21097
21098
21099
21100
21101if (!Ext.dd.DragDropMgr) {
21102
21103
21104Ext.dd.DragDropMgr = function() {
21105
21106    var Event = Ext.EventManager;
21107
21108    return {
21109
21110        
21111        ids: {},
21112
21113        
21114        handleIds: {},
21115
21116        
21117        dragCurrent: null,
21118
21119        
21120        dragOvers: {},
21121
21122        
21123        deltaX: 0,
21124
21125        
21126        deltaY: 0,
21127
21128        
21129        preventDefault: true,
21130
21131        
21132        stopPropagation: true,
21133
21134        
21135        initialized: false,
21136
21137        
21138        locked: false,
21139
21140        
21141        init: function() {
21142            this.initialized = true;
21143        },
21144
21145        
21146        POINT: 0,
21147
21148        
21149        INTERSECT: 1,
21150
21151        
21152        mode: 0,
21153
21154        
21155        _execOnAll: function(sMethod, args) {
21156            for (var i in this.ids) {
21157                for (var j in this.ids[i]) {
21158                    var oDD = this.ids[i][j];
21159                    if (! this.isTypeOfDD(oDD)) {
21160                        continue;
21161                    }
21162                    oDD[sMethod].apply(oDD, args);
21163                }
21164            }
21165        },
21166
21167        
21168        _onLoad: function() {
21169
21170            this.init();
21171
21172
21173            Event.on(document, "mouseup",   this.handleMouseUp, this, true);
21174            Event.on(document, "mousemove", this.handleMouseMove, this, true);
21175            Event.on(window,   "unload",    this._onUnload, this, true);
21176            Event.on(window,   "resize",    this._onResize, this, true);
21177            
21178
21179        },
21180
21181        
21182        _onResize: function(e) {
21183            this._execOnAll("resetConstraints", []);
21184        },
21185
21186        
21187        lock: function() { this.locked = true; },
21188
21189        
21190        unlock: function() { this.locked = false; },
21191
21192        
21193        isLocked: function() { return this.locked; },
21194
21195        
21196        locationCache: {},
21197
21198        
21199        useCache: true,
21200
21201        
21202        clickPixelThresh: 3,
21203
21204        
21205        clickTimeThresh: 350,
21206
21207        
21208        dragThreshMet: false,
21209
21210        
21211        clickTimeout: null,
21212
21213        
21214        startX: 0,
21215
21216        
21217        startY: 0,
21218
21219        
21220        regDragDrop: function(oDD, sGroup) {
21221            if (!this.initialized) { this.init(); }
21222
21223            if (!this.ids[sGroup]) {
21224                this.ids[sGroup] = {};
21225            }
21226            this.ids[sGroup][oDD.id] = oDD;
21227        },
21228
21229        
21230        removeDDFromGroup: function(oDD, sGroup) {
21231            if (!this.ids[sGroup]) {
21232                this.ids[sGroup] = {};
21233            }
21234
21235            var obj = this.ids[sGroup];
21236            if (obj && obj[oDD.id]) {
21237                delete obj[oDD.id];
21238            }
21239        },
21240
21241        
21242        _remove: function(oDD) {
21243            for (var g in oDD.groups) {
21244                if (g && this.ids[g] && this.ids[g][oDD.id]) {
21245                    delete this.ids[g][oDD.id];
21246                }
21247            }
21248            delete this.handleIds[oDD.id];
21249        },
21250
21251        
21252        regHandle: function(sDDId, sHandleId) {
21253            if (!this.handleIds[sDDId]) {
21254                this.handleIds[sDDId] = {};
21255            }
21256            this.handleIds[sDDId][sHandleId] = sHandleId;
21257        },
21258
21259        
21260        isDragDrop: function(id) {
21261            return ( this.getDDById(id) ) ? true : false;
21262        },
21263
21264        
21265        getRelated: function(p_oDD, bTargetsOnly) {
21266            var oDDs = [];
21267            for (var i in p_oDD.groups) {
21268                for (var j in this.ids[i]) {
21269                    var dd = this.ids[i][j];
21270                    if (! this.isTypeOfDD(dd)) {
21271                        continue;
21272                    }
21273                    if (!bTargetsOnly || dd.isTarget) {
21274                        oDDs[oDDs.length] = dd;
21275                    }
21276                }
21277            }
21278
21279            return oDDs;
21280        },
21281
21282        
21283        isLegalTarget: function (oDD, oTargetDD) {
21284            var targets = this.getRelated(oDD, true);
21285            for (var i=0, len=targets.length;i<len;++i) {
21286                if (targets[i].id == oTargetDD.id) {
21287                    return true;
21288                }
21289            }
21290
21291            return false;
21292        },
21293
21294        
21295        isTypeOfDD: function (oDD) {
21296            return (oDD && oDD.__ygDragDrop);
21297        },
21298
21299        
21300        isHandle: function(sDDId, sHandleId) {
21301            return ( this.handleIds[sDDId] &&
21302                            this.handleIds[sDDId][sHandleId] );
21303        },
21304
21305        
21306        getDDById: function(id) {
21307            for (var i in this.ids) {
21308                if (this.ids[i][id]) {
21309                    return this.ids[i][id];
21310                }
21311            }
21312            return null;
21313        },
21314
21315        
21316        handleMouseDown: function(e, oDD) {
21317            if(Ext.QuickTips){
21318                Ext.QuickTips.ddDisable();
21319            }
21320            if(this.dragCurrent){
21321                
21322                
21323                this.handleMouseUp(e);
21324            }
21325            
21326            this.currentTarget = e.getTarget();
21327            this.dragCurrent = oDD;
21328
21329            var el = oDD.getEl();
21330
21331            
21332            this.startX = e.getPageX();
21333            this.startY = e.getPageY();
21334
21335            this.deltaX = this.startX - el.offsetLeft;
21336            this.deltaY = this.startY - el.offsetTop;
21337
21338            this.dragThreshMet = false;
21339
21340            this.clickTimeout = setTimeout(
21341                    function() {
21342                        var DDM = Ext.dd.DDM;
21343                        DDM.startDrag(DDM.startX, DDM.startY);
21344                    },
21345                    this.clickTimeThresh );
21346        },
21347
21348        
21349        startDrag: function(x, y) {
21350            clearTimeout(this.clickTimeout);
21351            if (this.dragCurrent) {
21352                this.dragCurrent.b4StartDrag(x, y);
21353                this.dragCurrent.startDrag(x, y);
21354            }
21355            this.dragThreshMet = true;
21356        },
21357
21358        
21359        handleMouseUp: function(e) {
21360
21361            if(Ext.QuickTips){
21362                Ext.QuickTips.ddEnable();
21363            }
21364            if (! this.dragCurrent) {
21365                return;
21366            }
21367
21368            clearTimeout(this.clickTimeout);
21369
21370            if (this.dragThreshMet) {
21371                this.fireEvents(e, true);
21372            } else {
21373            }
21374
21375            this.stopDrag(e);
21376
21377            this.stopEvent(e);
21378        },
21379
21380        
21381        stopEvent: function(e){
21382            if(this.stopPropagation) {
21383                e.stopPropagation();
21384            }
21385
21386            if (this.preventDefault) {
21387                e.preventDefault();
21388            }
21389        },
21390
21391        
21392        stopDrag: function(e) {
21393            
21394            if (this.dragCurrent) {
21395                if (this.dragThreshMet) {
21396                    this.dragCurrent.b4EndDrag(e);
21397                    this.dragCurrent.endDrag(e);
21398                }
21399
21400                this.dragCurrent.onMouseUp(e);
21401            }
21402
21403            this.dragCurrent = null;
21404            this.dragOvers = {};
21405        },
21406
21407        
21408        handleMouseMove: function(e) {
21409            if (! this.dragCurrent) {
21410                return true;
21411            }
21412            
21413
21414            
21415            if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
21416                this.stopEvent(e);
21417                return this.handleMouseUp(e);
21418            }
21419
21420            if (!this.dragThreshMet) {
21421                var diffX = Math.abs(this.startX - e.getPageX());
21422                var diffY = Math.abs(this.startY - e.getPageY());
21423                if (diffX > this.clickPixelThresh ||
21424                            diffY > this.clickPixelThresh) {
21425                    this.startDrag(this.startX, this.startY);
21426                }
21427            }
21428
21429            if (this.dragThreshMet) {
21430                this.dragCurrent.b4Drag(e);
21431                this.dragCurrent.onDrag(e);
21432                if(!this.dragCurrent.moveOnly){
21433                    this.fireEvents(e, false);
21434                }
21435            }
21436
21437            this.stopEvent(e);
21438
21439            return true;
21440        },
21441
21442        
21443        fireEvents: function(e, isDrop) {
21444            var dc = this.dragCurrent;
21445
21446            
21447            
21448            if (!dc || dc.isLocked()) {
21449                return;
21450            }
21451
21452            var pt = e.getPoint();
21453
21454            
21455            var oldOvers = [];
21456
21457            var outEvts   = [];
21458            var overEvts  = [];
21459            var dropEvts  = [];
21460            var enterEvts = [];
21461
21462            
21463            
21464            for (var i in this.dragOvers) {
21465
21466                var ddo = this.dragOvers[i];
21467
21468                if (! this.isTypeOfDD(ddo)) {
21469                    continue;
21470                }
21471
21472                if (! this.isOverTarget(pt, ddo, this.mode)) {
21473                    outEvts.push( ddo );
21474                }
21475
21476                oldOvers[i] = true;
21477                delete this.dragOvers[i];
21478            }
21479
21480            for (var sGroup in dc.groups) {
21481
21482                if ("string" != typeof sGroup) {
21483                    continue;
21484                }
21485
21486                for (i in this.ids[sGroup]) {
21487                    var oDD = this.ids[sGroup][i];
21488                    if (! this.isTypeOfDD(oDD)) {
21489                        continue;
21490                    }
21491
21492                    if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
21493                        if (this.isOverTarget(pt, oDD, this.mode)) {
21494                            
21495                            if (isDrop) {
21496                                dropEvts.push( oDD );
21497                            
21498                            } else {
21499
21500                                
21501                                if (!oldOvers[oDD.id]) {
21502                                    enterEvts.push( oDD );
21503                                
21504                                } else {
21505                                    overEvts.push( oDD );
21506                                }
21507
21508                                this.dragOvers[oDD.id] = oDD;
21509                            }
21510                        }
21511                    }
21512                }
21513            }
21514
21515            if (this.mode) {
21516                if (outEvts.length) {
21517                    dc.b4DragOut(e, outEvts);
21518                    dc.onDragOut(e, outEvts);
21519                }
21520
21521                if (enterEvts.length) {
21522                    dc.onDragEnter(e, enterEvts);
21523                }
21524
21525                if (overEvts.length) {
21526                    dc.b4DragOver(e, overEvts);
21527                    dc.onDragOver(e, overEvts);
21528                }
21529
21530                if (dropEvts.length) {
21531                    dc.b4DragDrop(e, dropEvts);
21532                    dc.onDragDrop(e, dropEvts);
21533                }
21534
21535            } else {
21536                
21537                var len = 0;
21538                for (i=0, len=outEvts.length; i<len; ++i) {
21539                    dc.b4DragOut(e, outEvts[i].id);
21540                    dc.onDragOut(e, outEvts[i].id);
21541                }
21542
21543                
21544                for (i=0,len=enterEvts.length; i<len; ++i) {
21545                    
21546                    dc.onDragEnter(e, enterEvts[i].id);
21547                }
21548
21549                
21550                for (i=0,len=overEvts.length; i<len; ++i) {
21551                    dc.b4DragOver(e, overEvts[i].id);
21552                    dc.onDragOver(e, overEvts[i].id);
21553                }
21554
21555                
21556                for (i=0, len=dropEvts.length; i<len; ++i) {
21557                    dc.b4DragDrop(e, dropEvts[i].id);
21558                    dc.onDragDrop(e, dropEvts[i].id);
21559                }
21560
21561            }
21562
21563            
21564            if (isDrop && !dropEvts.length) {
21565                dc.onInvalidDrop(e);
21566            }
21567
21568        },
21569
21570        
21571        getBestMatch: function(dds) {
21572            var winner = null;
21573            
21574            
21575               
21576            
21577            
21578
21579            var len = dds.length;
21580
21581            if (len == 1) {
21582                winner = dds[0];
21583            } else {
21584                
21585                for (var i=0; i<len; ++i) {
21586                    var dd = dds[i];
21587                    
21588                    
21589                    
21590                    if (dd.cursorIsOver) {
21591                        winner = dd;
21592                        break;
21593                    
21594                    } else {
21595                        if (!winner ||
21596                            winner.overlap.getArea() < dd.overlap.getArea()) {
21597                            winner = dd;
21598                        }
21599                    }
21600                }
21601            }
21602
21603            return winner;
21604        },
21605
21606        
21607        refreshCache: function(groups) {
21608            for (var sGroup in groups) {
21609                if ("string" != typeof sGroup) {
21610                    continue;
21611                }
21612                for (var i in this.ids[sGroup]) {
21613                    var oDD = this.ids[sGroup][i];
21614
21615                    if (this.isTypeOfDD(oDD)) {
21616                    
21617                        var loc = this.getLocation(oDD);
21618                        if (loc) {
21619                            this.locationCache[oDD.id] = loc;
21620                        } else {
21621                            delete this.locationCache[oDD.id];
21622                            
21623                            
21624                            
21625                        }
21626                    }
21627                }
21628            }
21629        },
21630
21631        
21632        verifyEl: function(el) {
21633            if (el) {
21634                var parent;
21635                if(Ext.isIE){
21636                    try{
21637                        parent = el.offsetParent;
21638                    }catch(e){}
21639                }else{
21640                    parent = el.offsetParent;
21641                }
21642                if (parent) {
21643                    return true;
21644                }
21645            }
21646
21647            return false;
21648        },
21649
21650        
21651        getLocation: function(oDD) {
21652            if (! this.isTypeOfDD(oDD)) {
21653                return null;
21654            }
21655
21656            var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l, region;
21657
21658            try {
21659                pos= Ext.lib.Dom.getXY(el);
21660            } catch (e) { }
21661
21662            if (!pos) {
21663                return null;
21664            }
21665
21666            x1 = pos[0];
21667            x2 = x1 + el.offsetWidth;
21668            y1 = pos[1];
21669            y2 = y1 + el.offsetHeight;
21670
21671            t = y1 - oDD.padding[0];
21672            r = x2 + oDD.padding[1];
21673            b = y2 + oDD.padding[2];
21674            l = x1 - oDD.padding[3];
21675
21676            region = new Ext.lib.Region( t, r, b, l );
21677            
21678            el = Ext.get(el.parentNode);
21679            while (el && region) {
21680	            if (el.isScrollable()) {
21681	                
21682	                region = region.intersect(el.getRegion());
21683	            }
21684	            el = el.parent();
21685            }
21686            return region;
21687        },
21688
21689        
21690        isOverTarget: function(pt, oTarget, intersect) {
21691            
21692            var loc = this.locationCache[oTarget.id];
21693            if (!loc || !this.useCache) {
21694                loc = this.getLocation(oTarget);
21695                this.locationCache[oTarget.id] = loc;
21696
21697            }
21698
21699            if (!loc) {
21700                return false;
21701            }
21702
21703            oTarget.cursorIsOver = loc.contains( pt );
21704
21705            
21706            
21707            
21708            
21709            
21710            var dc = this.dragCurrent;
21711            if (!dc || !dc.getTargetCoord ||
21712                    (!intersect && !dc.constrainX && !dc.constrainY)) {
21713                return oTarget.cursorIsOver;
21714            }
21715
21716            oTarget.overlap = null;
21717
21718            
21719            
21720            
21721            
21722            var pos = dc.getTargetCoord(pt.x, pt.y);
21723
21724            var el = dc.getDragEl();
21725            var curRegion = new Ext.lib.Region( pos.y,
21726                                                   pos.x + el.offsetWidth,
21727                                                   pos.y + el.offsetHeight,
21728                                                   pos.x );
21729
21730            var overlap = curRegion.intersect(loc);
21731
21732            if (overlap) {
21733                oTarget.overlap = overlap;
21734                return (intersect) ? true : oTarget.cursorIsOver;
21735            } else {
21736                return false;
21737            }
21738        },
21739
21740        
21741        _onUnload: function(e, me) {
21742            Event.removeListener(document, "mouseup",   this.handleMouseUp, this);
21743            Event.removeListener(document, "mousemove", this.handleMouseMove, this);
21744            Event.removeListener(window,   "resize",    this._onResize, this);
21745            Ext.dd.DragDropMgr.unregAll();
21746        },
21747
21748        
21749        unregAll: function() {
21750
21751            if (this.dragCurrent) {
21752                this.stopDrag();
21753                this.dragCurrent = null;
21754            }
21755
21756            this._execOnAll("unreg", []);
21757
21758            for (var i in this.elementCache) {
21759                delete this.elementCache[i];
21760            }
21761
21762            this.elementCache = {};
21763            this.ids = {};
21764        },
21765
21766        
21767        elementCache: {},
21768
21769        
21770        getElWrapper: function(id) {
21771            var oWrapper = this.elementCache[id];
21772            if (!oWrapper || !oWrapper.el) {
21773                oWrapper = this.elementCache[id] =
21774                    new this.ElementWrapper(Ext.getDom(id));
21775            }
21776            return oWrapper;
21777        },
21778
21779        
21780        getElement: function(id) {
21781            return Ext.getDom(id);
21782        },
21783
21784        
21785        getCss: function(id) {
21786            var el = Ext.getDom(id);
21787            return (el) ? el.style : null;
21788        },
21789
21790        
21791        ElementWrapper: function(el) {
21792                
21793                this.el = el || null;
21794                
21795                this.id = this.el && el.id;
21796                
21797                this.css = this.el && el.style;
21798            },
21799
21800        
21801        getPosX: function(el) {
21802            return Ext.lib.Dom.getX(el);
21803        },
21804
21805        
21806        getPosY: function(el) {
21807            return Ext.lib.Dom.getY(el);
21808        },
21809
21810        
21811        swapNode: function(n1, n2) {
21812            if (n1.swapNode) {
21813                n1.swapNode(n2);
21814            } else {
21815                var p = n2.parentNode;
21816                var s = n2.nextSibling;
21817
21818                if (s == n1) {
21819                    p.insertBefore(n1, n2);
21820                } else if (n2 == n1.nextSibling) {
21821                    p.insertBefore(n2, n1);
21822                } else {
21823                    n1.parentNode.replaceChild(n2, n1);
21824                    p.insertBefore(n1, s);
21825                }
21826            }
21827        },
21828
21829        
21830        getScroll: function () {
21831            var t, l, dde=document.documentElement, db=document.body;
21832            if (dde && (dde.scrollTop || dde.scrollLeft)) {
21833                t = dde.scrollTop;
21834                l = dde.scrollLeft;
21835            } else if (db) {
21836                t = db.scrollTop;
21837                l = db.scrollLeft;
21838            } else {
21839
21840            }
21841            return { top: t, left: l };
21842        },
21843
21844        
21845        getStyle: function(el, styleProp) {
21846            return Ext.fly(el).getStyle(styleProp);
21847        },
21848
21849        
21850        getScrollTop: function () {
21851            return this.getScroll().top;
21852        },
21853
21854        
21855        getScrollLeft: function () {
21856            return this.getScroll().left;
21857        },
21858
21859        
21860        moveToEl: function (moveEl, targetEl) {
21861            var aCoord = Ext.lib.Dom.getXY(targetEl);
21862            Ext.lib.Dom.setXY(moveEl, aCoord);
21863        },
21864
21865        
21866        numericSort: function(a, b) {
21867            return (a - b);
21868        },
21869
21870        
21871        _timeoutCount: 0,
21872
21873        
21874        _addListeners: function() {
21875            var DDM = Ext.dd.DDM;
21876            if ( Ext.lib.Event && document ) {
21877                DDM._onLoad();
21878            } else {
21879                if (DDM._timeoutCount > 2000) {
21880                } else {
21881                    setTimeout(DDM._addListeners, 10);
21882                    if (document && document.body) {
21883                        DDM._timeoutCount += 1;
21884                    }
21885                }
21886            }
21887        },
21888
21889        
21890        handleWasClicked: function(node, id) {
21891            if (this.isHandle(id, node.id)) {
21892                return true;
21893            } else {
21894                
21895                var p = node.parentNode;
21896
21897                while (p) {
21898                    if (this.isHandle(id, p.id)) {
21899                        return true;
21900                    } else {
21901                        p = p.parentNode;
21902                    }
21903                }
21904            }
21905
21906            return false;
21907        }
21908
21909    };
21910
21911}();
21912
21913
21914Ext.dd.DDM = Ext.dd.DragDropMgr;
21915Ext.dd.DDM._addListeners();
21916
21917}
21918
21919
21920Ext.dd.DD = function(id, sGroup, config) {
21921    if (id) {
21922        this.init(id, sGroup, config);
21923    }
21924};
21925
21926Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
21927
21928    
21929    scroll: true,
21930
21931    
21932    autoOffset: function(iPageX, iPageY) {
21933        var x = iPageX - this.startPageX;
21934        var y = iPageY - this.startPageY;
21935        this.setDelta(x, y);
21936    },
21937
21938    
21939    setDelta: function(iDeltaX, iDeltaY) {
21940        this.deltaX = iDeltaX;
21941        this.deltaY = iDeltaY;
21942    },
21943
21944    
21945    setDragElPos: function(iPageX, iPageY) {
21946        
21947        
21948
21949        var el = this.getDragEl();
21950        this.alignElWithMouse(el, iPageX, iPageY);
21951    },
21952
21953    
21954    alignElWithMouse: function(el, iPageX, iPageY) {
21955        var oCoord = this.getTargetCoord(iPageX, iPageY);
21956        var fly = el.dom ? el : Ext.fly(el, '_dd');
21957        if (!this.deltaSetXY) {
21958            var aCoord = [oCoord.x, oCoord.y];
21959            fly.setXY(aCoord);
21960            var newLeft = fly.getLeft(true);
21961            var newTop  = fly.getTop(true);
21962            this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
21963        } else {
21964            fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
21965        }
21966
21967        this.cachePosition(oCoord.x, oCoord.y);
21968        this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
21969        return oCoord;
21970    },
21971
21972    
21973    cachePosition: function(iPageX, iPageY) {
21974        if (iPageX) {
21975            this.lastPageX = iPageX;
21976            this.lastPageY = iPageY;
21977        } else {
21978            var aCoord = Ext.lib.Dom.getXY(this.getEl());
21979            this.lastPageX = aCoord[0];
21980            this.lastPageY = aCoord[1];
21981        }
21982    },
21983
21984    
21985    autoScroll: function(x, y, h, w) {
21986
21987        if (this.scroll) {
21988            
21989            var clientH = Ext.lib.Dom.getViewHeight();
21990
21991            
21992            var clientW = Ext.lib.Dom.getViewWidth();
21993
21994            
21995            var st = this.DDM.getScrollTop();
21996
21997            
21998            var sl = this.DDM.getScrollLeft();
21999
22000            
22001            var bot = h + y;
22002
22003            
22004            var right = w + x;
22005
22006            
22007            
22008            
22009            var toBot = (clientH + st - y - this.deltaY);
22010
22011            
22012            var toRight = (clientW + sl - x - this.deltaX);
22013
22014
22015            
22016            
22017            var thresh = 40;
22018
22019            
22020            
22021            
22022            var scrAmt = (document.all) ? 80 : 30;
22023
22024            
22025            
22026            if ( bot > clientH && toBot < thresh ) {
22027                window.scrollTo(sl, st + scrAmt);
22028            }
22029
22030            
22031            
22032            if ( y < st && st > 0 && y - st < thresh ) {
22033                window.scrollTo(sl, st - scrAmt);
22034            }
22035
22036            
22037            
22038            if ( right > clientW && toRight < thresh ) {
22039                window.scrollTo(sl + scrAmt, st);
22040            }
22041
22042            
22043            
22044            if ( x < sl && sl > 0 && x - sl < thresh ) {
22045                window.scrollTo(sl - scrAmt, st);
22046            }
22047        }
22048    },
22049
22050    
22051    getTargetCoord: function(iPageX, iPageY) {
22052        var x = iPageX - this.deltaX;
22053        var y = iPageY - this.deltaY;
22054
22055        if (this.constrainX) {
22056            if (x < this.minX) { x = this.minX; }
22057            if (x > this.maxX) { x = this.maxX; }
22058        }
22059
22060        if (this.constrainY) {
22061            if (y < this.minY) { y = this.minY; }
22062            if (y > this.maxY) { y = this.maxY; }
22063        }
22064
22065        x = this.getTick(x, this.xTicks);
22066        y = this.getTick(y, this.yTicks);
22067
22068
22069        return {x:x, y:y};
22070    },
22071
22072    
22073    applyConfig: function() {
22074        Ext.dd.DD.superclass.applyConfig.call(this);
22075        this.scroll = (this.config.scroll !== false);
22076    },
22077
22078    
22079    b4MouseDown: function(e) {
22080        
22081        this.autoOffset(e.getPageX(),
22082                            e.getPageY());
22083    },
22084
22085    
22086    b4Drag: function(e) {
22087        this.setDragElPos(e.getPageX(),
22088                            e.getPageY());
22089    },
22090
22091    toString: function() {
22092        return ("DD " + this.id);
22093    }
22094
22095    
22096    
22097    
22098    
22099
22100});
22101
22102Ext.dd.DDProxy = function(id, sGroup, config) {
22103    if (id) {
22104        this.init(id, sGroup, config);
22105        this.initFrame();
22106    }
22107};
22108
22109
22110Ext.dd.DDProxy.dragElId = "ygddfdiv";
22111
22112Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
22113
22114    
22115    resizeFrame: true,
22116
22117    
22118    centerFrame: false,
22119
22120    
22121    createFrame: function() {
22122        var self = this;
22123        var body = document.body;
22124
22125        if (!body || !body.firstChild) {
22126            setTimeout( function() { self.createFrame(); }, 50 );
22127            return;
22128        }
22129
22130        var div = this.getDragEl();
22131
22132        if (!div) {
22133            div    = document.createElement("div");
22134            div.id = this.dragElId;
22135            var s  = div.style;
22136
22137            s.position   = "absolute";
22138            s.visibility = "hidden";
22139            s.cursor     = "move";
22140            s.border     = "2px solid #aaa";
22141            s.zIndex     = 999;
22142
22143            
22144            
22145            
22146            body.insertBefore(div, body.firstChild);
22147        }
22148    },
22149
22150    
22151    initFrame: function() {
22152        this.createFrame();
22153    },
22154
22155    applyConfig: function() {
22156        Ext.dd.DDProxy.superclass.applyConfig.call(this);
22157
22158        this.resizeFrame = (this.config.resizeFrame !== false);
22159        this.centerFrame = (this.config.centerFrame);
22160        this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
22161    },
22162
22163    
22164    showFrame: function(iPageX, iPageY) {
22165        var el = this.getEl();
22166        var dragEl = this.getDragEl();
22167        var s = dragEl.style;
22168
22169        this._resizeProxy();
22170
22171        if (this.centerFrame) {
22172            this.setDelta( Math.round(parseInt(s.width,  10)/2),
22173                           Math.round(parseInt(s.height, 10)/2) );
22174        }
22175
22176        this.setDragElPos(iPageX, iPageY);
22177
22178        Ext.fly(dragEl).show();
22179    },
22180
22181    
22182    _resizeProxy: function() {
22183        if (this.resizeFrame) {
22184            var el = this.getEl();
22185            Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
22186        }
22187    },
22188
22189    
22190    b4MouseDown: function(e) {
22191        var x = e.getPageX();
22192        var y = e.getPageY();
22193        this.autoOffset(x, y);
22194        this.setDragElPos(x, y);
22195    },
22196
22197    
22198    b4StartDrag: function(x, y) {
22199        
22200        this.showFrame(x, y);
22201    },
22202
22203    
22204    b4EndDrag: function(e) {
22205        Ext.fly(this.getDragEl()).hide();
22206    },
22207
22208    
22209    
22210    
22211    endDrag: function(e) {
22212
22213        var lel = this.getEl();
22214        var del = this.getDragEl();
22215
22216        
22217        del.style.visibility = "";
22218
22219        this.beforeMove();
22220        
22221        
22222        lel.style.visibility = "hidden";
22223        Ext.dd.DDM.moveToEl(lel, del);
22224        del.style.visibility = "hidden";
22225        lel.style.visibility = "";
22226
22227        this.afterDrag();
22228    },
22229
22230    beforeMove : function(){
22231
22232    },
22233
22234    afterDrag : function(){
22235
22236    },
22237
22238    toString: function() {
22239        return ("DDProxy " + this.id);
22240    }
22241
22242});
22243
22244Ext.dd.DDTarget = function(id, sGroup, config) {
22245    if (id) {
22246        this.initTarget(id, sGroup, config);
22247    }
22248};
22249
22250
22251Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
22252    
22253    getDragEl: Ext.emptyFn,
22254    
22255    isValidHandleChild: Ext.emptyFn,
22256    
22257    startDrag: Ext.emptyFn,
22258    
22259    endDrag: Ext.emptyFn,
22260    
22261    onDrag: Ext.emptyFn,
22262    
22263    onDragDrop: Ext.emptyFn,
22264    
22265    onDragEnter: Ext.emptyFn,
22266    
22267    onDragOut: Ext.emptyFn,
22268    
22269    onDragOver: Ext.emptyFn,
22270    
22271    onInvalidDrop: Ext.emptyFn,
22272    
22273    onMouseDown: Ext.emptyFn,
22274    
22275    onMouseUp: Ext.emptyFn,
22276    
22277    setXConstraint: Ext.emptyFn,
22278    
22279    setYConstraint: Ext.emptyFn,
22280    
22281    resetConstraints: Ext.emptyFn,
22282    
22283    clearConstraints: Ext.emptyFn,
22284    
22285    clearTicks: Ext.emptyFn,
22286    
22287    setInitPosition: Ext.emptyFn,
22288    
22289    setDragElId: Ext.emptyFn,
22290    
22291    setHandleElId: Ext.emptyFn,
22292    
22293    setOuterHandleElId: Ext.emptyFn,
22294    
22295    addInvalidHandleClass: Ext.emptyFn,
22296    
22297    addInvalidHandleId: Ext.emptyFn,
22298    
22299    addInvalidHandleType: Ext.emptyFn,
22300    
22301    removeInvalidHandleClass: Ext.emptyFn,
22302    
22303    removeInvalidHandleId: Ext.emptyFn,
22304    
22305    removeInvalidHandleType: Ext.emptyFn,
22306
22307    toString: function() {
22308        return ("DDTarget " + this.id);
22309    }
22310});
22311Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {    
22312    	
22313    active: false,
22314    	
22315    tolerance: 5,
22316    	
22317    autoStart: false,
22318    
22319    constructor : function(config){
22320        Ext.apply(this, config);
22321	    this.addEvents(
22322	        
22323	        'mousedown',
22324	        
22325	        'mouseup',
22326	        
22327	        'mousemove',
22328	        
22329	        'dragstart',
22330	        
22331	        'dragend',
22332	        
22333	        'drag'
22334	    );
22335	
22336	    this.dragRegion = new Ext.lib.Region(0,0,0,0);
22337	
22338	    if(this.el){
22339	        this.initEl(this.el);
22340	    }
22341        Ext.dd.DragTracker.superclass.constructor.call(this, config);
22342    },
22343
22344    initEl: function(el){
22345        this.el = Ext.get(el);
22346        el.on('mousedown', this.onMouseDown, this,
22347                this.delegate ? {delegate: this.delegate} : undefined);
22348    },
22349
22350    destroy : function(){
22351        this.el.un('mousedown', this.onMouseDown, this);
22352        delete this.el;
22353    },
22354
22355    onMouseDown: function(e, target){
22356        if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
22357            this.startXY = this.lastXY = e.getXY();
22358            this.dragTarget = this.delegate ? target : this.el.dom;
22359            if(this.preventDefault !== false){
22360                e.preventDefault();
22361            }
22362            Ext.getDoc().on({
22363                scope: this,
22364                mouseup: this.onMouseUp,
22365                mousemove: this.onMouseMove,
22366                selectstart: this.stopSelect
22367            });
22368            if(this.autoStart){
22369                this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
22370            }
22371        }
22372    },
22373
22374    onMouseMove: function(e, target){
22375        
22376        if(this.active && Ext.isIE && !e.browserEvent.button){
22377            e.preventDefault();
22378            this.onMouseUp(e);
22379            return;
22380        }
22381
22382        e.preventDefault();
22383        var xy = e.getXY(), s = this.startXY;
22384        this.lastXY = xy;
22385        if(!this.active){
22386            if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
22387                this.triggerStart(e);
22388            }else{
22389                return;
22390            }
22391        }
22392        this.fireEvent('mousemove', this, e);
22393        this.onDrag(e);
22394        this.fireEvent('drag', this, e);
22395    },
22396
22397    onMouseUp: function(e) {
22398        var doc = Ext.getDoc(),
22399            wasActive = this.active;
22400            
22401        doc.un('mousemove', this.onMouseMove, this);
22402        doc.un('mouseup', this.onMouseUp, this);
22403        doc.un('selectstart', this.stopSelect, this);
22404        e.preventDefault();
22405        this.clearStart();
22406        this.active = false;
22407        delete this.elRegion;
22408        this.fireEvent('mouseup', this, e);
22409        if(wasActive){
22410            this.onEnd(e);
22411            this.fireEvent('dragend', this, e);
22412        }
22413    },
22414
22415    triggerStart: function(e) {
22416        this.clearStart();
22417        this.active = true;
22418        this.onStart(e);
22419        this.fireEvent('dragstart', this, e);
22420    },
22421
22422    clearStart : function() {
22423        if(this.timer){
22424            clearTimeout(this.timer);
22425            delete this.timer;
22426        }
22427    },
22428
22429    stopSelect : function(e) {
22430        e.stopEvent();
22431        return false;
22432    },
22433    
22434    
22435    onBeforeStart : function(e) {
22436
22437    },
22438
22439    
22440    onStart : function(xy) {
22441
22442    },
22443
22444    
22445    onDrag : function(e) {
22446
22447    },
22448
22449    
22450    onEnd : function(e) {
22451
22452    },
22453
22454    
22455    getDragTarget : function(){
22456        return this.dragTarget;
22457    },
22458
22459    getDragCt : function(){
22460        return this.el;
22461    },
22462
22463    getXY : function(constrain){
22464        return constrain ?
22465               this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
22466    },
22467
22468    getOffset : function(constrain){
22469        var xy = this.getXY(constrain),
22470            s = this.startXY;
22471        return [s[0]-xy[0], s[1]-xy[1]];
22472    },
22473
22474    constrainModes: {
22475        'point' : function(xy){
22476
22477            if(!this.elRegion){
22478                this.elRegion = this.getDragCt().getRegion();
22479            }
22480
22481            var dr = this.dragRegion;
22482
22483            dr.left = xy[0];
22484            dr.top = xy[1];
22485            dr.right = xy[0];
22486            dr.bottom = xy[1];
22487
22488            dr.constrainTo(this.elRegion);
22489
22490            return [dr.left, dr.top];
22491        }
22492    }
22493});
22494Ext.dd.ScrollManager = function(){
22495    var ddm = Ext.dd.DragDropMgr;
22496    var els = {};
22497    var dragEl = null;
22498    var proc = {};
22499    
22500    var onStop = function(e){
22501        dragEl = null;
22502        clearProc();
22503    };
22504    
22505    var triggerRefresh = function(){
22506        if(ddm.dragCurrent){
22507             ddm.refreshCache(ddm.dragCurrent.groups);
22508        }
22509    };
22510    
22511    var doScroll = function(){
22512        if(ddm.dragCurrent){
22513            var dds = Ext.dd.ScrollManager;
22514            var inc = proc.el.ddScrollConfig ?
22515                      proc.el.ddScrollConfig.increment : dds.increment;
22516            if(!dds.animate){
22517                if(proc.el.scroll(proc.dir, inc)){
22518                    triggerRefresh();
22519                }
22520            }else{
22521                proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
22522            }
22523        }
22524    };
22525    
22526    var clearProc = function(){
22527        if(proc.id){
22528            clearInterval(proc.id);
22529        }
22530        proc.id = 0;
22531        proc.el = null;
22532        proc.dir = "";
22533    };
22534
22535    var startProc = function(el, dir){
22536        clearProc();
22537        proc.el = el;
22538        proc.dir = dir;
22539        var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
22540            freq  = (el.ddScrollConfig && el.ddScrollConfig.frequency)
22541                  ? el.ddScrollConfig.frequency
22542                  : Ext.dd.ScrollManager.frequency;
22543
22544        if (group === undefined || ddm.dragCurrent.ddGroup == group) {
22545            proc.id = setInterval(doScroll, freq);
22546        }
22547    };
22548    
22549    var onFire = function(e, isDrop){
22550        if(isDrop || !ddm.dragCurrent){ return; }
22551        var dds = Ext.dd.ScrollManager;
22552        if(!dragEl || dragEl != ddm.dragCurrent){
22553            dragEl = ddm.dragCurrent;
22554            
22555            dds.refreshCache();
22556        }
22557        
22558        var xy = Ext.lib.Event.getXY(e);
22559        var pt = new Ext.lib.Point(xy[0], xy[1]);
22560        for(var id in els){
22561            var el = els[id], r = el._region;
22562            var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
22563            if(r && r.contains(pt) && el.isScrollable()){
22564                if(r.bottom - pt.y <= c.vthresh){
22565                    if(proc.el != el){
22566                        startProc(el, "down");
22567                    }
22568                    return;
22569                }else if(r.right - pt.x <= c.hthresh){
22570                    if(proc.el != el){
22571                        startProc(el, "left");
22572                    }
22573                    return;
22574                }else if(pt.y - r.top <= c.vthresh){
22575                    if(proc.el != el){
22576                        startProc(el, "up");
22577                    }
22578                    return;
22579                }else if(pt.x - r.left <= c.hthresh){
22580                    if(proc.el != el){
22581                        startProc(el, "right");
22582                    }
22583                    return;
22584                }
22585            }
22586        }
22587        clearProc();
22588    };
22589    
22590    ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
22591    ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
22592    
22593    return {
22594        
22595        register : function(el){
22596            if(Ext.isArray(el)){
22597                for(var i = 0, len = el.length; i < len; i++) {
22598                	this.register(el[i]);
22599                }
22600            }else{
22601                el = Ext.get(el);
22602                els[el.id] = el;
22603            }
22604        },
22605        
22606        
22607        unregister : function(el){
22608            if(Ext.isArray(el)){
22609                for(var i = 0, len = el.length; i < len; i++) {
22610                	this.unregister(el[i]);
22611                }
22612            }else{
22613                el = Ext.get(el);
22614                delete els[el.id];
22615            }
22616        },
22617        
22618        
22619        vthresh : 25,
22620        
22621        hthresh : 25,
22622
22623        
22624        increment : 100,
22625        
22626        
22627        frequency : 500,
22628        
22629        
22630        animate: true,
22631        
22632        
22633        animDuration: .4,
22634        
22635        
22636        ddGroup: undefined,
22637        
22638        
22639        refreshCache : function(){
22640            for(var id in els){
22641                if(typeof els[id] == 'object'){ 
22642                    els[id]._region = els[id].getRegion();
22643                }
22644            }
22645        }
22646    };
22647}();
22648Ext.dd.Registry = function(){
22649    var elements = {}; 
22650    var handles = {}; 
22651    var autoIdSeed = 0;
22652
22653    var getId = function(el, autogen){
22654        if(typeof el == "string"){
22655            return el;
22656        }
22657        var id = el.id;
22658        if(!id && autogen !== false){
22659            id = "extdd-" + (++autoIdSeed);
22660            el.id = id;
22661        }
22662        return id;
22663    };
22664    
22665    return {
22666    
22667        register : function(el, data){
22668            data = data || {};
22669            if(typeof el == "string"){
22670                el = document.getElementById(el);
22671            }
22672            data.ddel = el;
22673            elements[getId(el)] = data;
22674            if(data.isHandle !== false){
22675                handles[data.ddel.id] = data;
22676            }
22677            if(data.handles){
22678                var hs = data.handles;
22679                for(var i = 0, len = hs.length; i < len; i++){
22680                	handles[getId(hs[i])] = data;
22681                }
22682            }
22683        },
22684
22685    
22686        unregister : function(el){
22687            var id = getId(el, false);
22688            var data = elements[id];
22689            if(data){
22690                delete elements[id];
22691                if(data.handles){
22692                    var hs = data.handles;
22693                    for(var i = 0, len = hs.length; i < len; i++){
22694                    	delete handles[getId(hs[i], false)];
22695                    }
22696                }
22697            }
22698        },
22699
22700    
22701        getHandle : function(id){
22702            if(typeof id != "string"){ 
22703                id = id.id;
22704            }
22705            return handles[id];
22706        },
22707
22708    
22709        getHandleFromEvent : function(e){
22710            var t = Ext.lib.Event.getTarget(e);
22711            return t ? handles[t.id] : null;
22712        },
22713
22714    
22715        getTarget : function(id){
22716            if(typeof id != "string"){ 
22717                id = id.id;
22718            }
22719            return elements[id];
22720        },
22721
22722    
22723        getTargetFromEvent : function(e){
22724            var t = Ext.lib.Event.getTarget(e);
22725            return t ? elements[t.id] || handles[t.id] : null;
22726        }
22727    };
22728}();
22729Ext.dd.StatusProxy = function(config){
22730    Ext.apply(this, config);
22731    this.id = this.id || Ext.id();
22732    this.el = new Ext.Layer({
22733        dh: {
22734            id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
22735                {tag: "div", cls: "x-dd-drop-icon"},
22736                {tag: "div", cls: "x-dd-drag-ghost"}
22737            ]
22738        }, 
22739        shadow: !config || config.shadow !== false
22740    });
22741    this.ghost = Ext.get(this.el.dom.childNodes[1]);
22742    this.dropStatus = this.dropNotAllowed;
22743};
22744
22745Ext.dd.StatusProxy.prototype = {
22746    
22747    dropAllowed : "x-dd-drop-ok",
22748    
22749    dropNotAllowed : "x-dd-drop-nodrop",
22750
22751    
22752    setStatus : function(cssClass){
22753        cssClass = cssClass || this.dropNotAllowed;
22754        if(this.dropStatus != cssClass){
22755            this.el.replaceClass(this.dropStatus, cssClass);
22756            this.dropStatus = cssClass;
22757        }
22758    },
22759
22760    
22761    reset : function(clearGhost){
22762        this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
22763        this.dropStatus = this.dropNotAllowed;
22764        if(clearGhost){
22765            this.ghost.update("");
22766        }
22767    },
22768
22769    
22770    update : function(html){
22771        if(typeof html == "string"){
22772            this.ghost.update(html);
22773        }else{
22774            this.ghost.update("");
22775            html.style.margin = "0";
22776            this.ghost.dom.appendChild(html);
22777        }
22778        var el = this.ghost.dom.firstChild; 
22779        if(el){
22780            Ext.fly(el).setStyle('float', 'none');
22781        }
22782    },
22783
22784    
22785    getEl : function(){
22786        return this.el;
22787    },
22788
22789    
22790    getGhost : function(){
22791        return this.ghost;
22792    },
22793
22794    
22795    hide : function(clear){
22796        this.el.hide();
22797        if(clear){
22798            this.reset(true);
22799        }
22800    },
22801
22802    
22803    stop : function(){
22804        if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
22805            this.anim.stop();
22806        }
22807    },
22808
22809    
22810    show : function(){
22811        this.el.show();
22812    },
22813
22814    
22815    sync : function(){
22816        this.el.sync();
22817    },
22818
22819    
22820    repair : function(xy, callback, scope){
22821        this.callback = callback;
22822        this.scope = scope;
22823        if(xy && this.animRepair !== false){
22824            this.el.addClass("x-dd-drag-repair");
22825            this.el.hideUnders(true);
22826            this.anim = this.el.shift({
22827                duration: this.repairDuration || .5,
22828                easing: 'easeOut',
22829                xy: xy,
22830                stopFx: true,
22831                callback: this.afterRepair,
22832                scope: this
22833            });
22834        }else{
22835            this.afterRepair();
22836        }
22837    },
22838
22839    
22840    afterRepair : function(){
22841        this.hide(true);
22842        if(typeof this.callback == "function"){
22843            this.callback.call(this.scope || this);
22844        }
22845        this.callback = null;
22846        this.scope = null;
22847    },
22848    
22849    destroy: function(){
22850        Ext.destroy(this.ghost, this.el);    
22851    }
22852};
22853Ext.dd.DragSource = function(el, config){
22854    this.el = Ext.get(el);
22855    if(!this.dragData){
22856        this.dragData = {};
22857    }
22858    
22859    Ext.apply(this, config);
22860    
22861    if(!this.proxy){
22862        this.proxy = new Ext.dd.StatusProxy();
22863    }
22864    Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
22865          {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
22866    
22867    this.dragging = false;
22868};
22869
22870Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
22871    
22872    
22873    dropAllowed : "x-dd-drop-ok",
22874    
22875    dropNotAllowed : "x-dd-drop-nodrop",
22876
22877    
22878    getDragData : function(e){
22879        return this.dragData;
22880    },
22881
22882    
22883    onDragEnter : function(e, id){
22884        var target = Ext.dd.DragDropMgr.getDDById(id);
22885        this.cachedTarget = target;
22886        if(this.beforeDragEnter(target, e, id) !== false){
22887            if(target.isNotifyTarget){
22888                var status = target.notifyEnter(this, e, this.dragData);
22889                this.proxy.setStatus(status);
22890            }else{
22891                this.proxy.setStatus(this.dropAllowed);
22892            }
22893            
22894            if(this.afterDragEnter){
22895                
22896                this.afterDragEnter(target, e, id);
22897            }
22898        }
22899    },
22900
22901    
22902    beforeDragEnter : function(target, e, id){
22903        return true;
22904    },
22905
22906    
22907    alignElWithMouse: function() {
22908        Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
22909        this.proxy.sync();
22910    },
22911
22912    
22913    onDragOver : function(e, id){
22914        var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22915        if(this.beforeDragOver(target, e, id) !== false){
22916            if(target.isNotifyTarget){
22917                var status = target.notifyOver(this, e, this.dragData);
22918                this.proxy.setStatus(status);
22919            }
22920
22921            if(this.afterDragOver){
22922                
22923                this.afterDragOver(target, e, id);
22924            }
22925        }
22926    },
22927
22928    
22929    beforeDragOver : function(target, e, id){
22930        return true;
22931    },
22932
22933    
22934    onDragOut : function(e, id){
22935        var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22936        if(this.beforeDragOut(target, e, id) !== false){
22937            if(target.isNotifyTarget){
22938                target.notifyOut(this, e, this.dragData);
22939            }
22940            this.proxy.reset();
22941            if(this.afterDragOut){
22942                
22943                this.afterDragOut(target, e, id);
22944            }
22945        }
22946        this.cachedTarget = null;
22947    },
22948
22949    
22950    beforeDragOut : function(target, e, id){
22951        return true;
22952    },
22953    
22954    
22955    onDragDrop : function(e, id){
22956        var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22957        if(this.beforeDragDrop(target, e, id) !== false){
22958            if(target.isNotifyTarget){
22959                if(target.notifyDrop(this, e, this.dragData)){ 
22960                    this.onValidDrop(target, e, id);
22961                }else{
22962                    this.onInvalidDrop(target, e, id);
22963                }
22964            }else{
22965                this.onValidDrop(target, e, id);
22966            }
22967            
22968            if(this.afterDragDrop){
22969                
22970                this.afterDragDrop(target, e, id);
22971            }
22972        }
22973        delete this.cachedTarget;
22974    },
22975
22976    
22977    beforeDragDrop : function(target, e, id){
22978        return true;
22979    },
22980
22981    
22982    onValidDrop : function(target, e, id){
22983        this.hideProxy();
22984        if(this.afterValidDrop){
22985            
22986            this.afterValidDrop(target, e, id);
22987        }
22988    },
22989
22990    
22991    getRepairXY : function(e, data){
22992        return this.el.getXY();  
22993    },
22994
22995    
22996    onInvalidDrop : function(target, e, id){
22997        this.beforeInvalidDrop(target, e, id);
22998        if(this.cachedTarget){
22999            if(this.cachedTarget.isNotifyTarget){
23000                this.cachedTarget.notifyOut(this, e, this.dragData);
23001            }
23002            this.cacheTarget = null;
23003        }
23004        this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
23005
23006        if(this.afterInvalidDrop){
23007            
23008            this.afterInvalidDrop(e, id);
23009        }
23010    },
23011
23012    
23013    afterRepair : function(){
23014        if(Ext.enableFx){
23015            this.el.highlight(this.hlColor || "c3daf9");
23016        }
23017        this.dragging = false;
23018    },
23019
23020    
23021    beforeInvalidDrop : function(target, e, id){
23022        return true;
23023    },
23024
23025    
23026    handleMouseDown : function(e){
23027        if(this.dragging) {
23028            return;
23029        }
23030        var data = this.getDragData(e);
23031        if(data && this.onBeforeDrag(data, e) !== false){
23032            this.dragData = data;
23033            this.proxy.stop();
23034            Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
23035        } 
23036    },
23037
23038    
23039    onBeforeDrag : function(data, e){
23040        return true;
23041    },
23042
23043    
23044    onStartDrag : Ext.emptyFn,
23045
23046    
23047    startDrag : function(x, y){
23048        this.proxy.reset();
23049        this.dragging = true;
23050        this.proxy.update("");
23051        this.onInitDrag(x, y);
23052        this.proxy.show();
23053    },
23054
23055    
23056    onInitDrag : function(x, y){
23057        var clone = this.el.dom.cloneNode(true);
23058        clone.id = Ext.id(); 
23059        this.proxy.update(clone);
23060        this.onStartDrag(x, y);
23061        return true;
23062    },
23063
23064    
23065    getProxy : function(){
23066        return this.proxy;  
23067    },
23068
23069    
23070    hideProxy : function(){
23071        this.proxy.hide();  
23072        this.proxy.reset(true);
23073        this.dragging = false;
23074    },
23075
23076    
23077    triggerCacheRefresh : function(){
23078        Ext.dd.DDM.refreshCache(this.groups);
23079    },
23080
23081    
23082    b4EndDrag: function(e) {
23083    },
23084
23085    
23086    endDrag : function(e){
23087        this.onEndDrag(this.dragData, e);
23088    },
23089
23090    
23091    onEndDrag : function(data, e){
23092    },
23093    
23094    
23095    autoOffset : function(x, y) {
23096        this.setDelta(-12, -20);
23097    },
23098    
23099    destroy: function(){
23100        Ext.dd.DragSource.superclass.destroy.call(this);
23101        Ext.destroy(this.proxy);
23102    }
23103});
23104Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
23105    
23106    constructor : function(el, config){
23107        this.el = Ext.get(el);
23108    
23109        Ext.apply(this, config);
23110    
23111        if(this.containerScroll){
23112            Ext.dd.ScrollManager.register(this.el);
23113        }
23114    
23115        Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
23116              {isTarget: true});        
23117    },
23118    
23119    
23120    
23121    
23122    dropAllowed : "x-dd-drop-ok",
23123    
23124    dropNotAllowed : "x-dd-drop-nodrop",
23125
23126    
23127    isTarget : true,
23128
23129    
23130    isNotifyTarget : true,
23131
23132    
23133    notifyEnter : function(dd, e, data){
23134        if(this.overClass){
23135            this.el.addClass(this.overClass);
23136        }
23137        return this.dropAllowed;
23138    },
23139
23140    
23141    notifyOver : function(dd, e, data){
23142        return this.dropAllowed;
23143    },
23144
23145    
23146    notifyOut : function(dd, e, data){
23147        if(this.overClass){
23148            this.el.removeClass(this.overClass);
23149        }
23150    },
23151
23152    
23153    notifyDrop : function(dd, e, data){
23154        return false;
23155    },
23156    
23157    destroy : function(){
23158        Ext.dd.DropTarget.superclass.destroy.call(this);
23159        if(this.containerScroll){
23160            Ext.dd.ScrollManager.unregister(this.el);
23161        }
23162    }
23163});
23164Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
23165    
23166    constructor : function(el, config){
23167        Ext.dd.DragZone.superclass.constructor.call(this, el, config);
23168        if(this.containerScroll){
23169            Ext.dd.ScrollManager.register(this.el);
23170        }
23171    },
23172    
23173    
23174    
23175    
23176
23177    
23178    getDragData : function(e){
23179        return Ext.dd.Registry.getHandleFromEvent(e);
23180    },
23181    
23182    
23183    onInitDrag : function(x, y){
23184        this.proxy.update(this.dragData.ddel.cloneNode(true));
23185        this.onStartDrag(x, y);
23186        return true;
23187    },
23188    
23189    
23190    afterRepair : function(){
23191        if(Ext.enableFx){
23192            Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
23193        }
23194        this.dragging = false;
23195    },
23196
23197    
23198    getRepairXY : function(e){
23199        return Ext.Element.fly(this.dragData.ddel).getXY();  
23200    },
23201    
23202    destroy : function(){
23203        Ext.dd.DragZone.superclass.destroy.call(this);
23204        if(this.containerScroll){
23205            Ext.dd.ScrollManager.unregister(this.el);
23206        }
23207    }
23208});
23209Ext.dd.DropZone = function(el, config){
23210    Ext.dd.DropZone.superclass.constructor.call(this, el, config);
23211};
23212
23213Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
23214    
23215    getTargetFromEvent : function(e){
23216        return Ext.dd.Registry.getTargetFromEvent(e);
23217    },
23218
23219    
23220    onNodeEnter : function(n, dd, e, data){
23221        
23222    },
23223
23224    
23225    onNodeOver : function(n, dd, e, data){
23226        return this.dropAllowed;
23227    },
23228
23229    
23230    onNodeOut : function(n, dd, e, data){
23231        
23232    },
23233
23234    
23235    onNodeDrop : function(n, dd, e, data){
23236        return false;
23237    },
23238
23239    
23240    onContainerOver : function(dd, e, data){
23241        return this.dropNotAllowed;
23242    },
23243
23244    
23245    onContainerDrop : function(dd, e, data){
23246        return false;
23247    },
23248
23249    
23250    notifyEnter : function(dd, e, data){
23251        return this.dropNotAllowed;
23252    },
23253
23254    
23255    notifyOver : function(dd, e, data){
23256        var n = this.getTargetFromEvent(e);
23257        if(!n){ 
23258            if(this.lastOverNode){
23259                this.onNodeOut(this.lastOverNode, dd, e, data);
23260                this.lastOverNode = null;
23261            }
23262            return this.onContainerOver(dd, e, data);
23263        }
23264        if(this.lastOverNode != n){
23265            if(this.lastOverNode){
23266                this.onNodeOut(this.lastOverNode, dd, e, data);
23267            }
23268            this.onNodeEnter(n, dd, e, data);
23269            this.lastOverNode = n;
23270        }
23271        return this.onNodeOver(n, dd, e, data);
23272    },
23273
23274    
23275    notifyOut : function(dd, e, data){
23276        if(this.lastOverNode){
23277            this.onNodeOut(this.lastOverNode, dd, e, data);
23278            this.lastOverNode = null;
23279        }
23280    },
23281
23282    
23283    notifyDrop : function(dd, e, data){
23284        if(this.lastOverNode){
23285            this.onNodeOut(this.lastOverNode, dd, e, data);
23286            this.lastOverNode = null;
23287        }
23288        var n = this.getTargetFromEvent(e);
23289        return n ?
23290            this.onNodeDrop(n, dd, e, data) :
23291            this.onContainerDrop(dd, e, data);
23292    },
23293
23294    
23295    triggerCacheRefresh : function(){
23296        Ext.dd.DDM.refreshCache(this.groups);
23297    }  
23298});
23299Ext.Element.addMethods({
23300    
23301    initDD : function(group, config, overrides){
23302        var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
23303        return Ext.apply(dd, overrides);
23304    },
23305
23306    
23307    initDDProxy : function(group, config, overrides){
23308        var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
23309        return Ext.apply(dd, overrides);
23310    },
23311
23312    
23313    initDDTarget : function(group, config, overrides){
23314        var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
23315        return Ext.apply(dd, overrides);
23316    }
23317});
23318
23319Ext.data.Api = (function() {
23320
23321    
23322    
23323    
23324    
23325    var validActions = {};
23326
23327    return {
23328        
23329        actions : {
23330            create  : 'create',
23331            read    : 'read',
23332            update  : 'update',
23333            destroy : 'destroy'
23334        },
23335
23336        
23337        restActions : {
23338            create  : 'POST',
23339            read    : 'GET',
23340            update  : 'PUT',
23341            destroy : 'DELETE'
23342        },
23343
23344        
23345        isAction : function(action) {
23346            return (Ext.data.Api.actions[action]) ? true : false;
23347        },
23348
23349        
23350        getVerb : function(name) {
23351            if (validActions[name]) {
23352                return validActions[name];  
23353            }
23354            for (var verb in this.actions) {
23355                if (this.actions[verb] === name) {
23356                    validActions[name] = verb;
23357                    break;
23358                }
23359            }
23360            return (validActions[name] !== undefined) ? validActions[name] : null;
23361        },
23362
23363        
23364        isValid : function(api){
23365            var invalid = [];
23366            var crud = this.actions; 
23367            for (var action in api) {
23368                if (!(action in crud)) {
23369                    invalid.push(action);
23370                }
23371            }
23372            return (!invalid.length) ? true : invalid;
23373        },
23374
23375        
23376        hasUniqueUrl : function(proxy, verb) {
23377            var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
23378            var unique = true;
23379            for (var action in proxy.api) {
23380                if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
23381                    break;
23382                }
23383            }
23384            return unique;
23385        },
23386
23387        
23388        prepare : function(proxy) {
23389            if (!proxy.api) {
23390                proxy.api = {}; 
23391            }
23392            for (var verb in this.actions) {
23393                var action = this.actions[verb];
23394                proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
23395                if (typeof(proxy.api[action]) == 'string') {
23396                    proxy.api[action] = {
23397                        url: proxy.api[action],
23398                        method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
23399                    };
23400                }
23401            }
23402        },
23403
23404        
23405        restify : function(proxy) {
23406            proxy.restful = true;
23407            for (var verb in this.restActions) {
23408                proxy.api[this.actions[verb]].method ||
23409                    (proxy.api[this.actions[verb]].method = this.restActions[verb]);
23410            }
23411            
23412            
23413            proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
23414                var reader = o.reader;
23415                var res = new Ext.data.Response({
23416                    action: action,
23417                    raw: response
23418                });
23419
23420                switch (response.status) {
23421                    case 200:   
23422                        return true;
23423                        break;
23424                    case 201:   
23425                        if (Ext.isEmpty(res.raw.responseText)) {
23426                          res.success = true;
23427                        } else {
23428                          
23429                          return true;
23430                        }
23431                        break;
23432                    case 204:  
23433                        res.success = true;
23434                        res.data = null;
23435                        break;
23436                    default:
23437                        return true;
23438                        break;
23439                }
23440                if (res.success === true) {
23441                    this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
23442                } else {
23443                    this.fireEvent('exception', this, 'remote', action, o, res, rs);
23444                }
23445                o.request.callback.call(o.request.scope, res.data, res, res.success);
23446
23447                return false;   
23448            }, proxy);
23449        }
23450    };
23451})();
23452
23453
23454Ext.data.Response = function(params, response) {
23455    Ext.apply(this, params, {
23456        raw: response
23457    });
23458};
23459Ext.data.Response.prototype = {
23460    message : null,
23461    success : false,
23462    status : null,
23463    root : null,
23464    raw : null,
23465
23466    getMessage : function() {
23467        return this.message;
23468    },
23469    getSuccess : function() {
23470        return this.success;
23471    },
23472    getStatus : function() {
23473        return this.status;
23474    },
23475    getRoot : function() {
23476        return this.root;
23477    },
23478    getRawResponse : function() {
23479        return this.raw;
23480    }
23481};
23482
23483
23484Ext.data.Api.Error = Ext.extend(Ext.Error, {
23485    constructor : function(message, arg) {
23486        this.arg = arg;
23487        Ext.Error.call(this, message);
23488    },
23489    name: 'Ext.data.Api'
23490});
23491Ext.apply(Ext.data.Api.Error.prototype, {
23492    lang: {
23493        'action-url-undefined': 'No fallback url defined for this action.  When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.',
23494        'invalid': 'received an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
23495        'invalid-url': 'Invalid url.  Please review your proxy configuration.',
23496        'execute': 'Attempted to execute an unknown action.  Valid API actions are defined in Ext.data.Api.actions"'
23497    }
23498});
23499
23500
23501
23502
23503Ext.data.SortTypes = {
23504    
23505    none : function(s){
23506        return s;
23507    },
23508    
23509    
23510    stripTagsRE : /<\/?[^>]+>/gi,
23511    
23512    
23513    asText : function(s){
23514        return String(s).replace(this.stripTagsRE, "");
23515    },
23516    
23517    
23518    asUCText : function(s){
23519        return String(s).toUpperCase().replace(this.stripTagsRE, "");
23520    },
23521    
23522    
23523    asUCString : function(s) {
23524    	return String(s).toUpperCase();
23525    },
23526    
23527    
23528    asDate : function(s) {
23529        if(!s){
23530            return 0;
23531        }
23532        if(Ext.isDate(s)){
23533            return s.getTime();
23534        }
23535    	return Date.parse(String(s));
23536    },
23537    
23538    
23539    asFloat : function(s) {
23540    	var val = parseFloat(String(s).replace(/,/g, ""));
23541    	return isNaN(val) ? 0 : val;
23542    },
23543    
23544    
23545    asInt : function(s) {
23546        var val = parseInt(String(s).replace(/,/g, ""), 10);
23547        return isNaN(val) ? 0 : val;
23548    }
23549};
23550Ext.data.Record = function(data, id){
23551    
23552    this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
23553    this.data = data || {};
23554};
23555
23556
23557Ext.data.Record.create = function(o){
23558    var f = Ext.extend(Ext.data.Record, {});
23559    var p = f.prototype;
23560    p.fields = new Ext.util.MixedCollection(false, function(field){
23561        return field.name;
23562    });
23563    for(var i = 0, len = o.length; i < len; i++){
23564        p.fields.add(new Ext.data.Field(o[i]));
23565    }
23566    f.getField = function(name){
23567        return p.fields.get(name);
23568    };
23569    return f;
23570};
23571
23572Ext.data.Record.PREFIX = 'ext-record';
23573Ext.data.Record.AUTO_ID = 1;
23574Ext.data.Record.EDIT = 'edit';
23575Ext.data.Record.REJECT = 'reject';
23576Ext.data.Record.COMMIT = 'commit';
23577
23578
23579
23580Ext.data.Record.id = function(rec) {
23581    rec.phantom = true;
23582    return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
23583};
23584
23585Ext.data.Record.prototype = {
23586    
23587    
23588    
23589    
23590    
23591    
23592    dirty : false,
23593    editing : false,
23594    error : null,
23595    
23596    modified : null,
23597    
23598    phantom : false,
23599
23600    
23601    join : function(store){
23602        
23603        this.store = store;
23604    },
23605
23606    
23607    set : function(name, value){
23608        var encode = Ext.isPrimitive(value) ? String : Ext.encode;
23609        if(encode(this.data[name]) == encode(value)) {
23610            return;
23611        }        
23612        this.dirty = true;
23613        if(!this.modified){
23614            this.modified = {};
23615        }
23616        if(this.modified[name] === undefined){
23617            this.modified[name] = this.data[name];
23618        }
23619        this.data[name] = value;
23620        if(!this.editing){
23621            this.afterEdit();
23622        }
23623    },
23624
23625    
23626    afterEdit : function(){
23627        if (this.store != undefined && typeof this.store.afterEdit == "function") {
23628            this.store.afterEdit(this);
23629        }
23630    },
23631
23632    
23633    afterReject : function(){
23634        if(this.store){
23635            this.store.afterReject(this);
23636        }
23637    },
23638
23639    
23640    afterCommit : function(){
23641        if(this.store){
23642            this.store.afterCommit(this);
23643        }
23644    },
23645
23646    
23647    get : function(name){
23648        return this.data[name];
23649    },
23650
23651    
23652    beginEdit : function(){
23653        this.editing = true;
23654        this.modified = this.modified || {};
23655    },
23656
23657    
23658    cancelEdit : function(){
23659        this.editing = false;
23660        delete this.modified;
23661    },
23662
23663    
23664    endEdit : function(){
23665        this.editing = false;
23666        if(this.dirty){
23667            this.afterEdit();
23668        }
23669    },
23670
23671    
23672    reject : function(silent){
23673        var m = this.modified;
23674        for(var n in m){
23675            if(typeof m[n] != "function"){
23676                this.data[n] = m[n];
23677            }
23678        }
23679        this.dirty = false;
23680        delete this.modified;
23681        this.editing = false;
23682        if(silent !== true){
23683            this.afterReject();
23684        }
23685    },
23686
23687    
23688    commit : function(silent){
23689        this.dirty = false;
23690        delete this.modified;
23691        this.editing = false;
23692        if(silent !== true){
23693            this.afterCommit();
23694        }
23695    },
23696
23697    
23698    getChanges : function(){
23699        var m = this.modified, cs = {};
23700        for(var n in m){
23701            if(m.hasOwnProperty(n)){
23702                cs[n] = this.data[n];
23703            }
23704        }
23705        return cs;
23706    },
23707
23708    
23709    hasError : function(){
23710        return this.error !== null;
23711    },
23712
23713    
23714    clearError : function(){
23715        this.error = null;
23716    },
23717
23718    
23719    copy : function(newId) {
23720        return new this.constructor(Ext.apply({}, this.data), newId || this.id);
23721    },
23722
23723    
23724    isModified : function(fieldName){
23725        return !!(this.modified && this.modified.hasOwnProperty(fieldName));
23726    },
23727
23728    
23729    isValid : function() {
23730        return this.fields.find(function(f) {
23731            return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
23732        },this) ? false : true;
23733    },
23734
23735    
23736    markDirty : function(){
23737        this.dirty = true;
23738        if(!this.modified){
23739            this.modified = {};
23740        }
23741        this.fields.each(function(f) {
23742            this.modified[f.name] = this.data[f.name];
23743        },this);
23744    }
23745};
23746
23747Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
23748    
23749
23750    
23751    register : function(){
23752        for(var i = 0, s; (s = arguments[i]); i++){
23753            this.add(s);
23754        }
23755    },
23756
23757    
23758    unregister : function(){
23759        for(var i = 0, s; (s = arguments[i]); i++){
23760            this.remove(this.lookup(s));
23761        }
23762    },
23763
23764    
23765    lookup : function(id){
23766        if(Ext.isArray(id)){
23767            var fields = ['field1'], expand = !Ext.isArray(id[0]);
23768            if(!expand){
23769                for(var i = 2, len = id[0].length; i <= len; ++i){
23770                    fields.push('field' + i);
23771                }
23772            }
23773            return new Ext.data.ArrayStore({
23774                fields: fields,
23775                data: id,
23776                expandData: expand,
23777                autoDestroy: true,
23778                autoCreated: true
23779
23780            });
23781        }
23782        return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
23783    },
23784
23785    
23786    getKey : function(o){
23787         return o.storeId;
23788    }
23789});
23790Ext.data.Store = Ext.extend(Ext.util.Observable, {
23791    
23792    
23793    
23794    
23795    
23796    
23797    
23798    writer : undefined,
23799    
23800    
23801    
23802    remoteSort : false,
23803
23804    
23805    autoDestroy : false,
23806
23807    
23808    pruneModifiedRecords : false,
23809
23810    
23811    lastOptions : null,
23812
23813    
23814    autoSave : true,
23815
23816    
23817    batch : true,
23818
23819    
23820    restful: false,
23821
23822    
23823    paramNames : undefined,
23824
23825    
23826    defaultParamNames : {
23827        start : 'start',
23828        limit : 'limit',
23829        sort : 'sort',
23830        dir : 'dir'
23831    },
23832
23833    isDestroyed: false,    
23834    hasMultiSort: false,
23835
23836    
23837    batchKey : '_ext_batch_',
23838
23839    constructor : function(config){
23840        
23841        
23842        
23843        
23844        this.data = new Ext.util.MixedCollection(false);
23845        this.data.getKey = function(o){
23846            return o.id;
23847        };
23848        
23849
23850        
23851        this.removed = [];
23852
23853        if(config && config.data){
23854            this.inlineData = config.data;
23855            delete config.data;
23856        }
23857
23858        Ext.apply(this, config);
23859
23860        
23861        this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
23862
23863        this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
23864
23865        if((this.url || this.api) && !this.proxy){
23866            this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
23867        }
23868        
23869        if (this.restful === true && this.proxy) {
23870            
23871            
23872            this.batch = false;
23873            Ext.data.Api.restify(this.proxy);
23874        }
23875
23876        if(this.reader){ 
23877            if(!this.recordType){
23878                this.recordType = this.reader.recordType;
23879            }
23880            if(this.reader.onMetaChange){
23881                this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
23882            }
23883            if (this.writer) { 
23884                if (this.writer instanceof(Ext.data.DataWriter) === false) {    
23885                    this.writer = this.buildWriter(this.writer);
23886                }
23887                this.writer.meta = this.reader.meta;
23888                this.pruneModifiedRecords = true;
23889            }
23890        }
23891
23892        
23893
23894        if(this.recordType){
23895            
23896            this.fields = this.recordType.prototype.fields;
23897        }
23898        this.modified = [];
23899
23900        this.addEvents(
23901            
23902            'datachanged',
23903            
23904            'metachange',
23905            
23906            'add',
23907            
23908            'remove',
23909            
23910            'update',
23911            
23912            'clear',
23913            
23914            'exception',
23915            
23916            'beforeload',
23917            
23918            'load',
23919            
23920            'loadexception',
23921            
23922            'beforewrite',
23923            
23924            'write',
23925            
23926            'beforesave',
23927            
23928            'save'
23929
23930        );
23931
23932        if(this.proxy){
23933            
23934            this.relayEvents(this.proxy,  ['loadexception', 'exception']);
23935        }
23936        
23937        if (this.writer) {
23938            this.on({
23939                scope: this,
23940                add: this.createRecords,
23941                remove: this.destroyRecord,
23942                update: this.updateRecord,
23943                clear: this.onClear
23944            });
23945        }
23946
23947        this.sortToggle = {};
23948        if(this.sortField){
23949            this.setDefaultSort(this.sortField, this.sortDir);
23950        }else if(this.sortInfo){
23951            this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
23952        }
23953
23954        Ext.data.Store.superclass.constructor.call(this);
23955
23956        if(this.id){
23957            this.storeId = this.id;
23958            delete this.id;
23959        }
23960        if(this.storeId){
23961            Ext.StoreMgr.register(this);
23962        }
23963        if(this.inlineData){
23964            this.loadData(this.inlineData);
23965            delete this.inlineData;
23966        }else if(this.autoLoad){
23967            this.load.defer(10, this, [
23968                typeof this.autoLoad == 'object' ?
23969                    this.autoLoad : undefined]);
23970        }
23971        
23972        this.batchCounter = 0;
23973        this.batches = {};
23974    },
23975
23976    
23977    buildWriter : function(config) {
23978        var klass = undefined,
23979            type = (config.format || 'json').toLowerCase();
23980        switch (type) {
23981            case 'json':
23982                klass = Ext.data.JsonWriter;
23983                break;
23984            case 'xml':
23985                klass = Ext.data.XmlWriter;
23986                break;
23987            default:
23988                klass = Ext.data.JsonWriter;
23989        }
23990        return new klass(config);
23991    },
23992
23993    
23994    destroy : function(){
23995        if(!this.isDestroyed){
23996            if(this.storeId){
23997                Ext.StoreMgr.unregister(this);
23998            }
23999            this.clearData();
24000            this.data = null;
24001            Ext.destroy(this.proxy);
24002            this.reader = this.writer = null;
24003            this.purgeListeners();
24004            this.isDestroyed = true;
24005        }
24006    },
24007
24008    
24009    add : function(records) {
24010        var i, len, record, index;
24011        
24012        records = [].concat(records);
24013        if (records.length < 1) {
24014            return;
24015        }
24016        
24017        for (i = 0, len = records.length; i < len; i++) {
24018            record = records[i];
24019            
24020            record.join(this);
24021            
24022            if (record.dirty || record.phantom) {
24023                this.modified.push(record);
24024            }
24025        }
24026        
24027        index = this.data.length;
24028        this.data.addAll(records);
24029        
24030        if (this.snapshot) {
24031            this.snapshot.addAll(records);
24032        }
24033        
24034        this.fireEvent('add', this, records, index);
24035    },
24036
24037    
24038    addSorted : function(record){
24039        var index = this.findInsertIndex(record);
24040        this.insert(index, record);
24041    },
24042    
24043    
24044    doUpdate: function(rec){
24045        var id = rec.id;
24046        
24047        this.getById(id).join(null);
24048        
24049        this.data.replace(id, rec);
24050        if (this.snapshot) {
24051            this.snapshot.replace(id, rec);
24052        }
24053        rec.join(this);
24054        this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
24055    },
24056
24057    
24058    remove : function(record){
24059        if(Ext.isArray(record)){
24060            Ext.each(record, function(r){
24061                this.remove(r);
24062            }, this);
24063            return;
24064        }
24065        var index = this.data.indexOf(record);
24066        if(index > -1){
24067            record.join(null);
24068            this.data.removeAt(index);
24069        }
24070        if(this.pruneModifiedRecords){
24071            this.modified.remove(record);
24072        }
24073        if(this.snapshot){
24074            this.snapshot.remove(record);
24075        }
24076        if(index > -1){
24077            this.fireEvent('remove', this, record, index);
24078        }
24079    },
24080
24081    
24082    removeAt : function(index){
24083        this.remove(this.getAt(index));
24084    },
24085
24086    
24087    removeAll : function(silent){
24088        var items = [];
24089        this.each(function(rec){
24090            items.push(rec);
24091        });
24092        this.clearData();
24093        if(this.snapshot){
24094            this.snapshot.clear();
24095        }
24096        if(this.pruneModifiedRecords){
24097            this.modified = [];
24098        }
24099        if (silent !== true) {  
24100            this.fireEvent('clear', this, items);
24101        }
24102    },
24103
24104    
24105    onClear: function(store, records){
24106        Ext.each(records, function(rec, index){
24107            this.destroyRecord(this, rec, index);
24108        }, this);
24109    },
24110
24111    
24112    insert : function(index, records) {
24113        var i, len, record;
24114        
24115        records = [].concat(records);
24116        for (i = 0, len = records.length; i < len; i++) {
24117            record = records[i];
24118            
24119            this.data.insert(index + i, record);
24120            record.join(this);
24121            
24122            if (record.dirty || record.phantom) {
24123                this.modified.push(record);
24124            }
24125        }
24126        
24127        if (this.snapshot) {
24128            this.snapshot.addAll(records);
24129        }
24130        
24131        this.fireEvent('add', this, records, index);
24132    },
24133
24134    
24135    indexOf : function(record){
24136        return this.data.indexOf(record);
24137    },
24138
24139    
24140    indexOfId : function(id){
24141        return this.data.indexOfKey(id);
24142    },
24143
24144    
24145    getById : function(id){
24146        return (this.snapshot || this.data).key(id);
24147    },
24148
24149    
24150    getAt : function(index){
24151        return this.data.itemAt(index);
24152    },
24153
24154    
24155    getRange : function(start, end){
24156        return this.data.getRange(start, end);
24157    },
24158
24159    
24160    storeOptions : function(o){
24161        o = Ext.apply({}, o);
24162        delete o.callback;
24163        delete o.scope;
24164        this.lastOptions = o;
24165    },
24166
24167    
24168    clearData: function(){
24169        this.data.each(function(rec) {
24170            rec.join(null);
24171        });
24172        this.data.clear();
24173    },
24174
24175    
24176    load : function(options) {
24177        options = Ext.apply({}, options);
24178        this.storeOptions(options);
24179        if(this.sortInfo && this.remoteSort){
24180            var pn = this.paramNames;
24181            options.params = Ext.apply({}, options.params);
24182            options.params[pn.sort] = this.sortInfo.field;
24183            options.params[pn.dir] = this.sortInfo.direction;
24184        }
24185        try {
24186            return this.execute('read', null, options); 
24187        } catch(e) {
24188            this.handleException(e);
24189            return false;
24190        }
24191    },
24192
24193    
24194    updateRecord : function(store, record, action) {
24195        if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
24196            this.save();
24197        }
24198    },
24199
24200    
24201    createRecords : function(store, records, index) {
24202        var modified = this.modified,
24203            length   = records.length,
24204            record, i;
24205        
24206        for (i = 0; i < length; i++) {
24207            record = records[i];
24208            
24209            if (record.phantom && record.isValid()) {
24210                record.markDirty();  
24211                
24212                if (modified.indexOf(record) == -1) {
24213                    modified.push(record);
24214                }
24215            }
24216        }
24217        if (this.autoSave === true) {
24218            this.save();
24219        }
24220    },
24221
24222    
24223    destroyRecord : function(store, record, index) {
24224        if (this.modified.indexOf(record) != -1) {  
24225            this.modified.remove(record);
24226        }
24227        if (!record.phantom) {
24228            this.removed.push(record);
24229
24230            
24231            
24232            
24233            record.lastIndex = index;
24234
24235            if (this.autoSave === true) {
24236                this.save();
24237            }
24238        }
24239    },
24240
24241    
24242    execute : function(action, rs, options,  batch) {
24243        
24244        if (!Ext.data.Api.isAction(action)) {
24245            throw new Ext.data.Api.Error('execute', action);
24246        }
24247        
24248        options = Ext.applyIf(options||{}, {
24249            params: {}
24250        });
24251        if(batch !== undefined){
24252            this.addToBatch(batch);
24253        }
24254        
24255        
24256        var doRequest = true;
24257
24258        if (action === 'read') {
24259            doRequest = this.fireEvent('beforeload', this, options);
24260            Ext.applyIf(options.params, this.baseParams);
24261        }
24262        else {
24263            
24264            
24265            if (this.writer.listful === true && this.restful !== true) {
24266                rs = (Ext.isArray(rs)) ? rs : [rs];
24267            }
24268            
24269            else if (Ext.isArray(rs) && rs.length == 1) {
24270                rs = rs.shift();
24271            }
24272            
24273            if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
24274                this.writer.apply(options.params, this.baseParams, action, rs);
24275            }
24276        }
24277        if (doRequest !== false) {
24278            
24279            if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
24280                options.params.xaction = action;    
24281            }
24282            
24283            
24284            
24285            
24286            
24287            this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
24288        }
24289        return doRequest;
24290    },
24291
24292    
24293    save : function() {
24294        if (!this.writer) {
24295            throw new Ext.data.Store.Error('writer-undefined');
24296        }
24297
24298        var queue = [],
24299            len,
24300            trans,
24301            batch,
24302            data = {},
24303            i;
24304        
24305        if(this.removed.length){
24306            queue.push(['destroy', this.removed]);
24307        }
24308
24309        
24310        var rs = [].concat(this.getModifiedRecords());
24311        if(rs.length){
24312            
24313            var phantoms = [];
24314            for(i = rs.length-1; i >= 0; i--){
24315                if(rs[i].phantom === true){
24316                    var rec = rs.splice(i, 1).shift();
24317                    if(rec.isValid()){
24318                        phantoms.push(rec);
24319                    }
24320                }else if(!rs[i].isValid()){ 
24321                    rs.splice(i,1);
24322                }
24323            }
24324            
24325            if(phantoms.length){
24326                queue.push(['create', phantoms]);
24327            }
24328
24329            
24330            if(rs.length){
24331                queue.push(['update', rs]);
24332            }
24333        }
24334        len = queue.length;
24335        if(len){
24336            batch = ++this.batchCounter;
24337            for(i = 0; i < len; ++i){
24338                trans = queue[i];
24339                data[trans[0]] = trans[1];
24340            }
24341            if(this.fireEvent('beforesave', this, data) !== false){
24342                for(i = 0; i < len; ++i){
24343                    trans = queue[i];
24344                    this.doTransaction(trans[0], trans[1], batch);
24345                }
24346                return batch;
24347            }
24348        }
24349        return -1;
24350    },
24351
24352    
24353    doTransaction : function(action, rs, batch) {
24354        function transaction(records) {
24355            try{
24356                this.execute(action, records, undefined, batch);
24357            }catch (e){
24358                this.handleException(e);
24359            }
24360        }
24361        if(this.batch === false){
24362            for(var i = 0, len = rs.length; i < len; i++){
24363                transaction.call(this, rs[i]);
24364            }
24365        }else{
24366            transaction.call(this, rs);
24367        }
24368    },
24369
24370    
24371    addToBatch : function(batch){
24372        var b = this.batches,
24373            key = this.batchKey + batch,
24374            o = b[key];
24375
24376        if(!o){
24377            b[key] = o = {
24378                id: batch,
24379                count: 0,
24380                data: {}
24381            };
24382        }
24383        ++o.count;
24384    },
24385
24386    removeFromBatch : function(batch, action, data){
24387        var b = this.batches,
24388            key = this.batchKey + batch,
24389            o = b[key],
24390            arr;
24391
24392
24393        if(o){
24394            arr = o.data[action] || [];
24395            o.data[action] = arr.concat(data);
24396            if(o.count === 1){
24397                data = o.data;
24398                delete b[key];
24399                this.fireEvent('save', this, batch, data);
24400            }else{
24401                --o.count;
24402            }
24403        }
24404    },
24405
24406    
24407    
24408    createCallback : function(action, rs, batch) {
24409        var actions = Ext.data.Api.actions;
24410        return (action == 'read') ? this.loadRecords : function(data, response, success) {
24411            
24412            this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
24413            
24414            if (success === true) {
24415                this.fireEvent('write', this, action, data, response, rs);
24416            }
24417            this.removeFromBatch(batch, action, data);
24418        };
24419    },
24420
24421    
24422    
24423    
24424    clearModified : function(rs) {
24425        if (Ext.isArray(rs)) {
24426            for (var n=rs.length-1;n>=0;n--) {
24427                this.modified.splice(this.modified.indexOf(rs[n]), 1);
24428            }
24429        } else {
24430            this.modified.splice(this.modified.indexOf(rs), 1);
24431        }
24432    },
24433
24434    
24435    reMap : function(record) {
24436        if (Ext.isArray(record)) {
24437            for (var i = 0, len = record.length; i < len; i++) {
24438                this.reMap(record[i]);
24439            }
24440        } else {
24441            delete this.data.map[record._phid];
24442            this.data.map[record.id] = record;
24443            var index = this.data.keys.indexOf(record._phid);
24444            this.data.keys.splice(index, 1, record.id);
24445            delete record._phid;
24446        }
24447    },
24448
24449    
24450    onCreateRecords : function(success, rs, data) {
24451        if (success === true) {
24452            try {
24453                this.reader.realize(rs, data);
24454            }
24455            catch (e) {
24456                this.handleException(e);
24457                if (Ext.isArray(rs)) {
24458                    
24459                    this.onCreateRecords(success, rs, data);
24460                }
24461            }
24462        }
24463    },
24464
24465    
24466    onUpdateRecords : function(success, rs, data) {
24467        if (success === true) {
24468            try {
24469                this.reader.update(rs, data);
24470            } catch (e) {
24471                this.handleException(e);
24472                if (Ext.isArray(rs)) {
24473                    
24474                    this.onUpdateRecords(success, rs, data);
24475                }
24476            }
24477        }
24478    },
24479
24480    
24481    onDestroyRecords : function(success, rs, data) {
24482        
24483        rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
24484        for (var i=0,len=rs.length;i<len;i++) {
24485            this.removed.splice(this.removed.indexOf(rs[i]), 1);
24486        }
24487        if (success === false) {
24488            
24489            
24490            for (i=rs.length-1;i>=0;i--) {
24491                this.insert(rs[i].lastIndex, rs[i]);    
24492            }
24493        }
24494    },
24495
24496    
24497    handleException : function(e) {
24498        
24499        Ext.handleError(e);
24500    },
24501
24502    
24503    reload : function(options){
24504        this.load(Ext.applyIf(options||{}, this.lastOptions));
24505    },
24506
24507    
24508    
24509    loadRecords : function(o, options, success){
24510        var i, len;
24511        
24512        if (this.isDestroyed === true) {
24513            return;
24514        }
24515        if(!o || success === false){
24516            if(success !== false){
24517                this.fireEvent('load', this, [], options);
24518            }
24519            if(options.callback){
24520                options.callback.call(options.scope || this, [], options, false, o);
24521            }
24522            return;
24523        }
24524        var r = o.records, t = o.totalRecords || r.length;
24525        if(!options || options.add !== true){
24526            if(this.pruneModifiedRecords){
24527                this.modified = [];
24528            }
24529            for(i = 0, len = r.length; i < len; i++){
24530                r[i].join(this);
24531            }
24532            if(this.snapshot){
24533                this.data = this.snapshot;
24534                delete this.snapshot;
24535            }
24536            this.clearData();
24537            this.data.addAll(r);
24538            this.totalLength = t;
24539            this.applySort();
24540            this.fireEvent('datachanged', this);
24541        }else{
24542            var toAdd = [],
24543                rec,
24544                cnt = 0;
24545            for(i = 0, len = r.length; i < len; ++i){
24546                rec = r[i];
24547                if(this.indexOfId(rec.id) > -1){
24548                    this.doUpdate(rec);
24549                }else{
24550                    toAdd.push(rec);
24551                    ++cnt;
24552                }
24553            }
24554            this.totalLength = Math.max(t, this.data.length + cnt);
24555            this.add(toAdd);
24556        }
24557        this.fireEvent('load', this, r, options);
24558        if(options.callback){
24559            options.callback.call(options.scope || this, r, options, true);
24560        }
24561    },
24562
24563    
24564    loadData : function(o, append){
24565        var r = this.reader.readRecords(o);
24566        this.loadRecords(r, {add: append}, true);
24567    },
24568
24569    
24570    getCount : function(){
24571        return this.data.length || 0;
24572    },
24573
24574    
24575    getTotalCount : function(){
24576        return this.totalLength || 0;
24577    },
24578
24579    
24580    getSortState : function(){
24581        return this.sortInfo;
24582    },
24583
24584    
24585    applySort : function(){
24586        if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
24587            this.sortData();
24588        }
24589    },
24590
24591    
24592    sortData : function() {
24593        var sortInfo  = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
24594            direction = sortInfo.direction || "ASC",
24595            sorters   = sortInfo.sorters,
24596            sortFns   = [];
24597
24598        
24599        if (!this.hasMultiSort) {
24600            sorters = [{direction: direction, field: sortInfo.field}];
24601        }
24602
24603        
24604        for (var i=0, j = sorters.length; i < j; i++) {
24605            sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
24606        }
24607        
24608        if (sortFns.length == 0) {
24609            return;
24610        }
24611
24612        
24613        
24614        var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
24615
24616        
24617        var fn = function(r1, r2) {
24618          var result = sortFns[0].call(this, r1, r2);
24619
24620          
24621          if (sortFns.length > 1) {
24622              for (var i=1, j = sortFns.length; i < j; i++) {
24623                  result = result || sortFns[i].call(this, r1, r2);
24624              }
24625          }
24626
24627          return directionModifier * result;
24628        };
24629
24630        
24631        this.data.sort(direction, fn);
24632        if (this.snapshot && this.snapshot != this.data) {
24633            this.snapshot.sort(direction, fn);
24634        }
24635    },
24636
24637    
24638    createSortFunction: function(field, direction) {
24639        direction = direction || "ASC";
24640        var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
24641
24642        var sortType = this.fields.get(field).sortType;
24643
24644        
24645        
24646        return function(r1, r2) {
24647            var v1 = sortType(r1.data[field]),
24648                v2 = sortType(r2.data[field]);
24649
24650            return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
24651        };
24652    },
24653
24654    
24655    setDefaultSort : function(field, dir) {
24656        dir = dir ? dir.toUpperCase() : 'ASC';
24657        this.sortInfo = {field: field, direction: dir};
24658        this.sortToggle[field] = dir;
24659    },
24660
24661    
24662    sort : function(fieldName, dir) {
24663        if (Ext.isArray(arguments[0])) {
24664            return this.multiSort.call(this, fieldName, dir);
24665        } else {
24666            return this.singleSort(fieldName, dir);
24667        }
24668    },
24669
24670    
24671    singleSort: function(fieldName, dir) {
24672        var field = this.fields.get(fieldName);
24673        if (!field) {
24674            return false;
24675        }
24676
24677        var name       = field.name,
24678            sortInfo   = this.sortInfo || null,
24679            sortToggle = this.sortToggle ? this.sortToggle[name] : null;
24680
24681        if (!dir) {
24682            if (sortInfo && sortInfo.field == name) { 
24683                dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
24684            } else {
24685                dir = field.sortDir;
24686            }
24687        }
24688
24689        this.sortToggle[name] = dir;
24690        this.sortInfo = {field: name, direction: dir};
24691        this.hasMultiSort = false;
24692
24693        if (this.remoteSort) {
24694            if (!this.load(this.lastOptions)) {
24695                if (sortToggle) {
24696                    this.sortToggle[name] = sortToggle;
24697                }
24698                if (sortInfo) {
24699                    this.sortInfo = sortInfo;
24700                }
24701            }
24702        } else {
24703            this.applySort();
24704            this.fireEvent('datachanged', this);
24705        }
24706        return true;
24707    },
24708
24709    
24710    multiSort: function(sorters, direction) {
24711        this.hasMultiSort = true;
24712        direction = direction || "ASC";
24713
24714        
24715        if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
24716            direction = direction.toggle("ASC", "DESC");
24717        }
24718
24719        
24720        this.multiSortInfo = {
24721            sorters  : sorters,
24722            direction: direction
24723        };
24724        
24725        if (this.remoteSort) {
24726            this.singleSort(sorters[0].field, sorters[0].direction);
24727
24728        } else {
24729            this.applySort();
24730            this.fireEvent('datachanged', this);
24731        }
24732    },
24733
24734    
24735    each : function(fn, scope){
24736        this.data.each(fn, scope);
24737    },
24738
24739    
24740    getModifiedRecords : function(){
24741        return this.modified;
24742    },
24743
24744    
24745    sum : function(property, start, end){
24746        var rs = this.data.items, v = 0;
24747        start = start || 0;
24748        end = (end || end === 0) ? end : rs.length-1;
24749
24750        for(var i = start; i <= end; i++){
24751            v += (rs[i].data[property] || 0);
24752        }
24753        return v;
24754    },
24755
24756    
24757    createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
24758        if(Ext.isEmpty(value, false)){
24759            return false;
24760        }
24761        value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
24762        return function(r) {
24763            return value.test(r.data[property]);
24764        };
24765    },
24766
24767    
24768    createMultipleFilterFn: function(filters) {
24769        return function(record) {
24770            var isMatch = true;
24771
24772            for (var i=0, j = filters.length; i < j; i++) {
24773                var filter = filters[i],
24774                    fn     = filter.fn,
24775                    scope  = filter.scope;
24776
24777                isMatch = isMatch && fn.call(scope, record);
24778            }
24779
24780            return isMatch;
24781        };
24782    },
24783
24784    
24785    filter : function(property, value, anyMatch, caseSensitive, exactMatch){
24786        var fn;
24787        
24788        if (Ext.isObject(property)) {
24789            property = [property];
24790        }
24791
24792        if (Ext.isArray(property)) {
24793            var filters = [];
24794
24795            
24796            for (var i=0, j = property.length; i < j; i++) {
24797                var filter = property[i],
24798                    func   = filter.fn,
24799                    scope  = filter.scope || this;
24800
24801                
24802                if (!Ext.isFunction(func)) {
24803                    func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
24804                }
24805
24806                filters.push({fn: func, scope: scope});
24807            }
24808
24809            fn = this.createMultipleFilterFn(filters);
24810        } else {
24811            
24812            fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
24813        }
24814
24815        return fn ? this.filterBy(fn) : this.clearFilter();
24816    },
24817
24818    
24819    filterBy : function(fn, scope){
24820        this.snapshot = this.snapshot || this.data;
24821        this.data = this.queryBy(fn, scope || this);
24822        this.fireEvent('datachanged', this);
24823    },
24824
24825    
24826    clearFilter : function(suppressEvent){
24827        if(this.isFiltered()){
24828            this.data = this.snapshot;
24829            delete this.snapshot;
24830            if(suppressEvent !== true){
24831                this.fireEvent('datachanged', this);
24832            }
24833        }
24834    },
24835
24836    
24837    isFiltered : function(){
24838        return !!this.snapshot && this.snapshot != this.data;
24839    },
24840
24841    
24842    query : function(property, value, anyMatch, caseSensitive){
24843        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24844        return fn ? this.queryBy(fn) : this.data.clone();
24845    },
24846
24847    
24848    queryBy : function(fn, scope){
24849        var data = this.snapshot || this.data;
24850        return data.filterBy(fn, scope||this);
24851    },
24852
24853    
24854    find : function(property, value, start, anyMatch, caseSensitive){
24855        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24856        return fn ? this.data.findIndexBy(fn, null, start) : -1;
24857    },
24858
24859    
24860    findExact: function(property, value, start){
24861        return this.data.findIndexBy(function(rec){
24862            return rec.get(property) === value;
24863        }, this, start);
24864    },
24865
24866    
24867    findBy : function(fn, scope, start){
24868        return this.data.findIndexBy(fn, scope, start);
24869    },
24870
24871    
24872    collect : function(dataIndex, allowNull, bypassFilter){
24873        var d = (bypassFilter === true && this.snapshot) ?
24874                this.snapshot.items : this.data.items;
24875        var v, sv, r = [], l = {};
24876        for(var i = 0, len = d.length; i < len; i++){
24877            v = d[i].data[dataIndex];
24878            sv = String(v);
24879            if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
24880                l[sv] = true;
24881                r[r.length] = v;
24882            }
24883        }
24884        return r;
24885    },
24886
24887    
24888    afterEdit : function(record){
24889        if(this.modified.indexOf(record) == -1){
24890            this.modified.push(record);
24891        }
24892        this.fireEvent('update', this, record, Ext.data.Record.EDIT);
24893    },
24894
24895    
24896    afterReject : function(record){
24897        this.modified.remove(record);
24898        this.fireEvent('update', this, record, Ext.data.Record.REJECT);
24899    },
24900
24901    
24902    afterCommit : function(record){
24903        this.modified.remove(record);
24904        this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
24905    },
24906
24907    
24908    commitChanges : function(){
24909        var modified = this.modified.slice(0),
24910            length   = modified.length,
24911            i;
24912            
24913        for (i = 0; i < length; i++){
24914            modified[i].commit();
24915        }
24916        
24917        this.modified = [];
24918        this.removed  = [];
24919    },
24920
24921    
24922    rejectChanges : function() {
24923        var modified = this.modified.slice(0),
24924            removed  = this.removed.slice(0).reverse(),
24925            mLength  = modified.length,
24926            rLength  = removed.length,
24927            i;
24928        
24929        for (i = 0; i < mLength; i++) {
24930            modified[i].reject();
24931        }
24932        
24933        for (i = 0; i < rLength; i++) {
24934            this.insert(removed[i].lastIndex || 0, removed[i]);
24935            removed[i].reject();
24936        }
24937        
24938        this.modified = [];
24939        this.removed  = [];
24940    },
24941
24942    
24943    onMetaChange : function(meta){
24944        this.recordType = this.reader.recordType;
24945        this.fields = this.recordType.prototype.fields;
24946        delete this.snapshot;
24947        if(this.reader.meta.sortInfo){
24948            this.sortInfo = this.reader.meta.sortInfo;
24949        }else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
24950            delete this.sortInfo;
24951        }
24952        if(this.writer){
24953            this.writer.meta = this.reader.meta;
24954        }
24955        this.modified = [];
24956        this.fireEvent('metachange', this, this.reader.meta);
24957    },
24958
24959    
24960    findInsertIndex : function(record){
24961        this.suspendEvents();
24962        var data = this.data.clone();
24963        this.data.add(record);
24964        this.applySort();
24965        var index = this.data.indexOf(record);
24966        this.data = data;
24967        this.resumeEvents();
24968        return index;
24969    },
24970
24971    
24972    setBaseParam : function (name, value){
24973        this.baseParams = this.baseParams || {};
24974        this.baseParams[name] = value;
24975    }
24976});
24977
24978Ext.reg('store', Ext.data.Store);
24979
24980
24981Ext.data.Store.Error = Ext.extend(Ext.Error, {
24982    name: 'Ext.data.Store'
24983});
24984Ext.apply(Ext.data.Store.Error.prototype, {
24985    lang: {
24986        'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
24987    }
24988});
24989
24990Ext.data.Field = Ext.extend(Object, {
24991    
24992    constructor : function(config){
24993        if(Ext.isString(config)){
24994            config = {name: config};
24995        }
24996        Ext.apply(this, config);
24997        
24998        var types = Ext.data.Types,
24999            st = this.sortType,
25000            t;
25001
25002        if(this.type){
25003            if(Ext.isString(this.type)){
25004                this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
25005            }
25006        }else{
25007            this.type = types.AUTO;
25008        }
25009
25010        
25011        if(Ext.isString(st)){
25012            this.sortType = Ext.data.SortTypes[st];
25013        }else if(Ext.isEmpty(st)){
25014            this.sortType = this.type.sortType;
25015        }
25016
25017        if(!this.convert){
25018            this.convert = this.type.convert;
25019        }
25020    },
25021    
25022    
25023    
25024    
25025    
25026    dateFormat: null,
25027    
25028    
25029    useNull: false,
25030    
25031    
25032    defaultValue: "",
25033    
25034    mapping: null,
25035    
25036    sortType : null,
25037    
25038    sortDir : "ASC",
25039    
25040    allowBlank : true
25041});
25042
25043Ext.data.DataReader = function(meta, recordType){
25044    
25045    this.meta = meta;
25046    
25047    this.recordType = Ext.isArray(recordType) ?
25048        Ext.data.Record.create(recordType) : recordType;
25049
25050    
25051    if (this.recordType){
25052        this.buildExtractors();
25053    }
25054};
25055
25056Ext.data.DataReader.prototype = {
25057    
25058    
25059    getTotal: Ext.emptyFn,
25060    
25061    getRoot: Ext.emptyFn,
25062    
25063    getMessage: Ext.emptyFn,
25064    
25065    getSuccess: Ext.emptyFn,
25066    
25067    getId: Ext.emptyFn,
25068    
25069    buildExtractors : Ext.emptyFn,
25070    
25071    extractValues : Ext.emptyFn,
25072
25073    
25074    realize: function(rs, data){
25075        if (Ext.isArray(rs)) {
25076            for (var i = rs.length - 1; i >= 0; i--) {
25077                
25078                if (Ext.isArray(data)) {
25079                    this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
25080                }
25081                else {
25082                    
25083                    
25084                    this.realize(rs.splice(i,1).shift(), data);
25085                }
25086            }
25087        }
25088        else {
25089            
25090            if (Ext.isArray(data) && data.length == 1) {
25091                data = data.shift();
25092            }
25093            if (!this.isData(data)) {
25094                
25095                
25096                throw new Ext.data.DataReader.Error('realize', rs);
25097            }
25098            rs.phantom = false; 
25099            rs._phid = rs.id;  
25100            rs.id = this.getId(data);
25101            rs.data = data;
25102
25103            rs.commit();
25104            rs.store.reMap(rs);
25105        }
25106    },
25107
25108    
25109    update : function(rs, data) {
25110        if (Ext.isArray(rs)) {
25111            for (var i=rs.length-1; i >= 0; i--) {
25112                if (Ext.isArray(data)) {
25113                    this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
25114                }
25115                else {
25116                    
25117                    
25118                    this.update(rs.splice(i,1).shift(), data);
25119                }
25120            }
25121        }
25122        else {
25123            
25124            if (Ext.isArray(data) && data.length == 1) {
25125                data = data.shift();
25126            }
25127            if (this.isData(data)) {
25128                rs.data = Ext.apply(rs.data, data);
25129            }
25130            rs.commit();
25131        }
25132    },
25133
25134    
25135    extractData : function(root, returnRecords) {
25136        
25137        var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
25138
25139        var rs = [];
25140
25141        
25142        
25143        if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
25144            root = [root];
25145        }
25146        var f       = this.recordType.prototype.fields,
25147            fi      = f.items,
25148            fl      = f.length,
25149            rs      = [];
25150        if (returnRecords === true) {
25151            var Record = this.recordType;
25152            for (var i = 0; i < root.length; i++) {
25153                var n = root[i];
25154                var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
25155                record[rawName] = n;    
25156                rs.push(record);
25157            }
25158        }
25159        else {
25160            for (var i = 0; i < root.length; i++) {
25161                var data = this.extractValues(root[i], fi, fl);
25162                data[this.meta.idProperty] = this.getId(root[i]);
25163                rs.push(data);
25164            }
25165        }
25166        return rs;
25167    },
25168
25169    
25170    isData : function(data) {
25171        return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
25172    },
25173
25174    
25175    onMetaChange : function(meta){
25176        delete this.ef;
25177        this.meta = meta;
25178        this.recordType = Ext.data.Record.create(meta.fields);
25179        this.buildExtractors();
25180    }
25181};
25182
25183
25184Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
25185    constructor : function(message, arg) {
25186        this.arg = arg;
25187        Ext.Error.call(this, message);
25188    },
25189    name: 'Ext.data.DataReader'
25190});
25191Ext.apply(Ext.data.DataReader.Error.prototype, {
25192    lang : {
25193        'update': "#update received invalid data from server.  Please see docs for DataReader#update and review your DataReader configuration.",
25194        'realize': "#realize was called with invalid remote-data.  Please see the docs for DataReader#realize and review your DataReader configuration.",
25195        'invalid-response': "#readResponse received an invalid response from the server."
25196    }
25197});
25198
25199Ext.data.DataWriter = function(config){
25200    Ext.apply(this, config);
25201};
25202Ext.data.DataWriter.prototype = {
25203
25204    
25205    writeAllFields : false,
25206    
25207    listful : false,    
25208
25209    
25210    apply : function(params, baseParams, action, rs) {
25211        var data    = [],
25212        renderer    = action + 'Record';
25213        
25214        if (Ext.isArray(rs)) {
25215            Ext.each(rs, function(rec){
25216                data.push(this[renderer](rec));
25217            }, this);
25218        }
25219        else if (rs instanceof Ext.data.Record) {
25220            data = this[renderer](rs);
25221        }
25222        this.render(params, baseParams, data);
25223    },
25224
25225    
25226    render : Ext.emptyFn,
25227
25228    
25229    updateRecord : Ext.emptyFn,
25230
25231    
25232    createRecord : Ext.emptyFn,
25233
25234    
25235    destroyRecord : Ext.emptyFn,
25236
25237    
25238    toHash : function(rec, config) {
25239        var map = rec.fields.map,
25240            data = {},
25241            raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
25242            m;
25243        Ext.iterate(raw, function(prop, value){
25244            if((m = map[prop])){
25245                data[m.mapping ? m.mapping : m.name] = value;
25246            }
25247        });
25248        
25249        
25250        
25251        if (rec.phantom) {
25252            if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
25253                delete data[this.meta.idProperty];
25254            }
25255        } else {
25256            data[this.meta.idProperty] = rec.id;
25257        }
25258        return data;
25259    },
25260
25261    
25262    toArray : function(data) {
25263        var fields = [];
25264        Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
25265        return fields;
25266    }
25267};
25268Ext.data.DataProxy = function(conn){
25269    
25270    
25271    conn = conn || {};
25272
25273    
25274    
25275    
25276
25277    this.api     = conn.api;
25278    this.url     = conn.url;
25279    this.restful = conn.restful;
25280    this.listeners = conn.listeners;
25281
25282    
25283    this.prettyUrls = conn.prettyUrls;
25284
25285    
25286
25287    this.addEvents(
25288        
25289        'exception',
25290        
25291        'beforeload',
25292        
25293        'load',
25294        
25295        'loadexception',
25296        
25297        'beforewrite',
25298        
25299        'write'
25300    );
25301    Ext.data.DataProxy.superclass.constructor.call(this);
25302
25303    
25304    try {
25305        Ext.data.Api.prepare(this);
25306    } catch (e) {
25307        if (e instanceof Ext.data.Api.Error) {
25308            e.toConsole();
25309        }
25310    }
25311    
25312    Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
25313};
25314
25315Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
25316    
25317    restful: false,
25318
25319    
25320    setApi : function() {
25321        if (arguments.length == 1) {
25322            var valid = Ext.data.Api.isValid(arguments[0]);
25323            if (valid === true) {
25324                this.api = arguments[0];
25325            }
25326            else {
25327                throw new Ext.data.Api.Error('invalid', valid);
25328            }
25329        }
25330        else if (arguments.length == 2) {
25331            if (!Ext.data.Api.isAction(arguments[0])) {
25332                throw new Ext.data.Api.Error('invalid', arguments[0]);
25333            }
25334            this.api[arguments[0]] = arguments[1];
25335        }
25336        Ext.data.Api.prepare(this);
25337    },
25338
25339    
25340    isApiAction : function(action) {
25341        return (this.api[action]) ? true : false;
25342    },
25343
25344    
25345    request : function(action, rs, params, reader, callback, scope, options) {
25346        if (!this.api[action] && !this.load) {
25347            throw new Ext.data.DataProxy.Error('action-undefined', action);
25348        }
25349        params = params || {};
25350        if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
25351            this.doRequest.apply(this, arguments);
25352        }
25353        else {
25354            callback.call(scope || this, null, options, false);
25355        }
25356    },
25357
25358
25359    
25360    load : null,
25361
25362    
25363    doRequest : function(action, rs, params, reader, callback, scope, options) {
25364        
25365        
25366        
25367        this.load(params, reader, callback, scope, options);
25368    },
25369
25370    
25371    onRead : Ext.emptyFn,
25372    
25373    onWrite : Ext.emptyFn,
25374    
25375    buildUrl : function(action, record) {
25376        record = record || null;
25377
25378        
25379        
25380        
25381        var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
25382        if (!url) {
25383            throw new Ext.data.Api.Error('invalid-url', action);
25384        }
25385
25386        
25387        
25388        
25389        
25390        
25391        
25392        var provides = null;
25393        var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
25394        if (m) {
25395            provides = m[2];    
25396            url      = m[1];    
25397        }
25398        
25399        if ((this.restful === true || this.prettyUrls === true) && record 
25399instanceof Ext.data.Record && !record.phantom) {
25400            url += '/' + record.id;
25401        }
25402        return (provides === null) ? url : url + provides;
25403    },
25404
25405    
25406    destroy: function(){
25407        this.purgeListeners();
25408    }
25409});
25410
25411
25412
25413Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
25414Ext.util.Observable.call(Ext.data.DataProxy);
25415
25416
25417Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
25418    constructor : function(message, arg) {
25419        this.arg = arg;
25420        Ext.Error.call(this, message);
25421    },
25422    name: 'Ext.data.DataProxy'
25423});
25424Ext.apply(Ext.data.DataProxy.Error.prototype, {
25425    lang: {
25426        'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function.  Please review your Proxy url/api-configuration.",
25427        'api-invalid': 'Recieved an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
25428    }
25429});
25430
25431
25432
25433Ext.data.Request = function(params) {
25434    Ext.apply(this, params);
25435};
25436Ext.data.Request.prototype = {
25437    
25438    action : undefined,
25439    
25440    rs : undefined,
25441    
25442    params: undefined,
25443    
25444    callback : Ext.emptyFn,
25445    
25446    scope : undefined,
25447    
25448    reader : undefined
25449};
25450
25451Ext.data.Response = function(params) {
25452    Ext.apply(this, params);
25453};
25454Ext.data.Response.prototype = {
25455    
25456    action: undefined,
25457    
25458    success : undefined,
25459    
25460    message : undefined,
25461    
25462    data: undefined,
25463    
25464    raw: undefined,
25465    
25466    records: undefined
25467};
25468
25469Ext.data.ScriptTagProxy = function(config){
25470    Ext.apply(this, config);
25471
25472    Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
25473
25474    this.head = document.getElementsByTagName("head")[0];
25475
25476    
25477};
25478
25479Ext.data.ScriptTagProxy.TRANS_ID = 1000;
25480
25481Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
25482    
25483    
25484    timeout : 30000,
25485    
25486    callbackParam : "callback",
25487    
25488    nocache : true,
25489
25490    
25491    doRequest : function(action, rs, params, reader, callback, scope, arg) {
25492        var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
25493
25494        var url = this.buildUrl(action, rs);
25495        if (!url) {
25496            throw new Ext.data.Api.Error('invalid-url', url);
25497        }
25498        url = Ext.urlAppend(url, p);
25499
25500        if(this.nocache){
25501            url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
25502        }
25503        var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
25504        var trans = {
25505            id : transId,
25506            action: action,
25507            cb : "stcCallback"+transId,
25508            scriptId : "stcScript"+transId,
25509            params : params,
25510            arg : arg,
25511            url : url,
25512            callback : callback,
25513            scope : scope,
25514            reader : reader
25515        };
25516        window[trans.cb] = this.createCallback(action, rs, trans);
25517        url += String.format("&{0}={1}", this.callbackParam, trans.cb);
25518        if(this.autoAbort !== false){
25519            this.abort();
25520        }
25521
25522        trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
25523
25524        var script = document.createElement("script");
25525        script.setAttribute("src", url);
25526        script.setAttribute("type", "text/javascript");
25527        script.setAttribute("id", trans.scriptId);
25528        this.head.appendChild(script);
25529
25530        this.trans = trans;
25531    },
25532
25533    
25534    createCallback : function(action, rs, trans) {
25535        var self = this;
25536        return function(res) {
25537            self.trans = false;
25538            self.destroyTrans(trans, true);
25539            if (action === Ext.data.Api.actions.read) {
25540                self.onRead.call(self, action, trans, res);
25541            } else {
25542                self.onWrite.call(self, action, trans, res, rs);
25543            }
25544        };
25545    },
25546    
25547    onRead : function(action, trans, res) {
25548        var result;
25549        try {
25550            result = trans.reader.readRecords(res);
25551        }catch(e){
25552            
25553            this.fireEvent("loadexception", this, trans, res, e);
25554
25555            this.fireEvent('exception', this, 'response', action, trans, res, e);
25556            trans.callback.call(trans.scope||window, null, trans.arg, false);
25557            return;
25558        }
25559        if (result.success === false) {
25560            
25561            this.fireEvent('loadexception', this, trans, res);
25562
25563            this.fireEvent('exception', this, 'remote', action, trans, res, null);
25564        } else {
25565            this.fireEvent("load", this, res, trans.arg);
25566        }
25567        trans.callback.call(trans.scope||window, result, trans.arg, result.success);
25568    },
25569    
25570    onWrite : function(action, trans, response, rs) {
25571        var reader = trans.reader;
25572        try {
25573            
25574            var res = reader.readResponse(action, response);
25575        } catch (e) {
25576            this.fireEvent('exception', this, 'response', action, trans, res, e);
25577            trans.callback.call(trans.scope||window, null, res, false);
25578            return;
25579        }
25580        if(!res.success === true){
25581            this.fireEvent('exception', this, 'remote', action, trans, res, rs);
25582            trans.callback.call(trans.scope||window, null, res, false);
25583            return;
25584        }
25585        this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
25586        trans.callback.call(trans.scope||window, res.data, res, true);
25587    },
25588
25589    
25590    isLoading : function(){
25591        return this.trans ? true : false;
25592    },
25593
25594    
25595    abort : function(){
25596        if(this.isLoading()){
25597            this.destroyTrans(this.trans);
25598        }
25599    },
25600
25601    
25602    destroyTrans : function(trans, isLoaded){
25603        this.head.removeChild(document.getElementById(trans.scriptId));
25604        clearTimeout(trans.timeoutId);
25605        if(isLoaded){
25606            window[trans.cb] = undefined;
25607            try{
25608                delete window[trans.cb];
25609            }catch(e){}
25610        }else{
25611            
25612            window[trans.cb] = function(){
25613                window[trans.cb] = undefined;
25614                try{
25615                    delete window[trans.cb];
25616                }catch(e){}
25617            };
25618        }
25619    },
25620
25621    
25622    handleFailure : function(trans){
25623        this.trans = false;
25624        this.destroyTrans(trans, false);
25625        if (trans.action === Ext.data.Api.actions.read) {
25626            
25627            this.fireEvent("loadexception", this, null, trans.arg);
25628        }
25629
25630        this.fireEvent('exception', this, 'response', trans.action, {
25631            response: null,
25632            options: trans.arg
25633        });
25634        trans.callback.call(trans.scope||window, null, trans.arg, false);
25635    },
25636
25637    
25638    destroy: function(){
25639        this.abort();
25640        Ext.data.ScriptTagProxy.superclass.destroy.call(this);
25641    }
25642});
25643Ext.data.HttpProxy = function(conn){
25644    Ext.data.HttpProxy.superclass.constructor.call(this, conn);
25645
25646    
25647    this.conn = conn;
25648
25649    
25650    
25651    
25652    
25653    this.conn.url = null;
25654
25655    this.useAjax = !conn || !conn.events;
25656
25657    
25658    var actions = Ext.data.Api.actions;
25659    this.activeRequest = {};
25660    for (var verb in actions) {
25661        this.activeRequest[actions[verb]] = undefined;
25662    }
25663};
25664
25665Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
25666    
25667    getConnection : function() {
25668        return this.useAjax ? Ext.Ajax : this.conn;
25669    },
25670
25671    
25672    setUrl : function(url, makePermanent) {
25673        this.conn.url = url;
25674        if (makePermanent === true) {
25675            this.url = url;
25676            this.api = null;
25677            Ext.data.Api.prepare(this);
25678        }
25679    },
25680
25681    
25682    doRequest : function(action, rs, params, reader, cb, scope, arg) {
25683        var  o = {
25684            method: (this.api[action]) ? this.api[action]['method'] : undefined,
25685            request: {
25686                callback : cb,
25687                scope : scope,
25688                arg : arg
25689            },
25690            reader: reader,
25691            callback : this.createCallback(action, rs),
25692            scope: this
25693        };
25694
25695        
25696        
25697        if (params.jsonData) {
25698            o.jsonData = params.jsonData;
25699        } else if (params.xmlData) {
25700            o.xmlData = params.xmlData;
25701        } else {
25702            o.params = params || {};
25703        }
25704        
25705        
25706        
25707        this.conn.url = this.buildUrl(action, rs);
25708
25709        if(this.useAjax){
25710
25711            Ext.applyIf(o, this.conn);
25712
25713            
25714            if (this.activeRequest[action]) {
25715                
25716                
25717                
25718                
25719                
25720            }
25721            this.activeRequest[action] = Ext.Ajax.request(o);
25722        }else{
25723            this.conn.request(o);
25724        }
25725        
25726        this.conn.url = null;
25727    },
25728
25729    
25730    createCallback : function(action, rs) {
25731        return function(o, success, response) {
25732            this.activeRequest[action] = undefined;
25733            if (!success) {
25734                if (action === Ext.data.Api.actions.read) {
25735                    
25736                    
25737                    this.fireEvent('loadexception', this, o, response);
25738                }
25739                this.fireEvent('exception', this, 'response', action, o, response);
25740                o.request.callback.call(o.request.scope, null, o.request.arg, false);
25741                return;
25742            }
25743            if (action === Ext.data.Api.actions.read) {
25744                this.onRead(action, o, response);
25745            } else {
25746                this.onWrite(action, o, response, rs);
25747            }
25748        };
25749    },
25750
25751    
25752    onRead : function(action, o, response) {
25753        var result;
25754        try {
25755            result = o.reader.read(response);
25756        }catch(e){
25757            
25758            
25759            this.fireEvent('loadexception', this, o, response, e);
25760
25761            this.fireEvent('exception', this, 'response', action, o, response, e);
25762            o.request.callback.call(o.request.scope, null, o.request.arg, false);
25763            return;
25764        }
25765        if (result.success === false) {
25766            
25767            
25768            this.fireEvent('loadexception', this, o, response);
25769
25770            
25771            var res = o.reader.readResponse(action, response);
25772            this.fireEvent('exception', this, 'remote', action, o, res, null);
25773        }
25774        else {
25775            this.fireEvent('load', this, o, o.request.arg);
25776        }
25777        
25778        
25779        
25780        o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
25781    },
25782    
25783    onWrite : function(action, o, response, rs) {
25784        var reader = o.reader;
25785        var res;
25786        try {
25787            res = reader.readResponse(action, response);
25788        } catch (e) {
25789            this.fireEvent('exception', this, 'response', action, o, response, e);
25790            o.request.callback.call(o.request.scope, null, o.request.arg, false);
25791            return;
25792        }
25793        if (res.success === true) {
25794            this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
25795        } else {
25796            this.fireEvent('exception', this, 'remote', action, o, res, rs);
25797        }
25798        
25799        
25800        
25801        o.request.callback.call(o.request.scope, res.data, res, res.success);
25802    },
25803
25804    
25805    destroy: function(){
25806        if(!this.useAjax){
25807            this.conn.abort();
25808        }else if(this.activeRequest){
25809            var actions = Ext.data.Api.actions;
25810            for (var verb in actions) {
25811                if(this.activeRequest[actions[verb]]){
25812                    Ext.Ajax.abort(this.activeRequest[actions[verb]]);
25813                }
25814            }
25815        }
25816        Ext.data.HttpProxy.superclass.destroy.call(this);
25817    }
25818});
25819Ext.data.MemoryProxy = function(data){
25820    
25821    var api = {};
25822    api[Ext.data.Api.actions.read] = true;
25823    Ext.data.MemoryProxy.superclass.constructor.call(this, {
25824        api: api
25825    });
25826    this.data = data;
25827};
25828
25829Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
25830    
25831
25832       
25833    doRequest : function(action, rs, params, reader, callback, scope, arg) {
25834        
25835        params = params || {};
25836        var result;
25837        try {
25838            result = reader.readRecords(this.data);
25839        }catch(e){
25840            
25841            this.fireEvent("loadexception", this, null, arg, e);
25842
25843            this.fireEvent('exception', this, 'response', action, arg, null, e);
25844            callback.call(scope, null, arg, false);
25845            return;
25846        }
25847        callback.call(scope, result, arg, true);
25848    }
25849});
25850Ext.data.Types = new function(){
25851    var st = Ext.data.SortTypes;
25852    Ext.apply(this, {
25853        
25854        stripRe: /[\$,%]/g,
25855        
25856        
25857        AUTO: {
25858            convert: function(v){ return v; },
25859            sortType: st.none,
25860            type: 'auto'
25861        },
25862
25863        
25864        STRING: {
25865            convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
25866            sortType: st.asUCString,
25867            type: 'string'
25868        },
25869
25870        
25871        INT: {
25872            convert: function(v){
25873                return v !== undefined && v !== null && v !== '' ?
25874                    parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25875            },
25876            sortType: st.none,
25877            type: 'int'
25878        },
25879        
25880        
25881        FLOAT: {
25882            convert: function(v){
25883                return v !== undefined && v !== null && v !== '' ?
25884                    parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25885            },
25886            sortType: st.none,
25887            type: 'float'
25888        },
25889        
25890        
25891        BOOL: {
25892            convert: function(v){ return v === true || v === 'true' || v == 1; },
25893            sortType: st.none,
25894            type: 'bool'
25895        },
25896        
25897        
25898        DATE: {
25899            convert: function(v){
25900                var df = this.dateFormat;
25901                if(!v){
25902                    return null;
25903                }
25904                if(Ext.isDate(v)){
25905                    return v;
25906                }
25907                if(df){
25908                    if(df == 'timestamp'){
25909                        return new Date(v*1000);
25910                    }
25911                    if(df == 'time'){
25912                        return new Date(parseInt(v, 10));
25913                    }
25914                    return Date.parseDate(v, df);
25915                }
25916                var parsed = Date.parse(v);
25917                return parsed ? new Date(parsed) : null;
25918            },
25919            sortType: st.asDate,
25920            type: 'date'
25921        }
25922    });
25923    
25924    Ext.apply(this, {
25925        
25926        BOOLEAN: this.BOOL,
25927        
25928        INTEGER: this.INT,
25929        
25930        NUMBER: this.FLOAT    
25931    });
25932};
25933Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
25934    
25935    encode : true,
25936    
25937    encodeDelete: false,
25938    
25939    constructor : function(config){
25940        Ext.data.JsonWriter.superclass.constructor.call(this, config);    
25941    },
25942
25943    
25944    render : function(params, baseParams, data) {
25945        if (this.encode === true) {
25946            
25947            Ext.apply(params, baseParams);
25948            params[this.meta.root] = Ext.encode(data);
25949        } else {
25950            
25951            var jdata = Ext.apply({}, baseParams);
25952            jdata[this.meta.root] = data;
25953            params.jsonData = jdata;
25954        }
25955    },
25956    
25957    createRecord : function(rec) {
25958       return this.toHash(rec);
25959    },
25960    
25961    updateRecord : function(rec) {
25962        return this.toHash(rec);
25963
25964    },
25965    
25966    destroyRecord : function(rec){
25967        if(this.encodeDelete){
25968            var data = {};
25969            data[this.meta.idProperty] = rec.id;
25970            return data;
25971        }else{
25972            return rec.id;
25973        }
25974    }
25975});
25976Ext.data.JsonReader = function(meta, recordType){
25977    meta = meta || {};
25978    
25979    
25980    
25981    
25982    Ext.applyIf(meta, {
25983        idProperty: 'id',
25984        successProperty: 'success',
25985        totalProperty: 'total'
25986    });
25987
25988    Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
25989};
25990Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
25991    
25992    
25993    read : function(response){
25994        var json = response.responseText;
25995        var o = Ext.decode(json);
25996        if(!o) {
25997            throw {message: 'JsonReader.read: Json object not found'};
25998        }
25999        return this.readRecords(o);
26000    },
26001
26002    
26003    
26004    readResponse : function(action, response) {
26005        var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
26006        if(!o) {
26007            throw new Ext.data.JsonReader.Error('response');
26008        }
26009
26010        var root = this.getRoot(o),
26011            success = this.getSuccess(o);
26012        if (success && action === Ext.data.Api.actions.create) {
26013            var def = Ext.isDefined(root);
26014            if (def && Ext.isEmpty(root)) {
26015                throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
26016            }
26017            else if (!def) {
26018                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
26019            }
26020        }
26021
26022        
26023        var res = new Ext.data.Response({
26024            action: action,
26025            success: success,
26026            data: (root) ? this.extractData(root, false) : [],
26027            message: this.getMessage(o),
26028            raw: o
26029        });
26030
26031        
26032        if (Ext.isEmpty(res.success)) {
26033            throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
26034        }
26035        return res;
26036    },
26037
26038    
26039    readRecords : function(o){
26040        
26041        this.jsonData = o;
26042        if(o.metaData){
26043            this.onMetaChange(o.metaData);
26044        }
26045        var s = this.meta, Record = this.recordType,
26046            f = Record.prototype.fields, fi = f.items, fl = f.length, v;
26047
26048        var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
26049        if(s.totalProperty){
26050            v = parseInt(this.getTotal(o), 10);
26051            if(!isNaN(v)){
26052                totalRecords = v;
26053            }
26054        }
26055        if(s.successProperty){
26056            v = this.getSuccess(o);
26057            if(v === false || v === 'false'){
26058                success = false;
26059            }
26060        }
26061
26062        
26063        return {
26064            success : success,
26065            records : this.extractData(root, true), 
26066            totalRecords : totalRecords
26067        };
26068    },
26069
26070    
26071    buildExtractors : function() {
26072        if(this.ef){
26073            return;
26074        }
26075        var s = this.meta, Record = this.recordType,
26076            f = Record.prototype.fields, fi = f.items, fl = f.length;
26077
26078        if(s.totalProperty) {
26079            this.getTotal = this.createAccessor(s.totalProperty);
26080        }
26081        if(s.successProperty) {
26082            this.getSuccess = this.createAccessor(s.successProperty);
26083        }
26084        if (s.messageProperty) {
26085            this.getMessage = this.createAccessor(s.messageProperty);
26086        }
26087        this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
26088        if (s.id || s.idProperty) {
26089            var g = this.createAccessor(s.id || s.idProperty);
26090            this.getId = function(rec) {
26091                var r = g(rec);
26092                return (r === undefined || r === '') ? null : r;
26093            };
26094        } else {
26095            this.getId = function(){return null;};
26096        }
26097        var ef = [];
26098        for(var i = 0; i < fl; i++){
26099            f = fi[i];
26100            var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
26101            ef.push(this.createAccessor(map));
26102        }
26103        this.ef = ef;
26104    },
26105
26106    
26107    simpleAccess : function(obj, subsc) {
26108        return obj[subsc];
26109    },
26110
26111    
26112    createAccessor : function(){
26113        var re = /[\[\.]/;
26114        return function(expr) {
26115            if(Ext.isEmpty(expr)){
26116                return Ext.emptyFn;
26117            }
26118            if(Ext.isFunction(expr)){
26119                return expr;
26120            }
26121            var i = String(expr).search(re);
26122            if(i >= 0){
26123                return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
26124            }
26125            return function(obj){
26126                return obj[expr];
26127            };
26128
26129        };
26130    }(),
26131
26132    
26133    extractValues : function(data, items, len) {
26134        var f, values = {};
26135        for(var j = 0; j < len; j++){
26136            f = items[j];
26137            var v = this.ef[j](data);
26138            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
26139        }
26140        return values;
26141    }
26142});
26143
26144
26145Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
26146    constructor : function(message, arg) {
26147        this.arg = arg;
26148        Ext.Error.call(this, message);
26149    },
26150    name : 'Ext.data.JsonReader'
26151});
26152Ext.apply(Ext.data.JsonReader.Error.prototype, {
26153    lang: {
26154        'response': 'An error occurred while json-decoding your server response',
26155        'successProperty-response': 'Could not locate your "successProperty" in your server response.  Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response.  See the JsonReader docs.',
26156        'root-undefined-config': 'Your JsonReader was configured without a "root" property.  Please review your JsonReader config and make sure to define the root property.  See the JsonReader docs.',
26157        'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty"  Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id").  See the JsonReader docs.',
26158        'root-empty': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
26159    }
26160});
26161
26162Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
26163    
26164    
26165    
26166    
26167    readRecords : function(o){
26168        this.arrayData = o;
26169        var s = this.meta,
26170            sid = s ? Ext.num(s.idIndex, s.id) : null,
26171            recordType = this.recordType,
26172            fields = recordType.prototype.fields,
26173            records = [],
26174            success = true,
26175            v;
26176
26177        var root = this.getRoot(o);
26178
26179        for(var i = 0, len = root.length; i < len; i++) {
26180            var n = root[i],
26181                values = {},
26182                id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
26183            for(var j = 0, jlen = fields.length; j < jlen; j++) {
26184                var f = fields.items[j],
26185                    k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
26186                v = n[k] !== undefined ? n[k] : f.defaultValue;
26187                v = f.convert(v, n);
26188                values[f.name] = v;
26189            }
26190            var record = new recordType(values, id);
26191            record.json = n;
26192            records[records.length] = record;
26193        }
26194
26195        var totalRecords = records.length;
26196
26197        if(s.totalProperty) {
26198            v = parseInt(this.getTotal(o), 10);
26199            if(!isNaN(v)) {
26200                totalRecords = v;
26201            }
26202        }
26203        if(s.successProperty){
26204            v = this.getSuccess(o);
26205            if(v === false || v === 'false'){
26206                success = false;
26207            }
26208        }
26209
26210        return {
26211            success : success,
26212            records : records,
26213            totalRecords : totalRecords
26214        };
26215    }
26216});
26217Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
26218    
26219    constructor: function(config){
26220        Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
26221            reader: new Ext.data.ArrayReader(config)
26222        }));
26223    },
26224
26225    loadData : function(data, append){
26226        if(this.expandData === true){
26227            var r = [];
26228            for(var i = 0, len = data.length; i < len; i++){
26229                r[r.length] = [data[i]];
26230            }
26231            data = r;
26232        }
26233        Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
26234    }
26235});
26236Ext.reg('arraystore', Ext.data.ArrayStore);
26237
26238
26239Ext.data.SimpleStore = Ext.data.ArrayStore;
26240Ext.reg('simplestore', Ext.data.SimpleStore);
26241Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
26242    
26243    constructor: function(config){
26244        Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
26245            reader: new Ext.data.JsonReader(config)
26246        }));
26247    }
26248});
26249Ext.reg('jsonstore', Ext.data.JsonStore);
26250Ext.data.XmlWriter = function(params) {
26251    Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
26252    
26253    this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
26254};
26255Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
26256    
26257    documentRoot: 'xrequest',
26258    
26259    forceDocumentRoot: false,
26260    
26261    root: 'records',
26262    
26263    xmlVersion : '1.0',
26264    
26265    xmlEncoding: 'ISO-8859-15',
26266    
26267    
26268    tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
26269
26270
26271    
26272    render : function(params, baseParams, data) {
26273        baseParams = this.toArray(baseParams);
26274        params.xmlData = this.tpl.applyTemplate({
26275            version: this.xmlVersion,
26276            encoding: this.xmlEncoding,
26277            documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
26278            record: this.meta.record,
26279            root: this.root,
26280            baseParams: baseParams,
26281            records: (Ext.isArray(data[0])) ? data : [data]
26282        });
26283    },
26284
26285    
26286    createRecord : function(rec) {
26287        return this.toArray(this.toHash(rec));
26288    },
26289
26290    
26291    updateRecord : function(rec) {
26292        return this.toArray(this.toHash(rec));
26293
26294    },
26295    
26296    destroyRecord : function(rec) {
26297        var data = {};
26298        data[this.meta.idProperty] = rec.id;
26299        return this.toArray(data);
26300    }
26301});
26302
26303Ext.data.XmlReader = function(meta, recordType){
26304    meta = meta || {};
26305
26306    
26307    Ext.applyIf(meta, {
26308        idProperty: meta.idProperty || meta.idPath || meta.id,
26309        successProperty: meta.successProperty || meta.success
26310    });
26311
26312    Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
26313};
26314Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
26315    
26316    read : function(response){
26317        var doc = response.responseXML;
26318        if(!doc) {
26319            throw {message: "XmlReader.read: XML Document not available"};
26320        }
26321        return this.readRecords(doc);
26322    },
26323
26324    
26325    readRecords : function(doc){
26326        
26327        this.xmlData = doc;
26328
26329        var root    = doc.documentElement || doc,
26330            q       = Ext.DomQuery,
26331            totalRecords = 0,
26332            success = true;
26333
26334        if(this.meta.totalProperty){
26335            totalRecords = this.getTotal(root, 0);
26336        }
26337        if(this.meta.successProperty){
26338            success = this.getSuccess(root);
26339        }
26340
26341        var records = this.extractData(q.select(this.meta.record, root), true); 
26342
26343        
26344        return {
26345            success : success,
26346            records : records,
26347            totalRecords : totalRecords || records.length
26348        };
26349    },
26350
26351    
26352    readResponse : function(action, response) {
26353        var q = Ext.DomQuery,
26354            doc = response.responseXML,
26355            root = doc.documentElement || doc;
26356
26357        
26358        var res = new Ext.data.Response({
26359            action: action,
26360            success : this.getSuccess(root),
26361            message: this.getMessage(root),
26362            data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
26363            raw: doc
26364        });
26365
26366        if (Ext.isEmpty(res.success)) {
26367            throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
26368        }
26369
26370        
26371        if (action === Ext.data.Api.actions.create) {
26372            var def = Ext.isDefined(res.data);
26373            if (def && Ext.isEmpty(res.data)) {
26374                throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
26375            }
26376            else if (!def) {
26377                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
26378            }
26379        }
26380        return res;
26381    },
26382
26383    getSuccess : function() {
26384        return true;
26385    },
26386
26387    
26388    buildExtractors : function() {
26389        if(this.ef){
26390            return;
26391        }
26392        var s       = this.meta,
26393            Record  = this.recordType,
26394            f       = Record.prototype.fields,
26395            fi      = f.items,
26396            fl      = f.length;
26397
26398        if(s.totalProperty) {
26399            this.getTotal = this.createAccessor(s.totalProperty);
26400        }
26401        if(s.successProperty) {
26402            this.getSuccess = this.createAccessor(s.successProperty);
26403        }
26404        if (s.messageProperty) {
26405            this.getMessage = this.createAccessor(s.messageProperty);
26406        }
26407        this.getRoot = function(res) {
26408            return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
26409        };
26410        if (s.idPath || s.idProperty) {
26411            var g = this.createAccessor(s.idPath || s.idProperty);
26412            this.getId = function(rec) {
26413                var id = g(rec) || rec.id;
26414                return (id === undefined || id === '') ? null : id;
26415            };
26416        } else {
26417            this.getId = function(){return null;};
26418        }
26419        var ef = [];
26420        for(var i = 0; i < fl; i++){
26421            f = fi[i];
26422            var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
26423            ef.push(this.createAccessor(map));
26424        }
26425        this.ef = ef;
26426    },
26427
26428    
26429    createAccessor : function(){
26430        var q = Ext.DomQuery;
26431        return function(key) {
26432            if (Ext.isFunction(key)) {
26433                return key;
26434            }
26435            switch(key) {
26436                case this.meta.totalProperty:
26437                    return function(root, def){
26438                        return q.selectNumber(key, root, def);
26439                    };
26440                    break;
26441                case this.meta.successProperty:
26442                    return function(root, def) {
26443                        var sv = q.selectValue(key, root, true);
26444                        var success = sv !== false && sv !== 'false';
26445                        return success;
26446                    };
26447                    break;
26448                default:
26449                    return function(root, def) {
26450                        return q.selectValue(key, root, def);
26451                    };
26452                    break;
26453            }
26454        };
26455    }(),
26456
26457    
26458    extractValues : function(data, items, len) {
26459        var f, values = {};
26460        for(var j = 0; j < len; j++){
26461            f = items[j];
26462            var v = this.ef[j](data);
26463            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
26464        }
26465        return values;
26466    }
26467});
26468Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
26469    
26470    constructor: function(config){
26471        Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
26472            reader: new Ext.data.XmlReader(config)
26473        }));
26474    }
26475});
26476Ext.reg('xmlstore', Ext.data.XmlStore);
26477Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
26478
26479    
26480    constructor: function(config) {
26481        config = config || {};
26482
26483        
26484        
26485        
26486        
26487        this.hasMultiSort  = true;
26488        this.multiSortInfo = this.multiSortInfo || {sorters: []};
26489
26490        var sorters    = this.multiSortInfo.sorters,
26491            groupField = config.groupField || this.groupField,
26492            sortInfo   = config.sortInfo || this.sortInfo,
26493            groupDir   = config.groupDir || this.groupDir;
26494
26495        
26496        if(groupField){
26497            sorters.push({
26498                field    : groupField,
26499                direction: groupDir
26500            });
26501        }
26502
26503        
26504        if (sortInfo) {
26505            sorters.push(sortInfo);
26506        }
26507
26508        Ext.data.GroupingStore.superclass.constructor.call(this, config);
26509
26510        this.addEvents(
26511          
26512          'groupchange'
26513        );
26514
26515        this.applyGroupField();
26516    },
26517
26518    
26519    
26520    remoteGroup : false,
26521    
26522    groupOnSort:false,
26523
26524    
26525    groupDir : 'ASC',
26526
26527    
26528    clearGrouping : function(){
26529        this.groupField = false;
26530
26531        if(this.remoteGroup){
26532            if(this.baseParams){
26533                delete this.baseParams.groupBy;
26534                delete this.baseParams.groupDir;
26535            }
26536            var lo = this.lastOptions;
26537            if(lo && lo.params){
26538                delete lo.params.groupBy;
26539                delete lo.params.groupDir;
26540            }
26541
26542            this.reload();
26543        }else{
26544            this.sort();
26545            this.fireEvent('datachanged', this);
26546        }
26547    },
26548
26549    
26550    groupBy : function(field, forceRegroup, direction) {
26551        direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
26552
26553        if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
26554            return; 
26555        }
26556
26557        
26558        
26559        var sorters = this.multiSortInfo.sorters;
26560        if (sorters.length > 0 && sorters[0].field == this.groupField) {
26561            sorters.shift();
26562        }
26563
26564        this.groupField = field;
26565        this.groupDir = direction;
26566        this.applyGroupField();
26567
26568        var fireGroupEvent = function() {
26569            this.fireEvent('groupchange', this, this.getGroupState());
26570        };
26571
26572        if (this.groupOnSort) {
26573            this.sort(field, direction);
26574            fireGroupEvent.call(this);
26575            return;
26576        }
26577
26578        if (this.remoteGroup) {
26579            this.on('load', fireGroupEvent, this, {single: true});
26580            this.reload();
26581        } else {
26582            this.sort(sorters);
26583            fireGroupEvent.call(this);
26584        }
26585    },
26586
26587    
26588    
26589    sort : function(fieldName, dir) {
26590        if (this.remoteSort) {
26591            return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
26592        }
26593
26594        var sorters = [];
26595
26596        
26597        if (Ext.isArray(arguments[0])) {
26598            sorters = arguments[0];
26599        } else if (fieldName == undefined) {
26600            
26601            
26602            sorters = this.sortInfo ? [this.sortInfo] : [];
26603        } else {
26604            
26605            
26606            var field = this.fields.get(fieldName);
26607            if (!field) return false;
26608
26609            var name       = field.name,
26610                sortInfo   = this.sortInfo || null,
26611                sortToggle = this.sortToggle ? this.sortToggle[name] : null;
26612
26613            if (!dir) {
26614                if (sortInfo && sortInfo.field == name) { 
26615                    dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
26616                } else {
26617                    dir = field.sortDir;
26618                }
26619            }
26620
26621            this.sortToggle[name] = dir;
26622            this.sortInfo = {field: name, direction: dir};
26623
26624            sorters = [this.sortInfo];
26625        }
26626
26627        
26628        if (this.groupField) {
26629            sorters.unshift({direction: this.groupDir, field: this.groupField});
26630        }
26631
26632        return this.multiSort.call(this, sorters, dir);
26633    },
26634
26635    
26636    applyGroupField: function(){
26637        if (this.remoteGroup) {
26638            if(!this.baseParams){
26639                this.baseParams = {};
26640            }
26641
26642            Ext.apply(this.baseParams, {
26643                groupBy : this.groupField,
26644                groupDir: this.groupDir
26645            });
26646
26647            var lo = this.lastOptions;
26648            if (lo && lo.params) {
26649                lo.params.groupDir = this.groupDir;
26650
26651                
26652                delete lo.params.groupBy;
26653            }
26654        }
26655    },
26656
26657    
26658    applyGrouping : function(alwaysFireChange){
26659        if(this.groupField !== false){
26660            this.groupBy(this.groupField, true, this.groupDir);
26661            return true;
26662        }else{
26663            if(alwaysFireChange === true){
26664                this.fireEvent('datachanged', this);
26665            }
26666            return false;
26667        }
26668    },
26669
26670    
26671    getGroupState : function(){
26672        return this.groupOnSort && this.groupField !== false ?
26673               (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
26674    }
26675});
26676Ext.reg('groupingstore', Ext.data.GroupingStore);
26677
26678Ext.data.DirectProxy = function(config){
26679    Ext.apply(this, config);
26680    if(typeof this.paramOrder == 'string'){
26681        this.paramOrder = this.paramOrder.split(/[\s,|]/);
26682    }
26683    Ext.data.DirectProxy.superclass.constructor.call(this, config);
26684};
26685
26686Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
26687    
26688    paramOrder: undefined,
26689
26690    
26691    paramsAsHash: true,
26692
26693    
26694    directFn : undefined,
26695
26696    
26697    doRequest : function(action, rs, params, reader, callback, scope, options) {
26698        var args = [],
26699            directFn = this.api[action] || this.directFn;
26700
26701        switch (action) {
26702            case Ext.data.Api.actions.create:
26703                args.push(params.jsonData);		
26704                break;
26705            case Ext.data.Api.actions.read:
26706                
26707                if(directFn.directCfg.method.len > 0){
26708                    if(this.paramOrder){
26709                        for(var i = 0, len = this.paramOrder.length; i < len; i++){
26710                            args.push(params[this.paramOrder[i]]);
26711                        }
26712                    }else if(this.paramsAsHash){
26713                        args.push(params);
26714                    }
26715                }
26716                break;
26717            case Ext.data.Api.actions.update:
26718                args.push(params.jsonData);        
26719                break;
26720            case Ext.data.Api.actions.destroy:
26721                args.push(params.jsonData);        
26722                break;
26723        }
26724
26725        var trans = {
26726            params : params || {},
26727            request: {
26728                callback : callback,
26729                scope : scope,
26730                arg : options
26731            },
26732            reader: reader
26733        };
26734
26735        args.push(this.createCallback(action, rs, trans), this);
26736        directFn.apply(window, args);
26737    },
26738
26739    
26740    createCallback : function(action, rs, trans) {
26741        var me = this;
26742        return function(result, res) {
26743            if (!res.status) {
26744                
26745                if (action === Ext.data.Api.actions.read) {
26746                    me.fireEvent("loadexception", me, trans, res, null);
26747                }
26748                me.fireEvent('exception', me, 'remote', action, trans, res, null);
26749                trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26750                return;
26751            }
26752            if (action === Ext.data.Api.actions.read) {
26753                me.onRead(action, trans, result, res);
26754            } else {
26755                me.onWrite(action, trans, result, res, rs);
26756            }
26757        };
26758    },
26759
26760    
26761    onRead : function(action, trans, result, res) {
26762        var records;
26763        try {
26764            records = trans.reader.readRecords(result);
26765        }
26766        catch (ex) {
26767            
26768            this.fireEvent("loadexception", this, trans, res, ex);
26769
26770            this.fireEvent('exception', this, 'response', action, trans, res, ex);
26771            trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26772            return;
26773        }
26774        this.fireEvent("load", this, res, trans.request.arg);
26775        trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
26776    },
26777    
26778    onWrite : function(action, trans, result, res, rs) {
26779        var data = trans.reader.extractData(trans.reader.getRoot(result), false);
26780        var success = trans.reader.getSuccess(result);
26781        success = (success !== false);
26782        if (success){
26783            this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
26784        }else{
26785            this.fireEvent('exception', this, 'remote', action, trans, result, rs);
26786        }
26787        trans.request.callback.call(trans.request.scope, data, res, success);
26788    }
26789});
26790
26791Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
26792    constructor : function(config){
26793        
26794        var c = Ext.apply({}, {
26795            batchTransactions: false
26796        }, config);
26797        Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
26798            proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
26799            reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
26800        }));
26801    }
26802});
26803Ext.reg('directstore', Ext.data.DirectStore);
26804
26805Ext.Direct = Ext.extend(Ext.util.Observable, {
26806    
26807
26808    
26809    exceptions: {
26810        TRANSPORT: 'xhr',
26811        PARSE: 'parse',
26812        LOGIN: 'login',
26813        SERVER: 'exception'
26814    },
26815
26816    
26817    constructor: function(){
26818        this.addEvents(
26819            
26820            'event',
26821            
26822            'exception'
26823        );
26824        this.transactions = {};
26825        this.providers = {};
26826    },
26827
26828    
26829    addProvider : function(provider){
26830        var a = arguments;
26831        if(a.length > 1){
26832            for(var i = 0, len = a.length; i < len; i++){
26833                this.addProvider(a[i]);
26834            }
26835            return;
26836        }
26837
26838        
26839        if(!provider.events){
26840            provider = new Ext.Direct.PROVIDERS[provider.type](provider);
26841        }
26842        provider.id = provider.id || Ext.id();
26843        this.providers[provider.id] = provider;
26844
26845        provider.on('data', this.onProviderData, this);
26846        provider.on('exception', this.onProviderException, this);
26847
26848
26849        if(!provider.isConnected()){
26850            provider.connect();
26851        }
26852
26853        return provider;
26854    },
26855
26856    
26857    getProvider : function(id){
26858        return this.providers[id];
26859    },
26860
26861    removeProvider : function(id){
26862        var provider = id.id ? id : this.providers[id];
26863        provider.un('data', this.onProviderData, this);
26864        provider.un('exception', this.onProviderException, this);
26865        delete this.providers[provider.id];
26866        return provider;
26867    },
26868
26869    addTransaction: function(t){
26870        this.transactions[t.tid] = t;
26871        return t;
26872    },
26873
26874    removeTransaction: function(t){
26875        delete this.transactions[t.tid || t];
26876        return t;
26877    },
26878
26879    getTransaction: function(tid){
26880        return this.transactions[tid.tid || tid];
26881    },
26882
26883    onProviderData : function(provider, e){
26884        if(Ext.isArray(e)){
26885            for(var i = 0, len = e.length; i < len; i++){
26886                this.onProviderData(provider, e[i]);
26887            }
26888            return;
26889        }
26890        if(e.name && e.name != 'event' && e.name != 'exception'){
26891            this.fireEvent(e.name, e);
26892        }else if(e.type == 'exception'){
26893            this.fireEvent('exception', e);
26894        }
26895        this.fireEvent('event', e, provider);
26896    },
26897
26898    createEvent : function(response, extraProps){
26899        return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
26900    }
26901});
26902
26903Ext.Direct = new Ext.Direct();
26904
26905Ext.Direct.TID = 1;
26906Ext.Direct.PROVIDERS = {};
26907Ext.Direct.Transaction = function(config){
26908    Ext.apply(this, config);
26909    this.tid = ++Ext.Direct.TID;
26910    this.retryCount = 0;
26911};
26912Ext.Direct.Transaction.prototype = {
26913    send: function(){
26914        this.provider.queueTransaction(this);
26915    },
26916
26917    retry: function(){
26918        this.retryCount++;
26919        this.send();
26920    },
26921
26922    getProvider: function(){
26923        return this.provider;
26924    }
26925};Ext.Direct.Event = function(config){
26926    Ext.apply(this, config);
26927};
26928
26929Ext.Direct.Event.prototype = {
26930    status: true,
26931    getData: function(){
26932        return this.data;
26933    }
26934};
26935
26936Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
26937    type: 'rpc',
26938    getTransaction: function(){
26939        return this.transaction || Ext.Direct.getTransaction(this.tid);
26940    }
26941});
26942
26943Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
26944    status: false,
26945    type: 'exception'
26946});
26947
26948Ext.Direct.eventTypes = {
26949    'rpc':  Ext.Direct.RemotingEvent,
26950    'event':  Ext.Direct.Event,
26951    'exception':  Ext.Direct.ExceptionEvent
26952};
26953
26954Ext.direct.Provider = Ext.extend(Ext.util.Observable, {    
26955    
26956        
26957        
26958    priority: 1,
26959
26960        
26961 
26962    
26963    constructor : function(config){
26964        Ext.apply(this, config);
26965        this.addEvents(
26966                        
26967            'connect',
26968                        
26969            'disconnect',
26970                        
26971            'data',
26972                                    
26973            'exception'
26974        );
26975        Ext.direct.Provider.superclass.constructor.call(this, config);
26976    },
26977
26978    
26979    isConnected: function(){
26980        return false;
26981    },
26982
26983    
26984    connect: Ext.emptyFn,
26985    
26986    
26987    disconnect: Ext.emptyFn
26988});
26989
26990Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
26991    parseResponse: function(xhr){
26992        if(!Ext.isEmpty(xhr.responseText)){
26993            if(typeof xhr.responseText == 'object'){
26994                return xhr.responseText;
26995            }
26996            return Ext.decode(xhr.responseText);
26997        }
26998        return null;
26999    },
27000
27001    getEvents: function(xhr){
27002        var data = null;
27003        try{
27004            data = this.parseResponse(xhr);
27005        }catch(e){
27006            var event = new Ext.Direct.ExceptionEvent({
27007                data: e,
27008                xhr: xhr,
27009                code: Ext.Direct.exceptions.PARSE,
27010                message: 'Error parsing json response: \n\n ' + data
27011            });
27012            return [event];
27013        }
27014        var events = [];
27015        if(Ext.isArray(data)){
27016            for(var i = 0, len = data.length; i < len; i++){
27017                events.push(Ext.Direct.createEvent(data[i]));
27018            }
27019        }else{
27020            events.push(Ext.Direct.createEvent(data));
27021        }
27022        return events;
27023    }
27024});
27025Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
27026    
27027    
27028    priority: 3,
27029    
27030    
27031    interval: 3000,
27032
27033    
27034    
27035    
27036
27037    
27038    constructor : function(config){
27039        Ext.direct.PollingProvider.superclass.constructor.call(this, config);
27040        this.addEvents(
27041            
27042            'beforepoll',            
27043            
27044            'poll'
27045        );
27046    },
27047
27048    
27049    isConnected: function(){
27050        return !!this.pollTask;
27051    },
27052
27053    
27054    connect: function(){
27055        if(this.url && !this.pollTask){
27056            this.pollTask = Ext.TaskMgr.start({
27057                run: function(){
27058                    if(this.fireEvent('beforepoll', this) !== false){
27059                        if(typeof this.url == 'function'){
27060                            this.url(this.baseParams);
27061                        }else{
27062                            Ext.Ajax.request({
27063                                url: this.url,
27064                                callback: this.onData,
27065                                scope: this,
27066                                params: this.baseParams
27067                            });
27068                        }
27069                    }
27070                },
27071                interval: this.interval,
27072                scope: this
27073            });
27074            this.fireEvent('connect', this);
27075        }else if(!this.url){
27076            throw 'Error initializing PollingProvider, no url configured.';
27077        }
27078    },
27079
27080    
27081    disconnect: function(){
27082        if(this.pollTask){
27083            Ext.TaskMgr.stop(this.pollTask);
27084            delete this.pollTask;
27085            this.fireEvent('disconnect', this);
27086        }
27087    },
27088
27089    
27090    onData: function(opt, success, xhr){
27091        if(success){
27092            var events = this.getEvents(xhr);
27093            for(var i = 0, len = events.length; i < len; i++){
27094                var e = events[i];
27095                this.fireEvent('data', this, e);
27096            }
27097        }else{
27098            var e = new Ext.Direct.ExceptionEvent({
27099                data: e,
27100                code: Ext.Direct.exceptions.TRANSPORT,
27101                message: 'Unable to connect to the server.',
27102                xhr: xhr
27103            });
27104            this.fireEvent('data', this, e);
27105        }
27106    }
27107});
27108
27109Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
27110Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {       
27111    
27112    
27113    
27114    
27115    
27116    
27117    
27118    
27119    
27120    enableBuffer: 10,
27121    
27122    
27123    maxRetries: 1,
27124    
27125    
27126    timeout: undefined,
27127
27128    constructor : function(config){
27129        Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
27130        this.addEvents(
27131                        
27132            'beforecall',            
27133                        
27134            'call'
27135        );
27136        this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
27137        this.transactions = {};
27138        this.callBuffer = [];
27139    },
27140
27141    
27142    initAPI : function(){
27143        var o = this.actions;
27144        for(var c in o){
27145            var cls = this.namespace[c] || (this.namespace[c] = {}),
27146                ms = o[c];
27147            for(var i = 0, len = ms.length; i < len; i++){
27148                var m = ms[i];
27149                cls[m.name] = this.createMethod(c, m);
27150            }
27151        }
27152    },
27153
27154    
27155    isConnected: function(){
27156        return !!this.connected;
27157    },
27158
27159    connect: function(){
27160        if(this.url){
27161            this.initAPI();
27162            this.connected = true;
27163            this.fireEvent('connect', this);
27164        }else if(!this.url){
27165            throw 'Error initializing RemotingProvider, no url c
27165onfigured.';
27166        }
27167    },
27168
27169    disconnect: function(){
27170        if(this.connected){
27171            this.connected = false;
27172            this.fireEvent('disconnect', this);
27173        }
27174    },
27175
27176    onData: function(opt, success, xhr){
27177        if(success){
27178            var events = this.getEvents(xhr);
27179            for(var i = 0, len = events.length; i < len; i++){
27180                var e = events[i],
27181                    t = this.getTransaction(e);
27182                this.fireEvent('data', this, e);
27183                if(t){
27184                    this.doCallback(t, e, true);
27185                    Ext.Direct.removeTransaction(t);
27186                }
27187            }
27188        }else{
27189            var ts = [].concat(opt.ts);
27190            for(var i = 0, len = ts.length; i < len; i++){
27191                var t = this.getTransaction(ts[i]);
27192                if(t && t.retryCount < this.maxRetries){
27193                    t.retry();
27194                }else{
27195                    var e = new Ext.Direct.ExceptionEvent({
27196                        data: e,
27197                        transaction: t,
27198                        code: Ext.Direct.exceptions.TRANSPORT,
27199                        message: 'Unable to connect to the server.',
27200                        xhr: xhr
27201                    });
27202                    this.fireEvent('data', this, e);
27203                    if(t){
27204                        this.doCallback(t, e, false);
27205                        Ext.Direct.removeTransaction(t);
27206                    }
27207                }
27208            }
27209        }
27210    },
27211
27212    getCallData: function(t){
27213        return {
27214            action: t.action,
27215            method: t.method,
27216            data: t.data,
27217            type: 'rpc',
27218            tid: t.tid
27219        };
27220    },
27221
27222    doSend : function(data){
27223        var o = {
27224            url: this.url,
27225            callback: this.onData,
27226            scope: this,
27227            ts: data,
27228            timeout: this.timeout
27229        }, callData;
27230
27231        if(Ext.isArray(data)){
27232            callData = [];
27233            for(var i = 0, len = data.length; i < len; i++){
27234                callData.push(this.getCallData(data[i]));
27235            }
27236        }else{
27237            callData = this.getCallData(data);
27238        }
27239
27240        if(this.enableUrlEncode){
27241            var params = {};
27242            params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
27243            o.params = params;
27244        }else{
27245            o.jsonData = callData;
27246        }
27247        Ext.Ajax.request(o);
27248    },
27249
27250    combineAndSend : function(){
27251        var len = this.callBuffer.length;
27252        if(len > 0){
27253            this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
27254            this.callBuffer = [];
27255        }
27256    },
27257
27258    queueTransaction: function(t){
27259        if(t.form){
27260            this.processForm(t);
27261            return;
27262        }
27263        this.callBuffer.push(t);
27264        if(this.enableBuffer){
27265            if(!this.callTask){
27266                this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
27267            }
27268            this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
27269        }else{
27270            this.combineAndSend();
27271        }
27272    },
27273
27274    doCall : function(c, m, args){
27275        var data = null, hs = args[m.len], scope = args[m.len+1];
27276
27277        if(m.len !== 0){
27278            data = args.slice(0, m.len);
27279        }
27280
27281        var t = new Ext.Direct.Transaction({
27282            provider: this,
27283            args: args,
27284            action: c,
27285            method: m.name,
27286            data: data,
27287            cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
27288        });
27289
27290        if(this.fireEvent('beforecall', this, t, m) !== false){
27291            Ext.Direct.addTransaction(t);
27292            this.queueTransaction(t);
27293            this.fireEvent('call', this, t, m);
27294        }
27295    },
27296
27297    doForm : function(c, m, form, callback, scope){
27298        var t = new Ext.Direct.Transaction({
27299            provider: this,
27300            action: c,
27301            method: m.name,
27302            args:[form, callback, scope],
27303            cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
27304            isForm: true
27305        });
27306
27307        if(this.fireEvent('beforecall', this, t, m) !== false){
27308            Ext.Direct.addTransaction(t);
27309            var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
27310                params = {
27311                    extTID: t.tid,
27312                    extAction: c,
27313                    extMethod: m.name,
27314                    extType: 'rpc',
27315                    extUpload: String(isUpload)
27316                };
27317            
27318            
27319            
27320            Ext.apply(t, {
27321                form: Ext.getDom(form),
27322                isUpload: isUpload,
27323                params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
27324            });
27325            this.fireEvent('call', this, t, m);
27326            this.processForm(t);
27327        }
27328    },
27329    
27330    processForm: function(t){
27331        Ext.Ajax.request({
27332            url: this.url,
27333            params: t.params,
27334            callback: this.onData,
27335            scope: this,
27336            form: t.form,
27337            isUpload: t.isUpload,
27338            ts: t
27339        });
27340    },
27341
27342    createMethod : function(c, m){
27343        var f;
27344        if(!m.formHandler){
27345            f = function(){
27346                this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
27347            }.createDelegate(this);
27348        }else{
27349            f = function(form, callback, scope){
27350                this.doForm(c, m, form, callback, scope);
27351            }.createDelegate(this);
27352        }
27353        f.directCfg = {
27354            action: c,
27355            method: m
27356        };
27357        return f;
27358    },
27359
27360    getTransaction: function(opt){
27361        return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
27362    },
27363
27364    doCallback: function(t, e){
27365        var fn = e.status ? 'success' : 'failure';
27366        if(t && t.cb){
27367            var hs = t.cb,
27368                result = Ext.isDefined(e.result) ? e.result : e.data;
27369            if(Ext.isFunction(hs)){
27370                hs(result, e);
27371            } else{
27372                Ext.callback(hs[fn], hs.scope, [result, e]);
27373                Ext.callback(hs.callback, hs.scope, [result, e]);
27374            }
27375        }
27376    }
27377});
27378Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
27379Ext.Resizable = Ext.extend(Ext.util.Observable, {
27380
27381    constructor: function(el, config){
27382        this.el = Ext.get(el);
27383        if(config && config.wrap){
27384            config.resizeChild = this.el;
27385            this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
27386            this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
27387            this.el.setStyle('overflow', 'hidden');
27388            this.el.setPositioning(config.resizeChild.getPositioning());
27389            config.resizeChild.clearPositioning();
27390            if(!config.width || !config.height){
27391                var csize = config.resizeChild.getSize();
27392                this.el.setSize(csize.width, csize.height);
27393            }
27394            if(config.pinned && !config.adjustments){
27395                config.adjustments = 'auto';
27396            }
27397        }
27398
27399        
27400        this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
27401        this.proxy.unselectable();
27402        this.proxy.enableDisplayMode('block');
27403
27404        Ext.apply(this, config);
27405
27406        if(this.pinned){
27407            this.disableTrackOver = true;
27408            this.el.addClass('x-resizable-pinned');
27409        }
27410        
27411        var position = this.el.getStyle('position');
27412        if(position != 'absolute' && position != 'fixed'){
27413            this.el.setStyle('position', 'relative');
27414        }
27415        if(!this.handles){ 
27416            this.handles = 's,e,se';
27417            if(this.multiDirectional){
27418                this.handles += ',n,w';
27419            }
27420        }
27421        if(this.handles == 'all'){
27422            this.handles = 'n s e w ne nw se sw';
27423        }
27424        var hs = this.handles.split(/\s*?[,;]\s*?| /);
27425        var ps = Ext.Resizable.positions;
27426        for(var i = 0, len = hs.length; i < len; i++){
27427            if(hs[i] && ps[hs[i]]){
27428                var pos = ps[hs[i]];
27429                this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
27430            }
27431        }
27432        
27433        this.corner = this.southeast;
27434
27435        if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
27436            this.updateBox = true;
27437        }
27438
27439        this.activeHandle = null;
27440
27441        if(this.resizeChild){
27442            if(typeof this.resizeChild == 'boolean'){
27443                this.resizeChild = Ext.get(this.el.dom.firstChild, true);
27444            }else{
27445                this.resizeChild = Ext.get(this.resizeChild, true);
27446            }
27447        }
27448
27449        if(this.adjustments == 'auto'){
27450            var rc = this.resizeChild;
27451            var hw = this.west, he = this.east, hn = this.north, hs = this.south;
27452            if(rc && (hw || hn)){
27453                rc.position('relative');
27454                rc.setLeft(hw ? hw.el.getWidth() : 0);
27455                rc.setTop(hn ? hn.el.getHeight() : 0);
27456            }
27457            this.adjustments = [
27458                (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
27459                (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
27460            ];
27461        }
27462
27463        if(this.draggable){
27464            this.dd = this.dynamic ?
27465                this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
27466            this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
27467            if(this.constrainTo){
27468                this.dd.constrainTo(this.constrainTo);
27469            }
27470        }
27471
27472        this.addEvents(
27473            
27474            'beforeresize',
27475            
27476            'resize'
27477        );
27478
27479        if(this.width !== null && this.height !== null){
27480            this.resizeTo(this.width, this.height);
27481        }else{
27482            this.updateChildSize();
27483        }
27484        if(Ext.isIE){
27485            this.el.dom.style.zoom = 1;
27486        }
27487        Ext.Resizable.superclass.constructor.call(this);
27488    },
27489
27490    
27491    adjustments : [0, 0],
27492    
27493    animate : false,
27494    
27495    
27496    disableTrackOver : false,
27497    
27498    draggable: false,
27499    
27500    duration : 0.35,
27501    
27502    dynamic : false,
27503    
27504    easing : 'easeOutStrong',
27505    
27506    enabled : true,
27507    
27508    
27509    handles : false,
27510    
27511    multiDirectional : false,
27512    
27513    height : null,
27514    
27515    width : null,
27516    
27517    heightIncrement : 0,
27518    
27519    widthIncrement : 0,
27520    
27521    minHeight : 5,
27522    
27523    minWidth : 5,
27524    
27525    maxHeight : 10000,
27526    
27527    maxWidth : 10000,
27528    
27529    minX: 0,
27530    
27531    minY: 0,
27532    
27533    pinned : false,
27534    
27535    preserveRatio : false,
27536    
27537    resizeChild : false,
27538    
27539    transparent: false,
27540    
27541    
27542    
27543
27544
27545    
27546    resizeTo : function(width, height){
27547        this.el.setSize(width, height);
27548        this.updateChildSize();
27549        this.fireEvent('resize', this, width, height, null);
27550    },
27551
27552    
27553    startSizing : function(e, handle){
27554        this.fireEvent('beforeresize', this, e);
27555        if(this.enabled){ 
27556
27557            if(!this.overlay){
27558                this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: '&#160;'}, Ext.getBody());
27559                this.overlay.unselectable();
27560                this.overlay.enableDisplayMode('block');
27561                this.overlay.on({
27562                    scope: this,
27563                    mousemove: this.onMouseMove,
27564                    mouseup: this.onMouseUp
27565                });
27566            }
27567            this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
27568
27569            this.resizing = true;
27570            this.startBox = this.el.getBox();
27571            this.startPoint = e.getXY();
27572            this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
27573                            (this.startBox.y + this.startBox.height) - this.startPoint[1]];
27574
27575            this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
27576            this.overlay.show();
27577
27578            if(this.constrainTo) {
27579                var ct = Ext.get(this.constrainTo);
27580                this.resizeRegion = ct.getRegion().adjust(
27581                    ct.getFrameWidth('t'),
27582                    ct.getFrameWidth('l'),
27583                    -ct.getFrameWidth('b'),
27584                    -ct.getFrameWidth('r')
27585                );
27586            }
27587
27588            this.proxy.setStyle('visibility', 'hidden'); 
27589            this.proxy.show();
27590            this.proxy.setBox(this.startBox);
27591            if(!this.dynamic){
27592                this.proxy.setStyle('visibility', 'visible');
27593            }
27594        }
27595    },
27596
27597    
27598    onMouseDown : function(handle, e){
27599        if(this.enabled){
27600            e.stopEvent();
27601            this.activeHandle = handle;
27602            this.startSizing(e, handle);
27603        }
27604    },
27605
27606    
27607    onMouseUp : function(e){
27608        this.activeHandle = null;
27609        var size = this.resizeElement();
27610        this.resizing = false;
27611        this.handleOut();
27612        this.overlay.hide();
27613        this.proxy.hide();
27614        this.fireEvent('resize', this, size.width, size.height, e);
27615    },
27616
27617    
27618    updateChildSize : function(){
27619        if(this.resizeChild){
27620            var el = this.el;
27621            var child = this.resizeChild;
27622            var adj = this.adjustments;
27623            if(el.dom.offsetWidth){
27624                var b = el.getSize(true);
27625                child.setSize(b.width+adj[0], b.height+adj[1]);
27626            }
27627            
27628            
27629            
27630            
27631            if(Ext.isIE){
27632                setTimeout(function(){
27633                    if(el.dom.offsetWidth){
27634                        var b = el.getSize(true);
27635                        child.setSize(b.width+adj[0], b.height+adj[1]);
27636                    }
27637                }, 10);
27638            }
27639        }
27640    },
27641
27642    
27643    snap : function(value, inc, min){
27644        if(!inc || !value){
27645            return value;
27646        }
27647        var newValue = value;
27648        var m = value % inc;
27649        if(m > 0){
27650            if(m > (inc/2)){
27651                newValue = value + (inc-m);
27652            }else{
27653                newValue = value - m;
27654            }
27655        }
27656        return Math.max(min, newValue);
27657    },
27658
27659    
27660    resizeElement : function(){
27661        var box = this.proxy.getBox();
27662        if(this.updateBox){
27663            this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
27664        }else{
27665            this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
27666        }
27667        this.updateChildSize();
27668        if(!this.dynamic){
27669            this.proxy.hide();
27670        }
27671        if(this.draggable && this.constrainTo){
27672            this.dd.resetConstraints();
27673            this.dd.constrainTo(this.constrainTo);
27674        }
27675        return box;
27676    },
27677
27678    
27679    constrain : function(v, diff, m, mx){
27680        if(v - diff < m){
27681            diff = v - m;
27682        }else if(v - diff > mx){
27683            diff = v - mx;
27684        }
27685        return diff;
27686    },
27687
27688    
27689    onMouseMove : function(e){
27690        if(this.enabled && this.activeHandle){
27691            try{
27692
27693            if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
27694                return;
27695            }
27696
27697            
27698            var curSize = this.curSize || this.startBox,
27699                x = this.startBox.x, y = this.startBox.y,
27700                ox = x,
27701                oy = y,
27702                w = curSize.width,
27703                h = curSize.height,
27704                ow = w,
27705                oh = h,
27706                mw = this.minWidth,
27707                mh = this.minHeight,
27708                mxw = this.maxWidth,
27709                mxh = this.maxHeight,
27710                wi = this.widthIncrement,
27711                hi = this.heightIncrement,
27712                eventXY = e.getXY(),
27713                diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
27714                diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
27715                pos = this.activeHandle.position,
27716                tw,
27717                th;
27718
27719            switch(pos){
27720                case 'east':
27721                    w += diffX;
27722                    w = Math.min(Math.max(mw, w), mxw);
27723                    break;
27724                case 'south':
27725                    h += diffY;
27726                    h = Math.min(Math.max(mh, h), mxh);
27727                    break;
27728                case 'southeast':
27729                    w += diffX;
27730                    h += diffY;
27731                    w = Math.min(Math.max(mw, w), mxw);
27732                    h = Math.min(Math.max(mh, h), mxh);
27733                    break;
27734                case 'north':
27735                    diffY = this.constrain(h, diffY, mh, mxh);
27736                    y += diffY;
27737                    h -= diffY;
27738                    break;
27739                case 'west':
27740                    diffX = this.constrain(w, diffX, mw, mxw);
27741                    x += diffX;
27742                    w -= diffX;
27743                    break;
27744                case 'northeast':
27745                    w += diffX;
27746                    w = Math.min(Math.max(mw, w), mxw);
27747                    diffY = this.constrain(h, diffY, mh, mxh);
27748                    y += diffY;
27749                    h -= diffY;
27750                    break;
27751                case 'northwest':
27752                    diffX = this.constrain(w, diffX, mw, mxw);
27753                    diffY = this.constrain(h, diffY, mh, mxh);
27754                    y += diffY;
27755                    h -= diffY;
27756                    x += diffX;
27757                    w -= diffX;
27758                    break;
27759               case 'southwest':
27760                    diffX = this.constrain(w, diffX, mw, mxw);
27761                    h += diffY;
27762                    h = Math.min(Math.max(mh, h), mxh);
27763                    x += diffX;
27764                    w -= diffX;
27765                    break;
27766            }
27767
27768            var sw = this.snap(w, wi, mw);
27769            var sh = this.snap(h, hi, mh);
27770            if(sw != w || sh != h){
27771                switch(pos){
27772                    case 'northeast':
27773                        y -= sh - h;
27774                    break;
27775                    case 'north':
27776                        y -= sh - h;
27777                        break;
27778                    case 'southwest':
27779                        x -= sw - w;
27780                    break;
27781                    case 'west':
27782                        x -= sw - w;
27783                        break;
27784                    case 'northwest':
27785                        x -= sw - w;
27786                        y -= sh - h;
27787                    break;
27788                }
27789                w = sw;
27790                h = sh;
27791            }
27792
27793            if(this.preserveRatio){
27794                switch(pos){
27795                    case 'southeast':
27796                    case 'east':
27797                        h = oh * (w/ow);
27798                        h = Math.min(Math.max(mh, h), mxh);
27799                        w = ow * (h/oh);
27800                       break;
27801                    case 'south':
27802                        w = ow * (h/oh);
27803                        w = Math.min(Math.max(mw, w), mxw);
27804                        h = oh * (w/ow);
27805                        break;
27806                    case 'northeast':
27807                        w = ow * (h/oh);
27808                        w = Math.min(Math.max(mw, w), mxw);
27809                        h = oh * (w/ow);
27810                    break;
27811                    case 'north':
27812                        tw = w;
27813                        w = ow * (h/oh);
27814                        w = Math.min(Math.max(mw, w), mxw);
27815                        h = oh * (w/ow);
27816                        x += (tw - w) / 2;
27817                        break;
27818                    case 'southwest':
27819                        h = oh * (w/ow);
27820                        h = Math.min(Math.max(mh, h), mxh);
27821                        tw = w;
27822                        w = ow * (h/oh);
27823                        x += tw - w;
27824                        break;
27825                    case 'west':
27826                        th = h;
27827                        h = oh * (w/ow);
27828                        h = Math.min(Math.max(mh, h), mxh);
27829                        y += (th - h) / 2;
27830                        tw = w;
27831                        w = ow * (h/oh);
27832                        x += tw - w;
27833                       break;
27834                    case 'northwest':
27835                        tw = w;
27836                        th = h;
27837                        h = oh * (w/ow);
27838                        h = Math.min(Math.max(mh, h), mxh);
27839                        w = ow * (h/oh);
27840                        y += th - h;
27841                        x += tw - w;
27842                        break;
27843
27844                }
27845            }
27846            this.proxy.setBounds(x, y, w, h);
27847            if(this.dynamic){
27848                this.resizeElement();
27849            }
27850            }catch(ex){}
27851        }
27852    },
27853
27854    
27855    handleOver : function(){
27856        if(this.enabled){
27857            this.el.addClass('x-resizable-over');
27858        }
27859    },
27860
27861    
27862    handleOut : function(){
27863        if(!this.resizing){
27864            this.el.removeClass('x-resizable-over');
27865        }
27866    },
27867
27868    
27869    getEl : function(){
27870        return this.el;
27871    },
27872
27873    
27874    getResizeChild : function(){
27875        return this.resizeChild;
27876    },
27877
27878    
27879    destroy : function(removeEl){
27880        Ext.destroy(this.dd, this.overlay, this.proxy);
27881        this.overlay = null;
27882        this.proxy = null;
27883
27884        var ps = Ext.Resizable.positions;
27885        for(var k in ps){
27886            if(typeof ps[k] != 'function' && this[ps[k]]){
27887                this[ps[k]].destroy();
27888            }
27889        }
27890        if(removeEl){
27891            this.el.update('');
27892            Ext.destroy(this.el);
27893            this.el = null;
27894        }
27895        this.purgeListeners();
27896    },
27897
27898    syncHandleHeight : function(){
27899        var h = this.el.getHeight(true);
27900        if(this.west){
27901            this.west.el.setHeight(h);
27902        }
27903        if(this.east){
27904            this.east.el.setHeight(h);
27905        }
27906    }
27907});
27908
27909
27910
27911Ext.Resizable.positions = {
27912    n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
27913};
27914
27915Ext.Resizable.Handle = Ext.extend(Object, {
27916    constructor : function(rz, pos, disableTrackOver, transparent, cls){
27917       if(!this.tpl){
27918            
27919            var tpl = Ext.DomHelper.createTemplate(
27920                {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
27921            );
27922            tpl.compile();
27923            Ext.Resizable.Handle.prototype.tpl = tpl;
27924        }
27925        this.position = pos;
27926        this.rz = rz;
27927        this.el = this.tpl.append(rz.el.dom, [this.position], true);
27928        this.el.unselectable();
27929        if(transparent){
27930            this.el.setOpacity(0);
27931        }
27932        if(!Ext.isEmpty(cls)){
27933            this.el.addClass(cls);
27934        }
27935        this.el.on('mousedown', this.onMouseDown, this);
27936        if(!disableTrackOver){
27937            this.el.on({
27938                scope: this,
27939                mouseover: this.onMouseOver,
27940                mouseout: this.onMouseOut
27941            });
27942        }
27943    },
27944
27945    
27946    afterResize : function(rz){
27947        
27948    },
27949    
27950    onMouseDown : function(e){
27951        this.rz.onMouseDown(this, e);
27952    },
27953    
27954    onMouseOver : function(e){
27955        this.rz.handleOver(this, e);
27956    },
27957    
27958    onMouseOut : function(e){
27959        this.rz.handleOut(this, e);
27960    },
27961    
27962    destroy : function(){
27963        Ext.destroy(this.el);
27964        this.el = null;
27965    }
27966});
27967
27968Ext.Window = Ext.extend(Ext.Panel, {
27969    
27970    
27971    
27972    
27973    
27974    
27975    
27976    
27977    
27978    
27979
27980    
27981    baseCls : 'x-window',
27982    
27983    resizable : true,
27984    
27985    draggable : true,
27986    
27987    closable : true,
27988    
27989    closeAction : 'close',
27990    
27991    constrain : false,
27992    
27993    constrainHeader : false,
27994    
27995    plain : false,
27996    
27997    minimizable : false,
27998    
27999    maximizable : false,
28000    
28001    minHeight : 100,
28002    
28003    minWidth : 200,
28004    
28005    expandOnShow : true,
28006    
28007    
28008    showAnimDuration: 0.25,
28009    
28010    
28011    hideAnimDuration: 0.25,
28012
28013    
28014    collapsible : false,
28015
28016    
28017    initHidden : undefined,
28018
28019    
28020    hidden : true,
28021
28022    
28023    
28024    
28025    
28026    
28027    elements : 'header,body',
28028    
28029    frame : true,
28030    
28031    floating : true,
28032
28033    
28034    initComponent : function(){
28035        this.initTools();
28036        Ext.Window.superclass.initComponent.call(this);
28037        this.addEvents(
28038            
28039            
28040            
28041            'resize',
28042            
28043            'maximize',
28044            
28045            'minimize',
28046            
28047            'restore'
28048        );
28049        
28050        if(Ext.isDefined(this.initHidden)){
28051            this.hidden = this.initHidden;
28052        }
28053        if(this.hidden === false){
28054            this.hidden = true;
28055            this.show();
28056        }
28057    },
28058
28059    
28060    getState : function(){
28061        return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
28062    },
28063
28064    
28065    onRender : function(ct, position){
28066        Ext.Window.superclass.onRender.call(this, ct, position);
28067
28068        if(this.plain){
28069            this.el.addClass('x-window-plain');
28070        }
28071
28072        
28073        this.focusEl = this.el.createChild({
28074                    tag: 'a', href:'#', cls:'x-dlg-focus',
28075                    tabIndex:'-1', html: '&#160;'});
28076        this.focusEl.swallowEvent('click', true);
28077
28078        this.proxy = this.el.createProxy('x-window-proxy');
28079        this.proxy.enableDisplayMode('block');
28080
28081        if(this.modal){
28082            this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
28083            this.mask.enableDisplayMode('block');
28084            this.mask.hide();
28085            this.mon(this.mask, 'click', this.focus, this);
28086        }
28087        if(this.maximizable){
28088            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
28089        }
28090    },
28091
28092    
28093    initEvents : function(){
28094        Ext.Window.superclass.initEvents.call(this);
28095        if(this.animateTarget){
28096            this.setAnimateTarget(this.animateTarget);
28097        }
28098
28099        if(this.resizable){
28100            this.resizer = new Ext.Resizable(this.el, {
28101                minWidth: this.minWidth,
28102                minHeight:this.minHeight,
28103                handles: this.resizeHandles || 'all',
28104                pinned: true,
28105                resizeElement : this.resizerAction,
28106                handleCls: 'x-window-handle'
28107            });
28108            this.resizer.window = this;
28109            this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
28110        }
28111
28112        if(this.draggable){
28113            this.header.addClass('x-window-draggable');
28114        }
28115        this.mon(this.el, 'mousedown', this.toFront, this);
28116        this.manager = this.manager || Ext.WindowMgr;
28117        this.manager.register(this);
28118        if(this.maximized){
28119            this.maximized = false;
28120            this.maximize();
28121        }
28122        if(this.closable){
28123            var km = this.getKeyMap();
28124            km.on(27, this.onEsc, this);
28125            km.disable();
28126        }
28127    },
28128
28129    initDraggable : function(){
28130        
28131        this.dd = new Ext.Window.DD(this);
28132    },
28133
28134   
28135    onEsc : function(k, e){
28136        if (this.activeGhost) {
28137            this.unghost();
28138        }
28139        e.stopEvent();
28140        this[this.closeAction]();
28141    },
28142
28143    
28144    beforeDestroy : function(){
28145        if(this.rendered){
28146            this.hide();
28147            this.clearAnchor();
28148            Ext.destroy(
28149                this.focusEl,
28150                this.resizer,
28151                this.dd,
28152                this.proxy,
28153                this.mask
28154            );
28155        }
28156        Ext.Window.superclass.beforeDestroy.call(this);
28157    },
28158
28159    
28160    onDestroy : function(){
28161        if(this.manager){
28162            this.manager.unregister(this);
28163        }
28164        Ext.Window.superclass.onDestroy.call(this);
28165    },
28166
28167    
28168    initTools : function(){
28169        if(this.minimizable){
28170            this.addTool({
28171                id: 'minimize',
28172                handler: this.minimize.createDelegate(this, [])
28173            });
28174        }
28175        if(this.maximizable){
28176            this.addTool({
28177                id: 'maximize',
28178                handler: this.maximize.createDelegate(this, [])
28179            });
28180            this.addTool({
28181                id: 'restore',
28182                handler: this.restore.createDelegate(this, []),
28183                hidden:true
28184            });
28185        }
28186        if(this.closable){
28187            this.addTool({
28188                id: 'close',
28189                handler: this[this.closeAction].createDelegate(this, [])
28190            });
28191        }
28192    },
28193
28194    
28195    resizerAction : function(){
28196        var box = this.proxy.getBox();
28197        this.proxy.hide();
28198        this.window.handleResize(box);
28199        return box;
28200    },
28201
28202    
28203    beforeResize : function(){
28204        this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); 
28205        this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
28206        this.resizeBox = this.el.getBox();
28207    },
28208
28209    
28210    updateHandles : function(){
28211        if(Ext.isIE && this.resizer){
28212            this.resizer.syncHandleHeight();
28213            this.el.repaint();
28214        }
28215    },
28216
28217    
28218    handleResize : function(box){
28219        var rz = this.resizeBox;
28220        if(rz.x != box.x || rz.y != box.y){
28221            this.updateBox(box);
28222        }else{
28223            this.setSize(box);
28224            if (Ext.isIE6 && Ext.isStrict) {
28225                this.doLayout();
28226            }
28227        }
28228        this.focus();
28229        this.updateHandles();
28230        this.saveState();
28231    },
28232
28233    
28234    focus : function(){
28235        var f = this.focusEl,
28236            db = this.defaultButton,
28237            t = typeof db,
28238            el,
28239            ct;
28240        if(Ext.isDefined(db)){
28241            if(Ext.isNumber(db) && this.fbar){
28242                f = this.fbar.items.get(db);
28243            }else if(Ext.isString(db)){
28244                f = Ext.getCmp(db);
28245            }else{
28246                f = db;
28247            }
28248            el = f.getEl();
28249            ct = Ext.getDom(this.container);
28250            if (el && ct) {
28251                if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
28252                    return;
28253                }
28254            }
28255        }
28256        f = f || this.focusEl;
28257        f.focus.defer(10, f);
28258    },
28259
28260    
28261    setAnimateTarget : function(el){
28262        el = Ext.get(el);
28263        this.animateTarget = el;
28264    },
28265
28266    
28267    beforeShow : function(){
28268        delete this.el.lastXY;
28269        delete this.el.lastLT;
28270        if(this.x === undefined || this.y === undefined){
28271            var xy = this.el.getAlignToXY(this.container, 'c-c');
28272            var pos = this.el.translatePoints(xy[0], xy[1]);
28273            this.x = this.x === undefined? pos.left : this.x;
28274            this.y = this.y === undefined? pos.top : this.y;
28275        }
28276        this.el.setLeftTop(this.x, this.y);
28277
28278        if(this.expandOnShow){
28279            this.expand(false);
28280        }
28281
28282        if(this.modal){
28283            Ext.getBody().addClass('x-body-masked');
28284            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
28285            this.mask.show();
28286        }
28287    },
28288
28289    
28290    show : function(animateTarget, cb, scope){
28291        if(!this.rendered){
28292            this.render(Ext.getBody());
28293        }
28294        if(this.hidden === false){
28295            this.toFront();
28296            return this;
28297        }
28298        if(this.fireEvent('beforeshow', this) === false){
28299            return this;
28300        }
28301        if(cb){
28302            this.on('show', cb, scope, {single:true});
28303        }
28304        this.hidden = false;
28305        if(Ext.isDefined(animateTarget)){
28306            this.setAnimateTarget(animateTarget);
28307        }
28308        this.beforeShow();
28309        if(this.animateTarget){
28310            this.animShow();
28311        }else{
28312            this.afterShow();
28313        }
28314        return this;
28315    },
28316
28317    
28318    afterShow : function(isAnim){
28319        if (this.isDestroyed){
28320            return false;
28321        }
28322        this.proxy.hide();
28323        this.el.setStyle('display', 'block');
28324        this.el.show();
28325        if(this.maximized){
28326            this.fitContainer();
28327        }
28328        if(Ext.isMac && Ext.isGecko2){ 
28329            this.cascade(this.setAutoScroll);
28330        }
28331
28332        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
28333            Ext.EventManager.onWindowResize(this.onWindowResize, this);
28334        }
28335        this.doConstrain();
28336        this.doLayout();
28337        if(this.keyMap){
28338            this.keyMap.enable();
28339        }
28340        this.toFront();
28341        this.updateHandles();
28342        if(isAnim && (Ext.isIE || Ext.isWebKit)){
28343            var sz = this.getSize();
28344            this.onResize(sz.width, sz.height);
28345        }
28346        this.onShow();
28347        this.fireEvent('show', this);
28348    },
28349
28350    
28351    animShow : function(){
28352        this.proxy.show();
28353        this.proxy.setBox(this.animateTarget.getBox());
28354        this.proxy.setOpacity(0);
28355        var b = this.getBox();
28356        this.el.setStyle('display', 'none');
28357        this.proxy.shift(Ext.apply(b, {
28358            callback: this.afterShow.createDelegate(this, [true], false),
28359            scope: this,
28360            easing: 'easeNone',
28361            duration: this.showAnimDuration,
28362            opacity: 0.5
28363        }));
28364    },
28365
28366    
28367    hide : function(animateTarget, cb, scope){
28368        if(this.hidden || this.fireEvent('beforehide', this) === false){
28369            return this;
28370        }
28371        if(cb){
28372            this.on('hide', cb, scope, {single:true});
28373        }
28374        this.hidden = true;
28375        if(animateTarget !== undefined){
28376            this.setAnimateTarget(animateTarget);
28377        }
28378        if(this.modal){
28379            this.mask.hide();
28380            Ext.getBody().removeClass('x-body-masked');
28381        }
28382        if(this.animateTarget){
28383            this.animHide();
28384        }else{
28385            this.el.hide();
28386            this.afterHide();
28387        }
28388        return this;
28389    },
28390
28391    
28392    afterHide : function(){
28393        this.proxy.hide();
28394        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
28395            Ext.EventManager.removeResizeListener(this.onWindowResize, this);
28396        }
28397        if(this.keyMap){
28398            this.keyMap.disable();
28399        }
28400        this.onHide();
28401        this.fireEvent('hide', this);
28402    },
28403
28404    
28405    animHide : function(){
28406        this.proxy.setOpacity(0.5);
28407        this.proxy.show();
28408        var tb = this.getBox(false);
28409        this.proxy.setBox(tb);
28410        this.el.hide();
28411        this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
28412            callback: this.afterHide,
28413            scope: this,
28414            duration: this.hideAnimDuration,
28415            easing: 'easeNone',
28416            opacity: 0
28417        }));
28418    },
28419
28420    
28421    onShow : Ext.emptyFn,
28422
28423    
28424    onHide : Ext.emptyFn,
28425
28426    
28427    onWindowResize : function(){
28428        if(this.maximized){
28429            this.fitContainer();
28430        }
28431        if(this.modal){
28432            this.mask.setSize('100%', '100%');
28433            var force = this.mask.dom.offsetHeight;
28434            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
28435        }
28436        this.doConstrain();
28437    },
28438
28439    
28440    doConstrain : function(){
28441        if(this.constrain || this.constrainHeader){
28442            var offsets;
28443            if(this.constrain){
28444                offsets = {
28445                    right:this.el.shadowOffset,
28446                    left:this.el.shadowOffset,
28447                    bottom:this.el.shadowOffset
28448                };
28449            }else {
28450                var s = this.getSize();
28451                offsets = {
28452                    right:-(s.width - 100),
28453                    bottom:-(s.height - 25 + this.el.getConstrainOffset())
28454                };
28455            }
28456
28457            var xy = this.el.getConstrainToXY(this.container, true, offsets);
28458            if(xy){
28459                this.setPosition(xy[0], xy[1]);
28460            }
28461        }
28462    },
28463
28464    
28465    ghost : function(cls){
28466        var ghost = this.createGhost(cls);
28467        var box = this.getBox(true);
28468        ghost.setLeftTop(box.x, box.y);
28469        ghost.setWidth(box.width);
28470        this.el.hide();
28471        this.activeGhost = ghost;
28472        return ghost;
28473    },
28474
28475    
28476    unghost : function(show, matchPosition){
28477        if(!this.activeGhost) {
28478            return;
28479        }
28480        if(show !== false){
28481            this.el.show();
28482            this.focus.defer(10, this);
28483            if(Ext.isMac && Ext.isGecko2){ 
28484                this.cascade(this.setAutoScroll);
28485            }
28486        }
28487        if(matchPosition !== false){
28488            this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
28489        }
28490        this.activeGhost.hide();
28491        this.activeGhost.remove();
28492        delete this.activeGhost;
28493    },
28494
28495    
28496    minimize : function(){
28497        this.fireEvent('minimize', this);
28498        return this;
28499    },
28500
28501    
28502    close : function(){
28503        if(this.fireEvent('beforeclose', this) !== false){
28504            if(this.hidden){
28505                this.doClose();
28506            }else{
28507                this.hide(null, this.doClose, this);
28508            }
28509        }
28510    },
28511
28512    
28513    doClose : function(){
28514        this.fireEvent('close', this);
28515        this.destroy();
28516    },
28517
28518    
28519    maximize : function(){
28520        if(!this.maximized){
28521            this.expand(false);
28522            this.restoreSize = this.getSize();
28523            this.restorePos = this.getPosition(true);
28524            if (this.maximizable){
28525                this.tools.maximize.hide();
28526                this.tools.restore.show();
28527            }
28528            this.maximized = true;
28529            this.el.disableShadow();
28530
28531            if(this.dd){
28532                this.dd.lock();
28533            }
28534            if(this.collapsible){
28535                this.tools.toggle.hide();
28536            }
28537            this.el.addClass('x-window-maximized');
28538            this.container.addClass('x-window-maximized-ct');
28539
28540            this.setPosition(0, 0);
28541            this.fitContainer();
28542            this.fireEvent('maximize', this);
28543        }
28544        return this;
28545    },
28546
28547    
28548    restore : function(){
28549        if(this.maximized){
28550            var t = this.tools;
28551            this.el.removeClass('x-window-maximized');
28552            if(t.restore){
28553                t.restore.hide();
28554            }
28555            if(t.maximize){
28556                t.maximize.show();
28557            }
28558            this.setPosition(this.restorePos[0], this.restorePos[1]);
28559            this.setSize(this.restoreSize.width, this.restoreSize.height);
28560            delete this.restorePos;
28561            delete this.restoreSize;
28562            this.maximized = false;
28563            this.el.enableShadow(true);
28564
28565            if(this.dd){
28566                this.dd.unlock();
28567            }
28568            if(this.collapsible && t.toggle){
28569                t.toggle.show();
28570            }
28571            this.container.removeClass('x-window-maximized-ct');
28572
28573            this.doConstrain();
28574            this.fireEvent('restore', this);
28575        }
28576        return this;
28577    },
28578
28579    
28580    toggleMaximize : function(){
28581        return this[this.maximized ? 'restore' : 'maximize']();
28582    },
28583
28584    
28585    fitContainer : function(){
28586        var vs = this.container.getViewSize(false);
28587        this.setSize(vs.width, vs.height);
28588    },
28589
28590    
28591    
28592    setZIndex : function(index){
28593        if(this.modal){
28594            this.mask.setStyle('z-index', index);
28595        }
28596        this.el.setZIndex(++index);
28597        index += 5;
28598
28599        if(this.resizer){
28600            this.resizer.proxy.setStyle('z-index', ++index);
28601        }
28602
28603        this.lastZIndex = index;
28604    },
28605
28606    
28607    alignTo : function(element, position, offsets){
28608        var xy = this.el.getAlignToXY(element, position, offsets);
28609        this.setPagePosition(xy[0], xy[1]);
28610        return this;
28611    },
28612
28613    
28614    anchorTo : function(el, alignment, offsets, monitorScroll){
28615        this.clearAnchor();
28616        this.anchorTarget = {
28617            el: el,
28618            alignment: alignment,
28619            offsets: offsets
28620        };
28621
28622        Ext.EventManager.onWindowResize(this.doAnchor, this);
28623        var tm = typeof monitorScroll;
28624        if(tm != 'undefined'){
28625            Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
28626                {buffer: tm == 'number' ? monitorScroll : 50});
28627        }
28628        return this.doAnchor();
28629    },
28630
28631    
28632    doAnchor : function(){
28633        var o = this.anchorTarget;
28634        this.alignTo(o.el, o.alignment, o.offsets);
28635        return this;
28636    },
28637
28638    
28639    clearAnchor : function(){
28640        if(this.anchorTarget){
28641            Ext.EventManager.removeResizeListener(this.doAnchor, this);
28642            Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
28643            delete this.anchorTarget;
28644        }
28645        return this;
28646    },
28647
28648    
28649    toFront : function(e){
28650        if(this.manager.bringToFront(this)){
28651            if(!e || !e.getTarget().focus){
28652                this.focus();
28653            }
28654        }
28655        return this;
28656    },
28657
28658    
28659    setActive : function(active){
28660        if(active){
28661            if(!this.maximized){
28662                this.el.enableShadow(true);
28663            }
28664            this.fireEvent('activate', this);
28665        }else{
28666            this.el.disableShadow();
28667            this.fireEvent('deactivate', this);
28668        }
28669    },
28670
28671    
28672    toBack : function(){
28673        this.manager.sendToBack(this);
28674        return this;
28675    },
28676
28677    
28678    center : function(){
28679        var xy = this.el.getAlignToXY(this.container, 'c-c');
28680        this.setPagePosition(xy[0], xy[1]);
28681        return this;
28682    }
28683
28684    
28685});
28686Ext.reg('window', Ext.Window);
28687
28688
28689Ext.Window.DD = Ext.extend(Ext.dd.DD, {
28690    
28691    constructor : function(win){
28692        this.win = win;
28693        Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
28694        this.setHandleElId(win.header.id);
28695        this.scroll = false;        
28696    },
28697    
28698    moveOnly:true,
28699    headerOffsets:[100, 25],
28700    startDrag : function(){
28701        var w = this.win;
28702        this.proxy = w.ghost(w.initialConfig.cls);
28703        if(w.constrain !== false){
28704            var so = w.el.shadowOffset;
28705            this.constrainTo(w.container, {right: so, left: so, bottom: so});
28706        }else if(w.constrainHeader !== false){
28707            var s = this.proxy.getSize();
28708            this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
28709        }
28710    },
28711    b4Drag : Ext.emptyFn,
28712
28713    onDrag : function(e){
28714        this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
28715    },
28716
28717    endDrag : function(e){
28718        this.win.unghost();
28719        this.win.saveState();
28720    }
28721});
28722
28723Ext.WindowGroup = function(){
28724    var list = {};
28725    var accessList = [];
28726    var front = null;
28727
28728    
28729    var sortWindows = function(d1, d2){
28730        return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
28731    };
28732
28733    
28734    var orderWindows = function(){
28735        var a = accessList, len = a.length;
28736        if(len > 0){
28737            a.sort(sortWindows);
28738            var seed = a[0].manager.zseed;
28739            for(var i = 0; i < len; i++){
28740                var win = a[i];
28741                if(win && !win.hidden){
28742                    win.setZIndex(seed + (i*10));
28743                }
28744            }
28745        }
28746        activateLast();
28747    };
28748
28749    
28750    var setActiveWin = function(win){
28751        if(win != front){
28752            if(front){
28753                front.setActive(false);
28754            }
28755            front = win;
28756            if(win){
28757                win.setActive(true);
28758            }
28759        }
28760    };
28761
28762    
28763    var activateLast = function(){
28764        for(var i = accessList.length-1; i >=0; --i) {
28765            if(!accessList[i].hidden){
28766                setActiveWin(accessList[i]);
28767                return;
28768            }
28769        }
28770        
28771        setActiveWin(null);
28772    };
28773
28774    return {
28775        
28776        zseed : 9000,
28777
28778        
28779        register : function(win){
28780            if(win.manager){
28781                win.manager.unregister(win);
28782            }
28783            win.manager = this;
28784
28785            list[win.id] = win;
28786            accessList.push(win);
28787            win.on('hide', activateLast);
28788        },
28789
28790        
28791        unregister : function(win){
28792            delete win.manager;
28793            delete list[win.id];
28794            win.un('hide', activateLast);
28795            accessList.remove(win);
28796        },
28797
28798        
28799        get : function(id){
28800            return typeof id == "object" ? id : list[id];
28801        },
28802
28803        
28804        bringToFront : function(win){
28805            win = this.get(win);
28806            if(win != front){
28807                win._lastAccess = new Date().getTime();
28808                orderWindows();
28809                return true;
28810            }
28811            return false;
28812        },
28813
28814        
28815        sendToBack : function(win){
28816            win = this.get(win);
28817            win._lastAccess = -(new Date().getTime());
28818            orderWindows();
28819            return win;
28820        },
28821
28822        
28823        hideAll : function(){
28824            for(var id in list){
28825                if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
28826                    list[id].hide();
28827                }
28828            }
28829        },
28830
28831        
28832        getActive : function(){
28833            return front;
28834        },
28835
28836        
28837        getBy : function(fn, scope){
28838            var r = [];
28839            for(var i = accessList.length-1; i >=0; --i) {
28840                var win = accessList[i];
28841                if(fn.call(scope||win, win) !== false){
28842                    r.push(win);
28843                }
28844            }
28845            return r;
28846        },
28847
28848        
28849        each : function(fn, scope){
28850            for(var id in list){
28851                if(list[id] && typeof list[id] != "function"){
28852                    if(fn.call(scope || list[id], list[id]) === false){
28853                        return;
28854                    }
28855                }
28856            }
28857        }
28858    };
28859};
28860
28861
28862
28863Ext.WindowMgr = new Ext.WindowGroup();
28864Ext.MessageBox = function(){
28865    var dlg, opt, mask, waitTimer,
28866        bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
28867        buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
28868        buttonNames = ['ok', 'yes', 'no', 'cancel'];
28869
28870    
28871    var handleButton = function(button){
28872        buttons[button].blur();
28873        if(dlg.isVisible()){
28874            dlg.hide();
28875            handleHide();
28876            Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
28877        }
28878    };
28879
28880    
28881    var handleHide = function(){
28882        if(opt && opt.cls){
28883            dlg.el.removeClass(opt.cls);
28884        }
28885        progressBar.reset();        
28886    };
28887
28888    
28889    var handleEsc = function(d, k, e){
28890        if(opt && opt.closable !== false){
28891            dlg.hide();
28892            handleHide();
28893        }
28894        if(e){
28895            e.stopEvent();
28896        }
28897    };
28898
28899    
28900    var updateButtons = function(b){
28901        var width = 0,
28902            cfg;
28903        if(!b){
28904            Ext.each(buttonNames, function(name){
28905                buttons[name].hide();
28906            });
28907            return width;
28908        }
28909        dlg.footer.dom.style.display = '';
28910        Ext.iterate(buttons, function(name, btn){
28911            cfg = b[name];
28912            if(cfg){
28913                btn.show();
28914                btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
28915                width += btn.getEl().getWidth() + 15;
28916            }else{
28917                btn.hide();
28918            }
28919        });
28920        return width;
28921    };
28922
28923    return {
28924        
28925        getDialog : function(titleText){
28926           if(!dlg){
28927                var btns = [];
28928                
28929                buttons = {};
28930                Ext.each(buttonNames, function(name){
28931                    btns.push(buttons[name] = new Ext.Button({
28932                        text: this.buttonText[name],
28933                        handler: handleButton.createCallback(name),
28934                        hideMode: 'offsets'
28935                    }));
28936                }, this);
28937                dlg = new Ext.Window({
28938                    autoCreate : true,
28939                    title:titleText,
28940                    resizable:false,
28941                    constrain:true,
28942                    constrainHeader:true,
28943                    minimizable : false,
28944                    maximizable : false,
28945                    stateful: false,
28946                    modal: true,
28947                    shim:true,
28948                    buttonAlign:"center",
28949                    width:400,
28950                    height:100,
28951                    minHeight: 80,
28952                    plain:true,
28953                    footer:true,
28954                    closable:true,
28955                    close : function(){
28956                        if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
28957                            handleButton("no");
28958                        }else{
28959                            handleButton("cancel");
28960                        }
28961                    },
28962                    fbar: new Ext.Toolbar({
28963                        items: btns,
28964                        enableOverflow: false
28965                    })
28966                });
28967                dlg.render(document.body);
28968                dlg.getEl().addClass('x-window-dlg');
28969                mask = dlg.mask;
28970                bodyEl = dlg.body.createChild({
28971                    html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
28972                });
28973                iconEl = Ext.get(bodyEl.dom.firstChild);
28974                var contentEl = bodyEl.dom.childNodes[1];
28975                msgEl = Ext.get(contentEl.firstChild);
28976                textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
28977                textboxEl.enableDisplayMode();
28978                textboxEl.addKeyListener([10,13], function(){
28979                    if(dlg.isVisible() && opt && opt.buttons){
28980                        if(opt.buttons.ok){
28981                            handleButton("ok");
28982                        }else if(opt.buttons.yes){
28983                            handleButton("yes");
28984                        }
28985                    }
28986                });
28987                textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
28988                textareaEl.enableDisplayMode();
28989                progressBar = new Ext.ProgressBar({
28990                    renderTo:bodyEl
28991                });
28992               bodyEl.createChild({cls:'x-clear'});
28993            }
28994            return dlg;
28995        },
28996
28997        
28998        updateText : function(text){
28999            if(!dlg.isVisible() && !opt.width){
29000                dlg.setSize(this.maxWidth, 100); 
29001            }
29002            
29003            msgEl.update(text ? text + ' ' : '&#160;');
29004
29005            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
29006                mw = msgEl.getWidth() + msgEl.getMargins('lr'),
29007                fw = dlg.getFrameWidth('lr'),
29008                bw = dlg.body.getFrameWidth('lr'),
29009                w;
29010                
29011            w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
29012                    Math.max(opt.minWidth || this.minWidth, bwidth || 0));
29013
29014            if(opt.prompt === true){
29015                activeTextEl.setWidth(w-iw-fw-bw);
29016            }
29017            if(opt.progress === true || opt.wait === true){
29018                progressBar.setSize(w-iw-fw-bw);
29019            }
29020            if(Ext.isIE && w == bwidth){
29021                w += 4; 
29022            }
29023            msgEl.update(text || '&#160;');
29024            dlg.setSize(w, 'auto').center();
29025            return this;
29026        },
29027
29028        
29029        updateProgress : function(value, progressText, msg){
29030            progressBar.updateProgress(value, progressText);
29031            if(msg){
29032                this.updateText(msg);
29033            }
29034            return this;
29035        },
29036
29037        
29038        isVisible : function(){
29039            return dlg && dlg.isVisible();
29040        },
29041
29042        
29043        hide : function(){
29044            var proxy = dlg ? dlg.activeGhost : null;
29045            if(this.isVisible() || proxy){
29046                dlg.hide();
29047                handleHide();
29048                if (proxy){
29049                    
29050                    
29051                    dlg.unghost(false, false);
29052                } 
29053            }
29054            return this;
29055        },
29056
29057        
29058        show : function(options){
29059            if(this.isVisible()){
29060                this.hide();
29061            }
29062            opt = options;
29063            var d = this.getDialog(opt.title || "&#160;");
29064
29065            d.setTitle(opt.title || "&#160;");
29066            var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
29067            d.tools.close.setDisplayed(allowClose);
29068            activeTextEl = textboxEl;
29069            opt.prompt = opt.prompt || (opt.multiline ? true : false);
29070            if(opt.prompt){
29071                if(opt.multiline){
29072                    textboxEl.hide();
29073                    textareaEl.show();
29074                    textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
29075                    activeTextEl = textareaEl;
29076                }else{
29077                    textboxEl.show();
29078                    textareaEl.hide();
29079                }
29080            }else{
29081                textboxEl.hide();
29082                textareaEl.hide();
29083            }
29084            activeTextEl.dom.value = opt.value || "";
29085            if(opt.prompt){
29086                d.focusEl = activeTextEl;
29087            }else{
29088                var bs = opt.buttons;
29089                var db = null;
29090                if(bs && bs.ok){
29091                    db = buttons["ok"];
29092                }else if(bs && bs.yes){
29093                    db = buttons["yes"];
29094                }
29095                if (db){
29096                    d.focusEl = db;
29097                }
29098            }
29099            if(Ext.isDefined(opt.iconCls)){
29100              d.setIconClass(opt.iconCls);
29101            }
29102            this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
29103            bwidth = updateButtons(opt.buttons);
29104            progressBar.setVisible(opt.progress === true || opt.wait === true);
29105            this.updateProgress(0, opt.progressText);
29106            this.updateText(opt.msg);
29107            if(opt.cls){
29108                d.el.addClass(opt.cls);
29109            }
29110            d.proxyDrag = opt.proxyDrag === true;
29111            d.modal = opt.modal !== false;
29112            d.mask = opt.modal !== false ? mask : false;
29113            if(!d.isVisible()){
29114                
29115                document.body.appendChild(dlg.el.dom);
29116                d.setAnimateTarget(opt.animEl);
29117                
29118                d.on('show', function(){
29119                    if(allowClose === true){
29120                        d.keyMap.enable();
29121                    }else{
29122                        d.keyMap.disable();
29123                    }
29124                }, this, {single:true});
29125                d.show(opt.animEl);
29126            }
29127            if(opt.wait === true){
29128                progressBar.wait(opt.waitConfig);
29129            }
29130            return this;
29131        },
29132
29133        
29134        setIcon : function(icon){
29135            if(!dlg){
29136                bufferIcon = icon;
29137                return;
29138            }
29139            bufferIcon = undefined;
29140            if(icon && icon != ''){
29141                iconEl.removeClass('x-hidden');
29142                iconEl.replaceClass(iconCls, icon);
29143                bodyEl.addClass('x-dlg-icon');
29144                iconCls = icon;
29145            }else{
29146                iconEl.replaceClass(iconCls, 'x-hidden');
29147                bodyEl.removeClass('x-dlg-icon');
29148                iconCls = '';
29149            }
29150            return this;
29151        },
29152
29153        
29154        progress : function(title, msg, progressText){
29155            this.show({
29156                title : title,
29157                msg : msg,
29158                buttons: false,
29159                progress:true,
29160                closable:false,
29161                minWidth: this.minProgressWidth,
29162                progressText: progressText
29163            });
29164            return this;
29165        },
29166
29167        
29168        wait : function(msg, title, config){
29169            this.show({
29170                title : title,
29171                msg : msg,
29172                buttons: false,
29173                closable:false,
29174                wait:true,
29175                modal:true,
29176                minWidth: this.minProgressWidth,
29177                waitConfig: config
29178            });
29179            return this;
29180        },
29181
29182        
29183        alert : function(title, msg, fn, scope){
29184            this.show({
29185                title : title,
29186                msg : msg,
29187                buttons: this.OK,
29188                fn: fn,
29189                scope : scope,
29190                minWidth: this.minWidth
29191            });
29192            return this;
29193        },
29194
29195        
29196        confirm : function(title, msg, fn, scope){
29197            this.show({
29198                title : title,
29199                msg : msg,
29200                buttons: this.YESNO,
29201                fn: fn,
29202                scope : scope,
29203                icon: this.QUESTION,
29204                minWidth: this.minWidth
29205            });
29206            return this;
29207        },
29208
29209        
29210        prompt : function(title, msg, fn, scope, multiline, value){
29211            this.show({
29212                title : title,
29213                msg : msg,
29214                buttons: this.OKCANCEL,
29215                fn: fn,
29216                minWidth: this.minPromptWidth,
29217                scope : scope,
29218                prompt:true,
29219                multiline: multiline,
29220                value: value
29221            });
29222            return this;
29223        },
29224
29225        
29226        OK : {ok:true},
29227        
29228        CANCEL : {cancel:true},
29229        
29230        OKCANCEL : {ok:true, cancel:true},
29231        
29232        YESNO : {yes:true, no:true},
29233        
29234        YESNOCANCEL : {yes:true, no:true, cancel:true},
29235        
29236        INFO : 'ext-mb-info',
29237        
29238        WARNING : 'ext-mb-warning',
29239        
29240        QUESTION : 'ext-mb-question',
29241        
29242        ERROR : 'ext-mb-error',
29243
29244        
29245        defaultTextHeight : 75,
29246        
29247        maxWidth : 600,
29248        
29249        minWidth : 100,
29250        
29251        minProgressWidth : 250,
29252        
29253        minPromptWidth: 250,
29254        
29255        buttonText : {
29256            ok : "OK",
29257            cancel : "Cancel",
29258            yes : "Yes",
29259            no : "No"
29260        }
29261    };
29262}();
29263
29264
29265Ext.Msg = Ext.MessageBox;
29266Ext.dd.PanelProxy  = Ext.extend(Object, {
29267    
29268    constructor : function(panel, config){
29269        this.panel = panel;
29270        this.id = this.panel.id +'-ddproxy';
29271        Ext.apply(this, config);        
29272    },
29273    
29274    
29275    insertProxy : true,
29276
29277    
29278    setStatus : Ext.emptyFn,
29279    reset : Ext.emptyFn,
29280    update : Ext.emptyFn,
29281    stop : Ext.emptyFn,
29282    sync: Ext.emptyFn,
29283
29284    
29285    getEl : function(){
29286        return this.ghost;
29287    },
29288
29289    
29290    getGhost : function(){
29291        return this.ghost;
29292    },
29293
29294    
29295    getProxy : function(){
29296        return this.proxy;
29297    },
29298
29299    
29300    hide : function(){
29301        if(this.ghost){
29302            if(this.proxy){
29303                this.proxy.remove();
29304                delete this.proxy;
29305            }
29306            this.panel.el.dom.style.display = '';
29307            this.ghost.remove();
29308            delete this.ghost;
29309        }
29310    },
29311
29312    
29313    show : function(){
29314        if(!this.ghost){
29315            this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
29316            this.ghost.setXY(this.panel.el.getXY());
29317            if(this.insertProxy){
29318                this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
29319                this.proxy.setSize(this.panel.getSize());
29320            }
29321            this.panel.el.dom.style.display = 'none';
29322        }
29323    },
29324
29325    
29326    repair : function(xy, callback, scope){
29327        this.hide();
29328        if(typeof callback == "function"){
29329            callback.call(scope || this);
29330        }
29331    },
29332
29333    
29334    moveProxy : function(parentNode, before){
29335        if(this.proxy){
29336            parentNode.insertBefore(this.proxy.dom, before);
29337        }
29338    }
29339});
29340
29341
29342Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
29343    
29344    constructor : function(panel, cfg){
29345        this.panel = panel;
29346        this.dragData = {panel: panel};
29347        this.proxy = new Ext.dd.PanelProxy(panel, cfg);
29348        Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
29349        var h = panel.header,
29350            el = panel.body;
29351        if(h){
29352            this.setHandleElId(h.id);
29353            el = panel.header;
29354        }
29355        el.setStyle('cursor', 'move');
29356        this.scroll = false;        
29357    },
29358    
29359    showFrame: Ext.emptyFn,
29360    startDrag: Ext.emptyFn,
29361    b4StartDrag: function(x, y) {
29362        this.proxy.show();
29363    },
29364    b4MouseDown: function(e) {
29365        var x = e.getPageX(),
29366            y = e.getPageY();
29367        this.autoOffset(x, y);
29368    },
29369    onInitDrag : function(x, y){
29370        this.onStartDrag(x, y);
29371        return true;
29372    },
29373    createFrame : Ext.emptyFn,
29374    getDragEl : function(e){
29375        return this.proxy.ghost.dom;
29376    },
29377    endDrag : function(e){
29378        this.proxy.hide();
29379        this.panel.saveState();
29380    },
29381
29382    autoOffset : function(x, y) {
29383        x -= this.startPageX;
29384        y -= this.startPageY;
29385        this.setDelta(x, y);
29386    }
29387});
29388Ext.state.Provider = Ext.extend(Ext.util.Observable, {
29389    
29390    constructor : function(){
29391        
29392        this.addEvents("statechange");
29393        this.state = {};
29394        Ext.state.Provider.superclass.constructor.call(this);
29395    },
29396    
29397    
29398    get : function(name, defaultValue){
29399        return typeof this.state[name] == "undefined" ?
29400            defaultValue : this.state[name];
29401    },
29402
29403    
29404    clear : function(name){
29405        delete this.state[name];
29406        this.fireEvent("statechange", this, name, null);
29407    },
29408
29409    
29410    set : function(name, value){
29411        this.state[name] = value;
29412        this.fireEvent("statechange", this, name, value);
29413    },
29414
29415    
29416    decodeValue : function(cookie){
29417        
29418        var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
29419            matches = re.exec(unescape(cookie)),
29420            all,
29421            type,
29422            v,
29423            kv;
29424        if(!matches || !matches[1]){
29425            return; 
29426        }
29427        type = matches[1];
29428        v = matches[2];
29429        switch(type){
29430            case 'e':
29431                return null;
29432            case 'n':
29433                return parseFloat(v);
29434            case 'd':
29435                return new Date(Date.parse(v));
29436            case 'b':
29437                return (v == '1');
29438            case 'a':
29439                all = [];
29440                if(v != ''){
29441                    Ext.each(v.split('^'), function(val){
29442                        all.push(this.decodeValue(val));
29443                    }, this);
29444                }
29445                return all;
29446           case 'o':
29447                all = {};
29448                if(v != ''){
29449                    Ext.each(v.split('^'), function(val){
29450                        kv = val.split('=');
29451                        all[kv[0]] = this.decodeValue(kv[1]);
29452                    }, this);
29453                }
29454                return all;
29455           default:
29456                return v;
29457        }
29458    },
29459
29460    
29461    encodeValue : function(v){
29462        var enc,
29463            flat = '',
29464            i = 0,
29465            len,
29466            key;
29467        if(v == null){
29468            return 'e:1';    
29469        }else if(typeof v == 'number'){
29470            enc = 'n:' + v;
29471        }else if(typeof v == 'boolean'){
29472            enc = 'b:' + (v ? '1' : '0');
29473        }else if(Ext.isDate(v)){
29474            enc = 'd:' + v.toGMTString();
29475        }else if(Ext.isArray(v)){
29476            for(len = v.length; i < len; i++){
29477                flat += this.encodeValue(v[i]);
29478                if(i != len - 1){
29479                    flat += '^';
29480                }
29481            }
29482            enc = 'a:' + flat;
29483        }else if(typeof v == 'object'){
29484            for(key in v){
29485                if(typeof v[key] != 'function' && v[key] !== undefined){
29486                    flat += key + '=' + this.encodeValue(v[key]) + '^';
29487                }
29488            }
29489            enc = 'o:' + flat.substring(0, flat.length-1);
29490        }else{
29491            enc = 's:' + v;
29492        }
29493        return escape(enc);
29494    }
29495});
29496
29497Ext.state.Manager = function(){
29498    var provider = new Ext.state.Provider();
29499
29500    return {
29501        
29502        setProvider : function(stateProvider){
29503            provider = stateProvider;
29504        },
29505
29506        
29507        get : function(key, defaultValue){
29508            return provider.get(key, defaultValue);
29509        },
29510
29511        
29512         set : function(key, value){
29513            provider.set(key, value);
29514        },
29515
29516        
29517        clear : function(key){
29518            provider.clear(key);
29519        },
29520
29521        
29522        getProvider : function(){
29523            return provider;
29524        }
29525    };
29526}();
29527
29528Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
29529    
29530    constructor : function(config){
29531        Ext.state.CookieProvider.superclass.constructor.call(this);
29532        this.path = "/";
29533        this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); 
29534        this.domain = null;
29535        this.secure = false;
29536        Ext.apply(this, config);
29537        this.state = this.readCookies();
29538    },
29539    
29540    
29541    set : function(name, value){
29542        if(typeof value == "undefined" || value === null){
29543            this.clear(name);
29544            return;
29545        }
29546        this.setCookie(name, value);
29547        Ext.state.CookieProvider.superclass.set.call(this, name, value);
29548    },
29549
29550    
29551    clear : function(name){
29552        this.clearCookie(name);
29553        Ext.state.CookieProvider.superclass.clear.call(this, name);
29554    },
29555
29556    
29557    readCookies : function(){
29558        var cookies = {},
29559            c = document.cookie + ";",
29560            re = /\s?(.*?)=(.*?);/g,
29561    	    matches,
29562            name,
29563            value;
29564    	while((matches = re.exec(c)) != null){
29565            name = matches[1];
29566            value = matches[2];
29567            if(name && name.substring(0,3) == "ys-"){
29568                cookies[name.substr(3)] = this.decodeValue(value);
29569            }
29570        }
29571        return cookies;
29572    },
29573
29574    
29575    setCookie : function(name, value){
29576        document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
29577           ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
29578           ((this.path == null) ? "" : ("; path=" + this.path)) +
29579           ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
29580           ((this.secure == true) ? "; secure" : "");
29581    },
29582
29583    
29584    clearCookie : function(name){
29585        document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
29586           ((this.path == null) ? "" : ("; path=" + this.path)) +
29587           ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
29588           ((this.secure == true) ? "; secure" : "");
29589    }
29590});
29591Ext.DataView = Ext.extend(Ext.BoxComponent, {
29592    
29593    
29594    
29595    
29596    
29597    
29598    
29599    
29600    
29601    selectedClass : "x-view-selected",
29602    
29603    emptyText : "",
29604
29605    
29606    deferEmptyText: true,
29607    
29608    trackOver: false,
29609    
29610    
29611    blockRefresh: false,
29612
29613    
29614    last: false,
29615
29616    
29617    initComponent : function(){
29618        Ext.DataView.superclass.initComponent.call(this);
29619        if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
29620            this.tpl = new Ext.XTemplate(this.tpl);
29621        }
29622
29623        this.addEvents(
29624            
29625            "beforeclick",
29626            
29627            "click",
29628            
29629            "mouseenter",
29630            
29631            "mouseleave",
29632            
29633            "containerclick",
29634            
29635            "dblclick",
29636            
29637            "contextmenu",
29638            
29639            "containercontextmenu",
29640            
29641            "selectionchange",
29642
29643            
29644            "beforeselect"
29645        );
29646
29647        this.store = Ext.StoreMgr.lookup(this.store);
29648        this.all = new Ext.CompositeElementLite();
29649        this.selected = new Ext.CompositeElementLite();
29650    },
29651
29652    
29653    afterRender : function(){
29654        Ext.DataView.superclass.afterRender.call(this);
29655
29656		this.mon(this.getTemplateTarget(), {
29657            "click": this.onClick,
29658            "dblclick": this.onDblClick,
29659            "contextmenu": this.onContextMenu,
29660            scope:this
29661        });
29662
29663        if(this.overClass || this.trackOver){
29664            this.mon(this.getTemplateTarget(), {
29665                "mouseover": this.onMouseOver,
29666                "mouseout": this.onMouseOut,
29667                scope:this
29668            });
29669        }
29670
29671        if(this.store){
29672            this.bindStore(this.store, true);
29673        }
29674    },
29675
29676    
29677    refresh : function() {
29678        this.clearSelections(false, true);
29679        var el = this.getTemplateTarget(),
29680            records = this.store.getRange();
29681            
29682        el.update('');
29683        if(records.length < 1){
29684            if(!this.deferEmptyText || this.hasSkippedEmptyText){
29685                el.update(this.emptyText);
29686            }
29687            this.all.clear();
29688        }else{
29689            this.tpl.overwrite(el, this.collectData(records, 0));
29690            this.all.fill(Ext.query(this.itemSelector, el.dom));
29691            this.updateIndexes(0);
29692        }
29693        this.hasSkippedEmptyText = true;
29694    },
29695
29696    getTemplateTarget: function(){
29697        return this.el;
29698    },
29699
29700    
29701    prepareData : function(data){
29702        return data;
29703    },
29704
29705    
29706    collectData : function(records, startIndex){
29707        var r = [],
29708            i = 0,
29709            len = records.length;
29710        for(; i < len; i++){
29711            r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
29712        }
29713        return r;
29714    },
29715
29716    
29717    bufferRender : function(records, index){
29718        var div = document.createElement('div');
29719        this.tpl.overwrite(div, this.collectData(records, index));
29720        return Ext.query(this.itemSelector, div);
29721    },
29722
29723    
29724    onUpdate : function(ds, record){
29725        var index = this.store.indexOf(record);
29726        if(index > -1){
29727            var sel = this.isSelected(index),
29728                original = this.all.elements[index],
29729                node = this.bufferRender([record], index)[0];
29730
29731            this.all.replaceElement(index, node, true);
29732            if(sel){
29733                this.selected.replaceElement(original, node);
29734                this.all.item(index).addClass(this.selectedClass);
29735            }
29736            this.updateIndexes(index, index);
29737        }
29738    },
29739
29740    
29741    onAdd : function(ds, records, index){
29742        if(this.all.getCount() === 0){
29743            this.refresh();
29744            return;
29745        }
29746        var nodes = this.bufferRender(records, index), n, a = this.all.elements;
29747        if(index < this.all.getCount()){
29748            n = this.all.item(index).insertSibling(nodes, 'before', true);
29749            a.splice.apply(a, [index, 0].concat(nodes));
29750        }else{
29751            n = this.all.last().insertSibling(nodes, 'after', true);
29752            a.push.apply(a, nodes);
29753        }
29754        this.updateIndexes(index);
29755    },
29756
29757    
29758    onRemove : function(ds, record, index){
29759        this.deselect(index);
29760        this.all.removeElement(index, true);
29761        this.updateIndexes(index);
29762        if (this.store.getCount() === 0){
29763            this.refresh();
29764        }
29765    },
29766
29767    
29768    refreshNode : function(index){
29769        this.onUpdate(this.store, this.store.getAt(index));
29770    },
29771
29772    
29773    updateIndexes : function(startIndex, endIndex){
29774        var ns = this.all.elements;
29775        startIndex = startIndex || 0;
29776        endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
29777        for(var i = startIndex; i <= endIndex; i++){
29778            ns[i].viewIndex = i;
29779        }
29780    },
29781    
29782    
29783    getStore : function(){
29784        return this.store;
29785    },
29786
29787    
29788    bindStore : function(store, initial){
29789        if(!initial && this.store){
29790            if(store !== this.store && this.store.autoDestroy){
29791                this.store.destroy();
29792            }else{
29793                this.store.un("beforeload", this.onBeforeLoad, this);
29794                this.store.un("datachanged", this.onDataChanged, this);
29795                this.store.un("add", this.onAdd, this);
29796                this.store.un("remove", this.onRemove, this);
29797                this.store.un("update", this.onUpdate, this);
29798                this.store.un("clear", this.refresh, this);
29799            }
29800            if(!store){
29801                this.store = null;
29802            }
29803        }
29804        if(store){
29805            store = Ext.StoreMgr.lookup(store);
29806            store.on({
29807                scope: this,
29808                beforeload: this.onBeforeLoad,
29809                datachanged: this.onDataChanged,
29810                add: this.onAdd,
29811                remove: this.onRemove,
29812                update: this.onUpdate,
29813                clear: this.refresh
29814            });
29815        }
29816        this.store = store;
29817        if(store){
29818            this.refresh();
29819        }
29820    },
29821    
29822    
29823    onDataChanged: function() {
29824        if (this.blockRefresh !== true) {
29825            this.refresh.apply(this, arguments);
29826        }
29827    },
29828
29829    
29830    findItemFromChild : function(node){
29831        return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
29832    },
29833
29834    
29835    onClick : function(e){
29836        var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
29837            index;
29838        if(item){
29839            index = this.indexOf(item);
29840            if(this.onItemClick(item, index, e) !== false){
29841                this.fireEvent("click", this, index, item, e);
29842            }
29843        }else{
29844            if(this.fireEvent("containerclick", this, e) !== false){
29845                this.onContainerClick(e);
29846            }
29847        }
29848    },
29849
29850    onContainerClick : function(e){
29851        this.clearSelections();
29852    },
29853
29854    
29855    onContextMenu : function(e){
29856        var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29857        if(item){
29858            this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
29859        }else{
29860            this.fireEvent("containercontextmenu", this, e);
29861        }
29862    },
29863
29864    
29865    onDblClick : function(e){
29866        var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29867        if(item){
29868            this.fireEvent("dblclick", this, this.indexOf(item), item, e);
29869        }
29870    },
29871
29872    
29873    onMouseOver : function(e){
29874        var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29875        if(item && item !== this.lastItem){
29876            this.lastItem = item;
29877            Ext.fly(item).addClass(this.overClass);
29878            this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
29879        }
29880    },
29881
29882    
29883    onMouseOut : function(e){
29884        if(this.lastItem){
29885            if(!e.within(this.lastItem, true, true)){
29886                Ext.fly(this.lastItem).removeClass(this.overClass);
29887                this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
29888                delete this.lastItem;
29889            }
29890        }
29891    },
29892
29893    
29894    onItemClick : function(item, index, e){
29895        if(this.fireEvent("beforeclick", this, index, item, e) === false){
29896            return false;
29897        }
29898        if(this.multiSelect){
29899            this.doMultiSelection(item, index, e);
29900            e.preventDefault();
29901        }else if(this.singleSelect){
29902            this.doSingleSelection(item, index, e);
29903            e.preventDefault();
29904        }
29905        return true;
29906    },
29907
29908    
29909    doSingleSelection : function(item, index, e){
29910        if(e.ctrlKey && this.isSelected(index)){
29911            this.deselect(index);
29912        }else{
29913            this.select(index, false);
29914        }
29915    },
29916
29917    
29918    doMultiSelection : function(item, index, e){
29919        if(e.shiftKey && this.last !== false){
29920            var last = this.last;
29921            this.selectRange(last, index, e.ctrlKey);
29922            this.last = last; 
29923        }else{
29924            if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
29925                this.deselect(index);
29926            }else{
29927                this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
29928            }
29929        }
29930    },
29931
29932    
29933    getSelectionCount : function(){
29934        return this.selected.getCount();
29935    },
29936
29937    
29938    getSelectedNodes : function(){
29939        return this.selected.elements;
29940    },
29941
29942    
29943    getSelectedIndexes : function(){
29944        var indexes = [], 
29945            selected = this.selected.elements,
29946            i = 0,
29947            len = selected.length;
29948            
29949        for(; i < len; i++){
29950            indexes.push(selected[i].viewIndex);
29951        }
29952        return indexes;
29953    },
29954
29955    
29956    getSelectedRecords : function(){
29957        return this.getRecords(this.selected.elements);
29958    },
29959
29960    
29961    getRecords : function(nodes){
29962        var records = [], 
29963            i = 0,
29964            len = nodes.length;
29965            
29966        for(; i < len; i++){
29967            records[records.length] = this.store.getAt(nodes[i].viewIndex);
29968        }
29969        return records;
29970    },
29971
29972    
29973    getRecord : function(node){
29974        return this.store.getAt(node.viewIndex);
29975    },
29976
29977    
29978    clearSelections : function(suppressEvent, skipUpdate){
29979        if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
29980            if(!skipUpdate){
29981                this.selected.removeClass(this.selectedClass);
29982            }
29983            this.selected.clear();
29984            this.last = false;
29985            if(!suppressEvent){
29986                this.fireEvent("selectionchange", this, this.selected.elements);
29987            }
29988        }
29989    },
29990
29991    
29992    isSelected : function(node){
29993        return this.selected.contains(this.getNode(node));
29994    },
29995
29996    
29997    deselect : function(node){
29998        if(this.isSelected(node)){
29999            node = this.getNode(node);
30000            this.selected.removeElement(node);
30001            if(this.last == node.viewIndex){
30002                this.last = false;
30003            }
30004            Ext.fly(node).removeClass(this.selectedClass);
30005            this.fireEvent("selectionchange", this, this.selected.elements);
30006        }
30007    },
30008
30009    
30010    select : function(nodeInfo, keepExisting, suppressEvent){
30011        if(Ext.isArray(nodeInfo)){
30012            if(!keepExisting){
30013                this.clearSelections(true);
30014            }
30015            for(var i = 0, len = nodeInfo.length; i < len; i++){
30016                this.select(nodeInfo[i], true, true);
30017            }
30018            if(!suppressEvent){
30019                this.fireEvent("selectionchange", this, this.selected.elements);
30020            }
30021        } else{
30022            var node = this.getNode(nodeInfo);
30023            if(!keepExisting){
30024                this.clearSelections(true);
30025            }
30026            if(node && !this.isSelected(node)){
30027                if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
30028                    Ext.fly(node).addClass(this.selectedClass);
30029                    this.selected.add(node);
30030                    this.last = node.viewIndex;
30031                    if(!suppressEvent){
30032                        this.fireEvent("selectionchange", this, this.selected.elements);
30033                    }
30034                }
30035            }
30036        }
30037    },
30038
30039    
30040    selectRange : function(start, end, keepExisting){
30041        if(!keepExisting){
30042            this.clearSelections(true);
30043        }
30044        this.select(this.getNodes(start, end), true);
30045    },
30046
30047    
30048    getNode : function(nodeInfo){
30049        if(Ext.isString(nodeInfo)){
30050            return document.getElementById(nodeInfo);
30051        }else if(Ext.isNumber(nodeInfo)){
30052            return this.all.elements[nodeInfo];
30053        }else if(nodeInfo instanceof Ext.data.Record){
30054            var idx = this.store.indexOf(nodeInfo);
30055            return this.all.elements[idx];
30056        }
30057        return nodeInfo;
30058    },
30059
30060    
30061    getNodes : function(start, end){
30062        var ns = this.all.elements,
30063            nodes = [],
30064            i;
30065            
30066        start = start || 0;
30067        end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
30068        if(start <= end){
30069            for(i = start; i <= end && ns[i]; i++){
30070                nodes.push(ns[i]);
30071            }
30072        } else{
30073            for(i = start; i >= end && ns[i]; i--){
30074                nodes.push(ns[i]);
30075            }
30076        }
30077        return nodes;
30078    },
30079
30080    
30081    indexOf : function(node){
30082        node = this.getNode(node);
30083        if(Ext.isNumber(node.viewIndex)){
30084            return node.viewIndex;
30085        }
30086        return this.all.indexOf(node);
30087    },
30088
30089    
30090    onBeforeLoad : function(){
30091        if(this.loadingText){
30092            this.clearSelections(false, true);
30093            this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
30094            this.all.clear();
30095        }
30096    },
30097
30098    onDestroy : function(){
30099        this.all.clear();
30100        this.selected.clear();
30101        Ext.DataView.superclass.onDestroy.call(this);
30102        this.bindStore(null);
30103    }
30104});
30105
30106
30107Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
30108
30109Ext.reg('dataview', Ext.DataView);
30110
30111Ext.list.ListView = Ext.extend(Ext.DataView, {
30112    
30113    
30114    
30115    itemSelector: 'dl',
30116    
30117    selectedClass:'x-list-selected',
30118    
30119    overClass:'x-list-over',
30120    
30121    
30122    scrollOffset : undefined,
30123    
30124    columnResize: true,
30125    
30126    
30127    columnSort: true,
30128    
30129
30130    
30131    maxColumnWidth: Ext.isIE ? 99 : 100,
30132
30133    initComponent : function(){
30134        if(this.columnResize){
30135            this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
30136            this.colResizer.init(this);
30137        }
30138        if(this.columnSort){
30139            this.colSorter = new Ext.list.Sorter(this.columnSort);
30140            this.colSorter.init(this);
30141        }
30142        if(!this.internalTpl){
30143            this.internalTpl = new Ext.XTemplate(
30144                '<div class="x-list-header"><div class="x-list-header-inner">',
30145                    '<tpl for="columns">',
30146                    '<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
30147                        '{header}',
30148                    '</em></div>',
30149                    '</tpl>',
30150                    '<div class="x-clear"></div>',
30151                '</div></div>',
30152                '<div class="x-list-body"><div class="x-list-body-inner">',
30153                '</div></div>'
30154            );
30155        }
30156        if(!this.tpl){
30157            this.tpl = new Ext.XTemplate(
30158                '<tpl for="rows">',
30159                    '<dl>',
30160                        '<tpl for="parent.columns">',
30161                        '<dt style="width:{[values.width*100]}%;text-align:{align};">',
30162                        '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
30163                            '{[values.tpl.apply(parent)]}',
30164                        '</em></dt>',
30165                        '</tpl>',
30166                        '<div class="x-clear"></div>',
30167                    '</dl>',
30168                '</tpl>'
30169            );
30170        };
30171
30172        var cs = this.columns,
30173            allocatedWidth = 0,
30174            colsWithWidth = 0,
30175            len = cs.length,
30176            columns = [];
30177
30178        for(var i = 0; i < len; i++){
30179            var c = cs[i];
30180            if(!c.isColumn) {
30181                c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
30182                c = Ext.create(c);
30183            }
30184            if(c.width) {
30185                allocatedWidth += c.width*100;
30186                if(allocatedWidth > this.maxColumnWidth){
30187                    c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
30188                }
30189                colsWithWidth++;
30190            }
30191            columns.push(c);
30192        }
30193
30194        cs = this.columns = columns;
30195
30196        
30197        if(colsWithWidth < len){
30198            var remaining = len - colsWithWidth;
30199            if(allocatedWidth < this.maxColumnWidth){
30200                var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
30201                for(var j = 0; j < len; j++){
30202                    var c = cs[j];
30203                    if(!c.width){
30204                        c.width = perCol;
30205                    }
30206                }
30207            }
30208        }
30209        Ext.list.ListView.superclass.initComponent.call(this);
30210    },
30211
30212    onRender : function(){
30213        this.autoEl = {
30214            cls: 'x-list-wrap'
30215        };
30216        Ext.list.ListView.superclass.onRender.apply(this, arguments);
30217
30218        this.internalTpl.overwrite(this.el, {columns: this.columns});
30219
30220        this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
30221        this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
30222
30223        if(this.hideHeaders){
30224            this.el.dom.firstChild.style.display = 'none';
30225        }
30226    },
30227
30228    getTemplateTarget : function(){
30229        return this.innerBody;
30230    },
30231
30232    
30233    collectData : function(){
30234        var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
30235        return {
30236            columns: this.columns,
30237            rows: rs
30238        };
30239    },
30240
30241    verifyInternalSize : function(){
30242        if(this.lastSize){
30243            this.onResize(this.lastSize.width, this.lastSize.height);
30244        }
30245    },
30246
30247    
30248    onResize : function(w, h){
30249        var body = this.innerBody.dom,
30250            header = this.innerHd.dom,
30251            scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
30252            parentNode;
30253            
30254        if(!body){
30255            return;
30256        }
30257        parentNode = body.parentNode;
30258        if(Ext.isNumber(w)){
30259            if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
30260                body.style.width = scrollWidth;
30261                header.style.width = scrollWidth;
30262            }else{
30263                body.style.width = w + 'px';
30264                header.style.width = w + 'px';
30265                setTimeout(function(){
30266                    if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
30267                        body.style.width = scrollWidth;
30268                        header.style.width = scrollWidth;
30269                    }
30270                }, 10);
30271            }
30272        }
30273        if(Ext.isNumber(h)){
30274            parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
30275        }
30276    },
30277
30278    updateIndexes : function(){
30279        Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
30280        this.verifyInternalSize();
30281    },
30282
30283    findHeaderIndex : function(header){
30284        header = header.dom || header;
30285        var parentNode = header.parentNode, 
30286            children = parentNode.parentNode.childNodes,
30287            i = 0,
30288            c;
30289        for(; c = children[i]; i++){
30290            if(c == parentNode){
30291                return i;
30292            }
30293        }
30294        return -1;
30295    },
30296
30297    setHdWidths : function(){
30298        var els = this.innerHd.dom.getElementsByTagName('div'),
30299            i = 0,
30300            columns = this.columns,
30301            len = columns.length;
30302            
30303        for(; i < len; i++){
30304            els[i].style.width = (columns[i].width*100) + '%';
30305        }
30306    }
30307});
30308
30309Ext.reg('listview', Ext.list.ListView);
30310
30311
30312Ext.ListView = Ext.list.ListView;
30313Ext.list.Column = Ext.extend(Object, {
30314    
30315    isColumn: true,
30316    
30317            
30318    align: 'left',
30319        
30320    header: '',
30321    
30322        
30323    width: null,
30324
30325    
30326    cls: '',
30327    
30328    
30329
30330    
30331    
30332    constructor : function(c){
30333        if(!c.tpl){
30334            c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
30335        }
30336        else if(Ext.isString(c.tpl)){
30337            c.tpl = new Ext.XTemplate(c.tpl);
30338        }
30339        
30340        Ext.apply(this, c);
30341    }
30342});
30343
30344Ext.reg('lvcolumn', Ext.list.Column);
30345
30346
30347Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
30348        
30349    format: '0,000.00',
30350    
30351    constructor : function(c) {
30352        c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');       
30353        Ext.list.NumberColumn.superclass.constructor.call(this, c);
30354    }
30355});
30356
30357Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
30358
30359
30360Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
30361    format: 'm/d/Y',
30362    constructor : function(c) {
30363        c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');      
30364        Ext.list.DateColumn.superclass.constructor.call(this, c);
30365    }
30366});
30367Ext.reg('lvdatecolumn', Ext.list.DateColumn);
30368
30369
30370Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
30371    
30372    trueText: 'true',
30373    
30374    falseText: 'false',
30375    
30376    undefinedText: '&#160;',
30377    
30378    constructor : function(c) {
30379        c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
30380        
30381        var t = this.trueText, f = this.falseText, u = this.undefinedText;
30382        c.tpl.format = function(v){
30383            if(v === undefined){
30384                return u;
30385            }
30386            if(!v || v === 'false'){
30387                return f;
30388            }
30389            return t;
30390        };
30391        
30392        Ext.list.DateColumn.superclass.constructor.call(this, c);
30393    }
30394});
30395
30396Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
30397Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
30398    
30399    minPct: .05,
30400
30401    constructor: function(config){
30402        Ext.apply(this, config);
30403        Ext.list.ColumnResizer.superclass.constructor.call(this);
30404    },
30405    init : function(listView){
30406        this.view = listView;
30407        listView.on('render', this.initEvents, this);
30408    },
30409
30410    initEvents : function(view){
30411        view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
30412        this.tracker = new Ext.dd.DragTracker({
30413            onBeforeStart: this.onBeforeStart.createDelegate(this),
30414            onStart: this.onStart.createDelegate(this),
30415            onDrag: this.onDrag.createDelegate(this),
30416            onEnd: this.onEnd.createDelegate(this),
30417            tolerance: 3,
30418            autoStart: 300
30419        });
30420        this.tracker.initEl(view.innerHd);
30421        view.on('beforedestroy', this.tracker.destroy, this.tracker);
30422    },
30423
30424    handleHdMove : function(e, t){
30425        var handleWidth = 5,
30426            x = e.getPageX(),
30427            header = e.getTarget('em', 3, true);
30428        if(header){
30429            var region = header.getRegion(),
30430                style = header.dom.style,
30431                parentNode = header.dom.parentNode;
30432
30433            if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
30434                this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
30435                style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
30436            } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
30437                this.activeHd = header;
30438                style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
30439            } else{
30440                delete this.activeHd;
30441                style.cursor = '';
30442            }
30443        }
30444    },
30445
30446    onBeforeStart : function(e){
30447        this.dragHd = this.activeHd;
30448        return !!this.dragHd;
30449    },
30450
30451    onStart: function(e){
30452        
30453        var me = this,
30454            view = me.view,
30455            dragHeader = me.dragHd,
30456            x = me.tracker.getXY()[0];            
30457        
30458        me.proxy = view.el.createChild({cls:'x-list-resizer'});
30459        me.dragX = dragHeader.getX();
30460        me.headerIndex = view.findHeaderIndex(dragHeader);
30461        
30462        me.headersDisabled = view.disableHeaders;
30463        view.disableHeaders = true;
30464        
30465        me.proxy.setHeight(view.el.getHeight());
30466        me.proxy.setX(me.dragX);
30467        me.proxy.setWidth(x - me.dragX);
30468        
30469        this.setBoundaries();
30470        
30471    },
30472    
30473    
30474    setBoundaries: function(relativeX){
30475        var view = this.view,
30476            headerIndex = this.headerIndex,
30477            width = view.innerHd.getWidth(),
30478            relativeX = view.innerHd.getX(),
30479            minWidth = Math.ceil(width * this.minPct),
30480            maxWidth = width - minWidth,
30481            numColumns = view.columns.length,
30482            headers = view.innerHd.select('em', true),
30483            minX = minWidth + relativeX,
30484            maxX = maxWidth + relativeX,
30485            header;
30486          
30487        if (numColumns == 2) {
30488            this.minX = minX;
30489            this.maxX = maxX;
30490        }else{
30491            header = headers.item(headerIndex + 2);
30492            this.minX = headers.item(headerIndex).getX() + minWidth;
30493            this.maxX = header ? header.getX() - minWidth : maxX;
30494            if (headerIndex == 0) {
30495                
30496                this.minX = minX;
30497            }
30497 else if (headerIndex == numColumns - 2) {
30498                
30499                this.maxX = maxX;
30500            }
30501        }
30502    },
30503
30504    onDrag: function(e){
30505        var me = this,
30506            cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);
30507            
30508        me.proxy.setWidth(cursorX - this.dragX);
30509    },
30510
30511    onEnd: function(e){
30512        
30513        var newWidth = this.proxy.getWidth(),
30514            index = this.headerIndex,
30515            view = this.view,
30516            columns = view.columns,
30517            width = view.innerHd.getWidth(),
30518            newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
30519            disabled = this.headersDisabled,
30520            headerCol = columns[index],
30521            otherCol = columns[index + 1],
30522            totalPercent = headerCol.width + otherCol.width;
30523
30524        this.proxy.remove();
30525
30526        headerCol.width = newPercent;
30527        otherCol.width = totalPercent - newPercent;
30528      
30529        delete this.dragHd;
30530        view.setHdWidths();
30531        view.refresh();
30532        
30533        setTimeout(function(){
30534            view.disableHeaders = disabled;
30535        }, 100);
30536    }
30537});
30538
30539
30540Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
30541Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
30542    
30543    sortClasses : ["sort-asc", "sort-desc"],
30544
30545    constructor: function(config){
30546        Ext.apply(this, config);
30547        Ext.list.Sorter.superclass.constructor.call(this);
30548    },
30549
30550    init : function(listView){
30551        this.view = listView;
30552        listView.on('render', this.initEvents, this);
30553    },
30554
30555    initEvents : function(view){
30556        view.mon(view.innerHd, 'click', this.onHdClick, this);
30557        view.innerHd.setStyle('cursor', 'pointer');
30558        view.mon(view.store, 'datachanged', this.updateSortState, this);
30559        this.updateSortState.defer(10, this, [view.store]);
30560    },
30561
30562    updateSortState : function(store){
30563        var state = store.getSortState();
30564        if(!state){
30565            return;
30566        }
30567        this.sortState = state;
30568        var cs = this.view.columns, sortColumn = -1;
30569        for(var i = 0, len = cs.length; i < len; i++){
30570            if(cs[i].dataIndex == state.field){
30571                sortColumn = i;
30572                break;
30573            }
30574        }
30575        if(sortColumn != -1){
30576            var sortDir = state.direction;
30577            this.updateSortIcon(sortColumn, sortDir);
30578        }
30579    },
30580
30581    updateSortIcon : function(col, dir){
30582        var sc = this.sortClasses;
30583        var hds = this.view.innerHd.select('em').removeClass(sc);
30584        hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
30585    },
30586
30587    onHdClick : function(e){
30588        var hd = e.getTarget('em', 3);
30589        if(hd && !this.view.disableHeaders){
30590            var index = this.view.findHeaderIndex(hd);
30591            this.view.store.sort(this.view.columns[index].dataIndex);
30592        }
30593    }
30594});
30595
30596
30597Ext.ListView.Sorter = Ext.list.Sorter;
30598Ext.TabPanel = Ext.extend(Ext.Panel,  {
30599    
30600    
30601    
30602    deferredRender : true,
30603    
30604    tabWidth : 120,
30605    
30606    minTabWidth : 30,
30607    
30608    resizeTabs : false,
30609    
30610    enableTabScroll : false,
30611    
30612    scrollIncrement : 0,
30613    
30614    scrollRepeatInterval : 400,
30615    
30616    scrollDuration : 0.35,
30617    
30618    animScroll : true,
30619    
30620    tabPosition : 'top',
30621    
30622    baseCls : 'x-tab-panel',
30623    
30624    autoTabs : false,
30625    
30626    autoTabSelector : 'div.x-tab',
30627    
30628    activeTab : undefined,
30629    
30630    tabMargin : 2,
30631    
30632    plain : false,
30633    
30634    wheelIncrement : 20,
30635
30636    
30637    idDelimiter : '__',
30638
30639    
30640    itemCls : 'x-tab-item',
30641
30642    
30643    elements : 'body',
30644    headerAsText : false,
30645    frame : false,
30646    hideBorders :true,
30647
30648    
30649    initComponent : function(){
30650        this.frame = false;
30651        Ext.TabPanel.superclass.initComponent.call(this);
30652        this.addEvents(
30653            
30654            'beforetabchange',
30655            
30656            'tabchange',
30657            
30658            'contextmenu'
30659        );
30660        
30661        this.setLayout(new Ext.layout.CardLayout(Ext.apply({
30662            layoutOnCardChange: this.layoutOnTabChange,
30663            deferredRender: this.deferredRender
30664        }, this.layoutConfig)));
30665
30666        if(this.tabPosition == 'top'){
30667            this.elements += ',header';
30668            this.stripTarget = 'header';
30669        }else {
30670            this.elements += ',footer';
30671            this.stripTarget = 'footer';
30672        }
30673        if(!this.stack){
30674            this.stack = Ext.TabPanel.AccessStack();
30675        }
30676        this.initItems();
30677    },
30678
30679    
30680    onRender : function(ct, position){
30681        Ext.TabPanel.superclass.onRender.call(this, ct, position);
30682
30683        if(this.plain){
30684            var pos = this.tabPosition == 'top' ? 'header' : 'footer';
30685            this[pos].addClass('x-tab-panel-'+pos+'-plain');
30686        }
30687
30688        var st = this[this.stripTarget];
30689
30690        this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
30691            tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
30692
30693        var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
30694        st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
30695        this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
30696
30697        
30698        this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: '&#160;'}]});
30699        this.strip.createChild({cls:'x-clear'});
30700
30701        this.body.addClass('x-tab-panel-body-'+this.tabPosition);
30702
30703        
30704        if(!this.itemTpl){
30705            var tt = new Ext.Template(
30706                 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
30707                 '<a class="x-tab-right" href="#"><em class="x-tab-left">',
30708                 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
30709                 '</em></a></li>'
30710            );
30711            tt.disableFormats = true;
30712            tt.compile();
30713            Ext.TabPanel.prototype.itemTpl = tt;
30714        }
30715
30716        this.items.each(this.initTab, this);
30717    },
30718
30719    
30720    afterRender : function(){
30721        Ext.TabPanel.superclass.afterRender.call(this);
30722        if(this.autoTabs){
30723            this.readTabs(false);
30724        }
30725        if(this.activeTab !== undefined){
30726            var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
30727            delete this.activeTab;
30728            this.setActiveTab(item);
30729        }
30730    },
30731
30732    
30733    initEvents : function(){
30734        Ext.TabPanel.superclass.initEvents.call(this);
30735        this.mon(this.strip, {
30736            scope: this,
30737            mousedown: this.onStripMouseDown,
30738            contextmenu: this.onStripContextMenu
30739        });
30740        if(this.enableTabScroll){
30741            this.mon(this.strip, 'mousewheel', this.onWheel, this);
30742        }
30743    },
30744
30745    
30746    findTargets : function(e){
30747        var item = null,
30748            itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
30749
30750        if(itemEl){
30751            item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
30752            if(item.disabled){
30753                return {
30754                    close : null,
30755                    item : null,
30756                    el : null
30757                };
30758            }
30759        }
30760        return {
30761            close : e.getTarget('.x-tab-strip-close', this.strip),
30762            item : item,
30763            el : itemEl
30764        };
30765    },
30766
30767    
30768    onStripMouseDown : function(e){
30769        if(e.button !== 0){
30770            return;
30771        }
30772        e.preventDefault();
30773        var t = this.findTargets(e);
30774        if(t.close){
30775            if (t.item.fireEvent('beforeclose', t.item) !== false) {
30776                t.item.fireEvent('close', t.item);
30777                this.remove(t.item);
30778            }
30779            return;
30780        }
30781        if(t.item && t.item != this.activeTab){
30782            this.setActiveTab(t.item);
30783        }
30784    },
30785
30786    
30787    onStripContextMenu : function(e){
30788        e.preventDefault();
30789        var t = this.findTargets(e);
30790        if(t.item){
30791            this.fireEvent('contextmenu', this, t.item, e);
30792        }
30793    },
30794
30795    
30796    readTabs : function(removeExisting){
30797        if(removeExisting === true){
30798            this.items.each(function(item){
30799                this.remove(item);
30800            }, this);
30801        }
30802        var tabs = this.el.query(this.autoTabSelector);
30803        for(var i = 0, len = tabs.length; i < len; i++){
30804            var tab = tabs[i],
30805                title = tab.getAttribute('title');
30806            tab.removeAttribute('title');
30807            this.add({
30808                title: title,
30809                contentEl: tab
30810            });
30811        }
30812    },
30813
30814    
30815    initTab : function(item, index){
30816        var before = this.strip.dom.childNodes[index],
30817            p = this.getTemplateArgs(item),
30818            el = before ?
30819                 this.itemTpl.insertBefore(before, p) :
30820                 this.itemTpl.append(this.strip, p),
30821            cls = 'x-tab-strip-over',
30822            tabEl = Ext.get(el);
30823
30824        tabEl.hover(function(){
30825            if(!item.disabled){
30826                tabEl.addClass(cls);
30827            }
30828        }, function(){
30829            tabEl.removeClass(cls);
30830        });
30831
30832        if(item.tabTip){
30833            tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
30834        }
30835        item.tabEl = el;
30836
30837        
30838        tabEl.select('a').on('click', function(e){
30839            if(!e.getPageX()){
30840                this.onStripMouseDown(e);
30841            }
30842        }, this, {preventDefault: true});
30843
30844        item.on({
30845            scope: this,
30846            disable: this.onItemDisabled,
30847            enable: this.onItemEnabled,
30848            titlechange: this.onItemTitleChanged,
30849            iconchange: this.onItemIconChanged,
30850            beforeshow: this.onBeforeShowItem
30851        });
30852    },
30853
30854
30855
30856    
30857    getTemplateArgs : function(item) {
30858        var cls = item.closable ? 'x-tab-strip-closable' : '';
30859        if(item.disabled){
30860            cls += ' x-item-disabled';
30861        }
30862        if(item.iconCls){
30863            cls += ' x-tab-with-icon';
30864        }
30865        if(item.tabCls){
30866            cls += ' ' + item.tabCls;
30867        }
30868
30869        return {
30870            id: this.id + this.idDelimiter + item.getItemId(),
30871            text: item.title,
30872            cls: cls,
30873            iconCls: item.iconCls || ''
30874        };
30875    },
30876
30877    
30878    onAdd : function(c){
30879        Ext.TabPanel.superclass.onAdd.call(this, c);
30880        if(this.rendered){
30881            var items = this.items;
30882            this.initTab(c, items.indexOf(c));
30883            this.delegateUpdates();
30884        }
30885    },
30886
30887    
30888    onBeforeAdd : function(item){
30889        var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
30890        if(existing){
30891            this.setActiveTab(item);
30892            return false;
30893        }
30894        Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
30895        var es = item.elements;
30896        item.elements = es ? es.replace(',header', '') : es;
30897        item.border = (item.border === true);
30898    },
30899
30900    
30901    onRemove : function(c){
30902        var te = Ext.get(c.tabEl);
30903        
30904        if(te){
30905            te.select('a').removeAllListeners();
30906            Ext.destroy(te);
30907        }
30908        Ext.TabPanel.superclass.onRemove.call(this, c);
30909        this.stack.remove(c);
30910        delete c.tabEl;
30911        c.un('disable', this.onItemDisabled, this);
30912        c.un('enable', this.onItemEnabled, this);
30913        c.un('titlechange', this.onItemTitleChanged, this);
30914        c.un('iconchange', this.onItemIconChanged, this);
30915        c.un('beforeshow', this.onBeforeShowItem, this);
30916        if(c == this.activeTab){
30917            var next = this.stack.next();
30918            if(next){
30919                this.setActiveTab(next);
30920            }else if(this.items.getCount() > 0){
30921                this.setActiveTab(0);
30922            }else{
30923                this.setActiveTab(null);
30924            }
30925        }
30926        if(!this.destroying){
30927            this.delegateUpdates();
30928        }
30929    },
30930
30931    
30932    onBeforeShowItem : function(item){
30933        if(item != this.activeTab){
30934            this.setActiveTab(item);
30935            return false;
30936        }
30937    },
30938
30939    
30940    onItemDisabled : function(item){
30941        var el = this.getTabEl(item);
30942        if(el){
30943            Ext.fly(el).addClass('x-item-disabled');
30944        }
30945        this.stack.remove(item);
30946    },
30947
30948    
30949    onItemEnabled : function(item){
30950        var el = this.getTabEl(item);
30951        if(el){
30952            Ext.fly(el).removeClass('x-item-disabled');
30953        }
30954    },
30955
30956    
30957    onItemTitleChanged : function(item){
30958        var el = this.getTabEl(item);
30959        if(el){
30960            Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
30961        }
30962    },
30963
30964    
30965    onItemIconChanged : function(item, iconCls, oldCls){
30966        var el = this.getTabEl(item);
30967        if(el){
30968            el = Ext.get(el);
30969            el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
30970            el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
30971        }
30972    },
30973
30974    
30975    getTabEl : function(item){
30976        var c = this.getComponent(item);
30977        return c ? c.tabEl : null;
30978    },
30979
30980    
30981    onResize : function(){
30982        Ext.TabPanel.superclass.onResize.apply(this, arguments);
30983        this.delegateUpdates();
30984    },
30985
30986    
30987    beginUpdate : function(){
30988        this.suspendUpdates = true;
30989    },
30990
30991    
30992    endUpdate : function(){
30993        this.suspendUpdates = false;
30994        this.delegateUpdates();
30995    },
30996
30997    
30998    hideTabStripItem : function(item){
30999        item = this.getComponent(item);
31000        var el = this.getTabEl(item);
31001        if(el){
31002            el.style.display = 'none';
31003            this.delegateUpdates();
31004        }
31005        this.stack.remove(item);
31006    },
31007
31008    
31009    unhideTabStripItem : function(item){
31010        item = this.getComponent(item);
31011        var el = this.getTabEl(item);
31012        if(el){
31013            el.style.display = '';
31014            this.delegateUpdates();
31015        }
31016    },
31017
31018    
31019    delegateUpdates : function(){
31020        var rendered = this.rendered;
31021        if(this.suspendUpdates){
31022            return;
31023        }
31024        if(this.resizeTabs && rendered){
31025            this.autoSizeTabs();
31026        }
31027        if(this.enableTabScroll && rendered){
31028            this.autoScrollTabs();
31029        }
31030    },
31031
31032    
31033    autoSizeTabs : function(){
31034        var count = this.items.length,
31035            ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
31036            ow = this[ce].dom.offsetWidth,
31037            aw = this[ce].dom.clientWidth;
31038
31039        if(!this.resizeTabs || count < 1 || !aw){ 
31040            return;
31041        }
31042
31043        var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); 
31044        this.lastTabWidth = each;
31045        var lis = this.strip.query('li:not(.x-tab-edge)');
31046        for(var i = 0, len = lis.length; i < len; i++) {
31047            var li = lis[i],
31048                inner = Ext.fly(li).child('.x-tab-strip-inner', true),
31049                tw = li.offsetWidth,
31050                iw = inner.offsetWidth;
31051            inner.style.width = (each - (tw-iw)) + 'px';
31052        }
31053    },
31054
31055    
31056    adjustBodyWidth : function(w){
31057        if(this.header){
31058            this.header.setWidth(w);
31059        }
31060        if(this.footer){
31061            this.footer.setWidth(w);
31062        }
31063        return w;
31064    },
31065
31066    
31067    setActiveTab : function(item){
31068        item = this.getComponent(item);
31069        if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
31070            return;
31071        }
31072        if(!this.rendered){
31073            this.activeTab = item;
31074            return;
31075        }
31076        if(this.activeTab != item){
31077            if(this.activeTab){
31078                var oldEl = this.getTabEl(this.activeTab);
31079                if(oldEl){
31080                    Ext.fly(oldEl).removeClass('x-tab-strip-active');
31081                }
31082            }
31083            this.activeTab = item;
31084            if(item){
31085                var el = this.getTabEl(item);
31086                Ext.fly(el).addClass('x-tab-strip-active');
31087                this.stack.add(item);
31088
31089                this.layout.setActiveItem(item);
31090                
31091                this.delegateUpdates();
31092                if(this.scrolling){
31093                    this.scrollToTab(item, this.animScroll);
31094                }
31095            }
31096            this.fireEvent('tabchange', this, item);
31097        }
31098    },
31099
31100    
31101    getActiveTab : function(){
31102        return this.activeTab || null;
31103    },
31104
31105    
31106    getItem : function(item){
31107        return this.getComponent(item);
31108    },
31109
31110    
31111    autoScrollTabs : function(){
31112        this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
31113        var count = this.items.length,
31114            ow = this.pos.dom.offsetWidth,
31115            tw = this.pos.dom.clientWidth,
31116            wrap = this.stripWrap,
31117            wd = wrap.dom,
31118            cw = wd.offsetWidth,
31119            pos = this.getScrollPos(),
31120            l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
31121
31122        if(!this.enableTabScroll || cw < 20){ 
31123            return;
31124        }
31125        if(count == 0 || l <= tw){
31126            
31127            wd.scrollLeft = 0;
31128            wrap.setWidth(tw);
31129            if(this.scrolling){
31130                this.scrolling = false;
31131                this.pos.removeClass('x-tab-scrolling');
31132                this.scrollLeft.hide();
31133                this.scrollRight.hide();
31134                
31135                if(Ext.isAir || Ext.isWebKit){
31136                    wd.style.marginLeft = '';
31137                    wd.style.marginRight = '';
31138                }
31139            }
31140        }else{
31141            if(!this.scrolling){
31142                this.pos.addClass('x-tab-scrolling');
31143                
31144                if(Ext.isAir || Ext.isWebKit){
31145                    wd.style.marginLeft = '18px';
31146                    wd.style.marginRight = '18px';
31147                }
31148            }
31149            tw -= wrap.getMargins('lr');
31150            wrap.setWidth(tw > 20 ? tw : 20);
31151            if(!this.scrolling){
31152                if(!this.scrollLeft){
31153                    this.createScrollers();
31154                }else{
31155                    this.scrollLeft.show();
31156                    this.scrollRight.show();
31157                }
31158            }
31159            this.scrolling = true;
31160            if(pos > (l-tw)){ 
31161                wd.scrollLeft = l-tw;
31162            }else{ 
31163                this.scrollToTab(this.activeTab, false);
31164            }
31165            this.updateScrollButtons();
31166        }
31167    },
31168
31169    
31170    createScrollers : function(){
31171        this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
31172        var h = this.stripWrap.dom.offsetHeight;
31173
31174        
31175        var sl = this.pos.insertFirst({
31176            cls:'x-tab-scroller-left'
31177        });
31178        sl.setHeight(h);
31179        sl.addClassOnOver('x-tab-scroller-left-over');
31180        this.leftRepeater = new Ext.util.ClickRepeater(sl, {
31181            interval : this.scrollRepeatInterval,
31182            handler: this.onScrollLeft,
31183            scope: this
31184        });
31185        this.scrollLeft = sl;
31186
31187        
31188        var sr = this.pos.insertFirst({
31189            cls:'x-tab-scroller-right'
31190        });
31191        sr.setHeight(h);
31192        sr.addClassOnOver('x-tab-scroller-right-over');
31193        this.rightRepeater = new Ext.util.ClickRepeater(sr, {
31194            interval : this.scrollRepeatInterval,
31195            handler: this.onScrollRight,
31196            scope: this
31197        });
31198        this.scrollRight = sr;
31199    },
31200
31201    
31202    getScrollWidth : function(){
31203        return this.edge.getOffsetsTo(this.stripWrap)[0] + this.get
31203ScrollPos();
31204    },
31205
31206    
31207    getScrollPos : function(){
31208        return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
31209    },
31210
31211    
31212    getScrollArea : function(){
31213        return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
31214    },
31215
31216    
31217    getScrollAnim : function(){
31218        return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
31219    },
31220
31221    
31222    getScrollIncrement : function(){
31223        return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
31224    },
31225
31226    
31227
31228    scrollToTab : function(item, animate){
31229        if(!item){
31230            return;
31231        }
31232        var el = this.getTabEl(item),
31233            pos = this.getScrollPos(),
31234            area = this.getScrollArea(),
31235            left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
31236            right = left + el.offsetWidth;
31237        if(left < pos){
31238            this.scrollTo(left, animate);
31239        }else if(right > (pos + area)){
31240            this.scrollTo(right - area, animate);
31241        }
31242    },
31243
31244    
31245    scrollTo : function(pos, animate){
31246        this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
31247        if(!animate){
31248            this.updateScrollButtons();
31249        }
31250    },
31251
31252    onWheel : function(e){
31253        var d = e.getWheelDelta()*this.wheelIncrement*-1;
31254        e.stopEvent();
31255
31256        var pos = this.getScrollPos(),
31257            newpos = pos + d,
31258            sw = this.getScrollWidth()-this.getScrollArea();
31259
31260        var s = Math.max(0, Math.min(sw, newpos));
31261        if(s != pos){
31262            this.scrollTo(s, false);
31263        }
31264    },
31265
31266    
31267    onScrollRight : function(){
31268        var sw = this.getScrollWidth()-this.getScrollArea(),
31269            pos = this.getScrollPos(),
31270            s = Math.min(sw, pos + this.getScrollIncrement());
31271        if(s != pos){
31272            this.scrollTo(s, this.animScroll);
31273        }
31274    },
31275
31276    
31277    onScrollLeft : function(){
31278        var pos = this.getScrollPos(),
31279            s = Math.max(0, pos - this.getScrollIncrement());
31280        if(s != pos){
31281            this.scrollTo(s, this.animScroll);
31282        }
31283    },
31284
31285    
31286    updateScrollButtons : function(){
31287        var pos = this.getScrollPos();
31288        this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
31289        this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
31290    },
31291
31292    
31293    beforeDestroy : function() {
31294        Ext.destroy(this.leftRepeater, this.rightRepeater);
31295        this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
31296        this.activeTab = null;
31297        Ext.TabPanel.superclass.beforeDestroy.apply(this);
31298    }
31299
31300    
31301    
31302    
31303    
31304    
31305    
31306    
31307    
31308    
31309    
31310    
31311    
31312});
31313Ext.reg('tabpanel', Ext.TabPanel);
31314
31315
31316Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
31317
31318
31319Ext.TabPanel.AccessStack = function(){
31320    var items = [];
31321    return {
31322        add : function(item){
31323            items.push(item);
31324            if(items.length > 10){
31325                items.shift();
31326            }
31327        },
31328
31329        remove : function(item){
31330            var s = [];
31331            for(var i = 0, len = items.length; i < len; i++) {
31332                if(items[i] != item){
31333                    s.push(items[i]);
31334                }
31335            }
31336            items = s;
31337        },
31338
31339        next : function(){
31340            return items.pop();
31341        }
31342    };
31343};
31344
31345Ext.Button = Ext.extend(Ext.BoxComponent, {
31346    
31347    hidden : false,
31348    
31349    disabled : false,
31350    
31351    pressed : false,
31352
31353    
31354
31355    
31356
31357    
31358    enableToggle : false,
31359    
31360    
31361    
31362    menuAlign : 'tl-bl?',
31363
31364    
31365    
31366    
31367    type : 'button',
31368
31369    
31370    menuClassTarget : 'tr:nth(2)',
31371
31372    
31373    clickEvent : 'click',
31374
31375    
31376    handleMouseEvents : true,
31377
31378    
31379    tooltipType : 'qtip',
31380
31381    
31382    buttonSelector : 'button:first-child',
31383
31384    
31385    scale : 'small',
31386
31387    
31388
31389    
31390    iconAlign : 'left',
31391
31392    
31393    arrowAlign : 'right',
31394
31395    
31396    
31397    
31398    
31399
31400    initComponent : function(){
31401        if(this.menu){
31402            
31403            
31404            if (Ext.isArray(this.menu)){
31405                this.menu = { items: this.menu };
31406            }
31407            
31408            
31409            
31410            if (Ext.isObject(this.menu)){
31411                this.menu.ownerCt = this;
31412            }
31413            
31414            this.menu = Ext.menu.MenuMgr.get(this.menu);
31415            this.menu.ownerCt = undefined;
31416        }
31417        
31418        Ext.Button.superclass.initComponent.call(this);
31419
31420        this.addEvents(
31421            
31422            'click',
31423            
31424            'toggle',
31425            
31426            'mouseover',
31427            
31428            'mouseout',
31429            
31430            'menushow',
31431            
31432            'menuhide',
31433            
31434            'menutriggerover',
31435            
31436            'menutriggerout'
31437        );
31438        
31439        if(Ext.isString(this.toggleGroup)){
31440            this.enableToggle = true;
31441        }
31442    },
31443
31444
31445    getTemplateArgs : function(){
31446        return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
31447    },
31448
31449    
31450    setButtonClass : function(){
31451        if(this.useSetClass){
31452            if(!Ext.isEmpty(this.oldCls)){
31453                this.el.removeClass([this.oldCls, 'x-btn-pressed']);
31454            }
31455            this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
31456            this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
31457        }
31458    },
31459
31460    
31461    getMenuClass : function(){
31462        return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
31463    },
31464
31465    
31466    onRender : function(ct, position){
31467        if(!this.template){
31468            if(!Ext.Button.buttonTemplate){
31469                
31470                Ext.Button.buttonTemplate = new Ext.Template(
31471                    '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
31472                    '<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>',
31473                    '<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{2}" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
31474                    '<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',
31475                    '</tbody></table>');
31476                Ext.Button.buttonTemplate.compile();
31477            }
31478            this.template = Ext.Button.buttonTemplate;
31479        }
31480
31481        var btn, targs = this.getTemplateArgs();
31482
31483        if(position){
31484            btn = this.template.insertBefore(position, targs, true);
31485        }else{
31486            btn = this.template.append(ct, targs, true);
31487        }
31488        
31489        this.btnEl = btn.child(this.buttonSelector);
31490        this.mon(this.btnEl, {
31491            scope: this,
31492            focus: this.onFocus,
31493            blur: this.onBlur
31494        });
31495
31496        this.initButtonEl(btn, this.btnEl);
31497
31498        Ext.ButtonToggleMgr.register(this);
31499    },
31500
31501    
31502    initButtonEl : function(btn, btnEl){
31503        this.el = btn;
31504        this.setIcon(this.icon);
31505        this.setText(this.text);
31506        this.setIconClass(this.iconCls);
31507        if(Ext.isDefined(this.tabIndex)){
31508            btnEl.dom.tabIndex = this.tabIndex;
31509        }
31510        if(this.tooltip){
31511            this.setTooltip(this.tooltip, true);
31512        }
31513
31514        if(this.handleMouseEvents){
31515            this.mon(btn, {
31516                scope: this,
31517                mouseover: this.onMouseOver,
31518                mousedown: this.onMouseDown
31519            });
31520
31521            
31522            
31523        }
31524
31525        if(this.menu){
31526            this.mon(this.menu, {
31527                scope: this,
31528                show: this.onMenuShow,
31529                hide: this.onMenuHide
31530            });
31531        }
31532
31533        if(this.repeat){
31534            var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
31535            this.mon(repeater, 'click', this.onRepeatClick, this);
31536        }else{
31537            this.mon(btn, this.clickEvent, this.onClick, this);
31538        }
31539    },
31540
31541    
31542    afterRender : function(){
31543        Ext.Button.superclass.afterRender.call(this);
31544        this.useSetClass = true;
31545        this.setButtonClass();
31546        this.doc = Ext.getDoc();
31547        this.doAutoWidth();
31548    },
31549
31550    
31551    setIconClass : function(cls){
31552        this.iconCls = cls;
31553        if(this.el){
31554            this.btnEl.dom.className = '';
31555            this.btnEl.addClass(['x-btn-text', cls || '']);
31556            this.setButtonClass();
31557        }
31558        return this;
31559    },
31560
31561    
31562    setTooltip : function(tooltip,  initial){
31563        if(this.rendered){
31564            if(!initial){
31565                this.clearTip();
31566            }
31567            if(Ext.isObject(tooltip)){
31568                Ext.QuickTips.register(Ext.apply({
31569                      target: this.btnEl.id
31570                }, tooltip));
31571                this.tooltip = tooltip;
31572            }else{
31573                this.btnEl.dom[this.tooltipType] = tooltip;
31574            }
31575        }else{
31576            this.tooltip = tooltip;
31577        }
31578        return this;
31579    },
31580
31581    
31582    clearTip : function(){
31583        if(Ext.isObject(this.tooltip)){
31584            Ext.QuickTips.unregister(this.btnEl);
31585        }
31586    },
31587
31588    
31589    beforeDestroy : function(){
31590        if(this.rendered){
31591            this.clearTip();
31592        }
31593        if(this.menu && this.destroyMenu !== false) {
31594            Ext.destroy(this.btnEl, this.menu);
31595        }
31596        Ext.destroy(this.repeater);
31597    },
31598
31599    
31600    onDestroy : function(){
31601        if(this.rendered){
31602            this.doc.un('mouseover', this.monitorMouseOver, this);
31603            this.doc.un('mouseup', this.onMouseUp, this);
31604            delete this.doc;
31605            delete this.btnEl;
31606            Ext.ButtonToggleMgr.unregister(this);
31607        }
31608        Ext.Button.superclass.onDestroy.call(this);
31609    },
31610
31611    
31612    doAutoWidth : function(){
31613        if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
31614            this.el.setWidth('auto');
31615            if(Ext.isIE7 && Ext.isStrict){
31616                var ib = this.btnEl;
31617                if(ib && ib.getWidth() > 20){
31618                    ib.clip();
31619                    ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
31620                }
31621            }
31622            if(this.minWidth){
31623                if(this.el.getWidth() < this.minWidth){
31624                    this.el.setWidth(this.minWidth);
31625                }
31626            }
31627        }
31628    },
31629
31630    
31631    setHandler : function(handler, scope){
31632        this.handler = handler;
31633        this.scope = scope;
31634        return this;
31635    },
31636
31637    
31638    setText : function(text){
31639        this.text = text;
31640        if(this.el){
31641            this.btnEl.update(text || '&#160;');
31642            this.setButtonClass();
31643        }
31644        this.doAutoWidth();
31645        return this;
31646    },
31647
31648    
31649    setIcon : function(icon){
31650        this.icon = icon;
31651        if(this.el){
31652            this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
31653            this.setButtonClass();
31654        }
31655        return this;
31656    },
31657
31658    
31659    getText : function(){
31660        return this.text;
31661    },
31662
31663    
31664    toggle : function(state, suppressEvent){
31665        state = state === undefined ? !this.pressed : !!state;
31666        if(state != this.pressed){
31667            if(this.rendered){
31668                this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
31669            }
31670            this.pressed = state;
31671            if(!suppressEvent){
31672                this.fireEvent('toggle', this, state);
31673                if(this.toggleHandler){
31674                    this.toggleHandler.call(this.scope || this, this, state);
31675                }
31676            }
31677        }
31678        return this;
31679    },
31680
31681    
31682    onDisable : function(){
31683        this.onDisableChange(true);
31684    },
31685
31686    
31687    onEnable : function(){
31688        this.onDisableChange(false);
31689    },
31690
31691    onDisableChange : function(disabled){
31692        if(this.el){
31693            if(!Ext.isIE6 || !this.text){
31694                this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
31695            }
31696            this.el.dom.disabled = disabled;
31697        }
31698        this.disabled = disabled;
31699    },
31700
31701    
31702    showMenu : function(){
31703        if(this.rendered && this.menu){
31704            if(this.tooltip){
31705                Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
31706            }
31707            if(this.menu.isVisible()){
31708                this.menu.hide();
31709            }
31710            this.menu.ownerCt = this;
31711            this.menu.show(this.el, this.menuAlign);
31712        }
31713        return this;
31714    },
31715
31716    
31717    hideMenu : function(){
31718        if(this.hasVisibleMenu()){
31719            this.menu.hide();
31720        }
31721        return this;
31722    },
31723
31724    
31725    hasVisibleMenu : function(){
31726        return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
31727    },
31728    
31729    
31730    onRepeatClick : function(repeat, e){
31731        this.onClick(e);
31732    },
31733
31734    
31735    onClick : function(e){
31736        if(e){
31737            e.preventDefault();
31738        }
31739        if(e.button !== 0){
31740            return;
31741        }
31742        if(!this.disabled){
31743            this.doToggle();
31744            if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
31745                this.showMenu();
31746            }
31747            this.fireEvent('click', this, e);
31748            if(this.handler){
31749                
31750                this.handler.call(this.scope || this, this, e);
31751            }
31752        }
31753    },
31754    
31755    
31756    doToggle: function(){
31757        if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
31758            this.toggle();
31759        }
31760    },
31761
31762    
31763    isMenuTriggerOver : function(e, internal){
31764        return this.menu && !internal;
31765    },
31766
31767    
31768    isMenuTriggerOut : function(e, internal){
31769        return this.menu && !internal;
31770    },
31771
31772    
31773    onMouseOver : function(e){
31774        if(!this.disabled){
31775            var internal = e.within(this.el,  true);
31776            if(!internal){
31777                this.el.addClass('x-btn-over');
31778                if(!this.monitoringMouseOver){
31779                    this.doc.on('mouseover', this.monitorMouseOver, this);
31780                    this.monitoringMouseOver = true;
31781                }
31782                this.fireEvent('mouseover', this, e);
31783            }
31784            if(this.isMenuTriggerOver(e, internal)){
31785                this.fireEvent('menutriggerover', this, this.menu, e);
31786            }
31787        }
31788    },
31789
31790    
31791    monitorMouseOver : function(e){
31792        if(e.target != this.el.dom && !e.within(this.el)){
31793            if(this.monitoringMouseOver){
31794                this.doc.un('mouseover', this.monitorMouseOver, this);
31795                this.monitoringMouseOver = false;
31796            }
31797            this.onMouseOut(e);
31798        }
31799    },
31800
31801    
31802    onMouseOut : function(e){
31803        var internal = e.within(this.el) && e.target != this.el.dom;
31804        this.el.removeClass('x-btn-over');
31805        this.fireEvent('mouseout', this, e);
31806        if(this.isMenuTriggerOut(e, internal)){
31807            this.fireEvent('menutriggerout', this, this.menu, e);
31808        }
31809    },
31810
31811    focus : function() {
31812        this.btnEl.focus();
31813    },
31814
31815    blur : function() {
31816        this.btnEl.blur();
31817    },
31818
31819    
31820    onFocus : function(e){
31821        if(!this.disabled){
31822            this.el.addClass('x-btn-focus');
31823        }
31824    },
31825    
31826    onBlur : function(e){
31827        this.el.removeClass('x-btn-focus');
31828    },
31829
31830    
31831    getClickEl : function(e, isUp){
31832       return this.el;
31833    },
31834
31835    
31836    onMouseDown : function(e){
31837        if(!this.disabled && e.button === 0){
31838            this.getClickEl(e).addClass('x-btn-click');
31839            this.doc.on('mouseup', this.onMouseUp, this);
31840        }
31841    },
31842    
31843    onMouseUp : function(e){
31844        if(e.button === 0){
31845            this.getClickEl(e, true).removeClass('x-btn-click');
31846            this.doc.un('mouseup', this.onMouseUp, this);
31847        }
31848    },
31849    
31850    onMenuShow : function(e){
31851        if(this.menu.ownerCt == this){
31852            this.menu.ownerCt = this;
31853            this.ignoreNextClick = 0;
31854            this.el.addClass('x-btn-menu-active');
31855            this.fireEvent('menushow', this, this.menu);
31856        }
31857    },
31858    
31859    onMenuHide : function(e){
31860        if(this.menu.ownerCt == this){
31861            this.el.removeClass('x-btn-menu-active');
31862            this.ignoreNextClick = this.restoreClick.defer(250, this);
31863            this.fireEvent('menuhide', this, this.menu);
31864            delete this.menu.ownerCt;
31865        }
31866    },
31867
31868    
31869    restoreClick : function(){
31870        this.ignoreNextClick = 0;
31871    }
31872
31873    
31874    
31875    
31876    
31877    
31878    
31879});
31880Ext.reg('button', Ext.Button);
31881
31882
31883Ext.ButtonToggleMgr = function(){
31884   var groups = {};
31885
31886   function toggleGroup(btn, state){
31887       if(state){
31888           var g = groups[btn.toggleGroup];
31889           for(var i = 0, l = g.length; i < l; i++){
31890               if(g[i] != btn){
31891                   g[i].toggle(false);
31892               }
31893           }
31894       }
31895   }
31896
31897   return {
31898       register : function(btn){
31899           if(!btn.toggleGroup){
31900               return;
31901           }
31902           var g = groups[btn.toggleGroup];
31903           if(!g){
31904               g = groups[btn.toggleGroup] = [];
31905           }
31906           g.push(btn);
31907           btn.on('toggle', toggleGroup);
31908       },
31909
31910       unregister : function(btn){
31911           if(!btn.toggleGroup){
31912               return;
31913           }
31914           var g = groups[btn.toggleGroup];
31915           if(g){
31916               g.remove(btn);
31917               btn.un('toggle', toggleGroup);
31918           }
31919       },
31920
31921       
31922       getPressed : function(group){
31923           var g = groups[group];
31924           if(g){
31925               for(var i = 0, len = g.length; i < len; i++){
31926                   if(g[i].pressed === true){
31927                       return g[i];
31928                   }
31929               }
31930           }
31931           return null;
31932       }
31933   };
31934}();
31935
31936Ext.SplitButton = Ext.extend(Ext.Button, {
31937	
31938    arrowSelector : 'em',
31939    split: true,
31940
31941    
31942    initComponent : function(){
31943        Ext.SplitButton.superclass.initComponent.call(this);
31944        
31945        this.addEvents("arrowclick");
31946    },
31947
31948    
31949    onRender : function(){
31950        Ext.SplitButton.superclass.onRender.apply(this, arguments);
31951        if(this.arrowTooltip){
31952            this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
31953        }
31954    },
31955
31956    
31957    setArrowHandler : function(handler, scope){
31958        this.arrowHandler = handler;
31959        this.scope = scope;
31960    },
31961
31962    getMenuClass : function(){
31963        return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
31964    },
31965
31966    isClickOnArrow : function(e){
31967	if (this.arrowAlign != 'bottom') {
31968	    var visBtn = this.el.child('em.x-btn-split');
31969	    var right = visBtn.getRegion().right - visBtn.getPadding('r');
31970	    return e.getPageX() > right;
31971	} else {
31972	    return e.getPageY() > this.btnEl.getRegion().bottom;
31973	}
31974    },
31975
31976    
31977    onClick : function(e, t){
31978        e.preventDefault();
31979        if(!this.disabled){
31980            if(this.isClickOnArrow(e)){
31981                if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
31982                    this.showMenu();
31983                }
31984                this.fireEvent("arrowclick", this, e);
31985                if(this.arrowHandler){
31986                    this.arrowHandler.call(this.scope || this, this, e);
31987                }
31988            }else{
31989                this.doToggle();
31990                this.fireEvent("click", this, e);
31991                if(this.handler){
31992                    this.handler.call(this.scope || this, this, e);
31993                }
31994            }
31995        }
31996    },
31997
31998    
31999    isMenuTriggerOver : function(e){
32000        return this.menu && e.target.tagName == this.arrowSelector;
32001    },
32002
32003    
32004    isMenuTriggerOut : function(e, internal){
32005        return this.menu && e.target.tagName != this.arrowSelector;
32006    }
32007});
32008
32009Ext.reg('splitbutton', Ext.SplitButton);
32010Ext.CycleButton = Ext.extend(Ext.SplitButton, {
32011    
32012    
32013    
32014    
32015    
32016    
32017
32018    
32019    getItemText : function(item){
32020        if(item && this.showText === true){
32021            var text = '';
32022            if(this.prependText){
32023                text += this.prependText;
32024            }
32025            text += item.text;
32026            return text;
32027        }
32028        return undefined;
32029    },
32030
32031    
32032    setActiveItem : function(item, suppressEvent){
32033        if(!Ext.isObject(item)){
32034            item = this.menu.getComponent(item);
32035        }
32036        if(item){
32037            if(!this.rendered){
32038                this.text = this.getItemText(item);
32039                this.iconCls = item.iconCls;
32040            }else{
32041                var t = this.getItemText(item);
32042                if(t){
32043                    this.setText(t);
32044                }
32045                this.setIconClass(item.iconCls);
32046            }
32047            this.activeItem = item;
32048            if(!item.checked){
32049                item.setChecked(true, suppressEvent);
32050            }
32051            if(this.forceIcon){
32052                this.setIconClass(this.forceIcon);
32053            }
32054            if(!suppressEvent){
32055                this.fireEvent('change', this, item);
32056            }
32057        }
32058    },
32059
32060    
32061    getActiveItem : function(){
32062        return this.activeItem;
32063    },
32064
32065    
32066    initComponent : function(){
32067        this.addEvents(
32068            
32069            "change"
32070        );
32071
32072        if(this.changeHandler){
32073            this.on('change', this.changeHandler, this.scope||this);
32074            delete this.changeHandler;
32075        }
32076
32077        this.itemCount = this.items.length;
32078
32079        this.menu = {cls:'x-cycle-menu', items:[]};
32080        var checked = 0;
32081        Ext.each(this.items, function(item, i){
32082            Ext.apply(item, {
32083                group: item.group || this.id,
32084                itemIndex: i,
32085                checkHandler: this.checkHandler,
32086                scope: this,
32087                checked: item.checked || false
32088            });
32089            this.menu.items.push(item);
32090            if(item.checked){
32091                checked = i;
32092            }
32093        }, this);
32094        Ext.CycleButton.superclass.initComponent.call(this);
32095        this.on('click', this.toggleSelected, this);
32096        this.setActiveItem(checked, true);
32097    },
32098
32099    
32100    checkHandler : function(item, pressed){
32101        if(pressed){
32102            this.setActiveItem(item);
32103        }
32104    },
32105
32106    
32107    toggleSelected : function(){
32108        var m = this.menu;
32109        m.render();
32110        
32111        if(!m.hasLayout){
32112            m.doLayout();
32113        }
32114        
32115        var nextIdx, checkItem;
32116        for (var i = 1; i < this.itemCount; i++) {
32117            nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
32118            
32119            checkItem = m.items.itemAt(nextIdx);
32120            
32121            if (!checkItem.disabled) {
32122                checkItem.setChecked(true);
32123                break;
32124            }
32125        }
32126    }
32127});
32128Ext.reg('cycle', Ext.CycleButton);
32129Ext.Toolbar = function(config){
32130    if(Ext.isArray(config)){
32131        config = {items: config, layout: 'toolbar'};
32132    } else {
32133        config = Ext.apply({
32134            layout: 'toolbar'
32135        }, config);
32136        if(config.buttons) {
32137            config.items = config.buttons;
32138        }
32139    }
32140    Ext.Toolbar.superclass.constructor.call(this, config);
32141};
32142
32143(function(){
32144
32145var T = Ext.Toolbar;
32146
32147Ext.extend(T, Ext.Container, {
32148
32149    defaultType: 'button',
32150
32151    
32152
32153    enableOverflow : false,
32154
32155    
32156    
32157
32158    trackMenus : true,
32159    internalDefaults: {removeMode: 'container', hideParent: true},
32160    toolbarCls: 'x-toolbar',
32161
32162    initComponent : function(){
32163        T.superclass.initComponent.call(this);
32164
32165        
32166        this.addEvents('overflowchange');
32167    },
32168
32169    
32170    onRender : function(ct, position){
32171        if(!this.el){
32172            if(!this.autoCreate){
32173                this.autoCreate = {
32174                    cls: this.toolbarCls + ' x-small-editor'
32175                };
32176            }
32177            this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
32178            Ext.Toolbar.superclass.onRender.apply(this, arguments);
32179        }
32180    },
32181
32182    
32183
32184    
32185    lookupComponent : function(c){
32186        if(Ext.isString(c)){
32187            if(c == '-'){
32188                c = new T.Separator();
32189            }else if(c == ' '){
32190                c = new T.Spacer();
32191            }else if(c == '->'){
32192                c = new T.Fill();
32193            }else{
32194                c = new T.TextItem(c);
32195            }
32196            this.applyDefaults(c);
32197        }else{
32198            if(c.isFormField || c.render){ 
32199                c = this.createComponent(c);
32200            }else if(c.tag){ 
32201                c = new T.Item({autoEl: c});
32202            }else if(c.tagName){ 
32203                c = new T.Item({el:c});
32204            }else if(Ext.isObject(c)){ 
32205                c = c.xtype ? this.createComponent(c) : this.constructButton(c);
32206            }
32207        }
32208        return c;
32209    },
32210
32211    
32212    applyDefaults : function(c){
32213        if(!Ext.isString(c)){
32214            c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
32215            var d = this.internalDefaults;
32216            if(c.events){
32217                Ext.applyIf(c.initialConfig, d);
32218                Ext.apply(c, d);
32219            }else{
32220                Ext.applyIf(c, d);
32221            }
32222        }
32223        return c;
32224    },
32225
32226    
32227    addSeparator : function(){
32228        return this.add(new T.Separator());
32229    },
32230
32231    
32232    addSpacer : function(){
32233        return this.add(new T.Spacer());
32234    },
32235
32236    
32237    addFill : function(){
32238        this.add(new T.Fill());
32239    },
32240
32241    
32242    addElement : function(el){
32243        return this.addItem(new T.Item({el:el}));
32244    },
32245
32246    
32247    addItem : function(item){
32248        return this.add.apply(this, arguments);
32249    },
32250
32251    
32252    addButton : function(config){
32253        if(Ext.isArray(config)){
32254            var buttons = [];
32255            for(var i = 0, len = config.length; i < len; i++) {
32256                buttons.push(this.addButton(config[i]));
32257            }
32258            return buttons;
32259        }
32260        return this.add(this.constructButton(config));
32261    },
32262
32263    
32264    addText : function(text){
32265        return this.addItem(new T.TextItem(text));
32266    },
32267
32268    
32269    addDom : function(config){
32270        return this.add(new T.Item({autoEl: config}));
32271    },
32272
32273    
32274    addField : function(field){
32275        return this.add(field);
32276    },
32277
32278    
32279    insertButton : function(index, item){
32280        if(Ext.isArray(item)){
32281            var buttons = [];
32282            for(var i = 0, len = item.length; i < len; i++) {
32283               buttons.push(this.insertButton(index + i, item[i]));
32284            }
32285            return buttons;
32286        }
32287        return Ext.Toolbar.superclass.insert.call(this, index, item);
32288    },
32289
32290    
32291    trackMenu : function(item, remove){
32292        if(this.trackMenus && item.menu){
32293            var method = remove ? 'mun' : 'mon';
32294            this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
32295            this[method](item, 'menushow', this.onButtonMenuShow, this);
32296            this[method](item, 'menuhide', this.onButtonMenuHide, this);
32297        }
32298    },
32299
32300    
32301    constructButton : function(item){
32302        var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
32303        return b;
32304    },
32305
32306    
32307    onAdd : function(c){
32308        Ext.Toolbar.superclass.onAdd.call(this);
32309        this.trackMenu(c);
32310        if(this.disabled){
32311            c.disable();
32312        }
32313    },
32314
32315    
32316    onRemove : function(c){
32317        Ext.Toolbar.superclass.onRemove.call(this);
32318        if (c == this.activeMenuBtn) {
32319            delete this.activeMenuBtn;
32320        }
32321        this.trackMenu(c, true);
32322    },
32323
32324    
32325    onDisable : function(){
32326        this.items.each(function(item){
32327             if(item.disable){
32328                 item.disable();
32329             }
32330        });
32331    },
32332
32333    
32334    onEnable : function(){
32335        this.items.each(function(item){
32336             if(item.enable){
32337                 item.enable();
32338             }
32339        });
32340    },
32341
32342    
32343    onButtonTriggerOver : function(btn){
32344        if(this.activeMenuBtn && this.activeMenuBtn != btn){
32345            this.activeMenuBtn.hideMenu();
32346            btn.showMenu();
32347            this.activeMenuBtn = btn;
32348        }
32349    },
32350
32351    
32352    onButtonMenuShow : function(btn){
32353        this.activeMenuBtn = btn;
32354    },
32355
32356    
32357    onButtonMenuHide : function(btn){
32358        delete this.activeMenuBtn;
32359    }
32360});
32361Ext.reg('toolbar', Ext.Toolbar);
32362
32363
32364T.Item = Ext.extend(Ext.BoxComponent, {
32365    hideParent: true, 
32366    enable:Ext.emptyFn,
32367    disable:Ext.emptyFn,
32368    focus:Ext.emptyFn
32369    
32370});
32371Ext.reg('tbitem', T.Item);
32372
32373
32374T.Separator = Ext.extend(T.Item, {
32375    onRender : function(ct, position){
32376        this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
32377    }
32378});
32379Ext.reg('tbseparator', T.Separator);
32380
32381
32382T.Spacer = Ext.extend(T.Item, {
32383    
32384
32385    onRender : function(ct, position){
32386        this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
32387    }
32388});
32389Ext.reg('tbspacer', T.Spacer);
32390
32391
32392T.Fill = Ext.extend(T.Item, {
32393    
32394    render : Ext.emptyFn,
32395    isFill : true
32396});
32397Ext.reg('tbfill', T.Fill);
32398
32399
32400T.TextItem = Ext.extend(T.Item, {
32401    
32402
32403    constructor: function(config){
32404        T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
32405    },
32406
32407    
32408    onRender : function(ct, position) {
32409        this.autoEl = {cls: 'xtb-text', html: this.text || ''};
32410        T.TextItem.superclass.onRender.call(this, ct, position);
32411    },
32412
32413    
32414    setText : function(t) {
32415        if(this.rendered){
32416            this.el.update(t);
32417        }else{
32418            this.text = t;
32419        }
32420    }
32421});
32422Ext.reg('tbtext', T.TextItem);
32423
32424
32425T.Button = Ext.extend(Ext.Button, {});
32426T.SplitButton = Ext.extend(Ext.SplitButton, {});
32427Ext.reg('tbbutton', T.Button);
32428Ext.reg('tbsplit', T.SplitButton);
32429
32430})();
32431
32432Ext.ButtonGroup = Ext.extend(Ext.Panel, {
32433    
32434    
32435    baseCls: 'x-btn-group',
32436    
32437    layout:'table',
32438    defaultType: 'button',
32439    
32440    frame: true,
32441    internalDefaults: {removeMode: 'container', hideParent: true},
32442
32443    initComponent : function(){
32444        this.layoutConfig = this.layoutConfig || {};
32445        Ext.applyIf(this.layoutConfig, {
32446            columns : this.columns
32447        });
32448        if(!this.title){
32449            this.addClass('x-btn-group-notitle');
32450        }
32451        this.on('afterlayout', this.onAfterLayout, this);
32452        Ext.ButtonGroup.superclass.initComponent.call(this);
32453    },
32454
32455    applyDefaults : function(c){
32456        c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
32457        var d = this.internalDefaults;
32458        if(c.events){
32459            Ext.applyIf(c.initialConfig, d);
32460            Ext.apply(c, d);
32461        }else{
32462            Ext.applyIf(c, d);
32463        }
32464        return c;
32465    },
32466
32467    onAfterLayout : function(){
32468        var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
32469        this.body.setWidth(bodyWidth);
32470        this.el.setWidth(bodyWidth + this.getFrameWidth());
32471    }
32472    
32473});
32474
32475Ext.reg('buttongroup', Ext.ButtonGroup);
32476
32477(function() {
32478
32479var T = Ext.Toolbar;
32480
32481Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
32482    
32483    
32484    
32485    pageSize : 20,
32486    
32487    
32488    displayMsg : 'Displaying {0} - {1} of {2}',
32489    
32490    emptyMsg : 'No data to display',
32491    
32492    beforePageText : 'Page',
32493    
32494    afterPageText : 'of {0}',
32495    
32496    firstText : 'First Page',
32497    
32498    prevText : 'Previous Page',
32499    
32500    nextText : 'Next Page',
32501    
32502    lastText : 'Last Page',
32503    
32504    refreshText : 'Refresh',
32505
32506    
32507
32508    
32509
32510    
32511
32512    initComponent : function(){
32513        var pagingItems = [this.first = new T.Button({
32514            tooltip: this.firstText,
32515            overflowText: this.firstText,
32516            iconCls: 'x-tbar-page-first',
32517            disabled: true,
32518            handler: this.moveFirst,
32519            scope: this
32520        }), this.prev = new T.Button({
32521            tooltip: this.prevText,
32522            overflowText: this.prevText,
32523            iconCls: 'x-tbar-page-prev',
32524            disabled: true,
32525            handler: this.movePrevious,
32526            scope: this
32527        }), '-', this.beforePageText,
32528        this.inputItem = new Ext.form.NumberField({
32529            cls: 'x-tbar-page-number',
32530            allowDecimals: false,
32531            allowNegative: false,
32532            enableKeyEvents: true,
32533            selectOnFocus: true,
32534            submitValue: false,
32535            listeners: {
32536                scope: this,
32537                keydown: this.onPagingKeyDown,
32538                blur: this.onPagingBlur
32539            }
32540        }), this.afterTextItem = new T.TextItem({
32541            text: String.format(this.afterPageText, 1)
32542        }), '-', this.next = new T.Button({
32543            tooltip: this.nextText,
32544            overflowText: this.nextText,
32545            iconCls: 'x-tbar-page-next',
32546            disabled: true,
32547            handler: this.moveNext,
32548            scope: this
32549        }), this.last = new T.Button({
32550            tooltip: this.lastText,
32551            overflowText: this.lastText,
32552            iconCls: 'x-tbar-page-last',
32553            disabled: true,
32554            handler: this.moveLast,
32555            scope: this
32556        }), '-', this.refresh = new T.Button({
32557            tooltip: this.refreshText,
32558            overflowText: this.refreshText,
32559            iconCls: 'x-tbar-loading',
32560            handler: this.doRefresh,
32561            scope: this
32562        })];
32563
32564
32565        var userItems = this.items || this.buttons || [];
32566        if (this.prependButtons) {
32567            this.items = userItems.concat(pagingItems);
32568        }else{
32569            this.items = pagingItems.concat(userItems);
32570        }
32571        delete this.buttons;
32572        if(this.displayInfo){
32573            this.items.push('->');
32574            this.items.push(this.displayItem = new T.TextItem({}));
32575        }
32576        Ext.PagingToolbar.superclass.initComponent.call(this);
32577        this.addEvents(
32578            
32579            'change',
32580            
32581            'beforechange'
32582        );
32583        this.on('afterlayout', this.onFirstLayout, this, {single: true});
32584        this.cursor = 0;
32585        this.bindStore(this.store, true);
32586    },
32587
32588    
32589    onFirstLayout : function(){
32590        if(this.dsLoaded){
32591            this.onLoad.apply(this, this.dsLoaded);
32592        }
32593    },
32594
32595    
32596    updateInfo : function(){
32597        if(this.displayItem){
32598            var count = this.store.getCount();
32599            var msg = count == 0 ?
32600                this.emptyMsg :
32601                String.format(
32602                    this.displayMsg,
32603                    this.cursor+1, this.cursor+count, this.store.getTotalCount()
32604                );
32605            this.displayItem.setText(msg);
32606        }
32607    },
32608
32609    
32610    onLoad : function(store, r, o){
32611        if(!this.rendered){
32612            this.dsLoaded = [store, r, o];
32613            return;
32614        }
32615        var p = this.getParams();
32616        this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
32617        var d = this.getPageData(), ap = d.activePage, ps = d.pages;
32618
32619        this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
32620        this.inputItem.setValue(ap);
32621        this.first.setDisabled(ap == 1);
32622        this.prev.setDisabled(ap == 1);
32623        this.next.setDisabled(ap == ps);
32624        this.last.setDisabled(ap == ps);
32625        this.refresh.enable();
32626        this.updateInfo();
32627        this.fireEvent('change', this, d);
32628    },
32629
32630    
32631    getPageData : function(){
32632        var total = this.store.getTotalCount();
32633        return {
32634            total : total,
32635            activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
32636            pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
32637        };
32638    },
32639
32640    
32641    changePage : function(page){
32642        this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
32643    },
32644
32645    
32646    onLoadError : function(){
32647        if(!this.rendered){
32648            return;
32649        }
32650        this.refresh.enable();
32651    },
32652
32653    
32654    readPage : function(d){
32655        var v = this.inputItem.getValue(), pageNum;
32656        if (!v || isNaN(pageNum = parseInt(v, 10))) {
32657            this.inputItem.setValue(d.activePage);
32658            return false;
32659        }
32660        return pageNum;
32661    },
32662
32663    onPagingFocus : function(){
32664        this.inputItem.select();
32665    },
32666
32667    
32668    onPagingBlur : function(e){
32669        this.inputItem.setValue(this.getPageData().activePage);
32670    },
32671
32672    
32673    onPagingKeyDown : function(field, e){
32674        var k = e.getKey(), d = this.getPageData(), pageNum;
32675        if (k == e.RETURN) {
32676            e.stopEvent();
32677            pageNum = this.readPage(d);
32678            if(pageNum !== false){
32679                pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
32680                this.doLoad(pageNum * this.pageSize);
32681            }
32682        }else if (k == e.HOME || k == e.END){
32683            e.stopEvent();
32684            pageNum = k == e.HOME ? 1 : d.pages;
32685            field.setValue(pageNum);
32686        }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
32687            e.stopEvent();
32688            if((pageNum = this.readPage(d))){
32689                var increment = e.shiftKey ? 10 : 1;
32690                if(k == e.DOWN || k == e.PAGEDOWN){
32691                    increment *= -1;
32692                }
32693                pageNum += increment;
32694                if(pageNum >= 1 & pageNum <= d.pages){
32695                    field.setValue(pageNum);
32696                }
32697            }
32698        }
32699    },
32700
32701    
32702    getParams : function(){
32703        
32704        return this.paramNames || this.store.paramNames;
32705    },
32706
32707    
32708    beforeLoad : function(){
32709        if(this.rendered && this.refresh){
32710            this.refresh.disable();
32711        }
32712    },
32713
32714    
32715    doLoad : function(start){
32716        var o = {}, pn = this.getParams();
32717        o[pn.start] = start;
32718        o[pn.limit] = this.pageSize;
32719        if(this.fireEvent('beforechange', this, o) !== false){
32720            this.store.load({params:o});
32721        }
32722    },
32723
32724    
32725    moveFirst : function(){
32726        this.doLoad(0);
32727    },
32728
32729    
32730    movePrevious : function(){
32731        this.doLoad(Math.max(0, this.cursor-this.pageSize));
32732    },
32733
32734    
32735    moveNext : function(){
32736        this.doLoad(this.cursor+this.pageSize);
32737    },
32738
32739    
32740    moveLast : function(){
32741        var total = this.store.getTotalCount(),
32742            extra = total % this.pageSize;
32743
32744        this.doLoad(extra ? (total - extra) : total - this.pageSize);
32745    },
32746
32747    
32748    doRefresh : function(){
32749        this.doLoad(this.cursor);
32750    },
32751
32752    
32753    bindStore : function(store, initial){
32754        var doLoad;
32755        if(!initial && this.store){
32756            if(store !== this.store && this.store.autoDestroy){
32757                this.store.destroy();
32758            }else{
32759                this.store.un('beforeload', this.beforeLoad, this);
32760                this.store.un('load', this.onLoad, this);
32761                this.store.un('exception', this.onLoadError, this);
32762            }
32763            if(!store){
32764                this.store = null;
32765            }
32766        }
32767        if(store){
32768            store = Ext.StoreMgr.lookup(store);
32769            store.on({
32770                scope: this,
32771                beforeload: this.beforeLoad,
32772                load: this.onLoad,
32773                exception: this.onLoadError
32774            });
32775            doLoad = true;
32776        }
32777        this.store = store;
32778        if(doLoad){
32779            this.onLoad(store, null, {});
32780        }
32781    },
32782
32783    
32784    unbind : function(store){
32785        this.bindStore(null);
32786    },
32787
32788    
32789    bind : function(store){
32790        this.bindStore(store);
32791    },
32792
32793    
32794    onDestroy : function(){
32795        this.bindStore(null);
32796        Ext.PagingToolbar.superclass.onDestroy.call(this);
32797    }
32798});
32799
32800})();
32801Ext.reg('paging', Ext.PagingToolbar);
32802Ext.History = (function () {
32803    var iframe, hiddenField;
32804    var ready = false;
32805    var currentToken;
32806
32807    function getHash() {
32808        var href = location.href, i = href.indexOf("#"),
32809            hash = i >= 0 ? href.substr(i + 1) : null;
32810             
32811        if (Ext.isGecko) {
32812            hash = decodeURIComponent(hash);
32813        }
32814        return hash;
32815    }
32816
32817    function doSave() {
32818        hiddenField.value = currentToken;
32819    }
32820
32821    function handleStateChange(token) {
32822        currentToken = token;
32823        Ext.History.fireEvent('change', token);
32824    }
32825
32826    function updateIFrame (token) {
32827        var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
32828        try {
32829            var doc = iframe.contentWindow.document;
32830            doc.open();
32831            doc.write(html);
32832            doc.close();
32833            return true;
32834        } catch (e) {
32835            return false;
32836        }
32837    }
32838
32839    function checkIFrame() {
32840        if (!iframe.contentWindow || !iframe.contentWindow.document) {
32841            setTimeout(checkIFrame, 10);
32842            return;
32843        }
32844
32845        var doc = iframe.contentWindow.document;
32846        var elem = doc.getElementById("state");
32847        var token = elem ? elem.innerText : null;
32848
32849        var hash = getHash();
32850
32851        setInterval(function () {
32852
32853            doc = iframe.contentWindow.document;
32854            elem = doc.getElementById("state");
32855
32856            var newtoken = elem ? elem.innerText : null;
32857
32858            var newHash = getHash();
32859
32860            if (newtoken !== token) {
32861                token = newtoken;
32862                handleStateChange(token);
32863                location.hash = token;
32864                hash = token;
32865                doSave();
32866            } else if (newHash !== hash) {
32867                hash = newHash;
32868                updateIFrame(newHash);
32869            }
32870
32871        }, 50);
32872
32873        ready = true;
32874
32875        Ext.History.fireEvent('ready', Ext.History);
32876    }
32877
32878    function startUp() {
32879        currentToken = hiddenField.value ? hiddenField.value : getHash();
32880
32881        if (Ext.isIE) {
32882            checkIFrame();
32883        } else {
32884            var hash = getHash();
32885            setInterval(function () {
32886                var newHash = getHash();
32887                if (newHash !== hash) {
32888                    hash = newHash;
32889                    handleStateChange(hash);
32890                    doSave();
32891                }
32892            }, 50);
32893            ready = true;
32894            Ext.History.fireEvent('ready', Ext.History);
32895        }
32896    }
32897
32898    return {
32899        
32900        fieldId: 'x-history-field',
32901        
32902        iframeId: 'x-history-frame',
32903
32904        events:{},
32905
32906        
32907        init: function (onReady, scope) {
32908            if(ready) {
32909                Ext.callback(onReady, scope, [this]);
32910                return;
32911            }
32912            if(!Ext.isReady){
32913                Ext.onReady(function(){
32914                    Ext.History.init(onReady, scope);
32915                });
32916                return;
32917            }
32918            hiddenField = Ext.getDom(Ext.History.fieldId);
32919            if (Ext.isIE) {
32920                iframe = Ext.getDom(Ext.History.iframeId);
32921            }
32922            this.addEvents(
32923                
32924                'ready',
32925                
32926                'change'
32927            );
32928            if(onReady){
32929                this.on('ready', onReady, scope, {single:true});
32930            }
32931            startUp();
32932        },
32933
32934        
32935        add: function (token, preventDup) {
32936            if(preventDup !== false){
32937                if(this.getToken() == token){
32938                    return true;
32939                }
32940            }
32941            if (Ext.isIE) {
32942                return updateIFrame(token);
32943            } else {
32944                location.hash = token;
32945                return true;
32946            }
32947        },
32948
32949        
32950        back: function(){
32951            history.go(-1);
32952        },
32953
32954        
32955        forward: function(){
32956            history.go(1);
32957        },
32958
32959        
32960        getToken: function() {
32961            return ready ? currentToken : getHash();
32962        }
32963    };
32964})();
32965Ext.apply(Ext.History, new Ext.util.Observable());
32966Ext.Tip = Ext.extend(Ext.Panel, {
32967    
32968    
32969    
32970    minWidth : 40,
32971    
32972    maxWidth : 300,
32973    
32974    shadow : "sides",
32975    
32976    defaultAlign : "tl-bl?",
32977    autoRender: true,
32978    quickShowInterval : 250,
32979
32980    
32981    frame:true,
32982    hidden:true,
32983    baseCls: 'x-tip',
32984    floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
32985    autoHeight:true,
32986
32987    closeAction: 'hide',
32988
32989    
32990    initComponent : function(){
32991        Ext.Tip.superclass.initComponent.call(this);
32992        if(this.closable && !this.title){
32993            this.elements += ',header';
32994        }
32995    },
32996
32997    
32998    afterRender : function(){
32999        Ext.Tip.superclass.afterRender.call(this);
33000        if(this.closable){
33001            this.addTool({
33002                id: 'close',
33003                handler: this[this.closeAction],
33004                scope: this
33005            });
33006        }
33007    },
33008
33009    
33010    showAt : function(xy){
33011        Ext.Tip.superclass.show.call(this);
33012        if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
33013            this.doAutoWidth();
33014        }
33015        if(this.constrainPosition){
33016            xy = this.el.adjustForConstraints(xy);
33017        }
33018        this.setPagePosition(xy[0], xy[1]);
33019    },
33020
33021    
33022    doAutoWidth : function(adjust){
33023        adjust = adjust || 0;
33024        var bw = this.body.getTextWidth();
33025        if(this.title){
33026            bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
33027        }
33028        bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
33029        this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
33030        
33031        
33032        if(Ext.isIE7 && !this.repainted){
33033            this.el.repaint();
33034            this.repainted = true;
33035        }
33036    },
33037
33038    
33039    showBy : function(el, pos){
33040        if(!this.rendered){
33041            this.render(Ext.getBody());
33042        }
33043        this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
33044    },
33045
33046    initDraggable : function(){
33047        this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
33048        this.header.addClass('x-tip-draggable');
33049    }
33050});
33051
33052Ext.reg('tip', Ext.Tip);
33053
33054
33055Ext.Tip.DD = function(tip, config){
33056    Ext.apply(this, config);
33057    this.tip = tip;
33058    Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
33059    this.setHandleElId(tip.header.id);
33060    this.scroll = false;
33061};
33062
33063Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
33064    moveOnly:true,
33065    scroll:false,
33066    headerOffsets:[100, 25],
33067    startDrag : function(){
33068        this.tip.el.disableShadow();
33069    },
33070    endDrag : function(e){
33071        this.tip.el.enableShadow(true);
33072    }
33073});
33074Ext.ToolTip = Ext.extend(Ext.Tip, {
33075    
33076    
33077    
33078    
33079    showDelay : 500,
33080    
33081    hideDelay : 200,
33082    
33083    dismissDelay : 5000,
33084    
33085    
33086    trackMouse : false,
33087    
33088    anchorToTarget : true,
33089    
33090    anchorOffset : 0,
33091    
33092
33093    
33094    targetCounter : 0,
33095
33096    constrainPosition : false,
33097
33098    
33099    initComponent : function(){
33100        Ext.ToolTip.superclass.initComponent.call(this);
33101        this.lastActive = new Date();
33102        this.initTarget(this.target);
33103        this.origAnchor = this.anchor;
33104    },
33105
33106    
33107    onRender : function(ct, position){
33108        Ext.ToolTip.superclass.onRender.call(this, ct, position);
33109        this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
33110        this.anchorEl = this.el.createChild({
33111            cls: 'x-tip-anchor ' + this.anchorCls
33112        });
33113    },
33114
33115    
33116    afterRender : function(){
33117        Ext.ToolTip.superclass.afterRender.call(this);
33118        this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
33119    },
33120
33121    
33122    initTarget : function(target){
33123        var t;
33124        if((t = Ext.get(target))){
33125            if(this.target){
33126                var tg = Ext.get(this.target);
33127                this.mun(tg, 'mouseover', this.onTargetOver, this);
33128                this.mun(tg, 'mouseout', this.onTargetOut, this);
33129                this.mun(tg, 'mousemove', this.onMouseMove, this);
33130            }
33131            this.mon(t, {
33132                mouseover: this.onTargetOver,
33133                mouseout: this.onTargetOut,
33134                mousemove: this.onMouseMove,
33135                scope: this
33136            });
33137            this.target = t;
33138        }
33139        if(this.anchor){
33140            this.anchorTarget = this.target;
33141        }
33142    },
33143
33144    
33145    onMouseMove : function(e){
33146        var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
33147        if (t) {
33148            this.targetXY = e.getXY();
33149            if (t === this.triggerElement) {
33150                if(!this.hidden && this.trackMouse){
33151                    this.setPagePosition(this.getTargetXY());
33152                }
33153            } else {
33154                this.hide();
33155                this.lastActive = new Date(0);
33156                this.onTargetOver(e);
33157            }
33158        } else if (!this.closable && this.isVisible()) {
33159            this.hide();
33160        }
33161    },
33162
33163    
33164    getTargetXY : function(){
33165        if(this.delegate){
33166            this.anchorTarget = this.triggerElement;
33167        }
33168        if(this.anchor){
33169            this.targetCounter++;
33170            var offsets = this.getOffsets(),
33171                xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
33172                dw = Ext.lib.Dom.getViewWidth() - 5,
33173                dh = Ext.lib.Dom.getViewHeight() - 5,
33174                de = document.documentElement,
33175                bd = document.body,
33176                scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
33177                scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
33178                axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
33179                sz = this.getSize();
33180                
33181            this.anchorEl.removeClass(this.anchorCls);
33182
33183            if(this.targetCounter < 2){
33184                if(axy[0] < scrollX){
33185                    if(this.anchorToTarget){
33186                        this.defaultAlign = 'l-r';
33187                        if(this.mouseOffset){this.mouseOffset[0] *= -1;}
33188                    }
33189                    this.anchor = 'left';
33190                    return this.getTargetXY();
33191                }
33192                if(axy[0]+sz.width > dw){
33193                    if(this.anchorToTarget){
33194                        this.defaultAlign = 'r-l';
33195                        if(this.mouseOffset){this.mouseOffset[0] *= -1;}
33196                    }
33197                    this.anchor = 'right';
33198                    return this.getTargetXY();
33199                }
33200                if(axy[1] < scrollY){
33201                    if(this.anchorToTarget){
33202                        this.defaultAlign = 't-b';
33203                        if(this.mouseOffset){this.mouseOffset[1] *= -1;}
33204                    }
33205                    this.anchor = 'top';
33206                    return this.getTargetXY();
33207                }
33208                if(axy[1]+sz.height > dh){
33209                    if(this.anchorToTarget){
33210                        this.defaultAlign = 'b-t';
33211                        if(this.mouseOffset){this.mouseOffset[1] *= -1;}
33212                    }
33213                    this.anchor = 'bottom';
33214                    return this.getTargetXY();
33215                }
33216            }
33217
33218            this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
33219            this.anchorEl.addClass(this.anchorCls);
33220            this.targetCounter = 0;
33221            return axy;
33222        }else{
33223            var mouseOffset = this.getMouseOffset();
33224            return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
33225        }
33226    },
33227
33228    getMouseOffset : function(){
33229        var offset = this.anchor ? [0,0] : [15,18];
33230        if(this.mouseOffset){
33231            offset[0] += this.mouseOffset[0];
33232            offset[1] += this.mouseOffset[1];
33233        }
33234        return offset;
33235    },
33236
33237    
33238    getAnchorPosition : function(){
33239        if(this.anchor){
33240            this.tipAnchor = this.anchor.charAt(0);
33241        }else{
33242            var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
33243            if(!m){
33244               throw 'AnchorTip.defaultAlign is invalid';
33245            }
33246            this.tipAnchor = m[1].charAt(0);
33247        }
33248
33249        switch(this.tipAnchor){
33250            case 't': return 'top';
33251            case 'b': return 'bottom';
33252            case 'r': return 'right';
33253        }
33254        return 'left';
33255    },
33256
33257    
33258    getAnchorAlign : function(){
33259        switch(this.anchor){
33260            case 'top'  : return 'tl-bl';
33261            case 'left' : return 'tl-tr';
33262            case 'right': return 'tr-tl';
33263            default     : return 'bl-tl';
33264        }
33265    },
33266
33267    
33268    getOffsets : function(){
33269        var offsets, 
33270            ap = this.getAnchorPosition().charAt(0);
33271        if(this.anchorToTarget && !this.trackMouse){
33272            switch(ap){
33273                case 't':
33274                    offsets = [0, 9];
33275                    break;
33276                case 'b':
33277                    offsets = [0, -13];
33278                    break;
33279                case 'r':
33280                    offsets = [-13, 0];
33281                    break;
33282                default:
33283                    offsets = [9, 0];
33284                    break;
33285            }
33286        }else{
33287            switch(ap){
33288                case 't':
33289                    offsets = [-15-this.anchorOffset, 30];
33290                    break;
33291                case 'b':
33292                    offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
33293                    break;
33294                case 'r':
33295                    offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
33296                    break;
33297                default:
33298                    offsets = [25, -13-this.anchorOffset];
33299                    break;
33300            }
33301        }
33302        var mouseOffset = this.getMouseOffset();
33303        offsets[0] += mouseOffset[0];
33304        offsets[1] += mouseOffset[1];
33305
33306        return offsets;
33307    },
33308
33309    
33310    onTargetOver : function(e){
33311        if(this.disabled || e.within(this.target.dom, true)){
33312            return;
33313        }
33314        var t = e.getTarget(this.delegate);
33315        if (t) {
33316            this.triggerElement = t;
33317            this.clearTimer('hide');
33318            this.targetXY = e.getXY();
33319            this.delayShow();
33320        }
33321    },
33322
33323    
33324    delayShow : function(){
33325        if(this.hidden && !this.showTimer){
33326            if(this.lastActive.getElapsed() < this.quickShowInterval){
33327                this.show();
33328            }else{
33329                this.showTimer = this.show.defer(this.showDelay, this);
33330            }
33331        }else if(!this.hidden && this.autoHide !== false){
33332            this.show();
33333        }
33334    },
33335
33336    
33337    onTargetOut : function(e){
33338        if(this.disabled || e.within(this.target.dom, true)){
33339            return;
33340        }
33341        this.clearTimer('show');
33342        if(this.autoHide !== false){
33343            this.delayHide();
33344        }
33345    },
33346
33347    
33348    delayHide : function(){
33349        if(!this.hidden && !this.hideTimer){
33350            this.hideTimer = this.hide.defer(this.hideDelay, this);
33351        }
33352    },
33353
33354    
33355    hide: function(){
33356        this.clearTimer('dismiss');
33357        this.lastActive = new Date();
33358        if(this.anchorEl){
33359            this.anchorEl.hide();
33360        }
33361        Ext.ToolTip.superclass.hide.call(this);
33362        delete this.triggerElement;
33363    },
33364
33365    
33366    show : function(){
33367        if(this.anchor){
33368            
33369            
33370            this.showAt([-1000,-1000]);
33371            this.origConstrainPosition = this.constrainPosition;
33372            this.constrainPosition = false;
33373            this.anchor = this.origAnchor;
33374        }
33375        this.showAt(this.getTargetXY());
33376
33377        if(this.anchor){
33378            this.anchorEl.show();
33379            this.syncAnchor();
33380            this.constrainPosition = this.origConstrainPosition;
33381        }else{
33382            this.anchorEl.hide();
33383        }
33384    },
33385
33386    
33387    showAt : function(xy){
33388        this.lastActive = new Date();
33389        this.clearTimers();
33390        Ext.ToolTip.superclass.showAt.call(this, xy);
33391        if(this.dismissDelay && this.autoHide !== false){
33392            this.dismissTimer = this.hide.defer(this.dismissDelay, this);
33393        }
33394        if(this.anchor && !this.anchorEl.isVisible()){
33395            this.syncAnchor();
33396            this.anchorEl.show();
33397        }else{
33398            this.anchorEl.hide();
33399        }
33400    },
33401
33402    
33403    syncAnchor : function(){
33404        var anchorPos, targetPos, offset;
33405        switch(this.tipAnchor.charAt(0)){
33406            case 't':
33407                anchorPos = 'b';
33408                targetPos = 'tl';
33409                offset = [20+this.anchorOffset, 2];
33410                break;
33411            case 'r':
33412                anchorPos = 'l';
33413                targetPos = 'tr';
33414                offset = [-2, 11+this.anchorOffset];
33415                break;
33416            case 'b':
33417                anchorPos = 't';
33418                targetPos = 'bl';
33419                offset = [20+this.anchorOffset, -2];
33420                break;
33421            default:
33422                anchorPos = 'r';
33423                targetPos = 'tl';
33424                offset = [2, 11+this.anchorOffset];
33425                break;
33426        }
33427        this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
33428    },
33429
33430    
33431    setPagePosition : function(x, y){
33432        Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
33433        if(this.anchor){
33434            this.syncAnchor();
33435        }
33436    },
33437
33438    
33439    clearTimer : function(name){
33440        name = name + 'Timer';
33441        clearTimeout(this[name]);
33442        delete this[name];
33443    },
33444
33445    
33446    clearTimers : function(){
33447        this.clearTimer('show');
33448        this.clearTimer('dismiss');
33449        this.clearTimer('hide');
33450    },
33451
33452    
33453    onShow : function(){
33454        Ext.ToolTip.superclass.onShow.call(this);
33455        Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
33456    },
33457
33458    
33459    onHide : function(){
33460        Ext.ToolTip.superclass.onHide.call(this);
33461        Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
33462    },
33463
33464    
33465    onDocMouseDown : function(e){
33466        if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
33467            this.disable();
33468            this.doEnable.defer(100, this);
33469        }
33470    },
33471    
33472    
33473    doEnable : function(){
33474        if(!this.isDestroyed){
33475            this.enable();
33476        }
33477    },
33478
33479    
33480    onDisable : function(){
33481        this.clearTimers();
33482        this.hide();
33483    },
33484
33485    
33486    adjustPosition : function(x, y){
33487        if(this.constrainPosition){
33488            var ay = this.targetXY[1], h = this.getSize().height;
33489            if(y <= ay && (y+h) >= ay){
33490                y = ay-h-5;
33491            }
33492        }
33493        return {x : x, y: y};
33494    },
33495    
33496    beforeDestroy : function(){
33497        this.clearTimers();
33498        Ext.destroy(this.anchorEl);
33499        delete this.anchorEl;
33500        delete this.target;
33501        delete this.anchorTarget;
33502        delete this.triggerElement;
33503        Ext.ToolTip.superclass.beforeDestroy.call(this);    
33504    },
33505
33506    
33507    onDestroy : function(){
33508        Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
33509        Ext.ToolTip.superclass.onDestroy.call(this);
33510    }
33511});
33512
33513Ext.reg('tooltip', Ext.ToolTip);
33514Ext.QuickTip = Ext.extend(Ext.ToolTip, {
33515    
33516    
33517    interceptTitles : false,
33518
33519    
33520    tagConfig : {
33521        namespace : "ext",
33522        attribute : "qtip",
33523        width : "qwidth",
33524        target : "target",
33525        title : "qtitle",
33526        hide : "hide",
33527        cls : "qclass",
33528        align : "qalign",
33529        anchor : "anchor"
33530    },
33531
33532    
33533    initComponent : function(){
33534        this.target = this.target || Ext.getDoc();
33535        this.targets = this.targets || {};
33536        Ext.QuickTip.superclass.initComponent.call(this);
33537    },
33538
33539    
33540    register : function(config){
33541        var cs = Ext.isArray(config) ? config : arguments;
33542        for(var i = 0, len = cs.length; i < len; i++){
33543            var c = cs[i];
33544            var target = c.target;
33545            if(target){
33546                if(Ext.isArray(target)){
33547                    for(var j = 0, jlen = target.length; j < jlen; j++){
33548                        this.targets[Ext.id(target[j])] = c;
33549                    }
33550                } else{
33551                    this.targets[Ext.id(target)] = c;
33552                }
33553            }
33554        }
33555    },
33556
33557    
33558    unregister : function(el){
33559        delete this.targets[Ext.id(el)];
33560    },
33561    
33562    
33563    cancelShow: function(el){
33564        var at = this.activeTarget;
33565        el = Ext.get(el).dom;
33566        if(this.isVisible()){
33567            if(at && at.el == el){
33568                this.hide();
33569            }
33570        }else if(at && at.el == el){
33571            this.clearTimer('show');
33572        }
33573    },
33574    
33575    getTipCfg: function(e) {
33576        var t = e.getTarget(), 
33577            ttp, 
33578            cfg;
33579        if(this.interceptTitles && t.title && Ext.isString(t.title)){
33580            ttp = t.title;
33581            t.qtip = ttp;
33582            t.removeAttribute("title");
33583            e.preventDefault();
33584        }else{
33585            cfg = this.tagConfig;
33586            ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
33587        }
33588        return ttp;
33589    },
33590
33591    
33592    onTargetOver : function(e){
33593        if(this.disabled){
33594            return;
33595        }
33596        this.targetXY = e.getXY();
33597        var t = e.getTarget();
33598        if(!t || t.nodeType !== 1 || t == document || t == document.body){
33599            return;
33600        }
33601        if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
33602            this.clearTimer('hide');
33603            this.show();
33604            return;
33605        }
33606        if(t && this.targets[t.id]){
33607            this.activeTarget = this.targets[t.id];
33608            this.activeTarget.el = t;
33609            this.anchor = this.activeTarget.anchor;
33610            if(this.anchor){
33611                this.anchorTarget = t;
33612            }
33613            this.delayShow();
33614            return;
33615        }
33616        var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
33617        if(ttp = this.getTipCfg(e)){
33618            var autoHide = et.getAttribute(cfg.hide, ns);
33619            this.activeTarget = {
33620                el: t,
33621                text: ttp,
33622                width: et.getAttribute(cfg.width, ns),
33623                autoHide: autoHide != "user" && autoHide !== 'false',
33624                title: et.getAttribute(cfg.title, ns),
33625                cls: et.getAttribute(cfg.cls, ns),
33626                align: et.getAttribute(cfg.align, ns)
33627                
33628            };
33629            this.anchor = et.getAttribute(cfg.anchor, ns);
33630            if(this.anchor){
33631                this.anchorTarget = t;
33632            }
33633            this.delayShow();
33634        }
33635    },
33636
33637    
33638    onTargetOut : function(e){
33639
33640        
33641        if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
33642            return;
33643        }
33644
33645        this.clearTimer('show');
33646        if(this.autoHide !== false){
33647            this.delayHide();
33648        }
33649    },
33650
33651    
33652    showAt : function(xy){
33653        var t = this.activeTarget;
33654        if(t){
33655            if(!this.rendered){
33656                this.render(Ext.getBody());
33657                this.activeTarget = t;
33658            }
33659            if(t.width){
33660                this.setWidth(t.width);
33661                this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
33662                this.measureWidth = false;
33663            } else{
33664                this.measureWidth = true;
33665            }
33666            this.setTitle(t.title || '');
33667            this.body.update(t.text);
33668            this.autoHide = t.autoHide;
33669            this.dismissDelay = t.dismissDelay || this.dismissDelay;
33670            if(this.lastCls){
33671                this.el.removeClass(this.lastCls);
33672                delete this.lastCls;
33673            }
33674            if(t.cls){
33675                this.el.addClass(t.cls);
33676                this.lastCls = t.cls;
33677            }
33678            if(this.anchor){
33679                this.constrainPosition = false;
33680            }else if(t.align){ 
33681                xy = this.el.getAlignToXY(t.el, t.align);
33682                this.constrainPosition = false;
33683            }else{
33684                this.constrainPosition = true;
33685            }
33686        }
33687        Ext.QuickTip.superclass.showAt.call(this, xy);
33688    },
33689
33690    
33691    hide: function(){
33692        delete this.activeTarget;
33693        Ext.QuickTip.superclass.hide.call(this);
33694    }
33695});
33696Ext.reg('quicktip', Ext.QuickTip);
33697Ext.QuickTips = function(){
33698    var tip,
33699        disabled = false;
33700        
33701    return {
33702        
33703        init : function(autoRender){
33704            if(!tip){
33705                if(!Ext.isReady){
33706                    Ext.onReady(function(){
33707                        Ext.QuickTips.init(autoRender);
33708                    });
33709                    return;
33710                }
33711                tip = new Ext.QuickTip({
33712                    elements:'header,body', 
33713                    disabled: disabled
33714                });
33715                if(autoRender !== false){
33716                    tip.render(Ext.getBody());
33717                }
33718            }
33719        },
33720        
33721        
33722        ddDisable : function(){
33723            
33724            if(tip && !disabled){
33725                tip.disable();
33726            }    
33727        },
33728        
33729        
33730        ddEnable : function(){
33731            
33732            if(tip && !disabled){
33733                tip.enable();
33734            }
33735        },
33736
33737        
33738        enable : function(){
33739            if(tip){
33740                tip.enable();
33741            }
33742            disabled = false;
33743        },
33744
33745        
33746        disable : function(){
33747            if(tip){
33748                tip.disable();
33749            }
33750            disabled = true;
33751        },
33752
33753        
33754        isEnabled : function(){
33755            return tip !== undefined && !tip.disabled;
33756        },
33757
33758        
33759        getQuickTip : function(){
33760            return tip;
33761        },
33762
33763        
33764        register : function(){
33765            tip.register.apply(tip, arguments);
33766        },
33767
33768        
33769        unregister : function(){
33770            tip.unregister.apply(tip, arguments);
33771        },
33772
33773        
33774        tips : function(){
33775            tip.register.apply(tip, arguments);
33776        }
33777    };
33778}();
33779Ext.slider.Tip = Ext.extend(Ext.Tip, {
33780    minWidth: 10,
33781    offsets : [0, -10],
33782    
33783    init: function(slider) {
33784        slider.on({
33785            scope    : this,
33786            dragstart: this.onSlide,
33787            drag     : this.onSlide,
33788            dragend  : this.hide,
33789            destroy  : this.destroy
33790        });
33791    },
33792    
33793    
33794    onSlide : function(slider, e, thumb) {
33795        this.show();
33796        this.body.update(this.getText(thumb));
33797        this.doAutoWidth();
33798        this.el.alignTo(thumb.el, 'b-t?', this.offsets);
33799    },
33800
33801    
33802    getText : function(thumb) {
33803        return String(thumb.value);
33804    }
33805});
33806
33807
33808Ext.ux.SliderTip = Ext.slider.Tip;
33809Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
33810    rootVisible : true,
33811    animate : Ext.enableFx,
33812    lines : true,
33813    enableDD : false,
33814    hlDrop : Ext.enableFx,
33815    pathSeparator : '/',
33816
33817    
33818    bubbleEvents : [],
33819
33820    initComponent : function(){
33821        Ext.tree.TreePanel.superclass.initComponent.call(this);
33822
33823        if(!this.eventModel){
33824            this.eventModel = new Ext.tree.TreeEventModel(this);
33825        }
33826
33827        
33828        var l = this.loader;
33829        if(!l){
33830            l = new Ext.tree.TreeLoader({
33831                dataUrl: this.dataUrl,
33832                requestMethod: this.requestMethod
33833            });
33834        }else if(Ext.isObject(l) && !l.load){
33835            l = new Ext.tree.TreeLoader(l);
33836        }
33837        this.loader = l;
33838
33839        this.nodeHash = {};
33840
33841        
33842        if(this.root){
33843            var r = this.root;
33844            delete this.root;
33845            this.setRootNode(r);
33846        }
33847
33848
33849        this.addEvents(
33850
33851            
33852           'append',
33853           
33854           'remove',
33855           
33856           'movenode',
33857           
33858           'insert',
33859           
33860           'beforeappend',
33861           
33862           'beforeremove',
33863           
33864           'beforemovenode',
33865           
33866            'beforeinsert',
33867
33868            
33869            'beforeload',
33870            
33871            'load',
33872            
33873            'textchange',
33874            
33875            'beforeexpandnode',
33876            
33877            'beforecollapsenode',
33878            
33879            'expandnode',
33880            
33881            'disabledchange',
33882            
33883            'collapsenode',
33884            
33885            'beforeclick',
33886            
33887            'click',
33888            
33889            'containerclick',
33890            
33891            'checkchange',
33892            
33893            'beforedblclick',
33894            
33895            'dblclick',
33896            
33897            'containerdblclick',
33898            
33899            'contextmenu',
33900            
33901            'containercontextmenu',
33902            
33903            'beforechildrenrendered',
33904           
33905            'startdrag',
33906            
33907            'enddrag',
33908            
33909            'dragdrop',
33910            
33911            'beforenodedrop',
33912            
33913            'nodedrop',
33914             
33915            'nodedragover'
33916        );
33917        if(this.singleExpand){
33918            this.on('beforeexpandnode', this.restrictExpand, this);
33919        }
33920    },
33921
33922    
33923    proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
33924        if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
33925            ename = ename+'node';
33926        }
33927        
33928        return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
33929    },
33930
33931
33932    
33933    getRootNode : function(){
33934        return this.root;
33935    },
33936
33937    
33938    setRootNode : function(node){
33939        this.destroyRoot();
33940        if(!node.render){ 
33941            node = this.loader.createNode(node);
33942        }
33943        this.root = node;
33944        node.ownerTree = this;
33945        node.isRoot = true;
33946        this.registerNode(node);
33947        if(!this.rootVisible){
33948            var uiP = node.attributes.uiProvider;
33949            node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
33950        }
33951        if(this.innerCt){
33952            this.clearInnerCt();
33953            this.renderRoot();
33954        }
33955        return node;
33956    },
33957    
33958    clearInnerCt : function(){
33959        this.innerCt.update('');    
33960    },
33961    
33962    
33963    renderRoot : function(){
33964        this.root.render();
33965        if(!this.rootVisible){
33966            this.root.renderChildren();
33967        }
33968    },
33969
33970    
33971    getNodeById : function(id){
33972        return this.nodeHash[id];
33973    },
33974
33975    
33976    registerNode : function(node){
33977        this.nodeHash[node.id] = node;
33978    },
33979
33980    
33981    unregisterNode : function(node){
33982        delete this.nodeHash[node.id];
33983    },
33984
33985    
33986    toString : function(){
33987        return '[Tree'+(this.id?' '+this.id:'')+']';
33988    },
33989
33990    
33991    restrictExpand : function(node){
33992        var p = node.parentNode;
33993        if(p){
33994            if(p.expandedChild && p.expandedChild.parentNode == p){
33995                p.expandedChild.collapse();
33996            }
33997            p.expandedChild = node;
33998        }
33999    },
34000
34001    
34002    getChecked : function(a, startNode){
34003        startNode = startNode || this.root;
34004        var r = [];
34005        var f = function(){
34006            if(this.attributes.checked){
34007                r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
34008            }
34009        };
34010        startNode.cascade(f);
34011        return r;
34012    },
34013
34014    
34015    getLoader : function(){
34016        return this.loader;
34017    },
34018
34019    
34020    expandAll : function(){
34021        this.root.expand(true);
34022    },
34023
34024    
34025    collapseAll : function(){
34026        this.root.collapse(true);
34027    },
34028
34029    
34030    getSelectionModel : function(){
34031        if(!this.selModel){
34032            this.selModel = new Ext.tree.DefaultSelectionModel();
34033        }
34034        return this.selModel;
34035    },
34036
34037    
34038    expandPath : function(path, attr, callback){
34039        if(Ext.isEmpty(path)){
34040            if(callback){
34041                callback(false, undefined);
34042            }
34043            return;
34044        }
34045        attr = attr || 'id';
34046        var keys = path.split(this.pathSeparator);
34047        var curNode = this.root;
34048        if(curNode.attributes[attr] != keys[1]){ 
34049            if(callback){
34050                callback(false, null);
34051            }
34052            return;
34053        }
34054        var index = 1;
34055        var f = function(){
34056            if(++index == keys.length){
34057                if(callback){
34058                    callback(true, curNode);
34059                }
34060                return;
34061            }
34062            var c = curNode.findChild(attr, keys[index]);
34063            if(!c){
34064                if(callback){
34065                    callback(false, curNode);
34066                }
34067                return;
34068            }
34069            curNode = c;
34070            c.expand(false, false, f);
34071        };
34072        curNode.expand(false, false, f);
34073    },
34074
34075    
34076    selectPath : function(path, attr, callback){
34077        if(Ext.isEmpty(path)){
34078            if(callback){
34079                callback(false, undefined);
34080            }
34081            return;
34082        }
34083        attr = attr || 'id';
34084        var keys = path.split(this.pathSeparator),
34085            v = keys.pop();
34086        if(keys.length > 1){
34087            var f = function(success, node){
34088                if(success && node){
34089                    var n = node.findChild(attr, v);
34090                    if(n){
34091                        n.select();
34092                        if(callback){
34093                            callback(true, n);
34094                        }
34095                    }else if(callback){
34096                        callback(false, n);
34097                    }
34098                }else{
34099                    if(callback){
34100                        callback(false, n);
34101                    }
34102                }
34103            };
34104            this.expandPath(keys.join(this.pathSeparator), attr, f);
34105        }else{
34106            this.root.select();
34107            if(callback){
34108                callback(true, this.root);
34109            }
34110        }
34111    },
34112
34113    
34114    getTreeEl : function(){
34115        return this.body;
34116    },
34117
34118    
34119    onRender : function(ct, position){
34120        Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
34121        this.el.addClass('x-tree');
34122        this.innerCt = this.body.createChild({tag:'ul',
34123               cls:'x-tree-root-ct ' +
34124               (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
34125    },
34126
34127    
34128    initEvents : function(){
34129        Ext.tree.TreePanel.superclass.initEvents.call(this);
34130
34131        if(this.containerScroll){
34132            Ext.dd.ScrollManager.register(this.body);
34133        }
34134        if((this.enableDD || this.enableDrop) && !this.dropZone){
34135           
34136             this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
34137               ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
34138           });
34139        }
34140        if((this.enableDD || this.enableDrag) && !this.dragZone){
34141           
34142            this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
34143               ddGroup: this.ddGroup || 'TreeDD',
34144               scroll: this.ddScroll
34145           });
34146        }
34147        this.getSelectionModel().init(this);
34148    },
34149
34150    
34151    afterRender : function(){
34152        Ext.tree.TreePanel.superclass.afterRender.call(this);
34153        this.renderRoot();
34154    },
34155
34156    beforeDestroy : function(){
34157        if(this.rendered){
34158            Ext.dd.ScrollManager.unregister(this.body);
34159            Ext.destroy(this.dropZone, this.dragZone);
34160        }
34161        this.destroyRoot();
34162        Ext.destroy(this.loader);
34163        this.nodeHash = this.root = this.loader = null;
34164        Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
34165    },
34166    
34167    
34168    destroyRoot : function(){
34169        if(this.root && this.root.destroy){
34170            this.root.destroy(true);
34171        }
34172    }
34173
34174    
34175    
34176    
34177    
34178    
34179    
34180    
34181    
34182    
34183    
34184    
34185    
34186    
34187    
34188    
34189    
34190    
34191    
34192    
34193    
34194    
34195    
34196    
34197    
34198    
34199    
34200    
34201    
34202    
34203    
34204    
34205
34206
34207
34208    
34209    
34210    
34211    
34212    
34213    
34214    
34215    
34216    
34217    
34218    
34219    
34220    
34221    
34222    
34223    
34224});
34225
34226Ext.tree.TreePanel.nodeTypes = {};
34227
34228Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
34229    this.tree = tree;
34230    this.tree.on('render', this.initEvents, this);
34231};
34232
34233Ext.tree.TreeEventModel.prototype = {
34234    initEvents : function(){
34235        var t = this.tree;
34236
34237        if(t.trackMouseOver !== false){
34238            t.mon(t.innerCt, {
34239                scope: this,
34240                mouseover: this.delegateOver,
34241                mouseout: this.delegateOut
34242            });
34243        }
34244        t.mon(t.getTreeEl(), {
34245            scope: this,
34246            click: this.delegateClick,
34247            dblclick: this.delegateDblClick,
34248            contextmenu: this.delegateContextMenu
34249        });
34250    },
34251
34252    getNode : function(e){
34253        var t;
34254        if(t = e.getTarget('.x-tree-node-el', 10)){
34255            var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
34256            if(id){
34257                return this.tree.getNodeById(id);
34258            }
34259        }
34260        return null;
34261    },
34262
34263    getNodeTarget : function(e){
34264        var t = e.getTarget('.x-tree-node-icon', 1);
34265        if(!t){
34266            t = e.getTarget('.x-tree-node-el', 6);
34267        }
34268        return t;
34269    },
34270
34271    delegateOut : function(e, t){
34272        if(!this.beforeEvent(e)){
34273            return;
34274        }
34275        if(e.getTarget('.x-tree-ec-icon', 1)){
34276            var n = this.getNode(e);
34277            this.onIconOut(e, n);
34278            if(n == this.lastEcOver){
34279                delete this.lastEcOver;
34280            }
34281        }
34282        if((t = this.getNodeTarget(e)) && !e.within(t, true)){
34283            this.onNodeOut(e, this.getNode(e));
34284        }
34285    },
34286
34287    delegateOver : function(e, t){
34288        if(!this.beforeEvent(e)){
34289            return;
34290        }
34291        if(Ext.isGecko && !this.trackingDoc){ 
34292            Ext.getBody().on('mouseover', this.trackExit, this);
34293            this.trackingDoc = true;
34294        }
34295        if(this.lastEcOver){ 
34296            this.onIconOut(e, this.lastEcOver);
34297            delete this.lastEcOver;
34298        }
34299        if(e.getTarget('.x-tree-ec-icon', 1)){
34300            this.lastEcOver = this.getNode(e);
34301            this.onIconOver(e, this.lastEcOver);
34302        }
34303        if(t = this.getNodeTarget(e)){
34304            this.onNodeOver(e, this.getNode(e));
34305        }
34306    },
34307
34308    trackExit : function(e){
34309        if(this.lastOverNode){
34310            if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
34311                this.onNodeOut(e, this.lastOverNode);
34312            }
34313            delete this.lastOverNode;
34314            Ext.getBody().un('mouseover', this.trackExit, this);
34315            this.trackingDoc = false;
34316        }
34317
34318    },
34319
34320    delegateClick : function(e, t){
34321        if(this.beforeEvent(e)){
34322            if(e.getTarget('input[type=checkbox]', 1)){
34323                this.onCheckboxClick(e, this.getNode(e));
34324            }else if(e.getTarget('.x-tree-ec-icon', 1)){
34325                this.onIconClick(e, this.getNode(e));
34326            }else if(this.getNodeTarget(e)){
34327                this.onNodeClick(e, this.getNode(e));
34328            }
34329        }else{
34330            this.checkContainerEvent(e, 'click');
34331        }
34332    },
34333
34334    delegateDblClick : function(e, t){
34335        if(this.beforeEvent(e)){
34336            if(this.getNodeTarget(e)){
34337                this.onNodeDblClick(e, this.getNode(e));
34338            }
34339        }else{
34340            this.checkContainerEvent(e, 'dblclick');
34341        }
34342    },
34343
34344    delegateContextMenu : function(e, t){
34345        if(this.beforeEvent(e)){
34346            if(this.getNodeTarget(e)){
34347                this.onNodeContextMenu(e, this.getNode(e));
34348            }
34349        }else{
34350            this.checkContainerEvent(e, 'contextmenu');
34351        }
34352    },
34353    
34354    checkContainerEvent: function(e, type){
34355        if(this.disabled){
34356            e.stopEvent();
34357            return false;
34358        }
34359        this.onContainerEvent(e, type);    
34360    },
34361
34362    onContainerEvent: function(e, type){
34363        this.tree.fireEvent('container' + type, this.tree, e);
34364    },
34365
34366    onNodeClick : function(e, node){
34367        node.ui.onClick(e);
34368    },
34369
34370    onNodeOver : function(e, node){
34371        this.lastOverNode = node;
34372        node.ui.onOver(e);
34373    },
34374
34375    onNodeOut : function(e, node){
34376        node.ui.onOut(e);
34377    },
34378
34379    onIconOver : function(e, node){
34380        node.ui.addClass('x-tree-ec-over');
34381    },
34382
34383    onIconOut : function(e, node){
34384        node.ui.removeClass('x-tree-ec-over');
34385    },
34386
34387    onIconClick : function(e, node){
34388        node.ui.ecClick(e);
34389    },
34390
34391    onCheckboxClick : function(e, node){
34392        node.ui.onCheckChange(e);
34393    },
34394
34395    onNodeDblClick : function(e, node){
34396        node.ui.onDblClick(e);
34397    },
34398
34399    onNodeContextMenu : function(e, node){
34400        node.ui.onContextMenu(e);
34401    },
34402
34403    beforeEvent : function(e){
34404        var node = this.getNode(e);
34405        if(this.disabled || !node || !node.ui){
34406            e.stopEvent();
34407            return false;
34408        }
34409        return true;
34410    },
34411
34412    disable: function(){
34413        this.disabled = true;
34414    },
34415
34416    enable: function(){
34417        this.disabled = false;
34418    }
34419};
34420Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
34421    
34422    constructor : function(config){
34423        this.selNode = null;
34424   
34425        this.addEvents(
34426            
34427            'selectionchange',
34428
34429            
34430            'beforeselect'
34431        );
34432
34433        Ext.apply(this, config);
34434        Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);    
34435    },
34436    
34437    init : function(tree){
34438        this.tree = tree;
34439        tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
34440        tree.on('click', this.onNodeClick, this);
34441    },
34442    
34443    onNodeClick : function(node, e){
34444        this.select(node);
34445    },
34446    
34447    
34448    select : function(node,  selectNextNode){
34449        
34450        if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
34451            return selectNextNode.call(this, node);
34452        }
34453        var last = this.selNode;
34454        if(node == last){
34455            node.ui.onSelectedChange(true);
34456        }else if(this.fireEvent('beforeselect', this, node, last) !== false){
34457            if(last && last.ui){
34458                last.ui.onSelectedChange(false);
34459            }
34460            this.selNode = node;
34461            node.ui.onSelectedChange(true);
34462            this.fireEvent('selectionchange', this, node, last);
34463        }
34464        return node;
34465    },
34466    
34467    
34468    unselect : function(node, silent){
34469        if(this.selNode == node){
34470            this.clearSelections(silent);
34471        }    
34472    },
34473    
34474    
34475    clearSelections : function(silent){
34476        var n = this.selNode;
34477        if(n){
34478            n.ui.onSelectedChange(false);
34479            this.selNode = null;
34480            if(silent !== true){
34481                this.fireEvent('selectionchange', this, null);
34482            }
34483        }
34484        return n;
34485    },
34486    
34487    
34488    getSelectedNode : function(){
34489        return this.selNode;    
34490    },
34491    
34492    
34493    isSelected : function(node){
34494        return this.selNode == node;  
34495    },
34496
34497    
34498    selectPrevious : function( s){
34499        if(!(s = s || this.selNode || this.lastSelNode)){
34500            return null;
34501        }
34502        
34503        var ps = s.previousSibling;
34504        if(ps){
34505            if(!ps.isExpanded() || ps.childNodes.length < 1){
34506                return this.select(ps, this.selectPrevious);
34507            } else{
34508                var lc = ps.lastChild;
34509                while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
34510                    lc = lc.lastChild;
34511                }
34512                return this.select(lc, this.selectPrevious);
34513            }
34514        } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
34515            return this.select(s.parentNode, this.selectPrevious);
34516        }
34517        return null;
34518    },
34519
34520    
34521    selectNext : function( s){
34522        if(!(s = s || this.selNode || this.lastSelNode)){
34523            return null;
34524        }
34525        
34526        if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
34527             return this.select(s.firstChild, this.selectNext);
34528         }else if(s.nextSibling){
34529             return this.select(s.nextSibling, this.selectNext);
34530         }else if(s.parentNode){
34531            var newS = null;
34532            s.parentNode.bubble(function(){
34533                if(this.nextSibling){
34534                    newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
34535                    return false;
34536                }
34537            });
34538            return newS;
34539         }
34540        return null;
34541    },
34542
34543    onKeyDown : function(e){
34544        var s = this.selNode || this.lastSelNode;
34545        
34546        var sm = this;
34547        if(!s){
34548            return;
34549        }
34550        var k = e.getKey();
34551        switch(k){
34552             case e.DOWN:
34553                 e.stopEvent();
34554                 this.selectNext();
34555             break;
34556             case e.UP:
34557                 e.stopEvent();
34558                 this.selectPrevious();
34559             break;
34560             case e.RIGHT:
34561                 e.preventDefault();
34562                 if(s.hasChildNodes()){
34563                     if(!s.isExpanded()){
34564                         s.expand();
34565                     }else if(s.firstChild){
34566                         this.select(s.firstChild, e);
34567                     }
34568                 }
34569             break;
34570             case e.LEFT:
34571                 e.preventDefault();
34572                 if(s.hasChildNodes() && s.isExpanded()){
34573                     s.collapse();
34574                 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
34575                     this.select(s.parentNode, e);
34576                 }
34577             break;
34578        };
34579    }
34580});
34581
34582
34583Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
34584    
34585    constructor : function(config){
34586        this.selNodes = [];
34587        this.selMap = {};
34588        this.addEvents(
34589            
34590            'selectionchange'
34591        );
34592        Ext.apply(this, config);
34593        Ext.tree.MultiSelectionModel.superclass.constructor.call(this);    
34594    },
34595    
34596    init : function(tree){
34597        this.tree = tree;
34598        tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
34599        tree.on('click', this.onNodeClick, this);
34600    },
34601    
34602    onNodeClick : function(node, e){
34603        if(e.ctrlKey && this.isSelected(node)){
34604            this.unselect(node);
34605        }else{
34606            this.select(node, e, e.ctrlKey);
34607        }
34608    },
34609    
34610    
34611    select : function(node, e, keepExisting){
34612        if(keepExisting !== true){
34613            this.clearSelections(true);
34614        }
34615        if(this.isSelected(node)){
34616            this.lastSelNode = node;
34617            return node;
34618        }
34619        this.selNodes.push(node);
34620        this.selMap[node.id] = node;
34621        this.lastSelNode = node;
34622        node.ui.onSelectedChange(true);
34623        this.fireEvent('selectionchange', this, this.selNodes);
34624        return node;
34625    },
34626    
34627    
34628    unselect : function(node){
34629        if(this.selMap[node.id]){
34630            node.ui.onSelectedChange(false);
34631            var sn = this.selNodes;
34632            var index = sn.indexOf(node);
34633            if(index != -1){
34634                this.selNodes.splice(index, 1);
34635            }
34636            delete this.selMap[node.id];
34637            this.fireEvent('selectionchange', this, this.selNodes);
34638        }
34639    },
34640    
34641    
34642    clearSelections : function(suppressEvent){
34643        var sn = this.selNodes;
34644        if(sn.length > 0){
34645            for(var i = 0, len = sn.length; i < len; i++){
34646                sn[i].ui.onSelectedChange(false);
34647            }
34648            this.selNodes = [];
34649            this.selMap = {};
34650            if(suppressEvent !== true){
34651                this.fireEvent('selectionchange', this, this.selNodes);
34652            }
34653        }
34654    },
34655    
34656    
34657    isSelected : function(node){
34658        return this.selMap[node.id] ? true : false;  
34659    },
34660    
34661    
34662    getSelectedNodes : function(){
34663        return this.selNodes.concat([]);
34664    },
34665
34666    onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
34667
34668    selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
34669
34670    selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
34671});
34672Ext.data.Tree = Ext.extend(Ext.util.Observable, {
34673    
34674    constructor: function(root){
34675        this.nodeHash = {};
34676        
34677        this.root = null;
34678        if(root){
34679            this.setRootNode(root);
34680        }
34681        this.addEvents(
34682            
34683            "append",
34684            
34685            "remove",
34686            
34687            "move",
34688            
34689            "insert",
34690            
34691            "beforeappend",
34692            
34693            "beforeremove",
34694            
34695            "beforemove",
34696            
34697            "beforeinsert"
34698        );
34699        Ext.data.Tree.superclass.constructor.call(this);        
34700    },
34701    
34702    
34703    pathSeparator: "/",
34704
34705    
34706    proxyNodeEvent : function(){
34707        return this.fireEvent.apply(this, arguments);
34708    },
34709
34710    
34711    getRootNode : function(){
34712        return this.root;
34713    },
34714
34715    
34716    setRootNode : function(node){
34717        this.root = node;
34718        node.ownerTree = this;
34719        node.isRoot = true;
34720        this.registerNode(node);
34721        return node;
34722    },
34723
34724    
34725    getNodeById : function(id){
34726        return this.nodeHash[id];
34727    },
34728
34729    
34730    registerNode : function(node){
34731        this.nodeHash[node.id] = node;
34732    },
34733
34734    
34735    unregisterNode : function(node){
34736        delete this.nodeHash[node.id];
34737    },
34738
34739    toString : function(){
34740        return "[Tree"+(this.id?" "+this.id:"")+"]";
34741    }
34742});
34743
34744
34745Ext.data.Node = Ext.extend(Ext.util.Observable, {
34746    
34747    constructor: function(attributes){
34748        
34749        this.attributes = attributes || {};
34750        this.leaf = this.attributes.leaf;
34751        
34752        this.id = this.attributes.id;
34753        if(!this.id){
34754            this.id = Ext.id(null, "xnode-");
34755            this.attributes.id = this.id;
34756        }
34757        
34758        this.childNodes = [];
34759        
34760        this.parentNode = null;
34761        
34762        this.firstChild = null;
34763        
34764        this.lastChild = null;
34765        
34766        this.previousSibling = null;
34767        
34768        this.nextSibling = null;
34769
34770        this.addEvents({
34771            
34772            "append" : true,
34773            
34774            "remove" : true,
34775            
34776            "move" : true,
34777            
34778            "insert" : true,
34779            
34780            "beforeappend" : true,
34781            
34782            "beforeremove" : true,
34783            
34784            "beforemove" : true,
34785             
34786            "beforeinsert" : true
34787        });
34788        this.listeners = this.attributes.listeners;
34789        Ext.data.Node.superclass.constructor.call(this);    
34790    },
34791    
34792    
34793    fireEvent : function(evtName){
34794        
34795        if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
34796            return false;
34797        }
34798        
34799        var ot = this.getOwnerTree();
34800        if(ot){
34801            if(ot.proxyNodeEvent.apply(ot, arguments) === false){
34802                return false;
34803            }
34804        }
34805        return true;
34806    },
34807
34808    
34809    isLeaf : function(){
34810        return this.leaf === true;
34811    },
34812
34813    
34814    setFirstChild : function(node){
34815        this.firstChild = node;
34816    },
34817
34818    
34819    setLastChild : function(node){
34820        this.lastChild = node;
34821    },
34822
34823
34824    
34825    isLast : function(){
34826       return (!this.parentNode ? true : this.parentNode.lastChild == this);
34827    },
34828
34829    
34830    isFirst : function(){
34831       return (!this.parentNode ? true : this.parentNode.firstChild == this);
34832    },
34833
34834    
34835    hasChildNodes : function(){
34836        return !this.isLeaf() && this.childNodes.length > 0;
34837    },
34838
34839    
34840    isExpandable : function(){
34841        return this.attributes.expandable || this.hasChildNodes();
34842    },
34843
34844    
34845    appendChild : function(node){
34846        var multi = false;
34847        if(Ext.isArray(node)){
34848            multi = node;
34849        }else if(arguments.length > 1){
34850            multi = arguments;
34851        }
34852        
34853        if(multi){
34854            for(var i = 0, len = multi.length; i < len; i++) {
34855                this.appendChild(multi[i]);
34856            }
34857        }else{
34858            if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
34859                return false;
34860            }
34861            var index = this.childNodes.length;
34862            var oldParent = node.parentNode;
34863            
34864            if(oldParent){
34865                if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
34866                    return false;
34867                }
34868                oldParent.removeChild(node);
34869            }
34870            index = this.childNodes.length;
34871            if(index === 0){
34872                this.setFirstChild(node);
34873            }
34874            this.childNodes.push(node);
34875            node.parentNode = this;
34876            var ps = this.childNodes[index-1];
34877            if(ps){
34878                node.previousSibling = ps;
34879                ps.nextSibling = node;
34880            }else{
34881                node.previousSibling = null;
34882            }
34883            node.nextSibling = null;
34884            this.setLastChild(node);
34885            node.setOwnerTree(this.getOwnerTree());
34886            this.fireEvent("append", this.ownerTree, this, node, index);
34887            if(oldParent){
34888                node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
34889            }
34890            return node;
34891        }
34892    },
34893
34894    
34895    removeChild : function(node, destroy){
34896        var index = this.childNodes.indexOf(node);
34897        if(index == -1){
34898            return false;
34899        }
34900        if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
34901            return false;
34902        }
34903
34904        
34905        this.childNodes.splice(index, 1);
34906
34907        
34908        if(node.previousSibling){
34909            node.previousSibling.nextSibling = node.nextSibling;
34910        }
34911        if(node.nextSibling){
34912            node.nextSibling.previousSibling = node.previousSibling;
34913        }
34914
34915        
34916        if(this.firstChild == node){
34917            this.setFirstChild(node.nextSibling);
34918        }
34919        if(this.lastChild == node){
34920            this.setLastChild(node.previousSibling);
34921        }
34922
34923        this.fireEvent("remove", this.ownerTree, this, node);
34924        if(destroy){
34925            node.destroy(true);
34926        }else{
34927            node.clear();
34928        }
34929        return node;
34930    },
34931
34932    
34933    clear : function(destroy){
34934        
34935        this.setOwnerTree(null, destroy);
34936        this.parentNode = this.previousSibling = this.nextSibling = null;
34937        if(destroy){
34938            this.firstChild = this.lastChild = null;
34939        }
34940    },
34941
34942    
34943    destroy : function( silent){
34944        
34945        if(silent === true){
34946            this.purgeListeners();
34947            this.clear(true);
34948            Ext.each(this.childNodes, function(n){
34949                n.destroy(true);
34950            });
34951            this.childNodes = null;
34952        }else{
34953            this.remove(true);
34954        }
34955    },
34956
34957    
34958    insertBefore : function(node, refNode){
34959        if(!refNode){ 
34960            return this.appendChild(node);
34961        }
34962        
34963        if(node == refNode){
34964            return false;
34965        }
34966
34967        if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
34968            return false;
34969        }
34970        var index = this.childNodes.indexOf(refNode);
34971        var oldParent = node.parentNode;
34972        var refIndex = index;
34973
34974        
34975        if(oldParent == this && this.childNodes.indexOf(node) < index){
34976            refIndex--;
34977        }
34978
34979        
34980        if(oldParent){
34981            if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
34982                return false;
34983            }
34984            oldParent.removeChild(node);
34985        }
34986        if(refIndex === 0){
34987            this.setFirstChild(node);
34988        }
34989        this.childNodes.splice(refIndex, 0, node);
34990        node.parentNode = this;
34991        var ps = this.childNodes[refIndex-1];
34992        if(ps){
34993            node.previousSibling = ps;
34994            ps.nextSibling = node;
34995        }else{
34996            node.previousSibling = null;
34997        }
34998        node.nextSibling = refNode;
34999        refNode.previousSibling = node;
35000        node.setOwnerTree(this.getOwnerTree());
35001        this.fireEvent("insert", this.ownerTree, this, node, refNode);
35002        if(oldParent){
35003            node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
35004        }
35005        return node;
35006    },
35007
35008    
35009    remove : function(destroy){
35010        if (this.parentNode) {
35011            this.parentNode.removeChild(this, destroy);
35012        }
35013        return this;
35014    },
35015
35016    
35017    removeAll : function(destroy){
35018        var cn = this.childNodes,
35019            n;
35020        while((n = cn[0])){
35021            this.removeChild(n, destroy);
35022        }
35023        return this;
35024    },
35025
35026    
35027    item : function(index){
35028        return this.childNodes[index];
35029    },
35030
35031    
35032    replaceChild : function(newChild, oldChild){
35033        var s = oldChild ? oldChild.nextSibling : null;
35034        this.removeChild(oldChild);
35035        this.insertBefore(newChild, s);
35036        return oldChild;
35037    },
35038
35039    
35040    indexOf : function(child){
35041        return this.childNodes.indexOf(child);
35042    },
35043
35044    
35045    getOwnerTree : function(){
35046        
35047        if(!this.ownerTree){
35048            var p = this;
35049            while(p){
35050                if(p.ownerTree){
35051                    this.ownerTree = p.ownerTree;
35052                    break;
35053                }
35054                p = p.parentNode;
35055            }
35056        }
35057        return this.ownerTree;
35058    },
35059
35060    
35061    getDepth : function(){
35062        var depth = 0;
35063        var p = this;
35064        while(p.parentNode){
35065            ++depth;
35066            p = p.parentNode;
35067        }
35068        return depth;
35069    },
35070
35071    
35072    setOwnerTree : function(tree, destroy){
35073        
35074        if(tree != this.ownerTree){
35075            if(this.ownerTree){
35076                this.ownerTree.unregisterNode(this);
35077            }
35078            this.ownerTree = tree;
35079            
35080            if(destroy !== true){
35081                Ext.each(this.childNodes, function(n){
35082                    n.setOwnerTree(tree);
35083                });
35084            }
35085            if(tree){
35086                tree.registerNode(this);
35087            }
35088        }
35089    },
35090
35091    
35092    setId: function(id){
35093        if(id !== this.id){
35094            var t = this.ownerTree;
35095            if(t){
35096                t.unregisterNode(this);
35097            }
35098            this.id = this.attributes.id = id;
35099            if(t){
35100                t.registerNode(this);
35101            }
35102            this.onIdChange(id);
35103        }
35104    },
35105
35106    
35107    onIdChange: Ext.emptyFn,
35108
35109    
35110    getPath : function(attr){
35111        attr = attr || "id";
35112        var p = this.parentNode;
35113        var b = [this.attributes[attr]];
35114        while(p){
35115            b.unshift(p.attributes[attr]);
35116            p = p.parentNode;
35117        }
35118        var sep = this.getOwnerTree().pathSeparator;
35119        return sep + b.join(sep);
35120    },
35121
35122    
35123    bubble : function(fn, scope, args){
35124        var p = this;
35125        while(p){
35126            if(fn.apply(scope || p, args || [p]) === false){
35127                break;
35128            }
35129            p = p.parentNode;
35130        }
35131    },
35132
35133    
35134    cascade : function(fn, scope, args){
35135        if(fn.apply(scope || this, args || [this]) !== false){
35136            var cs = this.childNodes;
35137            for(var i = 0, len = cs.length; i < len; i++) {
35138                cs[i].cascade(fn, scope, args);
35139            }
35140        }
35141    },
35142
35143    
35144    eachChild : function(fn, scope, args){
35145        var cs = this.childNodes;
35146        for(var i = 0, len = cs.length; i < len; i++) {
35147            if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
35148                break;
35149            }
35150        }
35151    },
35152
35153    
35154    findChild : function(attribute, value, deep){
35155        return this.findChildBy(function(){
35156            return this.attributes[attribute] == value;
35157        }, null, deep);
35158    },
35159
35160    
35161    findChildBy : function(fn, scope, deep){
35162        var cs = this.childNodes,
35163            len = cs.length,
35164            i = 0,
35165            n,
35166            res;
35167        for(; i < len; i++){
35168            n = cs[i];
35169            if(fn.call(scope || n, n) === true){
35170                return n;
35171            }else if (deep){
35172                res = n.findChildBy(fn, scope, deep);
35173                if(res != null){
35174                    return res;
35175                }
35176            }
35177            
35178        }
35179        return null;
35180    },
35181
35182    
35183    sort : function(fn, scope){
35184        var cs = this.childNodes;
35185        var len = cs.length;
35186        if(len > 0){
35187            var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
35188            cs.sort(sortFn);
35189            for(var i = 0; i < len; i++){
35190                var n = cs[i];
35191                n.previousSibling = cs[i-1];
35192                n.nextSibling = cs[i+1];
35193                if(i === 0){
35194                    this.setFirstChild(n);
35195                }
35196                if(i == len-1){
35197                    this.setLastChild(n);
35198                }
35199            }
35200        }
35201    },
35202
35203    
35204    contains : function(node){
35205        return node.isAncestor(this);
35206    },
35207
35208    
35209    isAncestor : function(node){
35210        var p = this.parentNode;
35211        while(p){
35212            if(p == node){
35213                return true;
35214            }
35215            p = p.parentNode;
35216        }
35217        return false;
35218    },
35219
35220    toString : function(){
35221        return "[Node"+(this.id?" "+this.id:"")+"]";
35222    }
35223});
35224Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {
35225    
35226    constructor : function(attributes){
35227        attributes = attributes || {};
35228        if(Ext.isString(attributes)){
35229            attributes = {text: attributes};
35230        }
35231        this.childrenRendered = false;
35232        this.rendered = false;
35233        Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
35234        this.expanded = attributes.expanded === true;
35235        this.isTarget = attributes.isTarget !== false;
35236        this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
35237        this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
35238
35239        
35240        this.text = attributes.text;
35241        
35242        this.disabled = attributes.disabled === true;
35243        
35244        this.hidden = attributes.hidden === true;
35245    
35246        this.addEvents(
35247            
35248            'textchange',
35249            
35250            'beforeexpand',
35251            
35252            'beforecollapse',
35253            
35254            'expand',
35255            
35256            'disabledchange',
35257            
35258            'collapse',
35259            
35260            'beforeclick',
35261            
35262            'click',
35263            
35264            'checkchange',
35265            
35266            'beforedblclick',
35267            
35268            'dblclick',
35269            
35270            'contextmenu',
35271            
35272            'beforechildrenrendered'
35273        );
35274    
35275        var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
35276    
35277        
35278        this.ui = new uiClass(this);    
35279    },
35280    
35281    preventHScroll : true,
35282    
35283    isExpanded : function(){
35284        return this.expanded;
35285    },
35286
35287
35288    getUI : function(){
35289        return this.ui;
35290    },
35291
35292    getLoader : function(){
35293        var owner;
35294        return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
35295    },
35296
35297    
35298    setFirstChild : function(node){
35299        var of = this.firstChild;
35300        Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
35301        if(this.childrenRendered && of && node != of){
35302            of.renderIndent(true, true);
35303        }
35304        if(this.rendered){
35305            this.renderIndent(true, true);
35306        }
35307    },
35308
35309    
35310    setLastChild : function(node){
35311        var ol = this.lastChild;
35312        Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
35313        if(this.childrenRendered && ol && node != ol){
35314            ol.renderIndent(true, true);
35315        }
35316        if(this.rendered){
35317            this.renderIndent(true, true);
35318        }
35319    },
35320
35321    
35322    
35323    appendChild : function(n){
35324        if(!n.render && !Ext.isArray(n)){
35325            n = this.getLoader().createNode(n);
35326        }
35327        var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
35328        if(node && this.childrenRendered){
35329            node.render();
35330        }
35331        this.ui.updateExpandIcon();
35332        return node;
35333    },
35334
35335    
35336    removeChild : function(node, destroy){
35337        this.ownerTree.getSelectionModel().unselect(node);
35338        Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
35339        
35340        if(!destroy){
35341            var rendered = node.ui.rendered;
35342            
35343            if(rendered){
35344                node.ui.remove();
35345            }
35346            if(rendered && this.childNodes.length < 1){
35347                this.collapse(false, false);
35348            }else{
35349                this.ui.updateExpandIcon();
35350            }
35351            if(!this.firstChild && !this.isHiddenRoot()){
35352                this.childrenRendered = false;
35353            }
35354        }
35355        return node;
35356    },
35357
35358    
35359    insertBefore : function(node, refNode){
35360        if(!node.render){
35361            node = this.getLoader().createNode(node);
35362        }
35363        var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
35364        if(newNode && refNode && this.childrenRendered){
35365            node.render();
35366        }
35367        this.ui.updateExpandIcon();
35368        return newNode;
35369    },
35370
35371    
35372    setText : function(text){
35373        var oldText = this.text;
35374        this.text = this.attributes.text = text;
35375        if(this.rendered){ 
35376            this.ui.onTextChange(this, text, oldText);
35377        }
35378        this.fireEvent('textchange', this, text, oldText);
35379    },
35380    
35381    
35382    setIconCls : function(cls){
35383        var old = this.attributes.iconCls;
35384        this.attributes.iconCls = cls;
35385        if(this.rendered){
35386            this.ui.onIconClsChange(this, cls, old);
35387        }
35388    },
35389    
35390    
35391    setTooltip : function(tip, title){
35392        this.attributes.qtip = tip;
35393        this.attributes.qtipTitle = title;
35394        if(this.rendered){
35395            this.ui.onTipChange(this, tip, title);
35396        }
35397    },
35398    
35399    
35400    setIcon : function(icon){
35401        this.attributes.icon = icon;
35402        if(this.rendered){
35403            this.ui.onIconChange(this, icon);
35404        }
35405    },
35406    
35407    
35408    setHref : function(href, target){
35409        this.attributes.href = href;
35410        this.attributes.hrefTarget = target;
35411        if(this.rendered){
35412            this.ui.onHrefChange(this, href, target);
35413        }
35414    },
35415    
35416    
35417    setCls : function(cls){
35418        var old = this.attributes.cls;
35419        this.attributes.cls = cls;
35420        if(this.rendered){
35421            this.ui.onClsChange(this, cls, old);
35422        }
35423    },
35424
35425    
35426    select : function(){
35427        var t = this.getOwnerTree();
35428        if(t){
35429            t.getSelectionModel().select(this);
35430        }
35431    },
35432
35433    
35434    unselect : function(silent){
35435        var t = this.getOwnerTree();
35436        if(t){
35437            t.getSelectionModel().unselect(this, silent);
35438        }
35439    },
35440
35441    
35442    isSelected : function(){
35443        var t = this.getOwnerTree();
35444        return t ? t.getSelectionModel().isSelected(this) : false;
35445    },
35446
35447    
35448    expand : function(deep, anim, callback, scope){
35449        if(!this.expanded){
35450            if(this.fireEvent('beforeexpand', this, deep, anim) === false){
35451                return;
35452            }
35453            if(!this.childrenRendered){
35454                this.renderChildren();
35455            }
35456            this.expanded = true;
35457            if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
35458                this.ui.animExpand(function(){
35459                    this.fireEvent('expand', this);
35460                    this.runCallback(callback, scope || this, [this]);
35461                    if(deep === true){
35462                        this.expandChildNodes(true, true);
35463                    }
35464                }.createDelegate(this));
35465                return;
35466            }else{
35467                this.ui.expand();
35468                this.fireEvent('expand', this);
35469                this.runCallback(callback, scope || this, [this]);
35470            }
35471        }else{
35472           this.runCallback(callback, scope || this, [this]);
35473        }
35474        if(deep === true){
35475            this.expandChildNodes(true);
35476        }
35477    },
35478
35479    runCallback : function(cb, scope, args){
35480        if(Ext.isFunction(cb)){
35481            cb.apply(scope, args);
35482        }
35483    },
35484
35485    isHiddenRoot : function(){
35486        return this.isRoot && !this.getOwnerTree().rootVisible;
35487    },
35488
35489    
35490    collapse : function(deep, anim, callback, scope){
35491        if(this.expanded && !this.isHiddenRoot()){
35492            if(this.fireEvent('beforecollapse', this, deep, anim) === false){
35493                return;
35494            }
35495            this.expanded = false;
35496            if((this.getOwnerTree().animate && anim !== false) || anim){
35497                this.ui.animCollapse(function(){
35498                    this.fireEvent('collapse', this);
35499                    this.runCallback(callback, scope || this, [this]);
35500                    if(deep === true){
35501                        this.collapseChildNodes(true);
35502                    }
35503                }.createDelegate(this));
35504                return;
35505            }else{
35506                this.ui.collapse();
35507                this.fireEvent('collapse', this);
35508                this.runCallback(callback, scope || this, [this]);
35509            }
35510        }else if(!this.expanded){
35511            this.runCallback(callback, scope || this, [this]);
35512        }
35513        if(deep === true){
35514            var cs = this.childNodes;
35515            for(var i = 0, len = cs.length; i < len; i++) {
35516            	cs[i].collapse(true, false);
35517            }
35518        }
35519    },
35520
35521    
35522    delayedExpand : function(delay){
35523        if(!this.expandProcId){
35524            this.expandProcId = this.expand.defer(delay, this);
35525        }
35526    },
35527
35528    
35529    cancelExpand : function(){
35530        if(this.expandProcId){
35531            clearTimeout(this.expandProcId);
35532        }
35533        this.expandProcId = false;
35534    },
35535
35536    
35537    toggle : function(){
35538        if(this.expanded){
35539            this.collapse();
35540        }else{
35541            this.expand();
35542        }
35543    },
35544
35545    
35546    ensureVisible : function(callback, scope){
35547        var tree = this.getOwnerTree();
35548        tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
35549            var node = tree.getNodeById(this.id);  
35550            tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
35551            this.runCallback(callback, scope || this, [this]);
35552        }.createDelegate(this));
35553    },
35554
35555    
35556    expandChildNodes : function(deep, anim) {
35557        var cs = this.childNodes,
35558            i,
35559            len = cs.length;
35560        for (i = 0; i < len; i++) {
35561        	cs[i].expand(deep, anim);
35562        }
35563    },
35564
35565    
35566    collapseChildNodes : function(deep){
35567        var cs = this.childNodes;
35568        for(var i = 0, len = cs.length; i < len; i++) {
35569        	cs[i].collapse(deep);
35570        }
35571    },
35572
35573    
35574    disable : function(){
35575        this.disabled = true;
35576        this.unselect();
35577        if(this.rendered && this.ui.onDisableChange){ 
35578            this.ui.onDisableChange(this, true);
35579        }
35580        this.fireEvent('disabledchange', this, true);
35581    },
35582
35583    
35584    enable : function(){
35585        this.disabled = false;
35586        if(this.rendered && this.ui.onDisableChange){ 
35587            this.ui.onDisableChange(this, false);
35588        }
35589        this.fireEvent('disabledchange', this, false);
35590    },
35591
35592    
35593    renderChildren : function(suppressEvent){
35594        if(suppressEvent !== false){
35595            this.fireEvent('beforechildrenrendered', this);
35596        }
35597        var cs = this.childNodes;
35598        for(var i = 0, len = cs.length; i < len; i++){
35599            cs[i].render(true);
35600        }
35601        this.childrenRendered = true;
35602    },
35603
35604    
35605    sort : function(fn, scope){
35606        Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
35607        if(this.childrenRendered){
35608            var cs = this.childNodes;
35609            for(var i = 0, len = cs.length; i < len; i++){
35610                cs[i].render(true);
35611            }
35612        }
35613    },
35614
35615    
35616    render : function(bulkRender){
35617        this.ui.render(bulkRender);
35618        if(!this.rendered){
35619            
35620            this.getOwnerTree().registerNode(this);
35621            this.rendered = true;
35622            if(this.expanded){
35623                this.expanded = false;
35624                this.expand(false, false);
35625            }
35626        }
35627    },
35628
35629    
35630    renderIndent : function(deep, refresh){
35631        if(refresh){
35632            this.ui.childIndent = null;
35633        }
35634        this.ui.renderIndent();
35635        if(deep === true && this.childrenRendered){
35636            var cs = this.childNodes;
35637            for(var i = 0, len = cs.length; i < len; i++){
35638                cs[i].renderIndent(true, refresh);
35639            }
35640        }
35641    },
35642
35643    beginUpdate : function(){
35644        this.childrenRendered = false;
35645    },
35646
35647    endUpdate : function(){
35648        if(this.expanded && this.rendered){
35649            this.renderChildren();
35650        }
35651    },
35652
35653    
35654    destroy : function(silent){
35655        if(silent === true){
35656            this.unselect(true);
35657        }
35658        Ext.tree.TreeNode.superclass.destroy.call(this, silent);
35659        Ext.destroy(this.ui, this.loader);
35660        this.ui = this.loader = null;
35661    },
35662
35663    
35664    onIdChange : function(id){
35665        this.ui.onIdChange(id);
35666    }
35667});
35668
35669Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
35670 Ext.tree.AsyncTreeNode = function(config){
35671    this.loaded = config && config.loaded === true;
35672    this.loading = false;
35673    Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
35674    
35675    this.addEvents('beforeload', 'load');
35676    
35677    
35678};
35679Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
35680    expand : function(deep, anim, callback, scope){
35681        if(this.loading){ 
35682            var timer;
35683            var f = function(){
35684                if(!this.loading){ 
35685                    clearInterval(timer);
35686                    this.expand(deep, anim, callback, scope);
35687                }
35688            }.createDelegate(this);
35689            timer = setInterval(f, 200);
35690            return;
35691        }
35692        if(!this.loaded){
35693            if(this.fireEvent("beforeload", this) === false){
35694                return;
35695            }
35696            this.loading = true;
35697            this.ui.beforeLoad(this);
35698            var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
35699            if(loader){
35700                loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
35701                return;
35702            }
35703        }
35704        Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
35705    },
35706    
35707    
35708    isLoading : function(){
35709        return this.loading;  
35710    },
35711    
35712    loadComplete : function(deep, anim, callback, scope){
35713        this.loading = false;
35714        this.loaded = true;
35715        this.ui.afterLoad(this);
35716        this.fireEvent("load", this);
35717        this.expand(deep, anim, callback, scope);
35718    },
35719    
35720    
35721    isLoaded : function(){
35722        return this.loaded;
35723    },
35724    
35725    hasChildNodes : function(){
35726        if(!this.isLeaf() && !this.loaded){
35727            return true;
35728        }else{
35729            return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
35730        }
35731    },
35732
35733    
35734    reload : function(callback, scope){
35735        this.collapse(false, false);
35736        while(this.firstChild){
35737            this.removeChild(this.firstChild).destroy();
35738        }
35739        this.childrenRendered = false;
35740        this.loaded = false;
35741        if(this.isHiddenRoot()){
35742            this.expanded = false;
35743        }
35744        this.expand(false, false, callback, scope);
35745    }
35746});
35747
35748Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
35749Ext.tree.TreeNodeUI = Ext.extend(Object, {
35750    
35751    constructor : function(node){
35752        Ext.apply(this, {
35753            node: node,
35754            rendered: false,
35755            animating: false,
35756            wasLeaf: true,
35757            ecc: 'x-tree-ec-icon x-tree-elbow',
35758            emptyIcon: Ext.BLANK_IMAGE_URL    
35759        });
35760    },
35761    
35762    
35763    removeChild : function(node){
35764        if(this.rendered){
35765            this.ctNode.removeChild(node.ui.getEl());
35766        }
35767    },
35768
35769    
35770    beforeLoad : function(){
35771         this.addClass("x-tree-node-loading");
35772    },
35773
35774    
35775    afterLoad : function(){
35776         this.removeClass("x-tree-node-loading");
35777    },
35778
35779    
35780    onTextChange : function(node, text, oldText){
35781        if(this.rendered){
35782            this.textNode.innerHTML = text;
35783        }
35784    },
35785    
35786    
35787    onIconClsChange : function(node, cls, oldCls){
35788        if(this.rendered){
35789            Ext.fly(this.iconNode).replaceClass(oldCls, cls);
35790        }
35791    },
35792    
35793    
35794    onIconChange : function(node, icon){
35795        if(this.rendered){
35796            
35797            var empty = Ext.isEmpty(icon);
35798            this.iconNode.src = empty ? this.emptyIcon : icon;
35799            Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
35800        }
35801    },
35802    
35803    
35804    onTipChange : function(node, tip, title){
35805        if(this.rendered){
35806            var hasTitle = Ext.isDefined(title);
35807            if(this.textNode.setAttributeNS){
35808                this.textNode.setAttributeNS("ext", "qtip", tip);
35809                if(hasTitle){
35810                    this.textNode.setAttributeNS("ext", "qtitle", title);
35811                }
35812            }else{
35813                this.textNode.setAttribute("ext:qtip", tip);
35814                if(hasTitle){
35815                    this.textNode.setAttribute("ext:qtitle", title);
35816                }
35817            }
35818        }
35819    },
35820    
35821    
35822    onHrefChange : function(node, href, target){
35823        if(this.rendered){
35824            this.anchor.href = this.getHref(href);
35825            if(Ext.isDefined(target)){
35826                this.anchor.target = target;
35827            }
35828        }
35829    },
35830    
35831    
35832    onClsChange : function(node, cls, oldCls){
35833        if(this.rendered){
35834            Ext.fly(this.elNode).replaceClass(oldCls, cls);
35835        }    
35836    },
35837
35838    
35839    onDisableChange : function(node, state){
35840        this.disabled = state;
35841        if (this.checkbox) {
35842            this.checkbox.disabled = state;
35843        }
35844        this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
35845    },
35846
35847    
35848    onSelectedChange : function(state){
35849        if(state){
35850            this.focus();
35851            this.addClass("x-tree-selected");
35852        }else{
35853            
35854            this.removeClass("x-tree-selected");
35855        }
35856    },
35857
35858    
35859    onMove : function(tree, node, oldParent, newParent, index, refNode){
35860        this.childIndent = null;
35861        if(this.rendered){
35862            var targetNode = newParent.ui.getContainer();
35863            if(!targetNode){
35864                this.holder = document.createElement("div");
35865                this.holder.appendChild(this.wrap);
35866                return;
35867            }
35868            var insertBefore = refNode ? refNode.ui.getEl() : null;
35869            if(insertBefore){
35870                targetNode.insertBefore(this.wrap, insertBefore);
35871            }else{
35872                targetNode.appendChild(this.wrap);
35873            }
35874            this.node.renderIndent(true, oldParent != newParent);
35875        }
35876    },
35877
35878
35879    addClass : function(cls){
35880        if(this.elNode){
35881            Ext.fly(this.elNode).addClass(cls);
35882        }
35883    },
35884
35885
35886    removeClass : function(cls){
35887        if(this.elNode){
35888            Ext.fly(this.elNode).removeClass(cls);
35889        }
35890    },
35891
35892    
35893    remove : function(){
35894        if(this.rendered){
35895            this.holder = document.createElement("div");
35896            this.holder.appendChild(this.wrap);
35897        }
35898    },
35899
35900    
35901    fireEvent : function(){
35902        return this.node.fireEvent.apply(this.node, arguments);
35903    },
35904
35905    
35906    initEvents : function(){
35907        this.node.on("move", this.onMove, this);
35908
35909        if(this.node.disabled){
35910            this.onDisableChange(this.node, true);
35911        }
35912        if(this.node.hidden){
35913            this.hide();
35914        }
35915        var ot = this.node.getOwnerTree();
35916        var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
35917        if(dd && (!this.node.isRoot || ot.rootVisible)){
35918            Ext.dd.Registry.register(this.elNode, {
35919                node: this.node,
35920                handles: this.getDDHandles(),
35921                isHandle: false
35922            });
35923        }
35924    },
35925
35926    
35927    getDDHandles : function(){
35928        return [this.iconNode, this.textNode, this.elNode];
35929    },
35930
35931
35932    hide : function(){
35933        this.node.hidden = true;
35934        if(this.wrap){
35935            this.wrap.style.display = "none";
35936        }
35937    },
35938
35939
35940    show : function(){
35941        this.node.hidden = false;
35942        if(this.wrap){
35943            this.wrap.style.display = "";
35944        }
35945    },
35946
35947    
35948    onContextMenu : function(e){
35949        if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
35950            e.preventDefault();
35951            this.focus();
35952            this.fireEvent("contextmenu", this.node, e);
35953        }
35954    },
35955
35956    
35957    onClick : function(e){
35958        if(this.dropping){
35959            e.stopEvent();
35960            return;
35961        }
35962        if(this.fireEvent("beforeclick", this.node, e) !== false){
35963            var a = e.getTarget('a');
35964            if(!this.disabled && this.node.attributes.href && a){
35965                this.fireEvent("click", this.node, e);
35966                return;
35967            }else if(a && e.ctrlKey){
35968                e.stopEvent();
35969            }
35970            e.preventDefault();
35971            if(this.disabled){
35972                return;
35973            }
35974
35975            if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
35976                this.node.toggle();
35977            }
35978
35979            this.fireEvent("click", this.node, e);
35980        }else{
35981            e.stopEvent();
35982        }
35983    },
35984
35985    
35986    onDblClick : function(e){
35987        e.preventDefault();
35988        if(this.disabled){
35989            return;
35990        }
35991        if(this.fireEvent("beforedblclick", this.node, e) !== false){
35992            if(this.checkbox){
35993                this.toggleCheck();
35994            }
35995            if(!this.animating && this.node.isExpandable()){
35996                this.node.toggle();
35997            }
35998            this.fireEvent("dblclick", this.node, e);
35999        }
36000    },
36001
36002    onOver : function(e){
36003        this.addClass('x-tree-node-over');
36004    },
36005
36006    onOut : function(e){
36007        this.removeClass('x-tree-node-over');
36008    },
36009
36010    
36011    onCheckChange : function(){
36012        var checked = this.checkbox.checked;
36013        
36014        this.checkbox.defaultChecked = checked;
36015        this.node.attributes.checked = checked;
36016        this.fireEvent('checkchange', this.node, checked);
36017    },
36018
36019    
36020    ecClick : function(e){
36021        if(!this.animating && this.node.isExpandable()){
36022            this.node.toggle();
36023        }
36024    },
36025
36026    
36027    startDrop : function(){
36028        this.dropping = true;
36029    },
36030
36031    
36032    endDrop : function(){
36033       setTimeout(function(){
36034           this.dropping = false;
36035       }.createDelegate(this), 50);
36036    },
36037
36038    
36039    expand : function(){
36040        this.updateExpandIcon();
36041        this.ctNode.style.display = "";
36042    },
36043
36044    
36045    focus : function(){
36046        if(!this.node.preventHScroll){
36047            try{this.anchor.focus();
36048            }catch(e){}
36049        }else{
36050            try{
36051                var noscroll = this.node.getOwnerTree().getTreeEl().dom;
36052                var l = noscroll.scrollLeft;
36053                this.anchor.focus();
36054                noscroll.scrollLeft = l;
36055            }catch(e){}
36056        }
36057    },
36058
36059
36060    toggleCheck : function(value){
36061        var cb = this.checkbox;
36062        if(cb){
36063            cb.checked = (value === undefined ? !cb.checked : value);
36064            this.onCheckChange();
36065        }
36066    },
36067
36068    
36069    blur : function(){
36070        try{
36071            this.anchor.blur();
36072        }catch(e){}
36073    },
36074
36075    
36076    animExpand : function(callback){
36077        var ct = Ext.get(this.ctNode);
36078        ct.stopFx();
36079        if(!this.node.isExpandable()){
36080            this.updateExpandIcon();
36081            this.ctNode.style.display = "";
36082            Ext.callback(callback);
36083            return;
36084        }
36085        this.animating = true;
36086        this.updateExpandIcon();
36087
36088        ct.slideIn('t', {
36089           callback : function(){
36090               this.animating = false;
36091               Ext.callback(callback);
36092            },
36093            scope: this,
36094            duration: this.node.ownerTree.duration || .25
36095        });
36096    },
36097
36098    
36099    highlight : function(){
36100        var tree = this.node.getOwnerTree();
36101        Ext.fly(this.wrap).highlight(
36102            tree.hlColor || "C3DAF9",
36103            {endColor: tree.hlBaseColor}
36104        );
36105    },
36106
36107    
36108    collapse : function(){
36109        this.updateExpandIcon();
36110        this.ctNode.style.display = "none";
36111    },
36112
36113    
36114    animCollapse : function(callback){
36115        var ct = Ext.get(this.ctNode);
36116        ct.enableDisplayMode('block');
36117        ct.stopFx();
36118
36119        this.animating = true;
36120        this.updateExpandIcon();
36121
36122        ct.slideOut('t', {
36123            callback : function(){
36124               this.animating = false;
36125               Ext.callback(callback);
36126            },
36127            scope: this,
36128            duration: this.node.ownerTree.duration || .25
36129        });
36130    },
36131
36132    
36133    getContainer : function(){
36134        return this.ctNode;
36135    },
36136
36137
36138    getEl : function(){
36139        return this.wrap;
36140    },
36141
36142    
36143    appendDDGhost : function(ghostNode){
36144        ghostNode.appendChild(this.elNode.cloneNode(true));
36145    },
36146
36147    
36148    getDDRepairXY : function(){
36149        return Ext.lib.Dom.getXY(this.iconNode);
36150    },
36151
36152    
36153    onRender : function(){
36154        this.render();
36155    },
36156
36157    
36158    render : function(bulkRender){
36159        var n = this.node, a = n.attributes;
36160        var targetNode = n.parentNode ?
36161              n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
36162
36163        if(!this.rendered){
36164            this.rendered = true;
36165
36166            this.renderElements(n, a, targetNode, bulkRender);
36167
36168            if(a.qtip){
36169                this.onTipChange(n, a.qtip, a.qtipTitle);
36170            }else if(a.qtipCfg){
36171                a.qtipCfg.target = Ext.id(this.textNode);
36172                Ext.QuickTips.register(a.qtipCfg);
36173            }
36174            this.initEvents();
36175            if(!this.node.expanded){
36176                this.updateExpandIcon(true);
36177            }
36178        }else{
36179            if(bulkRender === true) {
36180                targetNode.appendChild(this.wrap);
36181            }
36182        }
36183    },
36184
36185    
36186    renderElements : function(n, a, targetNode, bulkRender){
36187        
36188        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
36189
36190        var cb = Ext.isBoolean(a.checked),
36191            nel,
36192            href = this.getHref(a.href),
36193            buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
36194            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
36195            '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
36196            '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
36197            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
36198            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
36199             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
36200            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
36201            "</li>"].join('');
36202
36203        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
36204            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
36205        }else{
36206            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
36207        }
36208
36209        this.elNode = this.wrap.childNodes[0];
36210        this.ctNode = this.wrap.childNodes[1];
36211        var cs = this.elNode.childNodes;
36212        this.indentNode = cs[0];
36213        this.ecNode = cs[1];
36214        this.iconNode = cs[2];
36215        var index = 3;
36216        if(cb){
36217            this.checkbox = cs[3];
36218            
36219            this.checkbox.defaultChecked = this.checkbox.checked;
36220            index++;
36221        }
36222        this.anchor = cs[index];
36223        this.textNode = cs[index].firstChild;
36224    },
36225    
36226    
36227    getHref : function(href){
36228        return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
36229    },
36230
36231
36232    getAnchor : function(){
36233        return this.anchor;
36234    },
36235
36236
36237    getTextEl : function(){
36238        return this.textNode;
36239    },
36240
36241
36242    getIconEl : function(){
36243        return this.iconNode;
36244    },
36245
36246
36247    isChecked : function(){
36248        return this.checkbox ? this.checkbox.checked : false;
36249    },
36250
36251    
36252    updateExpandIcon : function(){
36253        if(this.rendered){
36254            var n = this.node,
36255                c1,
36256                c2,
36257                cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
36258                hasChild = n.hasChildNodes();
36259            if(hasChild || n.attributes.expandable){
36260                if(n.expanded){
36261                    cls += "-minus";
36262                    c1 = "x-tree-node-collapsed";
36263                    c2 = "x-tree-node-expanded";
36264                }else{
36265                    cls += "-plus";
36266                    c1 = "x-tree-node-expanded";
36267                    c2 = "x-tree-node-collapsed";
36268                }
36269                if(this.wasLeaf){
36270                    this.removeClass("x-tree-node-leaf");
36271                    this.wasLeaf = false;
36272                }
36273                if(this.c1 != c1 || this.c2 != c2){
36274                    Ext.fly(this.elNode).replaceClass(c1, c2);
36275                    this.c1 = c1; this.c2 = c2;
36276                }
36277            }else{
36278                if(!this.wasLeaf){
36279                    Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
36280                    delete this.c1;
36281                    delete this.c2;
36282                    this.wasLeaf = true;
36283                }
36284            }
36285            var ecc = "x-tree-ec-icon "+cls;
36286            if(this.ecc != ecc){
36287                this.ecNode.className = ecc;
36288                this.ecc = ecc;
36289            }
36290        }
36291    },
36292
36293    
36294    onIdChange: function(id){
36295        if(this.rendered){
36296            this.elNode.setAttribute('ext:tree-node-id', id);
36297        }
36298    },
36299
36300    
36301    getChildIndent : function(){
36302        if(!this.childIndent){
36303            var buf = [],
36304                p = this.node;
36305            while(p){
36306                if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
36307                    if(!p.isLast()) {
36308                        buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
36309                    } else {
36310                        buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
36311                    }
36312                }
36313                p = p.parentNode;
36314            }
36315            this.childIndent = buf.join("");
36316        }
36317        return this.childIndent;
36318    },
36319
36320    
36321    renderIndent : function(){
36322        if(this.rendered){
36323            var indent = "",
36324                p = this.node.parentNode;
36325            if(p){
36326                indent = p.ui.getChildIndent();
36327            }
36328            if(this.indentMarkup != indent){ 
36329                this.indentNode.innerHTML = indent;
36330                this.indentMarkup = indent;
36331            }
36332            this.updateExpandIcon();
36333        }
36334    },
36335
36336    destroy : function(){
36337        if(this.elNode){
36338            Ext.dd.Registry.unregister(this.elNode.id);
36339        }
36340
36341        Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
36342            if(this[el]){
36343                Ext.fly(this[el]).remove();
36344                delete this[el];
36345            }
36346        }, this);
36347        delete this.node;
36348    }
36349});
36350
36351
36352Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
36353    
36354    render : function(){
36355        if(!this.rendered){
36356            var targetNode = this.node.ownerTree.innerCt.dom;
36357            this.node.expanded = true;
36358            targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
36359            this.wrap = this.ctNode = targetNode.firstChild;
36360        }
36361    },
36362    collapse : Ext.emptyFn,
36363    expand : Ext.emptyFn
36364});
36365Ext.tree.TreeLoader = function(config){
36366    this.baseParams = {};
36367    Ext.apply(this, config);
36368
36369    this.addEvents(
36370        
36371        "beforeload",
36372        
36373        "load",
36374        
36375        "loadexception"
36376    );
36377    Ext.tree.TreeLoader.superclass.constructor.call(this);
36378    if(Ext.isString(this.paramOrder)){
36379        this.paramOrder = this.paramOrder.split(/[\s,|]/);
36380    }
36381};
36382
36383Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
36384    
36385    
36386    
36387    
36388    
36389    
36390    
36391    uiProviders : {},
36392
36393    
36394    clearOnLoad : true,
36395
36396    
36397    paramOrder: undefined,
36398
36399    
36400    paramsAsHash: false,
36401
36402    
36403    nodeParameter: 'node',
36404
36405    
36406    directFn : undefined,
36407
36408    
36409    load : function(node, callback, scope){
36410        if(this.clearOnLoad){
36411            while(node.firstChild){
36412                node.removeChild(node.firstChild);
36413            }
36414        }
36415        if(this.doPreload(node)){ 
36416            this.runCallback(callback, scope || node, [node]);
36417        }else if(this.directFn || this.dataUrl || this.url){
36418            this.requestData(node, callback, scope || node);
36419        }
36420    },
36421
36422    doPreload : function(node){
36423        if(node.attributes.children){
36424            if(node.childNodes.length < 1){ 
36425                var cs = node.attributes.children;
36426                node.beginUpdate();
36427                for(var i = 0, len = cs.length; i < len; i++){
36428                    var cn = node.appendChild(this.createNode(cs[i]));
36429                    if(this.preloadChildren){
36430                        this.doPreload(cn);
36431                    }
36432                }
36433                node.endUpdate();
36434            }
36435            return true;
36436        }
36437        return false;
36438    },
36439
36440    getParams: function(node){
36441        var bp = Ext.apply({}, this.baseParams),
36442            np = this.nodeParameter,
36443            po = this.paramOrder;
36444
36445        np && (bp[ np ] = node.id);
36446
36447        if(this.directFn){
36448            var buf = [node.id];
36449            if(po){
36450                
36451                if(np && po.indexOf(np) > -1){
36452                    buf = [];
36453                }
36454
36455                for(var i = 0, len = po.length; i < len; i++){
36456                    buf.push(bp[ po[i] ]);
36457                }
36458            }else if(this.paramsAsHash){
36459                buf = [bp];
36460            }
36461            return buf;
36462        }else{
36463            return bp;
36464        }
36465    },
36466
36467    requestData : function(node, callback, scope){
36468        if(this.fireEvent("beforeload", this, node, callback) !== false){
36469            if(this.directFn){
36470                var args = this.getParams(node);
36471                args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
36472                this.directFn.apply(window, args);
36473            }else{
36474                this.transId = Ext.Ajax.request({
36475                    method:this.requestMethod,
36476                    url: this.dataUrl||this.url,
36477                    success: this.handleResponse,
36478                    failure: this.handleFailure,
36479                    scope: this,
36480                    argument: {callback: callback, node: node, scope: scope},
36481                    params: this.getParams(node)
36482                });
36483            }
36484        }else{
36485            
36486            
36487            this.runCallback(callback, scope || node, []);
36488        }
36489    },
36490
36491    processDirectResponse: function(result, response, args){
36492        if(response.status){
36493            this.handleResponse({
36494                responseData: Ext.isArray(result) ? result : null,
36495                responseText: result,
36496                argument: args
36497            });
36498        }else{
36499            this.handleFailure({
36500                argument: args
36501            });
36502        }
36503    },
36504
36505    
36506    runCallback: function(cb, scope, args){
36507        if(Ext.isFunction(cb)){
36508            cb.apply(scope, args);
36509        }
36510    },
36511
36512    isLoading : function(){
36513        return !!this.transId;
36514    },
36515
36516    abort : function(){
36517        if(this.isLoading()){
36518            Ext.Ajax.abort(this.transId);
36519        }
36520    },
36521
36522    
36523    createNode : function(attr){
36524        
36525        if(this.baseAttrs){
36526            Ext.applyIf(attr, this.baseAttrs);
36527        }
36528        if(this.applyLoader !== false && !attr.loader){
36529            attr.loader = this;
36530        }
36531        if(Ext.isString(attr.uiProvider)){
36532           attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
36533        }
36534        if(attr.nodeType){
36535            return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
36536        }else{
36537            return attr.leaf ?
36538                        new Ext.tree.TreeNode(attr) :
36539                        new Ext.tree.AsyncTreeNode(attr);
36540        }
36541    },
36542
36543    processResponse : function(response, node, callback, scope){
36544        var json = response.responseText;
36545        try {
36546            var o = response.responseData || Ext.decode(json);
36547            node.beginUpdate();
36548            for(var i = 0, len = o.length; i < len; i++){
36549                var n = this.createNode(o[i]);
36550                if(n){
36551                    node.appendChild(n);
36552                }
36553            }
36554            node.endUpdate();
36555            this.runCallback(callback, scope || node, [node]);
36556        }catch(e){
36557            this.handleFailure(response);
36558        }
36559    },
36560
36561    handleResponse : function(response){
36562        this.transId = false;
36563        var a = response.argument;
36564        this.processResponse(response, a.node, a.callback, a.scope);
36565        this.fireEvent("load", this, a.node, response);
36566    },
36567
36568    handleFailure : function(response){
36569        this.transId = false;
36570        var a = response.argument;
36571        this.fireEvent("loadexception", this, a.node, response);
36572        this.runCallback(a.callback, a.scope || a.node, [a.node]);
36573    },
36574
36575    destroy : function(){
36576        this.abort();
36577        this.purgeListeners();
36578    }
36579});
36580Ext.tree.TreeFilter = function(tree, config){
36581    this.tree = tree;
36582    this.filtered = {};
36583    Ext.apply(this, config);
36584};
36585
36586Ext.tree.TreeFilter.prototype = {
36587    clearBlank:false,
36588    reverse:false,
36589    autoClear:false,
36590    remove:false,
36591
36592     
36593    filter : function(value, attr, startNode){
36594        attr = attr || "text";
36595        var f;
36596        if(typeof value == "string"){
36597            var vlen = value.length;
36598            
36599            if(vlen == 0 && this.clearBlank){
36600                this.clear();
36601                return;
36602            }
36603            value = value.toLowerCase();
36604            f = function(n){
36605                return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
36606            };
36607        }else if(value.exec){ 
36608            f = function(n){
36609                return value.test(n.attributes[attr]);
36610            };
36611        }else{
36612            throw 'Illegal filter type, must be string or regex';
36613        }
36614        this.filterBy(f, null, startNode);
36615	},
36616
36617    
36618    filterBy : function(fn, scope, startNode){
36619        startNode = startNode || this.tree.root;
36620        if(this.autoClear){
36621            this.clear();
36622        }
36623        var af = this.filtered, rv = this.reverse;
36624        var f = function(n){
36625            if(n == startNode){
36626                return true;
36627            }
36628            if(af[n.id]){
36629                return false;
36630            }
36631            var m = fn.call(scope || n, n);
36632            if(!m || rv){
36633                af[n.id] = n;
36634                n.ui.hide();
36635                return false;
36636            }
36637            return true;
36638        };
36639        startNode.cascade(f);
36640        if(this.remove){
36641           for(var id in af){
36642               if(typeof id != "function"){
36643                   var n = af[id];
36644                   if(n && n.parentNode){
36645                       n.parentNode.removeChild(n);
36646                   }
36647               }
36648           }
36649        }
36650    },
36651
36652    
36653    clear : function(){
36654        var t = this.tree;
36655        var af = this.filtered;
36656        for(var id in af){
36657            if(typeof id != "function"){
36658                var n = af[id];
36659                if(n){
36660                    n.ui.show();
36661                }
36662            }
36663        }
36664        this.filtered = {};
36665    }
36666};
36667
36668Ext.tree.TreeSorter = Ext.extend(Object, {
36669    
36670    constructor: function(tree, config){
36671        
36672    
36673    
36674    
36675    
36676    
36677
36678    Ext.apply(this, config);
36679    tree.on({
36680        scope: this,
36681        beforechildrenrendered: this.doSort,
36682        append: this.updateSort,
36683        insert: this.updateSort,
36684        textchange: this.updateSortParent
36685    });
36686
36687    var desc = this.dir && this.dir.toLowerCase() == 'desc',
36688        prop = this.property || 'text',
36689        sortType = this.sortType,
36690        folderSort = this.folderSort,
36691        caseSensitive = this.caseSensitive === true,
36692        leafAttr = this.leafAttr || 'leaf';
36693
36694    if(Ext.isString(sortType)){
36695        sortType = Ext.data.SortTypes[sortType];
36696    }
36697    this.sortFn = function(n1, n2){
36698        var attr1 = n1.attributes,
36699            attr2 = n2.attributes;
36700            
36701        if(folderSort){
36702            if(attr1[leafAttr] && !attr2[leafAttr]){
36703                return 1;
36704            }
36705            if(!attr1[leafAttr] && attr2[leafAttr]){
36706                return -1;
36707            }
36708        }
36709        var prop1 = attr1[prop],
36710            prop2 = attr2[prop],
36711            v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase()),
36712            v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
36713            
36714        if(v1 < v2){
36715            return desc ? 1 : -1;
36716        }else if(v1 > v2){
36717            return desc ? -1 : 1;
36718        }
36719        return 0;
36720    };
36721    },
36722    
36723    doSort : function(node){
36724        node.sort(this.sortFn);
36725    },
36726
36727    updateSort : function(tree, node){
36728        if(node.childrenRendered){
36729            this.doSort.defer(1, this, [node]);
36730        }
36731    },
36732
36733    updateSortParent : function(node){
36734        var p = node.parentNode;
36735        if(p && p.childrenRendered){
36736            this.doSort.defer(1, this, [p]);
36737        }
36738    }    
36739});
36740
36741if(Ext.dd.DropZone){
36742    
36743Ext.tree.TreeDropZone = function(tree, config){
36744    
36745    this.allowParentInsert = config.allowParentInsert || false;
36746    
36747    this.allowContainerDrop = config.allowContainerDrop || false;
36748    
36749    this.appendOnly = config.appendOnly || false;
36750
36751    Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
36752    
36753    this.tree = tree;
36754    
36755    this.dragOverData = {};
36756    
36757    this.lastInsertClass = "x-tree-no-status";
36758};
36759
36760Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
36761    
36762    ddGroup : "TreeDD",
36763
36764    
36765    expandDelay : 1000,
36766
36767    
36768    expandNode : function(node){
36769        if(node.hasChildNodes() && !node.isExpanded()){
36770            node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
36771        }
36772    },
36773
36774    
36775    queueExpand : function(node){
36776        this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
36777    },
36778
36779    
36780    cancelExpand : function(){
36781        if(this.expandProcId){
36782            clearTimeout(this.expandProcId);
36783            this.expandProcId = false;
36784        }
36785    },
36786
36787    
36788    isValidDropPoint : function(n, pt, dd, e, data){
36789        if(!n || !data){ return false; }
36790        var targetNode = n.node;
36791        var dropNode = data.node;
36792        
36793        if(!(targetNode && targetNode.isTarget && pt)){
36794            return false;
36795        }
36796        if(pt == "append" && targetNode.allowChildren === false){
36797            return false;
36798        }
36799        if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
36800            return false;
36801        }
36802        if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
36803            return false;
36804        }
36805        
36806        var overEvent = this.dragOverData;
36807        overEvent.tree = this.tree;
36808        overEvent.target = targetNode;
36809        overEvent.data = data;
36810        overEvent.point = pt;
36811        overEvent.source = dd;
36812        overEvent.rawEvent = e;
36813        overEvent.dropNode = dropNode;
36814        overEvent.cancel = false;  
36815        var result = this.tree.fireEvent("nodedragover", overEvent);
36816        return overEvent.cancel === false && result !== false;
36817    },
36818
36819    
36820    getDropPoint : function(e, n, dd){
36821        var tn = n.node;
36822        if(tn.isRoot){
36823            return tn.allowChildren !== false ? "append" : false; 
36824        }
36825        var dragEl = n.ddel;
36826        var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
36827        var y = Ext.lib.Event.getPageY(e);
36828        var noAppend = tn.allowChildren === false || tn.isLeaf();
36829        if(this.appendOnly || tn.parentNode.allowChildren === false){
36830            return noAppend ? false : "append";
36831        }
36832        var noBelow = false;
36833        if(!this.allowParentInsert){
36834            noBelow = tn.hasChildNodes() && tn.isExpanded();
36835        }
36836        var q = (b - t) / (noAppend ? 2 : 3);
36837        if(y >= t && y < (t + q)){
36838            return "above";
36839        }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
36840            return "below";
36841        }else{
36842            return "append";
36843        }
36844    },
36845
36846    
36847    onNodeEnter : function(n, dd, e, data){
36848        this.cancelExpand();
36849    },
36850    
36851    onContainerOver : function(dd, e, data) {
36852        if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36853            return this.dropAllowed;
36854        }
36855        return this.dropNotAllowed;
36856    },
36857
36858    
36859    onNodeOver : function(n, dd, e, data){
36860        var pt = this.getDropPoint(e, n, dd);
36861        var node = n.node;
36862        
36863        
36864        if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
36865            this.queueExpand(node);
36866        }else if(pt != "append"){
36867            this.cancelExpand();
36868        }
36869        
36870        
36871        var returnCls = this.dropNotAllowed;
36872        if(this.isValidDropPoint(n, pt, dd, e, data)){
36873           if(pt){
36874               var el = n.ddel;
36875               var cls;
36876               if(pt == "above"){
36877                   returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
36878                   cls = "x-tree-drag-insert-above";
36879               }else if(pt == "below"){
36880                   returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
36881                   cls = "x-tree-drag-insert-below";
36882               }else{
36883                   returnCls = "x-tree-drop-ok-append";
36884                   cls = "x-tree-drag-append";
36885               }
36886               if(this.lastInsertClass != cls){
36887                   Ext.fly(el).replaceClass(this.lastInsertClass, cls);
36888                   this.lastInsertClass = cls;
36889               }
36890           }
36891       }
36892       return returnCls;
36893    },
36894
36895    
36896    onNodeOut : function(n, dd, e, data){
36897        this.cancelExpand();
36898        this.removeDropIndicators(n);
36899    },
36900
36901    
36902    onNodeDrop : function(n, dd, e, data){
36903        var point = this.getDropPoint(e, n, dd);
36904        var targetNode = n.node;
36905        targetNode.ui.startDrop();
36906        if(!this.isValidDropPoint(n, point, dd, e, data)){
36907            targetNode.ui.endDrop();
36908            return false;
36909        }
36910        
36911        var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
36912        return this.processDrop(targetNode, data, point, dd, e, dropNode);
36913    },
36914    
36915    onContainerDrop : function(dd, e, data){
36916        if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36917            var targetNode = this.tree.getRootNode();       
36918            targetNode.ui.startDrop();
36919            var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
36920            return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
36921        }
36922        return false;
36923    },
36924    
36925    
36926    processDrop: function(target, data, point, dd, e, dropNode){
36927        var dropEvent = {
36928            tree : this.tree,
36929            target: target,
36930            data: data,
36931            point: point,
36932            source: dd,
36933            rawEvent: e,
36934            dropNode: dropNode,
36935            cancel: !dropNode,
36936            dropStatus: false
36937        };
36938        var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
36939        if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
36940            target.ui.endDrop();
36941            return dropEvent.dropStatus;
36942        }
36943    
36944        target = dropEvent.target;
36945        if(point == 'append' && !target.isExpanded()){
36946            target.expand(false, null, function(){
36947                this.completeDrop(dropEvent);
36948            }.createDelegate(this));
36949        }else{
36950            this.completeDrop(dropEvent);
36951        }
36952        return true;
36953    },
36954
36955    
36956    completeDrop : function(de){
36957        var ns = de.dropNode, p = de.point, t = de.target;
36958        if(!Ext.isArray(ns)){
36959            ns = [ns];
36960        }
36961        var n;
36962        for(var i = 0, len = ns.length; i < len; i++){
36963            n = ns[i];
36964            if(p == "above"){
36965                t.parentNode.insertBefore(n, t);
36966            }else if(p == "below"){
36967                t.parentNode.insertBefore(n, t.nextSibling);
36968            }else{
36969                t.appendChild(n);
36970            }
36971        }
36972        n.ui.focus();
36973        if(Ext.enableFx && this.tree.hlDrop){
36974            n.ui.highlight();
36975        }
36976        t.ui.endDrop();
36977        this.tree.fireEvent("nodedrop", de);
36978    },
36979
36980    
36981    afterNodeMoved : function(dd, data, e, targetNode, dropNode){
36982        if(Ext.enableFx && this.tree.hlDrop){
36983            dropNode.ui.focus();
36984            dropNode.ui.highlight();
36985        }
36986        this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
36987    },
36988
36989    
36990    getTree : function(){
36991        return this.tree;
36992    },
36993
36994    
36995    removeDropIndicators : function(n){
36996        if(n && n.ddel){
36997            var el = n.ddel;
36998            Ext.fly(el).removeClass([
36999                    "x-tree-drag-insert-above",
37000                    "x-tree-drag-insert-below",
37001                    "x-tree-drag-append"]);
37002            this.lastInsertClass = "_noclass";
37003        }
37004    },
37005
37006    
37007    beforeDragDrop : function(target, e, id){
37008        this.cancelExpand();
37009        return true;
37010    },
37011
37012    
37013    afterRepair : function(data){
37014        if(data && Ext.enableFx){
37015            data.node.ui.highlight();
37016        }
37017        this.hideProxy();
37018    }    
37019});
37020
37021}
37022if(Ext.dd.DragZone){
37023Ext.tree.TreeDragZone = function(tree, config){
37024    Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
37025    
37026    this.tree = tree;
37027};
37028
37029Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
37030    
37031    ddGroup : "TreeDD",
37032
37033    
37034    onBeforeDrag : function(data, e){
37035        var n = data.node;
37036        return n && n.draggable && !n.disabled;
37037    },
37038
37039    
37040    onInitDrag : function(e){
37041        var data = this.dragData;
37042        this.tree.getSelectionModel().select(data.node);
37043        this.tree.eventModel.disable();
37044        this.proxy.update("");
37045        data.node.ui.appendDDGhost(this.proxy.ghost.dom);
37046        this.tree.fireEvent("startdrag", this.tree, data.node, e);
37047    },
37048
37049    
37050    getRepairXY : function(e, data){
37051        return data.node.ui.getDDRepairXY();
37052    },
37053
37054    
37055    onEndDrag : function(data, e){
37056        this.tree.eventModel.enable.defer(100, this.tree.eventModel);
37057        this.tree.fireEvent("enddrag", this.tree, data.node, e);
37058    },
37059
37060    
37061    onValidDrop : function(dd, e, id){
37062        this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
37063        this.hideProxy();
37064    },
37065
37066    
37067    beforeInvalidDrop : function(e, id){
37068        
37069        var sm = this.tree.getSelectionModel();
37070        sm.clearSelections();
37071        sm.select(this.dragData.node);
37072    },
37073    
37074    
37075    afterRepair : function(){
37076        if (Ext.enableFx && this.tree.hlDrop) {
37077            Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
37078        }
37079        this.dragging = false;
37080    }
37081});
37082}
37083Ext.tree.TreeEditor = function(tree, fc, config){
37084    fc = fc || {};
37085    var field = fc.events ? fc : new Ext.form.TextField(fc);
37086    
37087    Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
37088
37089    this.tree = tree;
37090
37091    if(!tree.rendered){
37092        tree.on('render', this.initEditor, this);
37093    }else{
37094        this.initEditor(tree);
37095    }
37096};
37097
37098Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
37099    
37100    alignment: "l-l",
37101    
37102    autoSize: false,
37103    
37104    hideEl : false,
37105    
37106    cls: "x-small-editor x-tree-editor",
37107    
37108    shim:false,
37109    
37110    shadow:"frame",
37111    
37112    maxWidth: 250,
37113    
37114    editDelay : 350,
37115
37116    initEditor : function(tree){
37117        tree.on({
37118            scope      : this,
37119            beforeclick: this.beforeNodeClick,
37120            dblclick   : this.onNodeDblClick
37121        });
37122        
37123        this.on({
37124            scope          : this,
37125            complete       : this.updateNode,
37126            beforestartedit: this.fitToTree,
37127            specialkey     : this.onSpecialKey
37128        });
37129        
37130        this.on('startedit', this.bindScroll, this, {delay:10});
37131    },
37132
37133    
37134    fitToTree : function(ed, el){
37135        var td = this.tree.getTreeEl().dom, nd = el.dom;
37136        if(td.scrollLeft >  nd.offsetLeft){ 
37137            td.scrollLeft = nd.offsetLeft;
37138        }
37139        var w = Math.min(
37140                this.maxWidth,
37141                (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
37142        this.setSize(w, '');
37143    },
37144
37145    
37146    triggerEdit : function(node, defer){
37147        this.completeEdit();
37148		if(node.attributes.editable !== false){
37149           
37150			this.editNode = node;
37151            if(this.tree.autoScroll){
37152                Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
37153            }
37154            var value = node.text || '';
37155            if (!Ext.isGecko && Ext.isEmpty(node.text)){
37156                node.setText('&#160;');
37157            }
37158            this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
37159            return false;
37160        }
37161    },
37162
37163    
37164    bindScroll : function(){
37165        this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
37166    },
37167
37168    
37169    beforeNodeClick : function(node, e){
37170        clearTimeout(this.autoEditTimer);
37171        if(this.tree.getSelectionModel().isSelected(node)){
37172            e.stopEvent();
37173            return this.triggerEdit(node);
37174        }
37175    },
37176
37177    onNodeDblClick : function(node, e){
37178        clearTimeout(this.autoEditTimer);
37179    },
37180
37181    
37182    updateNode : function(ed, value){
37183        this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
37184        this.editNode.setText(value);
37185    },
37186
37187    
37188    onHide : function(){
37189        Ext.tree.TreeEditor.superclass.onHide.call(this);
37190        if(this.editNode){
37191            this.editNode.ui.focus.defer(50, this.editNode.ui);
37192        }
37193    },
37194
37195    
37196    onSpecialKey : function(field, e){
37197        var k = e.getKey();
37198        if(k == e.ESC){
37199            e.stopEvent();
37200            this.cancelEdit();
37201        }else if(k == e.ENTER && !e.hasModifier()){
37202            e.stopEvent();
37203            this.completeEdit();
37204        }
37205    },
37206    
37207    onDestroy : function(){
37208        clearTimeout(this.autoEditTimer);
37209        Ext.tree.TreeEditor.superclass.onDestroy.call(this);
37210        var tree = this.tree;
37211        tree.un('beforeclick', this.beforeNodeClick, this);
37212        tree.un('dblclick', this.onNodeDblClick, this);
37213    }
37214});
37215
37216var swfobject = function() {
37217    
37218    var UNDEF = "undefined",
37219        OBJECT = "object",
37220        SHOCKWAVE_FLASH = "Shockwave Flash",
37221        SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
37222        FLASH_MIME_TYPE = "application/x-shockwave-flash",
37223        EXPRESS_INSTALL_ID = "SWFObjectExprInst",
37224        ON_READY_STATE_CHANGE = "onreadystatechange",
37225        
37226        win = window,
37227        doc = document,
37228        nav = navigator,
37229        
37230        plugin = false,
37231        domLoadFnArr = [main],
37232        regObjArr = [],
37233        objIdArr = [],
37234        listenersArr = [],
37235        storedAltContent,
37236        storedAltContentId,
37237        storedCallbackFn,
37238        storedCallbackObj,
37239        isDomLoaded = false,
37240        isExpressInstallActive = false,
37241        dynamicStylesheet,
37242        dynamicStylesheetMedia,
37243        autoHideShow = true,
37244    
37245      
37246    ua = function() {
37247        var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
37248            u = nav.userAgent.toLowerCase(),
37249            p = nav.platform.toLowerCase(),
37250            windows = p ? (/win/).test(p) : /win/.test(u),
37251            mac = p ? (/mac/).test(p) : /mac/.test(u),
37252            webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, 
37253            ie = !+"\v1", 
37254            playerVersion = [0,0,0],
37255            d = null;
37256        if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
37257            d = nav.plugins[SHOCKWAVE_FLASH].description;
37258            if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { 
37259                plugin = true;
37260                ie = false; 
37261                d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
37262                playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
37263                playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
37264                playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
37265            }
37266        }
37267        else if (typeof win.ActiveXObject != UNDEF) {
37268            try {
37269                var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
37270                if (a) { 
37271                    d = a.GetVariable("$version");
37272                    if (d) {
37273                        ie = true; 
37274                        d = d.split(" ")[1].split(",");
37275                        playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
37276                    }
37277                }
37278            }
37279            catch(e) {}
37280        }
37281        return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
37282    }(),
37283    
37284     
37285    onDomLoad = function() {
37286        if (!ua.w3) { return; }
37287        if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { 
37288            callDomLoadFunctions();
37289        }
37290        if (!isDomLoaded) {
37291            if (typeof doc.addEventListener != UNDEF) {
37292                doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
37293            }       
37294            if (ua.ie && ua.win) {
37295                doc.attachEvent(ON_READY_STATE_CHANGE, function() {
37296                    if (doc.readyState == "complete") {
37297                        doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
37298                        callDomLoadFunctions();
37299                    }
37300                });
37301                if (win == top) { 
37302                    (function(){
37303                        if (isDomLoaded) { return; }
37304                        try {
37305                            doc.documentElement.doScroll("left");
37306                        }
37307                        catch(e) {
37308                            setTimeout(arguments.callee, 0);
37309                            return;
37310                        }
37311                        callDomLoadFunctions();
37312                    })();
37313                }
37314            }
37315            if (ua.wk) {
37316                (function(){
37317                    if (isDomLoaded) { return; }
37318                    if (!(/loaded|complete/).test(doc.readyState)) {
37319                        setTimeout(arguments.callee, 0);
37320                        return;
37321                    }
37322                    callDomLoadFunctions();
37323                })();
37324            }
37325            addLoadEvent(callDomLoadFunctions);
37326        }
37327    }();
37328    
37329    function callDomLoadFunctions() {
37330        if (isDomLoaded) { return; }
37331        try { 
37332            var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
37333            t.parentNode.removeChild(t);
37334        }
37335        catch (e) { return; }
37336        isDomLoaded = true;
37337        var dl = domLoadFnArr.length;
37338        for (var i = 0; i < dl; i++) {
37339            domLoadFnArr[i]();
37340        }
37341    }
37342    
37343    function addDomLoadEvent(fn) {
37344        if (isDomLoaded) {
37345            fn();
37346        }
37347        else { 
37348            domLoadFnArr[domLoadFnArr.length] = fn; 
37349        }
37350    }
37351    
37352    
37353    function addLoadEvent(fn) {
37354        if (typeof win.addEventListener != UNDEF) {
37355            win.addEventListener("load", fn, false);
37356        }
37357        else if (typeof doc.addEventListener != UNDEF) {
37358            doc.addEventListener("load", fn, false);
37359        }
37360        else if (typeof win.attachEvent != UNDEF) {
37361            addListener(win, "onload", fn);
37362        }
37363        else if (typeof win.onload == "function") {
37364            var fnOld = win.onload;
37365            win.onload = function() {
37366                fnOld();
37367                fn();
37368            };
37369        }
37370        else {
37371            win.onload = fn;
37372        }
37373    }
37374    
37375    
37376    function main() { 
37377        if (plugin) {
37378            testPlayerVersion();
37379        }
37380        else {
37381            matchVersions();
37382        }
37383    }
37384    
37385    
37386    function testPlayerVersion() {
37387        var b = doc.getElementsByTagName("body")[0];
37388        var o = createElement(OBJECT);
37389        o.setAttribute("type", FLASH_MIME_TYPE);
37390        var t = b.appendChild(o);
37391        if (t) {
37392            var counter = 0;
37393            (function(){
37394                if (typeof t.GetVariable != UNDEF) {
37395                    var d = t.GetVariable("$version");
37396                    if (d) {
37397                        d = d.split(" ")[1].split(",");
37398                        ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
37399                    }
37400                }
37401                else if (counter < 10) {
37402                    counter++;
37403                    setTimeout(arguments.callee, 10);
37404                    return;
37405                }
37406                b.removeChild(o);
37407                t = null;
37408                matchVersions();
37409            })();
37410        }
37411        else {
37412            matchVersions();
37413        }
37414    }
37415    
37416    
37417    function matchVersions() {
37418        var rl = regObjArr.length;
37419        if (rl > 0) {
37420            for (var i = 0; i < rl; i++) { 
37421                var id = regObjArr[i].id;
37422                var cb = regObjArr[i].callbackFn;
37423                var cbObj = {success:false, id:id};
37424                if (ua.pv[0] > 0) {
37425                    var obj = getElementById(id);
37426                    if (obj) {
37427                        if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { 
37428                            setVisibility(id, true);
37429                            if (cb) {
37430                                cbObj.success = true;
37431                                cbObj.ref = getObjectById(id);
37432                                cb(cbObj);
37433                            }
37434                        }
37435                        else if (regObjArr[i].expressInstall && canExpressInstall()) { 
37436                            var att = {};
37437                            att.data = regObjArr[i].expressInstall;
37438                            att.width = obj.getAttribute("width") || "0";
37439                            att.height = obj.getAttribute("height") || "0";
37440                            if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
37441                            if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
37442                            
37443                            var par = {};
37444                            var p = obj.getElementsByTagName("param");
37445                            var pl = p.length;
37446                            for (var j = 0; j < pl; j++) {
37447                                if (p[j].getAttribute("name").toLowerCase() != "movie") {
37448                                    par[p[j].getAttribute("name")] = p[j].getAttribute("value");
37449                                }
37450                            }
37451                            showExpressInstall(att, par, id, cb);
37452                        }
37453                        else { 
37454                            displayAltContent(obj);
37455                            if (cb) { cb(cbObj); }
37456                        }
37457                    }
37458                }
37459                else {  
37460                    setVisibility(id, true);
37461                    if (cb) {
37462                        var o = getObjectById(id); 
37463                        if (o && typeof o.SetVariable != UNDEF) { 
37464                            cbObj.success = true;
37465                            cbObj.ref = o;
37466                        }
37467                        cb(cbObj);
37468                    }
37469                }
37470            }
37471        }
37472    }
37473    
37474    function getObjectById(objectIdStr) {
37475        var r = null;
37476        var o = getElementById(objectIdStr);
37477        if (o && o.nodeName == "OBJECT") {
37478            if (typeof o.SetVariable != UNDEF) {
37479                r = o;
37480            }
37481            else {
37482                var n = o.getElementsByTagName(OBJECT)[0];
37483                if (n) {
37484                    r = n;
37485                }
37486            }
37487        }
37488        return r;
37489    }
37490    
37491    
37492    function canExpressInstall() {
37493        return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
37494    }
37495    
37496    
37497    function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
37498        isExpressInstallActive = true;
37499        storedCallbackFn = callbackFn || null;
37500        storedCallbackObj = {success:false, id:replaceElemIdStr};
37501        var obj = getElementById(replaceElemIdStr);
37502        if (obj) {
37503            if (obj.nodeName == "OBJECT") { 
37504                storedAltContent = abstractAltContent(obj);
37505                storedAltContentId = null;
37506            }
37507            else { 
37508                storedAltContent = obj;
37509                storedAltContentId = replaceElemIdStr;
37510            }
37511            att.id = EXPRESS_INSTALL_ID;
37512            if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
37513                att.width = "310";
37514            }
37515            
37516            if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
37517                att.height = "137";
37518            }
37519            doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
37520            var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
37521                fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
37522            if (typeof par.flashvars != UNDEF) {
37523                par.flashvars += "&" + fv;
37524            }
37525            else {
37526                par.flashvars = fv;
37527            }
37528            
37529            
37530            if (ua.ie && ua.win && obj.readyState != 4) {
37531                var newObj = createElement("div");
37532                replaceElemIdStr += "SWFObjectNew";
37533                newObj.setAttribute("id", replaceElemIdStr);
37534                obj.parentNode.insertBefore(newObj, obj); 
37535                obj.style.display = "none";
37536                (function(){
37537                    if (obj.readyState == 4) {
37538                        obj.parentNode.removeChild(obj);
37539                    }
37540                    else {
37541                        setTimeout(arguments.callee, 10);
37542                    }
37543                })();
37544            }
37545            createSWF(att, par, replaceElemIdStr);
37546        }
37547    }
37548    
37549    
37550    function displayAltContent(obj) {
37551        if (ua.ie && ua.win && obj.readyState != 4) {
37552            
37553            
37554            var el = createElement("div");
37555            obj.parentNode.insertBefore(el, obj); 
37556            el.parentNode.replaceChild(abstractAltContent(obj), el);
37557            obj.style.display = "none";
37558            (function(){
37559                if (obj.readyState == 4) {
37560                    obj.parentNode.removeChild(obj);
37561                }
37562                else {
37563                    setTimeout(arguments.callee, 10);
37564                }
37565            })();
37566        }
37567        else {
37568            obj.parentNode.replaceChild(abstractAltContent(obj), obj);
37569        }
37570    } 
37571
37572    fu
37572nction abstractAltContent(obj) {
37573        var ac = createElement("div");
37574        if (ua.win && ua.ie) {
37575            ac.innerHTML = obj.innerHTML;
37576        }
37577        else {
37578            var nestedObj = obj.getElementsByTagName(OBJECT)[0];
37579            if (nestedObj) {
37580                var c = nestedObj.childNodes;
37581                if (c) {
37582                    var cl = c.length;
37583                    for (var i = 0; i < cl; i++) {
37584                        if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
37585                            ac.appendChild(c[i].cloneNode(true));
37586                        }
37587                    }
37588                }
37589            }
37590        }
37591        return ac;
37592    }
37593    
37594    
37595    function createSWF(attObj, parObj, id) {
37596        var r, el = getElementById(id);
37597        if (ua.wk && ua.wk < 312) { return r; }
37598        if (el) {
37599            if (typeof attObj.id == UNDEF) { 
37600                attObj.id = id;
37601            }
37602            if (ua.ie && ua.win) { 
37603                var att = "";
37604                for (var i in attObj) {
37605                    if (attObj[i] != Object.prototype[i]) { 
37606                        if (i.toLowerCase() == "data") {
37607                            parObj.movie = attObj[i];
37608                        }
37609                        else if (i.toLowerCase() == "styleclass") { 
37610                            att += ' class="' + attObj[i] + '"';
37611                        }
37612                        else if (i.toLowerCase() != "classid") {
37613                            att += ' ' + i + '="' + attObj[i] + '"';
37614                        }
37615                    }
37616                }
37617                var par = "";
37618                for (var j in parObj) {
37619                    if (parObj[j] != Object.prototype[j]) { 
37620                        par += '<param name="' + j + '" value="' + parObj[j] + '" />';
37621                    }
37622                }
37623                el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
37624                objIdArr[objIdArr.length] = attObj.id; 
37625                r = getElementById(attObj.id);  
37626            }
37627            else { 
37628                var o = createElement(OBJECT);
37629                o.setAttribute("type", FLASH_MIME_TYPE);
37630                for (var m in attObj) {
37631                    if (attObj[m] != Object.prototype[m]) { 
37632                        if (m.toLowerCase() == "styleclass") { 
37633                            o.setAttribute("class", attObj[m]);
37634                        }
37635                        else if (m.toLowerCase() != "classid") { 
37636                            o.setAttribute(m, attObj[m]);
37637                        }
37638                    }
37639                }
37640                for (var n in parObj) {
37641                    if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { 
37642                        createObjParam(o, n, parObj[n]);
37643                    }
37644                }
37645                el.parentNode.replaceChild(o, el);
37646                r = o;
37647            }
37648        }
37649        return r;
37650    }
37651    
37652    function createObjParam(el, pName, pValue) {
37653        var p = createElement("param");
37654        p.setAttribute("name", pName);  
37655        p.setAttribute("value", pValue);
37656        el.appendChild(p);
37657    }
37658    
37659    
37660    function removeSWF(id) {
37661        var obj = getElementById(id);
37662        if (obj && obj.nodeName == "OBJECT") {
37663            if (ua.ie && ua.win) {
37664                obj.style.display = "none";
37665                (function(){
37666                    if (obj.readyState == 4) {
37667                        removeObjectInIE(id);
37668                    }
37669                    else {
37670                        setTimeout(arguments.callee, 10);
37671                    }
37672                })();
37673            }
37674            else {
37675                obj.parentNode.removeChild(obj);
37676            }
37677        }
37678    }
37679    
37680    function removeObjectInIE(id) {
37681        var obj = getElementById(id);
37682        if (obj) {
37683            for (var i in obj) {
37684                if (typeof obj[i] == "function") {
37685                    obj[i] = null;
37686                }
37687            }
37688            obj.parentNode.removeChild(obj);
37689        }
37690    }
37691    
37692    
37693    function getElementById(id) {
37694        var el = null;
37695        try {
37696            el = doc.getElementById(id);
37697        }
37698        catch (e) {}
37699        return el;
37700    }
37701    
37702    function createElement(el) {
37703        return doc.createElement(el);
37704    }
37705    
37706      
37707    function addListener(target, eventType, fn) {
37708        target.attachEvent(eventType, fn);
37709        listenersArr[listenersArr.length] = [target, eventType, fn];
37710    }
37711    
37712    
37713    function hasPlayerVersion(rv) {
37714        var pv = ua.pv, v = rv.split(".");
37715        v[0] = parseInt(v[0], 10);
37716        v[1] = parseInt(v[1], 10) || 0; 
37717        v[2] = parseInt(v[2], 10) || 0;
37718        return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
37719    }
37720    
37721      
37722    function createCSS(sel, decl, media, newStyle) {
37723        if (ua.ie && ua.mac) { return; }
37724        var h = doc.getElementsByTagName("head")[0];
37725        if (!h) { return; } 
37726        var m = (media && typeof media == "string") ? media : "screen";
37727        if (newStyle) {
37728            dynamicStylesheet = null;
37729            dynamicStylesheetMedia = null;
37730        }
37731        if (!dynamicStylesheet || dynamicStylesheetMedia != m) { 
37732            
37733            var s = createElement("style");
37734            s.setAttribute("type", "text/css");
37735            s.setAttribute("media", m);
37736            dynamicStylesheet = h.appendChild(s);
37737            if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
37738                dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
37739            }
37740            dynamicStylesheetMedia = m;
37741        }
37742        
37743        if (ua.ie && ua.win) {
37744            if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
37745                dynamicStylesheet.addRule(sel, decl);
37746            }
37747        }
37748        else {
37749            if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
37750                dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
37751            }
37752        }
37753    }
37754    
37755    function setVisibility(id, isVisible) {
37756        if (!autoHideShow) { return; }
37757        var v = isVisible ? "visible" : "hidden";
37758        if (isDomLoaded && getElementById(id)) {
37759            getElementById(id).style.visibility = v;
37760        }
37761        else {
37762            createCSS("#" + id, "visibility:" + v);
37763        }
37764    }
37765
37766    
37767    function urlEncodeIfNecessary(s) {
37768        var regex = /[\\\"<>\.;]/;
37769        var hasBadChars = regex.exec(s) != null;
37770        return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
37771    }
37772    
37773    
37774    var cleanup = function() {
37775        if (ua.ie && ua.win) {
37776            window.attachEvent("onunload", function() {
37777                
37778                var ll = listenersArr.length;
37779                for (var i = 0; i < ll; i++) {
37780                    listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
37781                }
37782                
37783                var il = objIdArr.length;
37784                for (var j = 0; j < il; j++) {
37785                    removeSWF(objIdArr[j]);
37786                }
37787                
37788                for (var k in ua) {
37789                    ua[k] = null;
37790                }
37791                ua = null;
37792                for (var l in swfobject) {
37793                    swfobject[l] = null;
37794                }
37795                swfobject = null;
37796                window.detachEvent('onunload', arguments.callee);
37797            });
37798        }
37799    }();
37800    
37801    return {
37802         
37803        registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
37804            if (ua.w3 && objectIdStr && swfVersionStr) {
37805                var regObj = {};
37806                regObj.id = objectIdStr;
37807                regObj.swfVersion = swfVersionStr;
37808                regObj.expressInstall = xiSwfUrlStr;
37809                regObj.callbackFn = callbackFn;
37810                regObjArr[regObjArr.length] = regObj;
37811                setVisibility(objectIdStr, false);
37812            }
37813            else if (callbackFn) {
37814                callbackFn({success:false, id:objectIdStr});
37815            }
37816        },
37817        
37818        getObjectById: function(objectIdStr) {
37819            if (ua.w3) {
37820                return getObjectById(objectIdStr);
37821            }
37822        },
37823        
37824        embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
37825            var callbackObj = {success:false, id:replaceElemIdStr};
37826            if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
37827                setVisibility(replaceElemIdStr, false);
37828                addDomLoadEvent(function() {
37829                    widthStr += ""; 
37830                    heightStr += "";
37831                    var att = {};
37832                    if (attObj && typeof attObj === OBJECT) {
37833                        for (var i in attObj) { 
37834                            att[i] = attObj[i];
37835                        }
37836                    }
37837                    att.data = swfUrlStr;
37838                    att.width = widthStr;
37839                    att.height = heightStr;
37840                    var par = {}; 
37841                    if (parObj && typeof parObj === OBJECT) {
37842                        for (var j in parObj) { 
37843                            par[j] = parObj[j];
37844                        }
37845                    }
37846                    if (flashvarsObj && typeof flashvarsObj === OBJECT) {
37847                        for (var k in flashvarsObj) { 
37848                            if (typeof par.flashvars != UNDEF) {
37849                                par.flashvars += "&" + k + "=" + flashvarsObj[k];
37850                            }
37851                            else {
37852                                par.flashvars = k + "=" + flashvarsObj[k];
37853                            }
37854                        }
37855                    }
37856                    if (hasPlayerVersion(swfVersionStr)) { 
37857                        var obj = createSWF(att, par, replaceElemIdStr);
37858                        if (att.id == replaceElemIdStr) {
37859                            setVisibility(replaceElemIdStr, true);
37860                        }
37861                        callbackObj.success = true;
37862                        callbackObj.ref = obj;
37863                    }
37864                    else if (xiSwfUrlStr && canExpressInstall()) { 
37865                        att.data = xiSwfUrlStr;
37866                        showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37867                        return;
37868                    }
37869                    else { 
37870                        setVisibility(replaceElemIdStr, true);
37871                    }
37872                    if (callbackFn) { callbackFn(callbackObj); }
37873                });
37874            }
37875            else if (callbackFn) { callbackFn(callbackObj); }
37876        },
37877        
37878        switchOffAutoHideShow: function() {
37879            autoHideShow = false;
37880        },
37881        
37882        ua: ua,
37883        
37884        getFlashPlayerVersion: function() {
37885            return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
37886        },
37887        
37888        hasFlashPlayerVersion: hasPlayerVersion,
37889        
37890        createSWF: function(attObj, parObj, replaceElemIdStr) {
37891            if (ua.w3) {
37892                return createSWF(attObj, parObj, replaceElemIdStr);
37893            }
37894            else {
37895                return undefined;
37896            }
37897        },
37898        
37899        showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
37900            if (ua.w3 && canExpressInstall()) {
37901                showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37902            }
37903        },
37904        
37905        removeSWF: function(objElemIdStr) {
37906            if (ua.w3) {
37907                removeSWF(objElemIdStr);
37908            }
37909        },
37910        
37911        createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
37912            if (ua.w3) {
37913                createCSS(selStr, declStr, mediaStr, newStyleBoolean);
37914            }
37915        },
37916        
37917        addDomLoadEvent: addDomLoadEvent,
37918        
37919        addLoadEvent: addLoadEvent,
37920        
37921        getQueryParamValue: function(param) {
37922            var q = doc.location.search || doc.location.hash;
37923            if (q) {
37924                if (/\?/.test(q)) { q = q.split("?")[1]; } 
37925                if (param == null) {
37926                    return urlEncodeIfNecessary(q);
37927                }
37928                var pairs = q.split("&");
37929                for (var i = 0; i < pairs.length; i++) {
37930                    if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
37931                        return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
37932                    }
37933                }
37934            }
37935            return "";
37936        },
37937        
37938        
37939        expressInstallCallback: function() {
37940            if (isExpressInstallActive) {
37941                var obj = getElementById(EXPRESS_INSTALL_ID);
37942                if (obj && storedAltContent) {
37943                    obj.parentNode.replaceChild(storedAltContent, obj);
37944                    if (storedAltContentId) {
37945                        setVisibility(storedAltContentId, true);
37946                        if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
37947                    }
37948                    if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
37949                }
37950                isExpressInstallActive = false;
37951            } 
37952        }
37953    };
37954}();
37955
37956Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
37957    
37958    flashVersion : '9.0.115',
37959
37960    
37961    backgroundColor: '#ffffff',
37962
37963    
37964    wmode: 'opaque',
37965
37966    
37967    flashVars: undefined,
37968
37969    
37970    flashParams: undefined,
37971
37972    
37973    url: undefined,
37974    swfId : undefined,
37975    swfWidth: '100%',
37976    swfHeight: '100%',
37977
37978    
37979    expressInstall: false,
37980
37981    initComponent : function(){
37982        Ext.FlashComponent.superclass.initComponent.call(this);
37983
37984        this.addEvents(
37985            
37986            'initialize'
37987        );
37988    },
37989
37990    onRender : function(){
37991        Ext.FlashComponent.superclass.onRender.apply(this, arguments);
37992
37993        var params = Ext.apply({
37994            allowScriptAccess: 'always',
37995            bgcolor: this.backgroundColor,
37996            wmode: this.wmode
37997        }, this.flashParams), vars = Ext.apply({
37998            allowedDomain: document.location.hostname,
37999            YUISwfId: this.getId(),
38000            YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
38001        }, this.flashVars);
38002
38003        new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
38004            this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
38005
38006        this.swf = Ext.getDom(this.id);
38007        this.el = Ext.get(this.swf);
38008    },
38009
38010    getSwfId : function(){
38011        return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
38012    },
38013
38014    getId : function(){
38015        return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
38016    },
38017
38018    onFlashEvent : function(e){
38019        switch(e.type){
38020            case "swfReady":
38021                this.initSwf();
38022                return;
38023            case "log":
38024                return;
38025        }
38026        e.component = this;
38027        this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
38028    },
38029
38030    initSwf : function(){
38031        this.onSwfReady(!!this.isInitialized);
38032        this.isInitialized = true;
38033        this.fireEvent('initialize', this);
38034    },
38035
38036    beforeDestroy: function(){
38037        if(this.rendered){
38038            swfobject.removeSWF(this.swf.id);
38039        }
38040        Ext.FlashComponent.superclass.beforeDestroy.call(this);
38041    },
38042
38043    onSwfReady : Ext.emptyFn
38044});
38045
38046
38047Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
38048
38049Ext.reg('flash', Ext.FlashComponent);
38050Ext.FlashEventProxy = {
38051    onEvent : function(id, e){
38052        var fp = Ext.getCmp(id);
38053        if(fp){
38054            fp.onFlashEvent(e);
38055        }else{
38056            arguments.callee.defer(10, this, [id, e]);
38057        }
38058    }
38059};
38060
38061 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
38062    refreshBuffer: 100,
38063
38064    
38065
38066    
38067    chartStyle: {
38068        padding: 10,
38069        animationEnabled: true,
38070        font: {
38071            name: 'Tahoma',
38072            color: 0x444444,
38073            size: 11
38074        },
38075        dataTip: {
38076            padding: 5,
38077            border: {
38078                color: 0x99bbe8,
38079                size:1
38080            },
38081            background: {
38082                color: 0xDAE7F6,
38083                alpha: .9
38084            },
38085            font: {
38086                name: 'Tahoma',
38087                color: 0x15428B,
38088                size: 10,
38089                bold: true
38090            }
38091        }
38092    },
38093
38094    
38095
38096    
38097    extraStyle: null,
38098
38099    
38100    seriesStyles: null,
38101
38102    
38103    disableCaching: Ext.isIE || Ext.isOpera,
38104    disableCacheParam: '_dc',
38105
38106    initComponent : function(){
38107        Ext.chart.Chart.superclass.initComponent.call(this);
38108        if(!this.url){
38109            this.url = Ext.chart.Chart.CHART_URL;
38110        }
38111        if(this.disableCaching){
38112            this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
38113        }
38114        this.addEvents(
38115            'itemmouseover',
38116            'itemmouseout',
38117            'itemclick',
38118            'itemdoubleclick',
38119            'itemdragstart',
38120            'itemdrag',
38121            'itemdragend',
38122            
38123            'beforerefresh',
38124            
38125            'refresh'
38126        );
38127        this.store = Ext.StoreMgr.lookup(this.store);
38128    },
38129
38130    
38131     setStyle: function(name, value){
38132         this.swf.setStyle(name, Ext.encode(value));
38133     },
38134
38135    
38136    setStyles: function(styles){
38137        this.swf.setStyles(Ext.encode(styles));
38138    },
38139
38140    
38141    setSeriesStyles: function(styles){
38142        this.seriesStyles = styles;
38143        var s = [];
38144        Ext.each(styles, function(style){
38145            s.push(Ext.encode(style));
38146        });
38147        this.swf.setSeriesStyles(s);
38148    },
38149
38150    setCategoryNames : function(names){
38151        this.swf.setCategoryNames(names);
38152    },
38153
38154    setLegendRenderer : function(fn, scope){
38155        var chart = this;
38156        scope = scope || chart;
38157        chart.removeFnProxy(chart.legendFnName);
38158        chart.legendFnName = chart.createFnProxy(function(name){
38159            return fn.call(scope, name);
38160        });
38161        chart.swf.setLegendLabelFunction(chart.legendFnName);
38162    },
38163
38164    setTipRenderer : function(fn, scope){
38165        var chart = this;
38166        scope = scope || chart;
38167        chart.removeFnProxy(chart.tipFnName);
38168        chart.tipFnName = chart.createFnProxy(function(item, index, series){
38169            var record = chart.store.getAt(index);
38170            return fn.call(scope, chart, record, index, series);
38171        });
38172        chart.swf.setDataTipFunction(chart.tipFnName);
38173    },
38174
38175    setSeries : function(series){
38176        this.series = series;
38177        this.refresh();
38178    },
38179
38180    
38181    bindStore : function(store, initial){
38182        if(!initial && this.store){
38183            if(store !== this.store && this.store.autoDestroy){
38184                this.store.destroy();
38185            }else{
38186                this.store.un("datachanged", this.refresh, this);
38187                this.store.un("add", this.delayRefresh, this);
38188                this.store.un("remove", this.delayRefresh, this);
38189                this.store.un("update", this.delayRefresh, this);
38190                this.store.un("clear", this.refresh, this);
38191            }
38192        }
38193        if(store){
38194            store = Ext.StoreMgr.lookup(store);
38195            store.on({
38196                scope: this,
38197                datachanged: this.refresh,
38198                add: this.delayRefresh,
38199                remove: this.delayRefresh,
38200                update: this.delayRefresh,
38201                clear: this.refresh
38202            });
38203        }
38204        this.store = store;
38205        if(store && !initial){
38206            this.refresh();
38207        }
38208    },
38209
38210    onSwfReady : function(isReset){
38211        Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
38212        var ref;
38213        this.swf.setType(this.type);
38214
38215        if(this.chartStyle){
38216            this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
38217        }
38218
38219        if(this.categoryNames){
38220            this.setCategoryNames(this.categoryNames);
38221        }
38222
38223        if(this.tipRenderer){
38224            ref = this.getFunctionRef(this.tipRenderer);
38225            this.setTipRenderer(ref.fn, ref.scope);
38226        }
38227        if(this.legendRenderer){
38228            ref = this.getFunctionRef(this.legendRenderer);
38229            this.setLegendRenderer(ref.fn, ref.scope);
38230        }
38231        if(!isReset){
38232            this.bindStore(this.store, true);
38233        }
38234        this.refresh.defer(10, this);
38235    },
38236
38237    delayRefresh : function(){
38238        if(!this.refreshTask){
38239            this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
38240        }
38241        this.refreshTask.delay(this.refreshBuffer);
38242    },
38243
38244    refresh : function(){
38245        if(this.fireEvent('beforerefresh', this) !== false){
38246            var styleChanged = false;
38247            
38248            var data = [], rs = this.store.data.items;
38249            for(var j = 0, len = rs.length; j < len; j++){
38250                data[j] = rs[j].data;
38251            }
38252            
38253            
38254            var dataProvider = [];
38255            var seriesCount = 0;
38256            var currentSeries = null;
38257            var i = 0;
38258            if(this.series){
38259                seriesCount = this.series.length;
38260                for(i = 0; i < seriesCount; i++){
38261                    currentSeries = this.series[i];
38262                    var clonedSeries = {};
38263                    for(var prop in currentSeries){
38264                        if(prop == "style" && currentSeries.style !== null){
38265                            clonedSeries.style = Ext.encode(currentSeries.style);
38266                            styleChanged = true;
38267                            
38268                            
38269                            
38270                            
38271                        } else{
38272                            clonedSeries[prop] = currentSeries[prop];
38273                        }
38274                    }
38275                    dataProvider.push(clonedSeries);
38276                }
38277            }
38278
38279            if(seriesCount > 0){
38280                for(i = 0; i < seriesCount; i++){
38281                    currentSeries = dataProvider[i];
38282                    if(!currentSeries.type){
38283                        currentSeries.type = this.type;
38284                    }
38285                    currentSeries.dataProvider = data;
38286                }
38287            } else{
38288                dataProvider.push({type: this.type, dataProvider: data});
38289            }
38290            this.swf.setDataProvider(dataProvider);
38291            if(this.seriesStyles){
38292                this.setSeriesStyles(this.seriesStyles);
38293            }
38294            this.fireEvent('refresh', this);
38295        }
38296    },
38297
38298    
38299    createFnProxy : function(fn){
38300        var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
38301        Ext.chart.Chart.proxyFunction[fnName] = fn;
38302        return 'Ext.chart.Chart.proxyFunction.' + fnName;
38303    },
38304
38305    
38306    removeFnProxy : function(fn){
38307        if(!Ext.isEmpty(fn)){
38308            fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
38309            delete Ext.chart.Chart.proxyFunction[fn];
38310        }
38311    },
38312
38313    
38314    getFunctionRef : function(val){
38315        if(Ext.isFunction(val)){
38316            return {
38317                fn: val,
38318                scope: this
38319            };
38320        }else{
38321            return {
38322                fn: val.fn,
38323                scope: val.scope || this
38324            };
38325        }
38326    },
38327
38328    
38329    onDestroy: function(){
38330        if (this.refreshTask && this.refreshTask.cancel){
38331            this.refreshTask.cancel();
38332        }
38333        Ext.chart.Chart.superclass.onDestroy.call(this);
38334        this.bindStore(null);
38335        this.removeFnProxy(this.tipFnName);
38336        this.removeFnProxy(this.legendFnName);
38337    }
38338});
38339Ext.reg('chart', Ext.chart.Chart);
38340Ext.chart.Chart.PROXY_FN_ID = 0;
38341Ext.chart.Chart.proxyFunction = {};
38342
38343
38344Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
38345
38346
38347Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
38348    type: 'pie',
38349
38350    onSwfReady : function(isReset){
38351        Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
38352
38353        this.setDataField(this.dataField);
38354        this.setCategoryField(this.categoryField);
38355    },
38356
38357    setDataField : function(field){
38358        this.dataField = field;
38359        this.swf.setDataField(field);
38360    },
38361
38362    setCategoryField : function(field){
38363        this.categoryField = field;
38364        this.swf.setCategoryField(field);
38365    }
38366});
38367Ext.reg('piechart', Ext.chart.PieChart);
38368
38369
38370Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
38371    onSwfReady : function(isReset){
38372        Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
38373        this.labelFn = [];
38374        if(this.xField){
38375            this.setXField(this.xField);
38376        }
38377        if(this.yField){
38378            this.setYField(this.yField);
38379        }
38380        if(this.xAxis){
38381            this.setXAxis(this.xAxis);
38382        }
38383        if(this.xAxes){
38384            this.setXAxes(this.xAxes);
38385        }
38386        if(this.yAxis){
38387            this.setYAxis(this.yAxis);
38388        }
38389        if(this.yAxes){
38390            this.setYAxes(this.yAxes);
38391        }
38392        if(Ext.isDefined(this.constrainViewport)){
38393            this.swf.setConstrainViewport(this.constrainViewport);
38394        }
38395    },
38396
38397    setXField : function(value){
38398        this.xField = value;
38399        this.swf.setHorizontalField(value);
38400    },
38401
38402    setYField : function(value){
38403        this.yField = value;
38404        this.swf.setVerticalField(value);
38405    },
38406
38407    setXAxis : function(value){
38408        this.xAxis = this.createAxis('xAxis', value);
38409        this.swf.setHorizontalAxis(this.xAxis);
38410    },
38411
38412    setXAxes : function(value){
38413        var axis;
38414        for(var i = 0; i < value.length; i++) {
38415            axis = this.createAxis('xAxis' + i, value[i]);
38416            this.swf.setHorizontalAxis(axis);
38417        }
38418    },
38419
38420    setYAxis : function(value){
38421        this.yAxis = this.createAxis('yAxis', value);
38422        this.swf.setVerticalAxis(this.yAxis);
38423    },
38424
38425    setYAxes : function(value){
38426        var axis;
38427        for(var i = 0; i < value.length; i++) {
38428            axis = this.createAxis('yAxis' + i, value[i]);
38429            this.swf.setVerticalAxis(axis);
38430        }
38431    },
38432
38433    createAxis : function(axis, value){
38434        var o = Ext.apply({}, value),
38435            ref,
38436            old;
38437
38438        if(this[axis]){
38439            old = this[axis].labelFunction;
38440            this.removeFnProxy(old);
38441            this.labelFn.remove(old);
38442        }
38443        if(o.labelRenderer){
38444            ref = this.getFunctionRef(o.labelRenderer);
38445            o.labelFunction = this.createFnProxy(function(v){
38446                return ref.fn.call(ref.scope, v);
38447            });
38448            delete o.labelRenderer;
38449            this.labelFn.push(o.labelFunction);
38450        }
38451        if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
38452            o.position = 'bottom';
38453        }
38454        return o;
38455    },
38456
38457    onDestroy : function(){
38458        Ext.chart.CartesianChart.superclass.onDestroy.call(this);
38459        Ext.each(this.labelFn, function(fn){
38460            this.removeFnProxy(fn);
38461        }, this);
38462    }
38463});
38464Ext.reg('cartesianchart', Ext.chart.CartesianChart);
38465
38466
38467Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
38468    type: 'line'
38469});
38470Ext.reg('linechart', Ext.chart.LineChart);
38471
38472
38473Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
38474    type: 'column'
38475});
38476Ext.reg('columnchart', Ext.chart.ColumnChart);
38477
38478
38479Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
38480    type: 'stackcolumn'
38481});
38482Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
38483
38484
38485Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
38486    type: 'bar'
38487});
38488Ext.reg('barchart', Ext.chart.BarChart);
38489
38490
38491Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
38492    type: 'stackbar'
38493});
38494Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
38495
38496
38497
38498
38499Ext.chart.Axis = function(config){
38500    Ext.apply(this, config);
38501};
38502
38503Ext.chart.Axis.prototype =
38504{
38505    
38506    type: null,
38507
38508    
38509    orientation: "horizontal",
38510
38511    
38512    reverse: false,
38513
38514    
38515    labelFunction: null,
38516
38517    
38518    hideOverlappingLabels: true,
38519
38520    
38521    labelSpacing: 2
38522};
38523
38524
38525Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
38526    type: "numeric",
38527
38528    
38529    minimum: NaN,
38530
38531    
38532    maximum: NaN,
38533
38534    
38535    majorUnit: NaN,
38536
38537    
38538    minorUnit: NaN,
38539
38540    
38541    snapToUnits: true,
38542
38543    
38544    alwaysShowZero: true,
38545
38546    
38547    scale: "linear",
38548
38549    
38550    roundMajorUnit: true,
38551
38552    
38553    calculateByLabelSize: true,
38554
38555    
38556    position: 'left',
38557
38558    
38559    adjustMaximumByMajorUnit: true,
38560
38561    
38562    adjustMinimumByMajorUnit: true
38563
38564});
38565
38566
38567Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
38568    type: "time",
38569
38570    
38571    minimum: null,
38572
38573    
38574    maximum: null,
38575
38576    
38577    majorUnit: NaN,
38578
38579    
38580    majorTimeUnit: null,
38581
38582    
38583    minorUnit: NaN,
38584
38585    
38586    minorTimeUnit: null,
38587
38588    
38589    snapToUnits: true,
38590
38591    
38592    stackingEnabled: false,
38593
38594    
38595    calculateByLabelSize: true
38596
38597});
38598
38599
38600Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
38601    type: "category",
38602
38603    
38604    categoryNames: null,
38605
38606    
38607    calculateCategoryCount: false
38608
38609});
38610
38611
38612Ext.chart.Series = function(config) { Ext.apply(this, config); };
38613
38614Ext.chart.Series.prototype =
38615{
38616    
38617    type: null,
38618
38619    
38620    displayName: null
38621};
38622
38623
38624Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
38625    
38626    xField: null,
38627
38628    
38629    yField: null,
38630
38631    
38632    showInLegend: true,
38633
38634    
38635    axis: 'primary'
38636});
38637
38638
38639Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
38640    type: "column"
38641});
38642
38643
38644Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
38645    type: "line"
38646});
38647
38648
38649Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
38650    type: "bar"
38651});
38652
38653
38654
38655Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
38656    type: "pie",
38657    dataField: null,
38658    categoryField: null
38659});
38660Ext.menu.Menu = Ext.extend(Ext.Container, {
38661    
38662    
38663    
38664    minWidth : 120,
38665    
38666    shadow : 'sides',
38667    
38668    subMenuAlign : 'tl-tr?',
38669    
38670    defaultAlign : 'tl-bl?',
38671    
38672    allowOtherMenus : false,
38673    
38674    ignoreParentClicks : false,
38675    
38676    enableScrolling : true,
38677    
38678    maxHeight : null,
38679    
38680    scrollIncrement : 24,
38681    
38682    showSeparator : true,
38683    
38684    defaultOffsets : [0, 0],
38685
38686    
38687    plain : false,
38688
38689    
38690    floating : true,
38691
38692
38693    
38694    zIndex: 15000,
38695
38696    
38697    hidden : true,
38698
38699    
38700    layout : 'menu',
38701    hideMode : 'offsets',    
38702    scrollerHeight : 8,
38703    autoLayout : true,       
38704    defaultType : 'menuitem',
38705    bufferResize : false,
38706
38707    initComponent : function(){
38708        if(Ext.isArray(this.initialConfig)){
38709            Ext.apply(this, {items:this.initialConfig});
38710        }
38711        this.addEvents(
38712            
38713            'click',
38714            
38715            'mouseover',
38716            
38717            'mouseout',
38718            
38719            'itemclick'
38720        );
38721        Ext.menu.MenuMgr.register(this);
38722        if(this.floating){
38723            Ext.EventManager.onWindowResize(this.hide, this);
38724        }else{
38725            if(this.initialConfig.hidden !== false){
38726                this.hidden = false;
38727            }
38728            this.internalDefaults = {hideOnClick: false};
38729        }
38730        Ext.menu.Menu.superclass.initComponent.call(this);
38731        if(this.autoLayout){
38732            var fn = this.doLayout.createDelegate(this, []);
38733            this.on({
38734                add: fn,
38735                remove: fn
38736            });
38737        }
38738    },
38739
38740    
38741    getLayoutTarget : function() {
38742        return this.ul;
38743    },
38744
38745    
38746    onRender : function(ct, position){
38747        if(!ct){
38748            ct = Ext.getBody();
38749        }
38750
38751        var dh = {
38752            id: this.getId(),
38753            cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
38754            style: this.style,
38755            cn: [
38756                {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
38757                {tag: 'ul', cls: 'x-menu-list'}
38758            ]
38759        };
38760        if(this.floating){
38761            this.el = new Ext.Layer({
38762                shadow: this.shadow,
38763                dh: dh,
38764                constrain: false,
38765                parentEl: ct,
38766                zindex: this.zIndex
38767            });
38768        }else{
38769            this.el = ct.createChild(dh);
38770        }
38771        Ext.menu.Menu.superclass.onRender.call(this, ct, position);
38772
38773        if(!this.keyNav){
38774            this.keyNav = new Ext.menu.MenuNav(this);
38775        }
38776        
38777        this.focusEl = this.el.child('a.x-menu-focus');
38778        this.ul = this.el.child('ul.x-menu-list');
38779        this.mon(this.ul, {
38780            scope: this,
38781            click: this.onClick,
38782            mouseover: this.onMouseOver,
38783            mouseout: this.onMouseOut
38784        });
38785        if(this.enableScrolling){
38786            this.mon(this.el, {
38787                scope: this,
38788                delegate: '.x-menu-scroller',
38789                click: this.onScroll,
38790                mouseover: this.deactivateActive
38791            });
38792        }
38793    },
38794
38795    
38796    findTargetItem : function(e){
38797        var t = e.getTarget('.x-menu-list-item', this.ul, true);
38798        if(t && t.menuItemId){
38799            return this.items.get(t.menuItemId);
38800        }
38801    },
38802
38803    
38804    onClick : function(e){
38805        var t = this.findTargetItem(e);
38806        if(t){
38807            if(t.isFormField){
38808                this.setActiveItem(t);
38809            }else if(t instanceof Ext.menu.BaseItem){
38810                if(t.menu && this.ignoreParentClicks){
38811                    t.expandMenu();
38812                    e.preventDefault();
38813                }else if(t.onClick){
38814                    t.onClick(e);
38815                    this.fireEvent('click', this, t, e);
38816                }
38817            }
38818        }
38819    },
38820
38821    
38822    setActiveItem : function(item, autoExpand){
38823        if(item != this.activeItem){
38824            this.deactivateActive();
38825            if((this.activeItem = item).isFormField){
38826                item.focus();
38827            }else{
38828                item.activate(autoExpand);
38829            }
38830        }else if(autoExpand){
38831            item.expandMenu();
38832        }
38833    },
38834
38835    deactivateActive : function(){
38836        var a = this.activeItem;
38837        if(a){
38838            if(a.isFormField){
38839                
38840                if(a.collapse){
38841                    a.collapse();
38842                }
38843            }else{
38844                a.deactivate();
38845            }
38846            delete this.activeItem;
38847        }
38848    },
38849
38850    
38851    tryActivate : function(start, step){
38852        var items = this.items;
38853        for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
38854            var item = items.get(i);
38855            if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
38856                this.setActiveItem(item, false);
38857                return item;
38858            }
38859        }
38860        return false;
38861    },
38862
38863    
38864    onMouseOver : function(e){
38865        var t = this.findTargetItem(e);
38866        if(t){
38867            if(t.canActivate && !t.disabled){
38868                this.setActiveItem(t, true);
38869            }
38870        }
38871        this.over = true;
38872        this.fireEvent('mouseover', this, e, t);
38873    },
38874
38875    
38876    onMouseOut : function(e){
38877        var t = this.findTargetItem(e);
38878        if(t){
38879            if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
38880                this.activeItem.deactivate();
38881                delete this.activeItem;
38882            }
38883        }
38884        this.over = false;
38885        this.fireEvent('mouseout', this, e, t);
38886    },
38887
38888    
38889    onScroll : function(e, t){
38890        if(e){
38891            e.stopEvent();
38892        }
38893        var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38894        ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
38895        if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
38896           this.onScrollerOut(null, t);
38897        }
38898    },
38899
38900    
38901    onScrollerIn : function(e, t){
38902        var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38903        if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
38904            Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
38905        }
38906    },
38907
38908    
38909    onScrollerOut : function(e, t){
38910        Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
38911    },
38912
38913    
38914    show : function(el, pos, parentMenu){
38915        if(this.floating){
38916            this.parentMenu = parentMenu;
38917            if(!this.el){
38918                this.render();
38919                this.doLayout(false, true);
38920            }
38921            this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
38922        }else{
38923            Ext.menu.Menu.superclass.show.call(this);
38924        }
38925    },
38926
38927    
38928    showAt : function(xy, parentMenu){
38929        if(this.fireEvent('beforeshow', this) !== false){
38930            this.parentMenu = parentMenu;
38931            if(!this.el){
38932                this.render();
38933            }
38934            if(this.enableScrolling){
38935                
38936                this.el.setXY(xy);
38937                
38938                xy[1] = this.constrainScroll(xy[1]);
38939                xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
38940            }else{
38941                
38942                xy = this.el.adjustForConstraints(xy);
38943            }
38944            this.el.setXY(xy);
38945            this.el.show();
38946            Ext.menu.Menu.superclass.onShow.call(this);
38947            if(Ext.isIE){
38948                
38949                this.fireEvent('autosize', this);
38950                if(!Ext.isIE8){
38951                    this.el.repaint();
38952                }
38953            }
38954            this.hidden = false;
38955            this.focus();
38956            this.fireEvent('show', this);
38957        }
38958    },
38959
38960    constrainScroll : function(y){
38961        var max, full = this.ul.setHeight('auto').getHeight(),
38962            returnY = y, normalY, parentEl, scrollTop, viewHeight;
38963        if(this.floating){
38964            parentEl = Ext.fly(this.el.dom.parentNode);
38965            scrollTop = parentEl.getScroll().top;
38966            viewHeight = parentEl.getViewSize().height;
38967            
38968            
38969            normalY = y - scrollTop;
38970            max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
38971            if(full > viewHeight) {
38972                max = viewHeight;
38973                
38974                returnY = y - normalY;
38975            } else if(max < full) {
38976                returnY = y - (full - max);
38977                max = full;
38978            }
38979        }else{
38980            max = this.getHeight();
38981        }
38982        
38983        if (this.maxHeight){
38984            max = Math.min(this.maxHeight, max);
38985        }
38986        if(full > max && max > 0){
38987            this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
38988            this.ul.setHeight(this.activeMax);
38989            this.createScrollers();
38990            this.el.select('.x-menu-scroller').setDisplayed('');
38991        }else{
38992            this.ul.setHeight(full);
38993            this.el.select('.x-menu-scroller').setDisplayed('none');
38994        }
38995        this.ul.dom.scrollTop = 0;
38996        return returnY;
38997    },
38998
38999    createScrollers : function(){
39000        if(!this.scroller){
39001            this.scroller = {
39002                pos: 0,
39003                top: this.el.insertFirst({
39004                    tag: 'div',
39005                    cls: 'x-menu-scroller x-menu-scroller-top',
39006                    html: '&#160;'
39007                }),
39008                bottom: this.el.createChild({
39009                    tag: 'div',
39010                    cls: 'x-menu-scroller x-menu-scroller-bottom',
39011                    html: '&#160;'
39012                })
39013            };
39014            this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
39015            this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
39016                listeners: {
39017                    click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
39018                }
39019            });
39020            this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
39021            this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
39022                listeners: {
39023                    click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
39024                }
39025            });
39026        }
39027    },
39028
39029    onLayout : function(){
39030        if(this.isVisible()){
39031            if(this.enableScrolling){
39032                this.constrainScroll(this.el.getTop());
39033            }
39034            if(this.floating){
39035                this.el.sync();
39036            }
39037        }
39038    },
39039
39040    focus : function(){
39041        if(!this.hidden){
39042            this.doFocus.defer(50, this);
39043        }
39044    },
39045
39046    doFocus : function(){
39047        if(!this.hidden){
39048            this.focusEl.focus();
39049        }
39050    },
39051
39052    
39053    hide : function(deep){
39054        if (!this.isDestroyed) {
39055            this.deepHide = deep;
39056            Ext.menu.Menu.superclass.hide.call(this);
39057            delete this.deepHide;
39058        }
39059    },
39060
39061    
39062    onHide : function(){
39063        Ext.menu.Menu.superclass.onHide.call(this);
39064        this.deactivateActive();
39065        if(this.el && this.floating){
39066            this.el.hide();
39067        }
39068        var pm = this.parentMenu;
39069        if(this.deepHide === true && pm){
39070            if(pm.floating){
39071                pm.hide(true);
39072            }else{
39073                pm.deactivateActive();
39074            }
39075        }
39076    },
39077
39078    
39079    lookupComponent : function(c){
39080         if(Ext.isString(c)){
39081            c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
39082             this.applyDefaults(c);
39083         }else{
39084            if(Ext.isObject(c)){
39085                c = this.getMenuItem(c);
39086            }else if(c.tagName || c.el){ 
39087                c = new Ext.BoxComponent({
39088                    el: c
39089                });
39090            }
39091         }
39092         return c;
39093    },
39094
39095    applyDefaults : function(c) {
39096        if (!Ext.isString(c)) {
39097            c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
39098            var d = this.internalDefaults;
39099            if(d){
39100                if(c.events){
39101                    Ext.applyIf(c.initialConfig, d);
39102                    Ext.apply(c, d);
39103                }else{
39104                    Ext.applyIf(c, d);
39105                }
39106            }
39107        }
39108        return c;
39109    },
39110
39111    
39112    getMenuItem : function(config) {
39113        config.ownerCt = this;
39114        
39115        if (!config.isXType) {
39116            if (!config.xtype && Ext.isBoolean(config.checked)) {
39117                return new Ext.menu.CheckItem(config);
39118            }
39119            return Ext.create(config, this.defaultType);
39120        }
39121        return config;
39122    },
39123
39124    
39125    addSeparator : function() {
39126        return this.add(new Ext.menu.Separator());
39127    },
39128
39129    
39130    addElement : function(el) {
39131        return this.add(new Ext.menu.BaseItem({
39132            el: el
39133        }));
39134    },
39135
39136    
39137    addItem : function(item) {
39138        return this.add(item);
39139    },
39140
39141    
39142    addMenuItem : function(config) {
39143        return this.add(this.getMenuItem(config));
39144    },
39145
39146    
39147    addText : function(text){
39148        return this.add(new Ext.menu.TextItem(text));
39149    },
39150
39151    
39152    onDestroy : function(){
39153        Ext.EventManager.removeResizeListener(this.hide, this);
39154        var pm = this.parentMenu;
39155        if(pm && pm.activeChild == this){
39156            delete pm.activeChild;
39157        }
39158        delete this.parentMenu;
39159        Ext.menu.Menu.superclass.onDestroy.call(this);
39160        Ext.menu.MenuMgr.unregister(this);
39161        if(this.keyNav) {
39162            this.keyNav.disable();
39163        }
39164        var s = this.scroller;
39165        if(s){
39166            Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
39167        }
39168        Ext.destroy(
39169            this.el,
39170            this.focusEl,
39171            this.ul
39172        );
39173    }
39174});
39175
39176Ext.reg('menu', Ext.menu.Menu);
39177
39178
39179Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
39180    function up(e, m){
39181        if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
39182            m.tryActivate(m.items.length-1, -1);
39183        }
39184    }
39185    function down(e, m){
39186        if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
39187            m.tryActivate(0, 1);
39188        }
39189    }
39190    return {
39191        constructor : function(menu){
39192            Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
39193            this.scope = this.menu = menu;
39194        },
39195
39196        doRelay : function(e, h){
39197            var k = e.getKey();
39198
39199            if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
39200                return false;
39201            }
39202            if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
39203                this.menu.tryActivate(0, 1);
39204                return false;
39205            }
39206            return h.call(this.scope || this, e, this.menu);
39207        },
39208
39209        tab: function(e, m) {
39210            e.stopEvent();
39211            if (e.shiftKey) {
39212                up(e, m);
39213            } else {
39214                down(e, m);
39215            }
39216        },
39217
39218        up : up,
39219
39220        down : down,
39221
39222        right : function(e, m){
39223            if(m.activeItem){
39224                m.activeItem.expandMenu(true);
39225            }
39226        },
39227
39228        left : function(e, m){
39229            m.hide();
39230            if(m.parentMenu && m.parentMenu.activeItem){
39231                m.parentMenu.activeItem.activate();
39232            }
39233        },
39234
39235        enter : function(e, m){
39236            if(m.activeItem){
39237                e.stopPropagation();
39238                m.activeItem.onClick(e);
39239                m.fireEvent('click', this, m.activeItem);
39240                return true;
39241            }
39242        }
39243    };
39244}());
39245
39246Ext.menu.MenuMgr = function(){
39247   var menus, 
39248       active, 
39249       map,
39250       groups = {}, 
39251       attached = false, 
39252       lastShow = new Date();
39253   
39254
39255   
39256   function init(){
39257       menus = {};
39258       active = new Ext.util.MixedCollection();
39259       map = Ext.getDoc().addKeyListener(27, hideAll);
39260       map.disable();
39261   }
39262
39263   
39264   function hideAll(){
39265       if(active && active.length > 0){
39266           var c = active.clone();
39267           c.each(function(m){
39268               m.hide();
39269           });
39270           return true;
39271       }
39272       return false;
39273   }
39274
39275   
39276   function onHide(m){
39277       active.remove(m);
39278       if(active.length < 1){
39279           map.disable();
39280           Ext.getDoc().un("mousedown", onMouseDown);
39281           attached = false;
39282       }
39283   }
39284
39285   
39286   function onShow(m){
39287       var last = active.last();
39288       lastShow = new Date();
39289       active.add(m);
39290       if(!attached){
39291           map.enable();
39292           Ext.getDoc().on("mousedown", onMouseDown);
39293           attached = true;
39294       }
39295       if(m.parentMenu){
39296          m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
39297          m.parentMenu.activeChild = m;
39298       }else if(last && !last.isDestroyed && last.isVisible()){
39299          m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
39300       }
39301   }
39302
39303   
39304   function onBeforeHide(m){
39305       if(m.activeChild){
39306           m.activeChild.hide();
39307       }
39308       if(m.autoHideTimer){
39309           clearTimeout(m.autoHideTimer);
39310           delete m.autoHideTimer;
39311       }
39312   }
39313
39314   
39315   function onBeforeShow(m){
39316       var pm = m.parentMenu;
39317       if(!pm && !m.allowOtherMenus){
39318           hideAll();
39319       }else if(pm && pm.activeChild){
39320           pm.activeChild.hide();
39321       }
39322   }
39323
39324   
39325   function onMouseDown(e){
39326       if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
39327           hideAll();
39328       }
39329   }
39330
39331   return {
39332
39333       
39334       hideAll : function(){
39335            return hideAll();
39336       },
39337
39338       
39339       register : function(menu){
39340           if(!menus){
39341               init();
39342           }
39343           menus[menu.id] = menu;
39344           menu.on({
39345               beforehide: onBeforeHide,
39346               hide: onHide,
39347               beforeshow: onBeforeShow,
39348               show: onShow
39349           });
39350       },
39351
39352        
39353       get : function(menu){
39354           if(typeof menu == "string"){ 
39355               if(!menus){  
39356                   return null;
39357               }
39358               return menus[menu];
39359           }else if(menu.events){  
39360               return menu;
39361           }else if(typeof menu.length == 'number'){ 
39362               return new Ext.menu.Menu({items:menu});
39363           }else{ 
39364               return Ext.create(menu, 'menu');
39365           }
39366       },
39367
39368       
39369       unregister : function(menu){
39370           delete menus[menu.id];
39371           menu.un("beforehide", onBeforeHide);
39372           menu.un("hide", onHide);
39373           menu.un("beforeshow", onBeforeShow);
39374           menu.un("show", onShow);
39375       },
39376
39377       
39378       registerCheckable : function(menuItem){
39379           var g = menuItem.group;
39380           if(g){
39381               if(!groups[g]){
39382                   groups[g] = [];
39383               }
39384               groups[g].push(menuItem);
39385           }
39386       },
39387
39388       
39389       unregisterCheckable : function(menuItem){
39390           var g = menuItem.group;
39391           if(g){
39392               groups[g].remove(menuItem);
39393           }
39394       },
39395       
39396       
39397       onCheckChange: function(item, state){
39398           if(item.group && state){
39399               var group = groups[item.group],
39400                   i = 0,
39401                   len = group.length,
39402                   current;
39403                   
39404               for(; i < len; i++){
39405                   current = group[i];
39406                   if(current != item){
39407                       current.setChecked(false);
39408                   }
39409               }
39410           }
39411       },
39412
39413       getCheckedItem : function(groupId){
39414           var g = groups[groupId];
39415           if(g){
39416               for(var i = 0, l = g.length; i < l; i++){
39417                   if(g[i].checked){
39418                       return g[i];
39419                   }
39420               }
39421           }
39422           return null;
39423       },
39424
39425       setCheckedItem : function(groupId, itemId){
39426           var g = groups[groupId];
39427           if(g){
39428               for(var i = 0, l = g.length; i < l; i++){
39429                   if(g[i].id == itemId){
39430                       g[i].setChecked(true);
39431                   }
39432               }
39433           }
39434           return null;
39435       }
39436   };
39437}();
39438
39439Ext.menu.BaseItem = Ext.extend(Ext.Component, {
39440    
39441    
39442    
39443    
39444    canActivate : false,
39445    
39446    activeClass : "x-menu-item-active",
39447    
39448    hideOnClick : true,
39449    
39450    clickHideDelay : 1,
39451
39452    
39453    ctype : "Ext.menu.BaseItem",
39454
39455    
39456    actionMode : "container",
39457
39458    initComponent : function(){
39459        Ext.menu.BaseItem.superclass.initComponent.call(this);
39460        this.addEvents(
39461            
39462            'click',
39463            
39464            'activate',
39465            
39466            'deactivate'
39467        );
39468        if(this.handler){
39469            this.on("click", this.handler, this.scope);
39470        }
39471    },
39472
39473    
39474    onRender : function(container, position){
39475        Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
39476        if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
39477            this.parentMenu = this.ownerCt;
39478        }else{
39479            this.container.addClass('x-menu-list-item');
39480            this.mon(this.el, {
39481                scope: this,
39482                click: this.onClick,
39483                mouseenter: this.activate,
39484                mouseleave: this.deactivate
39485            });
39486        }
39487    },
39488
39489    
39490    setHandler : function(handler, scope){
39491        if(this.handler){
39492            this.un("click", this.handler, this.scope);
39493        }
39494        this.on("click", this.handler = handler, this.scope = scope);
39495    },
39496
39497    
39498    onClick : function(e){
39499        if(!this.disabled && this.fireEvent("click", this, e) !== false
39500                && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
39501            this.handleClick(e);
39502        }else{
39503            e.stopEvent();
39504        }
39505    },
39506
39507    
39508    activate : function(){
39509        if(this.disabled){
39510            return false;
39511        }
39512        var li = this.container;
39513        li.addClass(this.activeClass);
39514        this.region = li.getRegion().adjust(2, 2, -2, -2);
39515        this.fireEvent("activate", this);
39516        return true;
39517    },
39518
39519    
39520    deactivate : function(){
39521        this.container.removeClass(this.activeClass);
39522        this.fireEvent("deactivate", this);
39523    },
39524
39525    
39526    shouldDeactivate : function(e){
39527        return !this.region || !this.region.contains(e.getPoint());
39528    },
39529
39530    
39531    handleClick : function(e){
39532        var pm = this.parentMenu;
39533        if(this.hideOnClick){
39534            if(pm.floating){
39535                this.clickHideDelayTimer = pm.hide.defer(this.clickHideDelay, pm, [true]);
39536            }else{
39537                pm.deactivateActive();
39538            }
39539        }
39540    },
39541    
39542    beforeDestroy: function(){
39543        clearTimeout(this.clickHideDelayTimer);
39544        Ext.menu.BaseItem.superclass.beforeDestroy.call(this);    
39545    },
39546
39547    
39548    expandMenu : Ext.emptyFn,
39549
39550    
39551    hideMenu : Ext.emptyFn
39552});
39553Ext.reg('menubaseitem', Ext.menu.BaseItem);
39554Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
39555    
39556    
39557    hideOnClick : false,
39558    
39559    itemCls : "x-menu-text",
39560    
39561    constructor : function(config) {
39562        if (typeof config == 'string') {
39563            config = {
39564                text: config
39565            };
39566        }
39567        Ext.menu.TextItem.superclass.constructor.call(this, config);
39568    },
39569
39570    
39571    onRender : function() {
39572        var s = document.createElement("span");
39573        s.className = this.itemCls;
39574        s.innerHTML = this.text;
39575        this.el = s;
39576        Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
39577    }
39578});
39579Ext.reg('menutextitem', Ext.menu.TextItem);
39580Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
39581    
39582    itemCls : "x-menu-sep",
39583    
39584    hideOnClick : false,
39585    
39586    
39587    activeClass: '',
39588
39589    
39590    onRender : function(li){
39591        var s = document.createElement("span");
39592        s.className = this.itemCls;
39593        s.innerHTML = "&#160;";
39594        this.el = s;
39595        li.addClass("x-menu-sep-li");
39596        Ext.menu.Separator.superclass.onRender.apply(this, arguments);
39597    }
39598});
39599Ext.reg('menuseparator', Ext.menu.Separator);
39600Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
39601    
39602    
39603    
39604    
39605    
39606    
39607    
39608    
39609    itemCls : 'x-menu-item',
39610    
39611    canActivate : true,
39612    
39613    showDelay: 200,
39614    
39615    
39616    altText: '',
39617    
39618    
39619    hideDelay: 200,
39620
39621    
39622    ctype: 'Ext.menu.Item',
39623
39624    initComponent : function(){
39625        Ext.menu.Item.superclass.initComponent.call(this);
39626        if(this.menu){
39627            
39628            
39629            if (Ext.isArray(this.menu)){
39630                this.menu = { items: this.menu };
39631            }
39632            
39633            
39634            
39635            if (Ext.isObject(this.menu)){
39636                this.menu.ownerCt = this;
39637            }
39638            
39639            this.menu = Ext.menu.MenuMgr.get(this.menu);
39640            this.menu.ownerCt = undefined;
39641        }
39642    },
39643
39644    
39645    onRender : function(container, position){
39646        if (!this.itemTpl) {
39647            this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
39648                '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
39649                    '<tpl if="hrefTarget">',
39650                        ' target="{hrefTarget}"',
39651                    '</tpl>',
39652                 '>',
39653                     '<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
39654                     '<span class="x-menu-item-text">{text}</span>',
39655                 '</a>'
39656             );
39657        }
39658        var a = this.getTemplateArgs();
39659        this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
39660        this.iconEl = this.el.child('img.x-menu-item-icon');
39661        this.textEl = this.el.child('.x-menu-item-text');
39662        if(!this.href) { 
39663            this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
39664        }
39665        Ext.menu.Item.superclass.onRender.call(this, container, position);
39666    },
39667
39668    getTemplateArgs: function() {
39669        return {
39670            id: this.id,
39671            cls: this.itemCls + (this.menu ?  ' x-menu-item-arrow' : '') + (this.cls ?  ' ' + this.cls : ''),
39672            href: this.href || '#',
39673            hrefTarget: this.hrefTarget,
39674            icon: this.icon || Ext.BLANK_IMAGE_URL,
39675            iconCls: this.iconCls || '',
39676            text: this.itemText||this.text||'&#160;',
39677            altText: this.altText || ''
39678        };
39679    },
39680
39681    
39682    setText : function(text){
39683        this.text = text||'&#160;';
39684        if(this.rendered){
39685            this.textEl.update(this.text);
39686            this.parentMenu.layout.doAutoSize();
39687        }
39688    },
39689
39690    
39691    setIconClass : function(cls){
39692        var oldCls = this.iconCls;
39693        this.iconCls = cls;
39694        if(this.rendered){
39695            this.iconEl.replaceClass(oldCls, this.iconCls);
39696        }
39697    },
39698
39699    
39700    beforeDestroy: function(){
39701        clearTimeout(this.showTimer);
39702        clearTimeout(this.hideTimer);
39703        if (this.menu){
39704            delete this.menu.ownerCt;
39705            this.menu.destroy();
39706        }
39707        Ext.menu.Item.superclass.beforeDestroy.call(this);
39708    },
39709
39710    
39711    handleClick : function(e){
39712        if(!this.href){ 
39713            e.stopEvent();
39714        }
39715        Ext.menu.Item.superclass.handleClick.apply(this, arguments);
39716    },
39717
39718    
39719    activate : function(autoExpand){
39720        if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
39721            this.focus();
39722            if(autoExpand){
39723                this.expandMenu();
39724            }
39725        }
39726        return true;
39727    },
39728
39729    
39730    shouldDeactivate : function(e){
39731        if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
39732            if(this.menu && this.menu.isVisible()){
39733                return !this.menu.getEl().getRegion().contains(e.getPoint());
39734            }
39735            return true;
39736        }
39737        return false;
39738    },
39739
39740    
39741    deactivate : function(){
39742        Ext.menu.Item.superclass.deactivate.apply(this, arguments);
39743        this.hideMenu();
39744    },
39745
39746    
39747    expandMenu : function(autoActivate){
39748        if(!this.disabled && this.menu){
39749            clearTimeout(this.hideTimer);
39750            delete this.hideTimer;
39751            if(!this.menu.isVisible() && !this.showTimer){
39752                this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
39753            }else if (this.menu.isVisible() && autoActivate){
39754                this.menu.tryActivate(0, 1);
39755            }
39756        }
39757    },
39758
39759    
39760    deferExpand : function(autoActivate){
39761        delete this.showTimer;
39762        this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
39763        if(autoActivate){
39764            this.menu.tryActivate(0, 1);
39765        }
39766    },
39767
39768    
39769    hideMenu : function(){
39770        clearTimeout(this.showTimer);
39771        delete this.showTimer;
39772        if(!this.hideTimer && this.menu && this.menu.isVisible()){
39773            this.hideTimer = this.deferHide.defer(this.hideDelay, this);
39774        }
39775    },
39776
39777    
39778    deferHide : function(){
39779        delete this.hideTimer;
39780        if(this.menu.over){
39781            this.parentMenu.setActiveItem(this, false);
39782        }else{
39783            this.menu.hide();
39784        }
39785    }
39786});
39787Ext.reg('menuitem', Ext.menu.Item);
39788Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
39789    
39790    
39791    itemCls : "x-menu-item x-menu-check-item",
39792    
39793    groupClass : "x-menu-group-item",
39794
39795    
39796    checked: false,
39797
39798    
39799    ctype: "Ext.menu.CheckItem",
39800    
39801    initComponent : function(){
39802        Ext.menu.CheckItem.superclass.initComponent.call(this);
39803	    this.addEvents(
39804	        
39805	        "beforecheckchange" ,
39806	        
39807	        "checkchange"
39808	    );
39809	    
39810	    if(this.checkHandler){
39811	        this.on('checkchange', this.checkHandler, this.scope);
39812	    }
39813	    Ext.menu.MenuMgr.registerCheckable(this);
39814    },
39815
39816    
39817    onRender : function(c){
39818        Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
39819        if(this.group){
39820            this.el.addClass(this.groupClass);
39821        }
39822        if(this.checked){
39823            this.checked = false;
39824            this.setChecked(true, true);
39825        }
39826    },
39827
39828    
39829    destroy : function(){
39830        Ext.menu.MenuMgr.unregisterCheckable(this);
39831        Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
39832    },
39833
39834    
39835    setChecked : function(state, suppressEvent){
39836        var suppress = suppressEvent === true;
39837        if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
39838            Ext.menu.MenuMgr.onCheckChange(this, state);
39839            if(this.container){
39840                this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
39841            }
39842            this.checked = state;
39843            if(!suppress){
39844                this.fireEvent("checkchange", this, state);
39845            }
39846        }
39847    },
39848
39849    
39850    handleClick : function(e){
39851       if(!this.disabled && !(this.checked && this.group)){
39852           this.setChecked(!this.checked);
39853       }
39854       Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
39855    }
39856});
39857Ext.reg('menucheckitem', Ext.menu.CheckItem);
39858 Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
39859    
39860    enableScrolling : false,
39861    
39862        
39863    
39864    hideOnClick : true,
39865    
39866    
39867    pickerId : null,
39868    
39869    
39870    
39871    
39872    cls : 'x-date-menu',
39873    
39874    
39875    
39876    
39877
39878    initComponent : function(){
39879        this.on('beforeshow', this.onBeforeShow, this);
39880        if(this.strict = (Ext.isIE7 && Ext.isStrict)){
39881            this.on('show', this.onShow, this, {single: true, delay: 20});
39882        }
39883        Ext.apply(this, {
39884            plain: true,
39885            showSeparator: false,
39886            items: this.picker = new Ext.DatePicker(Ext.applyIf({
39887                internalRender: this.strict || !Ext.isIE,
39888                ctCls: 'x-menu-date-item',
39889                id: this.pickerId
39890            }, this.initialConfig))
39891        });
39892        this.picker.purgeListeners();
39893        Ext.menu.DateMenu.superclass.initComponent.call(this);
39894        
39895        this.relayEvents(this.picker, ['select']);
39896        this.on('show', this.picker.focus, this.picker);
39897        this.on('select', this.menuHide, this);
39898        if(this.handler){
39899            this.on('select', this.handler, this.scope || this);
39900        }
39901    },
39902
39903    menuHide : function() {
39904        if(this.hideOnClick){
39905            this.hide(true);
39906        }
39907    },
39908
39909    onBeforeShow : function(){
39910        if(this.picker){
39911            this.picker.hideMonthPicker(true);
39912        }
39913    },
39914
39915    onShow : function(){
39916        var el = this.picker.getEl();
39917        el.setWidth(el.getWidth()); 
39918    }
39919 });
39920 Ext.reg('datemenu', Ext.menu.DateMenu);
39921 
39922 Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
39923    
39924    enableScrolling : false,
39925    
39926        
39927    
39928    
39929    hideOnClick : true,
39930    
39931    cls : 'x-color-menu',
39932    
39933    
39934    paletteId : null,
39935    
39936    
39937    
39938    
39939    
39940    
39941    
39942    
39943    
39944    
39945    initComponent : function(){
39946        Ext.apply(this, {
39947            plain: true,
39948            showSeparator: false,
39949            items: this.palette = new Ext.ColorPalette(Ext.applyIf({
39950                id: this.paletteId
39951            }, this.initialConfig))
39952        });
39953        this.palette.purgeListeners();
39954        Ext.menu.ColorMenu.superclass.initComponent.call(this);
39955        
39956        this.relayEvents(this.palette, ['select']);
39957        this.on('select', this.menuHide, this);
39958        if(this.handler){
39959            this.on('select', this.handler, this.scope || this);
39960        }
39961    },
39962
39963    menuHide : function(){
39964        if(this.hideOnClick){
39965            this.hide(true);
39966        }
39967    }
39968});
39969Ext.reg('colormenu', Ext.menu.ColorMenu);
39970
39971Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
39972    
39973    
39974    
39975    
39976    
39977    
39978
39979    
39980    invalidClass : 'x-form-invalid',
39981    
39982    invalidText : 'The value in this field is invalid',
39983    
39984    focusClass : 'x-form-focus',
39985    
39986    
39987    validationEvent : 'keyup',
39988    
39989    validateOnBlur : true,
39990    
39991    validationDelay : 250,
39992    
39993    defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
39994    
39995    fieldClass : 'x-form-field',
39996    
39997    msgTarget : 'qtip',
39998    
39999    msgFx : 'normal',
40000    
40001    readOnly : false,
40002    
40003    disabled : false,
40004    
40005    submitValue: true,
40006
40007    
40008    isFormField : true,
40009
40010    
40011    msgDisplay: '',
40012
40013    
40014    hasFocus : false,
40015
40016    
40017    initComponent : function(){
40018        Ext.form.Field.superclass.initComponent.call(this);
40019        this.addEvents(
40020            
40021            'focus',
40022            
40023            'blur',
40024            
40025            'specialkey',
40026            
40027            'change',
40028            
40029            'invalid',
40030            
40031            'valid'
40032        );
40033    },
40034
40035    
40036    getName : function(){
40037        return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
40038    },
40039
40040    
40041    onRender : function(ct, position){
40042        if(!this.el){
40043            var cfg = this.getAutoCreate();
40044
40045            if(!cfg.name){
40046                cfg.name = this.name || this.id;
40047            }
40048            if(this.inputType){
40049                cfg.type = this.inputType;
40050            }
40051            this.autoEl = cfg;
40052        }
40053        Ext.form.Field.superclass.onRender.call(this, ct, position);
40054        if(this.submitValue === false){
40055            this.el.dom.removeAttribute('name');
40056        }
40057        var type = this.el.dom.type;
40058        if(type){
40059            if(type == 'password'){
40060                type = 'text';
40061            }
40062            this.el.addClass('x-form-'+type);
40063        }
40064        if(this.readOnly){
40065            this.setReadOnly(true);
40066        }
40067        if(this.tabIndex !== undefined){
40068            this.el.dom.setAttribute('tabIndex', this.tabIndex);
40069        }
40070
40071        this.el.addClass([this.fieldClass, this.cls]);
40072    },
40073
40074    
40075    getItemCt : function(){
40076        return this.itemCt;
40077    },
40078
40079    
40080    initValue : function(){
40081        if(this.value !== undefined){
40082            this.setValue(this.value);
40083        }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
40084            this.setValue(this.el.dom.value);
40085        }
40086        
40087        this.originalValue = this.getValue();
40088    },
40089
40090    
40091    isDirty : function() {
40092        if(this.disabled || !this.rendered) {
40093            return false;
40094        }
40095        return String(this.getValue()) !== String(this.originalValue);
40096    },
40097
40098    
40099    setReadOnly : function(readOnly){
40100        if(this.rendered){
40101            this.el.dom.readOnly = readOnly;
40102        }
40103        this.readOnly = readOnly;
40104    },
40105
40106    
40107    afterRender : function(){
40108        Ext.form.Field.superclass.afterRender.call(this);
40109        this.initEvents();
40110        this.initValue();
40111    },
40112
40113    
40114    fireKey : function(e){
40115        if(e.isSpecialKey()){
40116            this.fireEvent('specialkey', this, e);
40117        }
40118    },
40119
40120    
40121    reset : function(){
40122        this.setValue(this.originalValue);
40123        this.clearInvalid();
40124    },
40125
40126    
40127    initEvents : function(){
40128        this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey,  this);
40129        this.mon(this.el, 'focus', this.onFocus, this);
40130
40131        
40132        
40133        this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
40134    },
40135
40136    
40137    preFocus: Ext.emptyFn,
40138
40139    
40140    onFocus : function(){
40141        this.preFocus();
40142        if(this.focusClass){
40143            this.el.addClass(this.focusClass);
40144        }
40145        if(!this.hasFocus){
40146            this.hasFocus = true;
40147            
40148            this.startValue = this.getValue();
40149            this.fireEvent('focus', this);
40150        }
40151    },
40152
40153    
40154    beforeBlur : Ext.emptyFn,
40155
40156    
40157    onBlur : function(){
40158        this.beforeBlur();
40159        if(this.focusClass){
40160            this.el.removeClass(this.focusClass);
40161        }
40162        this.hasFocus = false;
40163        if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
40164            this.validate();
40165        }
40166        var v = this.getValue();
40167        if(String(v) !== String(this.startValue)){
40168            this.fireEvent('change', this, v, this.startValue);
40169        }
40170        this.fireEvent('blur', this);
40171        this.postBlur();
40172    },
40173
40174    
40175    postBlur : Ext.emptyFn,
40176
40177    
40178    isValid : function(preventMark){
40179        if(this.disabled){
40180            return true;
40181        }
40182        var restore = this.preventMark;
40183        this.preventMark = preventMark === true;
40184        var v = this.validateValue(this.processValue(this.getRawValue()), preventMark);
40185        this.preventMark = restore;
40186        return v;
40187    },
40188
40189    
40190    validate : function(){
40191        if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
40192            this.clearInvalid();
40193            return true;
40194        }
40195        return false;
40196    },
40197
40198    
40199    processValue : function(value){
40200        return value;
40201    },
40202
40203    
40204     validateValue : function(value) {
40205         
40206         var error = this.getErrors(value)[0];
40207
40208         if (error == undefined) {
40209             return true;
40210         } else {
40211             this.markInvalid(error);
40212             return false;
40213         }
40214     },
40215    
40216    
40217    getErrors: function() {
40218        return [];
40219    },
40220
40221    
40222    getActiveError : function(){
40223        return this.activeError || '';
40224    },
40225
40226    
40227    markInvalid : function(msg){
40228        
40229        if (this.rendered && !this.preventMark) {
40230            msg = msg || this.invalidText;
40231
40232            var mt = this.getMessageHandler();
40233            if(mt){
40234                mt.mark(this, msg);
40235            }else if(this.msgTarget){
40236                this.el.addClass(this.invalidClass);
40237                var t = Ext.getDom(this.msgTarget);
40238                if(t){
40239                    t.innerHTML = msg;
40240                    t.style.display = this.msgDisplay;
40241                }
40242            }
40243        }
40244        
40245        this.setActiveError(msg);
40246    },
40247    
40248    
40249    clearInvalid : function(){
40250        
40251        if (this.rendered && !this.preventMark) {
40252            this.el.removeClass(this.invalidClass);
40253            var mt = this.getMessageHandler();
40254            if(mt){
40255                mt.clear(this);
40256            }else if(this.msgTarget){
40257                this.el.removeClass(this.invalidClass);
40258                var t = Ext.getDom(this.msgTarget);
40259                if(t){
40260                    t.innerHTML = '';
40261                    t.style.display = 'none';
40262                }
40263            }
40264        }
40265        
40266        this.unsetActiveError();
40267    },
40268
40269    
40270    setActiveError: function(msg, suppressEvent) {
40271        this.activeError = msg;
40272        if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
40273    },
40274    
40275    
40276    unsetActiveError: function(suppressEvent) {
40277        delete this.activeError;
40278        if (suppressEvent !== true) this.fireEvent('valid', this);
40279    },
40280
40281    
40282    getMessageHandler : function(){
40283        return Ext.form.MessageTargets[this.msgTarget];
40284    },
40285
40286    
40287    getErrorCt : function(){
40288        return this.el.findParent('.x-form-element', 5, true) || 
40289            this.el.findParent('.x-form-field-wrap', 5, true);   
40290    },
40291
40292    
40293    alignErrorEl : function(){
40294        this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
40295    },
40296
40297    
40298    alignErrorIcon : function(){
40299        this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
40300    },
40301
40302    
40303    getRawValue : function(){
40304        var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
40305        if(v === this.emptyText){
40306            v = '';
40307        }
40308        return v;
40309    },
40310
40311    
40312    getValue : function(){
40313        if(!this.rendered) {
40314            return this.value;
40315        }
40316        var v = this.el.getValue();
40317        if(v === this.emptyText || v === undefined){
40318            v = '';
40319        }
40320        return v;
40321    },
40322
40323    
40324    setRawValue : function(v){
40325        return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
40326    },
40327
40328    
40329    setValue : function(v){
40330        this.value = v;
40331        if(this.rendered){
40332            this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
40333            this.validate();
40334        }
40335        return this;
40336    },
40337
40338    
40339    append : function(v){
40340         this.setValue([this.getValue(), v].join(''));
40341    }
40342
40343    
40344    
40345
40346    
40347});
40348
40349
40350Ext.form.MessageTargets = {
40351    'qtip' : {
40352        mark: function(field, msg){
40353            field.el.addClass(field.invalidClass);
40354            field.el.dom.qtip = msg;
40355            field.el.dom.qclass = 'x-form-invalid-tip';
40356            if(Ext.QuickTips){ 
40357                Ext.QuickTips.enable();
40358            }
40359        },
40360        clear: function(field){
40361            field.el.removeClass(field.invalidClass);
40362            field.el.dom.qtip = '';
40363        }
40364    },
40365    'title' : {
40366        mark: function(field, msg){
40367            field.el.addClass(field.invalidClass);
40368            field.el.dom.title = msg;
40369        },
40370        clear: function(field){
40371            field.el.dom.title = '';
40372        }
40373    },
40374    'under' : {
40375        mark: function(field, msg){
40376            field.el.addClass(field.invalidClass);
40377            if(!field.errorEl){
40378                var elp = field.getErrorCt();
40379                if(!elp){ 
40380                    field.el.dom.title = msg;
40381                    return;
40382                }
40383                field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
40384                field.on('resize', field.alignErrorEl, field);
40385                field.on('destroy', function(){
40386                    Ext.destroy(this.errorEl);
40387                }, field);
40388            }
40389            field.alignErrorEl();
40390            field.errorEl.update(msg);
40391            Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
40392        },
40393        clear: function(field){
40394            field.el.removeClass(field.invalidClass);
40395            if(field.errorEl){
40396                Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
40397            }else{
40398                field.el.dom.title = '';
40399            }
40400        }
40401    },
40402    'side' : {
40403        mark: function(field, msg){
40404            field.el.addClass(field.invalidClass);
40405            if(!field.errorIcon){
40406                var elp = field.getErrorCt();
40407                
40408                if(!elp){
40409                    field.el.dom.title = msg;
40410                    return;
40411                }
40412                field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
40413                if (field.ownerCt) {
40414                    field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
40415                    field.ownerCt.on('expand', field.alignErrorIcon, field);
40416                }
40417                field.on('resize', field.alignErrorIcon, field);
40418                field.on('destroy', function(){
40419                    Ext.destroy(this.errorIcon);
40420                }, field);
40421            }
40422            field.alignErrorIcon();
40423            field.errorIcon.dom.qtip = msg;
40424            field.errorIcon.dom.qclass = 'x-form-invalid-tip';
40425            field.errorIcon.show();
40426        },
40427        clear: function(field){
40428            field.el.removeClass(field.invalidClass);
40429            if(field.errorIcon){
40430                field.errorIcon.dom.qtip = '';
40431                field.errorIcon.hide();
40432            }else{
40433                field.el.dom.title = '';
40434            }
40435        }
40436    }
40437};
40438
40439
40440Ext.form.Field.msgFx = {
40441    normal : {
40442        show: function(msgEl, f){
40443            msgEl.setDisplayed('block');
40444        },
40445
40446        hide : function(msgEl, f){
40447            msgEl.setDisplayed(false).update('');
40448        }
40449    },
40450
40451    slide : {
40452        show: function(msgEl, f){
40453            msgEl.slideIn('t', {stopFx:true});
40454        },
40455
40456        hide : function(msgEl, f){
40457            msgEl.slideOut('t', {stopFx:true,useDisplay:true});
40458        }
40459    },
40460
40461    slideRight : {
40462        show: function(msgEl, f){
40463            msgEl.fixDisplay();
40464            msgEl.alignTo(f.el, 'tl-tr');
40465            msgEl.slideIn('l', {stopFx:true});
40466        },
40467
40468        hide : function(msgEl, f){
40469            msgEl.slideOut('l', {stopFx:true,useDisplay:true});
40470        }
40471    }
40472};
40473Ext.reg('field', Ext.form.Field);
40474
40475Ext.form.TextField = Ext.extend(Ext.form.Field,  {
40476    
40477    
40478    
40479    grow : false,
40480    
40481    growMin : 30,
40482    
40483    growMax : 800,
40484    
40485    vtype : null,
40486    
40487    maskRe : null,
40488    
40489    disableKeyFilter : false,
40490    
40491    allowBlank : true,
40492    
40493    minLength : 0,
40494    
40495    maxLength : Number.MAX_VALUE,
40496    
40497    minLengthText : 'The minimum length for this field is {0}',
40498    
40499    maxLengthText : 'The maximum length for this field is {0}',
40500    
40501    selectOnFocus : false,
40502    
40503    blankText : 'This field is required',
40504    
40505    validator : null,
40506    
40507    regex : null,
40508    
40509    regexText : '',
40510    
40511    emptyText : null,
40512    
40513    emptyClass : 'x-form-empty-field',
40514
40515    
40516
40517    initComponent : function(){
40518        Ext.form.TextField.superclass.initComponent.call(this);
40519        this.addEvents(
40520            
40521            'autosize',
40522
40523            
40524            'keydown',
40525            
40526            'keyup',
40527            
40528            'keypress'
40529        );
40530    },
40531
40532    
40533    initEvents : function(){
40534        Ext.form.TextField.superclass.initEvents.call(this);
40535        if(this.validationEvent == 'keyup'){
40536            this.validationTask = new Ext.util.DelayedTask(this.validate, this);
40537            this.mon(this.el, 'keyup', this.filterValidation, this);
40538        }
40539        else if(this.validationEvent !== false && this.validationEvent != 'blur'){
40540        	this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
40541        }
40542        if(this.selectOnFocus || this.emptyText){            
40543            this.mon(this.el, 'mousedown', this.onMouseDown, this);
40544            
40545            if(this.emptyText){
40546                this.applyEmptyText();
40547            }
40548        }
40549        if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
40550        	this.mon(this.el, 'keypress', this.filterKeys, this);
40551        }
40552        if(this.grow){
40553        	this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
40554			this.mon(this.el, 'click', this.autoSize, this);
40555        }
40556        if(this.enableKeyEvents){
40557            this.mon(this.el, {
40558                scope: this,
40559                keyup: this.onKeyUp,
40560                keydown: this.onKeyDown,
40561                keypress: this.onKeyPress
40562            });
40563        }
40564    },
40565    
40566    onMouseDown: function(e){
40567        if(!this.hasFocus){
40568            this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
40569        }
40570    },
40571
40572    processValue : function(value){
40573        if(this.stripCharsRe){
40574            var newValue = value.replace(this.stripCharsRe, '');
40575            if(newValue !== value){
40576                this.setRawValue(newValue);
40577                return newValue;
40578            }
40579        }
40580        return value;
40581    },
40582
40583    filterValidation : function(e){
40584        if(!e.isNavKeyPress()){
40585            this.validationTask.delay(this.validationDelay);
40586        }
40587    },
40588    
40589    
40590    onDisable: function(){
40591        Ext.form.TextField.superclass.onDisable.call(this);
40592        if(Ext.isIE){
40593            this.el.dom.unselectable = 'on';
40594        }
40595    },
40596    
40597    
40598    onEnable: function(){
40599        Ext.form.TextField.superclass.onEnable.call(this);
40600        if(Ext.isIE){
40601            this.el.dom.unselectable = '';
40602        }
40603    },
40604
40605    
40606    onKeyUpBuffered : function(e){
40607        if(this.doAutoSize(e)){
40608            this.autoSize();
40609        }
40610    },
40611    
40612    
40613    doAutoSize : function(e){
40614        return !e.isNavKeyPress();
40615    },
40616
40617    
40618    onKeyUp : function(e){
40619        this.fireEvent('keyup', this, e);
40620    },
40621
40622    
40623    onKeyDown : function(e){
40624        this.fireEvent('keydown', this, e);
40625    },
40626
40627    
40628    onKeyPress : function(e){
40629        this.fireEvent('keypress', this, e);
40630    },
40631
40632    
40633    reset : function(){
40634        Ext.form.TextField.superclass.reset.call(this);
40635        this.applyEmptyText();
40636    },
40637
40638    applyEmptyText : function(){
40639        if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
40640            this.setRawValue(this.emptyText);
40641            this.el.addClass(this.emptyClass);
40642        }
40643    },
40644
40645    
40646    preFocus : function(){
40647        var el = this.el,
40648            isEmpty;
40649        if(this.emptyText){
40650            if(el.dom.value == this.emptyText){
40651                this.setRawValue('');
40652                isEmpty = true;
40653            }
40654            el.removeClass(this.emptyClass);
40655        }
40656        if(this.selectOnFocus || isEmpty){
40657            el.dom.select();
40658        }
40659    },
40660
40661    
40662    postBlur : function(){
40663        this.applyEmptyText();
40664    },
40665
40666    
40667    filterKeys : function(e){
40668        if(e.ctrlKey){
40669            return;
40670        }
40671        var k = e.getKey();
40672        if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
40673            return;
40674        }
40675        var cc = String.fromCharCode(e.getCharCode());
40676        if(!Ext.isGecko && e.isSpecialKey() && !cc){
40677            return;
40678        }
40679        if(!this.maskRe.test(cc)){
40680            e.stopEvent();
40681        }
40682    },
40683
40684    setValue : function(v){
40685        if(this.emptyText && this.el && !Ext.isEmpty(v)){
40686            this.el.removeClass(this.emptyClass);
40687        }
40688        Ext.form.TextField.superclass.setValue.apply(this, arguments);
40689        this.applyEmptyText();
40690        this.autoSize();
40691        return this;
40692    },
40693
40694    
40695    getErrors: function(value) {
40696        var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
40697        
40698        value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());        
40699        
40700        if (Ext.isFunction(this.validator)) {
40701            var msg = this.validator(value);
40702            if (msg !== true) {
40703                errors.push(msg);
40704            }
40705        }
40706        
40707        if (value.length < 1 || value === this.emptyText) {
40708            if (this.allowBlank) {
40709                
40710                return errors;
40711            } else {
40712                errors.push(this.blankText);
40713            }
40714        }
40715        
40716        if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { 
40717            errors.push(this.blankText);
40718        }
40719        
40720        if (value.length < this.minLength) {
40721            errors.push(String.format(this.minLengthText, this.minLength));
40722        }
40723        
40724        if (value.length > this.maxLength) {
40725            errors.push(String.format(this.maxLengthText, this.maxLength));
40726        }
40727        
40728        if (this.vtype) {
40729            var vt = Ext.form.VTypes;
40730            if(!vt[this.vtype](value, this)){
40731                errors.push(this.vtypeText || vt[this.vtype +'Text']);
40732            }
40733        }
40734        
40735        if (this.regex && !this.regex.test(value)) {
40736            errors.push(this.regexText);
40737        }
40738        
40739        return errors;
40740    },
40741
40742    
40743    selectText : function(start, end){
40744        var v = this.getRawValue();
40745        var doFocus = false;
40746        if(v.length > 0){
40747            start = start === undefined ? 0 : start;
40748            end = end === undefined ? v.length : end;
40749            var d = this.el.dom;
40750            if(d.setSelectionRange){
40751                d.setSelectionRange(start, end);
40752            }else if(d.createTextRange){
40753                var range = d.createTextRange();
40754                range.moveStart('character', start);
40755                range.moveEnd('character', end-v.length);
40756                range.select();
40757            }
40758            doFocus = Ext.isGecko || Ext.isOpera;
40759        }else{
40760            doFocus = true;
40761        }
40762        if(doFocus){
40763            this.focus();
40764        }
40765    },
40766
40767    
40768    autoSize : function(){
40769        if(!this.grow || !this.rendered){
40770            return;
40771        }
40772        if(!this.metrics){
40773            this.metrics = Ext.util.TextMetrics.createInstance(this.el);
40774        }
40775        var el = this.el;
40776        var v = el.dom.value;
40777        var d = document.createElement('div');
40778        d.appendChild(document.createTextNode(v));
40779        v = d.innerHTML;
40780        Ext.removeNode(d);
40781        d = null;
40782        v += '&#160;';
40783        var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) +  10, this.growMin));
40784        this.el.setWidth(w);
40785        this.fireEvent('autosize', this, w);
40786    },
40787	
40788	onDestroy: function(){
40789		if(this.validationTask){
40790			this.validationTask.cancel();
40791			this.validationTask = null;
40792		}
40793		Ext.form.TextField.superclass.onDestroy.call(this);
40794	}
40795});
40796Ext.reg('textfield', Ext.form.TextField);
40797
40798Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
40799    
40800    
40801    
40802    defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
40803    
40804    hideTrigger:false,
40805    
40806    editable: true,
40807    
40808    readOnly: false,
40809    
40810    wrapFocusClass: 'x-trigger-wrap-focus',
40811    
40812    autoSize: Ext.emptyFn,
40813    
40814    monitorTab : true,
40815    
40816    deferHeight : true,
40817    
40818    mimicing : false,
40819
40820    actionMode: 'wrap',
40821
40822    defaultTriggerWidth: 17,
40823
40824    
40825    onResize : function(w, h){
40826        Ext.form.TriggerField.superclass.onResize.call(this, w, h);
40827        var tw = this.getTriggerWidth();
40828        if(Ext.isNumber(w)){
40829            this.el.setWidth(w - tw);
40830        }
40831        this.wrap.setWidth(this.el.getWidth() + tw);
40832    },
40833
40834    getTriggerWidth: function(){
40835        var tw = this.trigger.getWidth();
40836        if(!this.hideTrigger && !this.readOnly && tw === 0){
40837            tw = this.defaultTriggerWidth;
40838        }
40839        return tw;
40840    },
40841
40842    
40843    alignErrorIcon : function(){
40844        if(this.wrap){
40845            this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
40846        }
40847    },
40848
40849    
40850    onRender : function(ct, position){
40851        this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
40852        Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
40853
40854        this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
40855        this.trigger = this.wrap.createChild(this.triggerConfig ||
40856                {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass});
40857        this.initTrigger();
40858        if(!this.width){
40859            this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
40860        }
40861        this.resizeEl = this.positionEl = this.wrap;
40862    },
40863
40864    getWidth: function() {
40865        return(this.el.getWidth() + this.trigger.getWidth());
40866    },
40867
40868    updateEditState: function(){
40869        if(this.rendered){
40870            if (this.readOnly) {
40871                this.el.dom.readOnly = true;
40872                this.el.addClass('x-trigger-noedit');
40873                this.mun(this.el, 'click', this.onTriggerClick, this);
40874                this.trigger.setDisplayed(false);
40875            } else {
40876                if (!this.editable) {
40877                    this.el.dom.readOnly = true;
40878                    this.el.addClass('x-trigger-noedit');
40879                    this.mon(this.el, 'click', this.onTriggerClick, this);
40880                } else {
40881                    this.el.dom.readOnly = false;
40882                    this.el.removeClass('x-trigger-noedit');
40883                    this.mun(this.el, 'click', this.onTriggerClick, this);
40884                }
40885                this.trigger.setDisplayed(!this.hideTrigger);
40886            }
40887            this.onResize(this.width || this.wrap.getWidth());
40888        }
40889    },
40890
40891    
40892    setHideTrigger: function(hideTrigger){
40893        if(hideTrigger != this.hideTrigger){
40894            this.hideTrigger = hideTrigger;
40895            this.updateEditState();
40896        }
40897    },
40898
40899    
40900    setEditable: function(editable){
40901        if(editable != this.editable){
40902            this.editable = editable;
40903            this.updateEditState();
40904        }
40905    },
40906
40907    
40908    setReadOnly: function(readOnly){
40909        if(readOnly != this.readOnly){
40910            this.readOnly = readOnly;
40911            this.updateEditState();
40912        }
40913    },
40914
40915    afterRender : function(){
40916        Ext.form.TriggerField.superclass.afterRender.call(this);
40917        this.updateEditState();
40918    },
40919
40920    
40921    initTrigger : function(){
40922        this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
40923        this.trigger.addClassOnOver('x-form-trigger-over');
40924        this.trigger.addClassOnClick('x-form-trigger-click');
40925    },
40926
40927    
40928    onDestroy : function(){
40929        Ext.destroy(this.trigger, this.wrap);
40930        if (this.mimicing){
40931            this.doc.un('mousedown', this.mimicBlur, this);
40932        }
40933        delete this.doc;
40934        Ext.form.TriggerField.superclass.onDestroy.call(this);
40935    },
40936
40937    
40938    onFocus : function(){
40939        Ext.form.TriggerField.superclass.onFocus.call(this);
40940        if(!this.mimicing){
40941            this.wrap.addClass(this.wrapFocusClass);
40942            this.mimicing = true;
40943            this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
40944            if(this.monitorTab){
40945                this.on('specialkey', this.checkTab, this);
40946            }
40947        }
40948    },
40949
40950    
40951    checkTab : function(me, e){
40952        if(e.getKey() == e.TAB){
40953            this.triggerBlur();
40954        }
40955    },
40956
40957    
40958    onBlur : Ext.emptyFn,
40959
40960    
40961    mimicBlur : function(e){
40962        if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
40963            this.triggerBlur();
40964        }
40965    },
40966
40967    
40968    triggerBlur : function(){
40969        this.mimicing = false;
40970        this.doc.un('mousedown', this.mimicBlur, this);
40971        if(this.monitorTab && this.el){
40972            this.un('specialkey', this.checkTab, this);
40973        }
40974        Ext.form.TriggerField.superclass.onBlur.call(this);
40975        if(this.wrap){
40976            this.wrap.removeClass(this.wrapFocusClass);
40977        }
40978    },
40979
40980    beforeBlur : Ext.emptyFn,
40981
40982    
40983    
40984    validateBlur : function(e){
40985        return true;
40986    },
40987
40988    
40989    onTriggerClick : Ext.emptyFn
40990
40991    
40992    
40993    
40994});
40995
40996
40997Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
40998    
40999    
41000    
41001
41002    initComponent : function(){
41003        Ext.form.TwinTriggerField.superclass.initComponent.call(this);
41004
41005        this.triggerConfig = {
41006            tag:'span', cls:'x-form-twin-triggers', cn:[
41007            {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class},
41008            {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class}
41009        ]};
41010    },
41011
41012    getTrigger : function(index){
41013        return this.triggers[index];
41014    },
41015    
41016    afterRender: function(){
41017        Ext.form.TwinTriggerField.superclass.afterRender.call(this);
41018        var triggers = this.triggers,
41019            i = 0,
41020            len = triggers.length;
41021            
41022        for(; i < len; ++i){
41023            if(this['hideTrigger' + (i + 1)]){
41024                    triggers[i].hide();
41025                }
41026
41027        }    
41028    },
41029
41030    initTrigger : function(){
41031        var ts = this.trigger.select('.x-form-trigger', true),
41032            triggerField = this;
41033            
41034        ts.each(function(t, all, index){
41035            var triggerIndex = 'Trigger'+(index+1);
41036            t.hide = function(){
41037                var w = triggerField.wrap.getWidth();
41038                this.dom.style.display = 'none';
41039                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
41040                triggerField['hidden' + triggerIndex] = true;
41041            };
41042            t.show = function(){
41043                var w = triggerField.wrap.getWidth();
41044                this.dom.style.display = '';
41045                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
41046                triggerField['hidden' + triggerIndex] = false;
41047            };
41048            this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
41049            t.addClassOnOver('x-form-trigger-over');
41050            t.addClassOnClick('x-form-trigger-click');
41051        }, this);
41052        this.triggers = ts.elements;
41053    },
41054
41055    getTriggerWidth: function(){
41056        var tw = 0;
41057        Ext.each(this.triggers, function(t, index){
41058            var triggerIndex = 'Trigger' + (index + 1),
41059                w = t.getWidth();
41060            if(w === 0 && !this['hidden' + triggerIndex]){
41061                tw += this.defaultTriggerWidth;
41062            }else{
41063                tw += w;
41064            }
41065        }, this);
41066        return tw;
41067    },
41068
41069    
41070    onDestroy : function() {
41071        Ext.destroy(this.triggers);
41072        Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
41073    },
41074
41075    
41076    onTrigger1Click : Ext.emptyFn,
41077    
41078    onTrigger2Click : Ext.emptyFn
41079});
41080Ext.reg('trigger', Ext.form.TriggerField);
41081
41082Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
41083    
41084    growMin : 60,
41085    
41086    growMax: 1000,
41087    growAppend : '&#160;\n&#160;',
41088
41089    enterIsSpecial : false,
41090
41091    
41092    preventScrollbars: false,
41093    
41094
41095    
41096    onRender : function(ct, position){
41097        if(!this.el){
41098            this.defaultAutoCreate = {
41099                tag: "textarea",
41100                style:"width:100px;height:60px;",
41101                autocomplete: "off"
41102            };
41103        }
41104        Ext.form.TextArea.superclass.onRender.call(this, ct, position);
41105        if(this.grow){
41106            this.textSizeEl = Ext.DomHelper.append(document.body, {
41107                tag: "pre", cls: "x-form-grow-sizer"
41108            });
41109            if(this.preventScrollbars){
41110                this.el.setStyle("overflow", "hidden");
41111            }
41112            this.el.setHeight(this.growMin);
41113        }
41114    },
41115
41116    onDestroy : function(){
41117        Ext.removeNode(this.textSizeEl);
41118        Ext.form.TextArea.superclass.onDestroy.call(this);
41119    },
41120
41121    fireKey : function(e){
41122        if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
41123            this.fireEvent("specialkey", this, e);
41124        }
41125    },
41126    
41127    
41128    doAutoSize : function(e){
41129        return !e.isNavKeyPress() || e.getKey() == e.ENTER;
41130    },
41131    
41132    
41133    filterValidation: function(e) {            
41134        if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
41135            this.validationTask.delay(this.validationDelay);
41136        }
41137    },
41138
41139    
41140    autoSize: function(){
41141        if(!this.grow || !this.textSizeEl){
41142            return;
41143        }
41144        var el = this.el,
41145            v = Ext.util.Format.htmlEncode(el.dom.value),
41146            ts = this.textSizeEl,
41147            h;
41148            
41149        Ext.fly(ts).setWidth(this.el.getWidth());
41150        if(v.length < 1){
41151            v = "&#160;&#160;";
41152        }else{
41153            v += this.growAppend;
41154            if(Ext.isIE){
41155                v = v.replace(/\n/g, '&#160;<br />');
41156            }
41157        }
41158        ts.innerHTML = v;
41159        h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
41160        if(h != this.lastHeight){
41161            this.lastHeight = h;
41162            this.el.setHeight(h);
41163            this.fireEvent("autosize", this, h);
41164        }
41165    }
41166});
41167Ext.reg('textarea', Ext.form.TextArea);
41168Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
41169    
41170    
41171    
41172    fieldClass: "x-form-field x-form-num-field",
41173    
41174    
41175    allowDecimals : true,
41176    
41177    
41178    decimalSeparator : ".",
41179    
41180    
41181    decimalPrecision : 2,
41182    
41183    
41184    allowNegative : true,
41185    
41186    
41187    minValue : Number.NEGATIVE_INFINITY,
41188    
41189    
41190    maxValue : Number.MAX_VALUE,
41191    
41192    
41193    minText : "The minimum value for this field is {0}",
41194    
41195    
41196    maxText : "The maximum value for this field is {0}",
41197    
41198    
41199    nanText : "{0} is not a valid number",
41200    
41201    
41202    baseChars : "0123456789",
41203    
41204    
41205    autoStripChars: false,
41206
41207    
41208    initEvents : function() {
41209        var allowed = this.baseChars + '';
41210        if (this.allowDecimals) {
41211            allowed += this.decimalSeparator;
41212        }
41213        if (this.allowNegative) {
41214            allowed += '-';
41215        }
41216        allowed = Ext.escapeRe(allowed);
41217        this.maskRe = new RegExp('[' + allowed + ']');
41218        if (this.autoStripChars) {
41219            this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
41220        }
41221        
41222        Ext.form.NumberField.superclass.initEvents.call(this);
41223    },
41224    
41225    
41226    getErrors: function(value) {
41227        var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
41228        
41229        value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
41230        
41231        if (value.length < 1) { 
41232             return errors;
41233        }
41234        
41235        value = String(value).replace(this.decimalSeparator, ".");
41236        
41237        if(isNaN(value)){
41238            errors.push(String.format(this.nanText, value));
41239        }
41240        
41241        var num = this.parseValue(value);
41242        
41243        if (num < this.minValue) {
41244            errors.push(String.format(this.minText, this.minValue));
41245        }
41246        
41247        if (num > this.maxValue) {
41248            errors.push(String.format(this.maxText, this.maxValue));
41249        }
41250        
41251        return errors;
41252    },
41253
41254    getValue : function() {
41255        return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
41256    },
41257
41258    setValue : function(v) {
41259    	v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
41260        v = this.fixPrecision(v);
41261        v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
41262        return Ext.form.NumberField.superclass.setValue.call(this, v);
41263    },
41264    
41265    
41266    setMinValue : function(value) {
41267        this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
41268    },
41269    
41270    
41271    setMaxValue : function(value) {
41272        this.maxValue = Ext.num(value, Number.MAX_VALUE);    
41273    },
41274
41275    
41276    parseValue : function(value) {
41277        value = parseFloat(String(value).replace(this.decimalSeparator, "."));
41278        return isNaN(value) ? '' : value;
41279    },
41280
41281    
41282    fixPrecision : function(value) {
41283        var nan = isNaN(value);
41284        
41285        if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
41286            return nan ? '' : value;
41287        }
41288        
41289        return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
41290    },
41291
41292    beforeBlur : function() {
41293        var v = this.parseValue(this.getRawValue());
41294        
41295        if (!Ext.isEmpty(v)) {
41296            this.setValue(v);
41297        }
41298    }
41299});
41300
41301Ext.reg('numberfield', Ext.form.NumberField);
41302
41303Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
41304    
41305    format : "m/d/Y",
41306    
41307    altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",
41308    
41309    disabledDaysText : "Disabled",
41310    
41311    disabledDatesText : "Disabled",
41312    
41313    minText : "The date in this field must be equal to or after {0}",
41314    
41315    maxText : "The date in this field must be equal to or before {0}",
41316    
41317    invalidText : "{0} is not a valid date - it must be in the format {1}",
41318    
41319    triggerClass : 'x-form-date-trigger',
41320    
41321    showToday : true,
41322    
41323    
41324    startDay : 0,
41325    
41326    
41327    
41328    
41329    
41330    
41331
41332    
41333    defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
41334
41335    
41336    
41337    initTime: '12', 
41338
41339    initTimeFormat: 'H',
41340
41341    
41342    safeParse : function(value, format) {
41343        if (Date.formatContainsHourInfo(format)) {
41344            
41345            return Date.parseDate(value, format);
41346        } else {
41347            
41348            var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
41349 
41350            if (parsedDate) {
41351                return parsedDate.clearTime();
41352            }
41353        }
41354    },
41355
41356    initComponent : function(){
41357        Ext.form.DateField.superclass.initComponent.call(this);
41358
41359        this.addEvents(
41360            
41361            'select'
41362        );
41363
41364        if(Ext.isString(this.minValue)){
41365            this.minValue = this.parseDate(this.minValue);
41366        }
41367        if(Ext.isString(this.maxValue)){
41368            this.maxValue = this.parseDate(this.maxValue);
41369        }
41370        this.disabledDatesRE = null;
41371        this.initDisabledDays();
41372    },
41373
41374    initEvents: function() {
41375        Ext.form.DateField.superclass.initEvents.call(this);
41376        this.keyNav = new Ext.KeyNav(this.el, {
41377            "down": function(e) {
41378                this.onTriggerClick();
41379            },
41380            scope: this,
41381            forceKeyDown: true
41382        });
41383    },
41384
41385
41386    
41387    initDisabledDays : function(){
41388        if(this.disabledDates){
41389            var dd = this.disabledDates,
41390                len = dd.length - 1,
41391                re = "(?:";
41392
41393            Ext.each(dd, function(d, i){
41394                re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
41395                if(i != len){
41396                    re += '|';
41397                }
41398            }, this);
41399            this.disabledDatesRE = new RegExp(re + ')');
41400        }
41401    },
41402
41403    
41404    setDisabledDates : function(dd){
41405        this.disabledDates = dd;
41406        this.initDisabledDays();
41407        if(this.menu){
41408            this.menu.picker.setDisabledDates(this.disabledDatesRE);
41409        }
41410    },
41411
41412    
41413    setDisabledDays : function(dd){
41414        this.disabledDays = dd;
41415        if(this.menu){
41416            this.menu.picker.setDisabledDays(dd);
41417        }
41418    },
41419
41420    
41421    setMinValue : function(dt){
41422        this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
41423        if(this.menu){
41424            this.menu.picker.setMinDate(this.minValue);
41425        }
41426    },
41427
41428    
41429    setMaxValue : function(dt){
41430        this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
41431        if(this.menu){
41432            this.menu.picker.setMaxDate(this.maxValue);
41433        }
41434    },
41435
41436    
41437    getErrors: function(value) {
41438        var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
41439
41440        value = this.formatDate(value || this.processValue(this.getRawValue()));
41441
41442        if (value.length < 1) { 
41443             return errors;
41444        }
41445
41446        var svalue = value;
41447        value = this.parseDate(value);
41448        if (!value) {
41449            errors.push(String.format(this.invalidText, svalue, this.format));
41450            return errors;
41451        }
41452
41453        var time = value.getTime();
41454        if (this.minValue && time < this.minValue.clearTime().getTime()) {
41455            errors.push(String.format(this.minText, this.formatDate(this.minValue)));
41456        }
41457
41458        if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
41459            errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
41460        }
41461
41462        if (this.disabledDays) {
41463            var day = value.getDay();
41464
41465            for(var i = 0; i < this.disabledDays.length; i++) {
41466                if (day === this.disabledDays[i]) {
41467                    errors.push(this.disabledDaysText);
41468                    break;
41469                }
41470            }
41471        }
41472
41473        var fvalue = this.formatDate(value);
41474        if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
41475            errors.push(String.format(this.disabledDatesText, fvalue));
41476        }
41477
41478        return errors;
41479    },
41480
41481    
41482    
41483    validateBlur : function(){
41484        return !this.menu || !this.menu.isVisible();
41485    },
41486
41487    
41488    getValue : function(){
41489        return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
41490    },
41491
41492    
41493    setValue : function(date){
41494        return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
41495    },
41496
41497    
41498    parseDate : function(value) {
41499        if(!value || Ext.isDate(value)){
41500            return value;
41501        }
41502
41503        var v = this.safeParse(value, this.format),
41504            af = this.altFormats,
41505            afa = this.altFormatsArray;
41506
41507        if (!v && af) {
41508            afa = afa || af.split("|");
41509
41510            for (var i = 0, len = afa.length; i < len && !v; i++) {
41511                v = this.safeParse(value, afa[i]);
41512            }
41513        }
41514        return v;
41515    },
41516
41517    
41518    onDestroy : function(){
41519        Ext.destroy(this.menu, this.keyNav);
41520        Ext.form.DateField.superclass.onDestroy.call(this);
41521    },
41522
41523    
41524    formatDate : function(date){
41525        return Ext.isDate(date) ? date.dateFormat(this.format) : date;
41526    },
41527
41528    
41529    
41530    
41531    onTriggerClick : function(){
41532        if(this.disabled){
41533            return;
41534        }
41535        if(this.menu == null){
41536            this.menu = new Ext.menu.DateMenu({
41537                hideOnClick: false,
41538                focusOnSelect: false
41539            });
41540        }
41541        this.onFocus();
41542        Ext.apply(this.menu.picker,  {
41543            minDate : this.minValue,
41544            maxDate : this.maxValue,
41545            disabledDatesRE : this.disabledDatesRE,
41546            disabledDatesText : this.disabledDatesText,
41547            disabledDays : this.disabledDays,
41548            disabledDaysText : this.disabledDaysText,
41549            format : this.format,
41550            showToday : this.showToday,
41551            startDay: this.startDay,
41552            minText : String.format(this.minText, this.formatDate(this.minValue)),
41553            maxText : String.format(this.maxText, this.formatDate(this.maxValue))
41554        });
41555        this.menu.picker.setValue(this.getValue() || new Date());
41556        this.menu.show(this.el, "tl-bl?");
41557        this.menuEvents('on');
41558    },
41559
41560    
41561    menuEvents: function(method){
41562        this.menu[method]('select', this.onSelect, this);
41563        this.menu[method]('hide', this.onMenuHide, this);
41564        this.menu[method]('show', this.onFocus, this);
41565    },
41566
41567    onSelect: function(m, d){
41568        this.setValue(d);
41569        this.fireEvent('select', this, d);
41570        this.menu.hide();
41571    },
41572
41573    onMenuHide: function(){
41574        this.focus(false, 60);
41575        this.menuEvents('un');
41576    },
41577
41578    
41579    beforeBlur : function(){
41580        var v = this.parseDate(this.getRawValue());
41581        if(v){
41582            this.setValue(v);
41583        }
41584    }
41585
41586    
41587    
41588    
41589    
41590});
41591Ext.reg('datefield', Ext.form.DateField);
41592
41593Ext.form.DisplayField = Ext.extend(Ext.form.Field,  {
41594    validationEvent : false,
41595    validateOnBlur : false,
41596    defaultAutoCreate : {tag: "div"},
41597    
41598    fieldClass : "x-form-display-field",
41599    
41600    htmlEncode: false,
41601
41602    
41603    initEvents : Ext.emptyFn,
41604
41605    isValid : function(){
41606        return true;
41607    },
41608
41609    validate : function(){
41610        return true;
41611    },
41612
41613    getRawValue : function(){
41614        var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
41615        if(v === this.emptyText){
41616            v = '';
41617        }
41618        if(this.htmlEncode){
41619            v = Ext.util.Format.htmlDecode(v);
41620        }
41621        return v;
41622    },
41623
41624    getValue : function(){
41625        return this.getRawValue();
41626    },
41627    
41628    getName: function() {
41629        return this.name;
41630    },
41631
41632    setRawValue : function(v){
41633        if(this.htmlEncode){
41634            v = Ext.util.Format.htmlEncode(v);
41635        }
41636        return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
41637    },
41638
41639    setValue : function(v){
41640        this.setRawValue(v);
41641        return this;
41642    }
41643    
41644    
41645    
41646    
41647    
41648    
41649});
41650
41651Ext.reg('displayfield', Ext.form.DisplayField);
41652
41653Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
41654    
41655    
41656    
41657    
41658    
41659
41660    
41661    defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
41662    
41663    
41664    
41665    
41666    
41667    
41668    
41669    listClass : '',
41670    
41671    selectedClass : 'x-combo-selected',
41672    
41673    listEmptyText: '',
41674    
41675    triggerClass : 'x-form-arrow-trigger',
41676    
41677    shadow : 'sides',
41678    
41679    listAlign : 'tl-bl?',
41680    
41681    maxHeight : 300,
41682    
41683    minHeight : 90,
41684    
41685    triggerAction : 'query',
41686    
41687    minChars : 4,
41688    
41689    autoSelect : true,
41690    
41691    typeAhead : false,
41692    
41693    queryDelay : 500,
41694    
41695    pageSize : 0,
41696    
41697    selectOnFocus : false,
41698    
41699    queryParam : 'query',
41700    
41701    loadingText : 'Loading...',
41702    
41703    resizable : false,
41704    
41705    handleHeight : 8,
41706    
41707    allQuery: '',
41708    
41709    mode: 'remote',
41710    
41711    minListWidth : 70,
41712    
41713    forceSelection : false,
41714    
41715    typeAheadDelay : 250,
41716    
41717
41718    
41719    lazyInit : true,
41720
41721    
41722    clearFilterOnReset : true,
41723
41724    
41725    submitValue: undefined,
41726
41727    
41728
41729    
41730    initComponent : function(){
41731        Ext.form.ComboBox.superclass.initComponent.call(this);
41732        this.addEvents(
41733            
41734            'expand',
41735            
41736            'collapse',
41737
41738            
41739            'beforeselect',
41740            
41741            'select',
41742            
41743            'beforequery'
41744        );
41745        if(this.transform){
41746            var s = Ext.getDom(this.transform);
41747            if(!this.hiddenName){
41748                this.hiddenName = s.name;
41749            }
41750            if(!this.store){
41751                this.mode = 'local';
41752                var d = [], opts = s.options;
41753                for(var i = 0, len = opts.length;i < len; i++){
41754                    var o = opts[i],
41755                        value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
41756                    if(o.selected && Ext.isEmpty(this.value, true)) {
41757                        this.value = value;
41758                    }
41759                    d.push([value, o.text]);
41760                }
41761                this.store = new Ext.data.ArrayStore({
41762                    idIndex: 0,
41763                    fields: ['value', 'text'],
41764                    data : d,
41765                    autoDestroy: true
41766                });
41767                this.valueField = 'value';
41768                this.displayField = 'text';
41769            }
41770            s.name = Ext.id(); 
41771            if(!this.lazyRender){
41772                this.target = true;
41773                this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
41774                this.render(this.el.parentNode, s);
41775            }
41776            Ext.removeNode(s);
41777        }
41778        
41779        else if(this.store){
41780            this.store = Ext.StoreMgr.lookup(this.store);
41781            if(this.store.autoCreated){
41782                this.displayField = this.valueField = 'field1';
41783                if(!this.store.expandData){
41784                    this.displayField = 'field2';
41785                }
41786                this.mode = 'local';
41787            }
41788        }
41789
41790        this.selectedIndex = -1;
41791        if(this.mode == 'local'){
41792            if(!Ext.isDefined(this.initialConfig.queryDelay)){
41793                this.queryDelay = 10;
41794            }
41795            if(!Ext.isDefined(this.initialConfig.minChars)){
41796                this.minChars = 0;
41797            }
41798        }
41799    },
41800
41801    
41802    onRender : function(ct, position){
41803        if(this.hiddenName && !Ext.isDefined(this.submitValue)){
41804            this.submitValue = false;
41805        }
41806        Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
41807        if(this.hiddenName){
41808            this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
41809                    id: (this.hiddenId || Ext.id())}, 'before', true);
41810
41811        }
41812        if(Ext.isGecko){
41813            this.el.dom.setAttribute('autocomplete', 'off');
41814        }
41815
41816        if(!this.lazyInit){
41817            this.initList();
41818        }else{
41819            this.on('focus', this.initList, this, {single: true});
41820        }
41821    },
41822
41823    
41824    initValue : function(){
41825        Ext.form.ComboBox.superclass.initValue.call(this);
41826        if(this.hiddenField){
41827            this.hiddenField.value =
41828                Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
41829        }
41830    },
41831
41832    getParentZIndex : function(){
41833        var zindex;
41834        if (this.ownerCt){
41835            this.findParentBy(function(ct){
41836                zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
41837                return !!zindex;
41838            });
41839        }
41840        return zindex;
41841    },
41842    
41843    getZIndex : function(listParent){
41844        listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
41845        var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
41846        if(!zindex){
41847            zindex = this.getParentZIndex();
41848        }
41849        return (zindex || 12000) + 5;
41850    },
41851
41852    
41853    initList : function(){
41854        if(!this.list){
41855            var cls = 'x-combo-list',
41856                listParent = Ext.getDom(this.getListParent() || Ext.getBody());
41857
41858            this.list = new Ext.Layer({
41859                parentEl: listParent,
41860                shadow: this.shadow,
41861                cls: [cls, this.listClass].join(' '),
41862                constrain:false,
41863                zindex: this.getZIndex(listParent)
41864            });
41865
41866            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
41867            this.list.setSize(lw, 0);
41868            this.list.swallowEvent('mousewheel');
41869            this.assetHeight = 0;
41870            if(this.syncFont !== false){
41871                this.list.setStyle('font-size', this.el.getStyle('font-size'));
41872            }
41873            if(this.title){
41874                this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
41875                this.assetHeight += this.header.getHeight();
41876            }
41877
41878            this.innerList = this.list.createChild({cls:cls+'-inner'});
41879            this.mon(this.innerList, 'mouseover', this.onViewOver, this);
41880            this.mon(this.innerList, 'mousemove', this.onViewMove, this);
41881            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
41882
41883            if(this.pageSize){
41884                this.footer = this.list.createChild({cls:cls+'-ft'});
41885                this.pageTb = new Ext.PagingToolbar({
41886                    store: this.store,
41887                    pageSize: this.pageSize,
41888                    renderTo:this.footer
41889                });
41890                this.assetHeight += this.footer.getHeight();
41891            }
41892
41893            if(!this.tpl){
41894                
41895                this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
41896                
41897            }
41898
41899            
41900            this.view = new Ext.DataView({
41901                applyTo: this.innerList,
41902                tpl: this.tpl,
41903                singleSelect: true,
41904                selectedClass: this.selectedClass,
41905                itemSelector: this.itemSelector || '.' + cls + '-item',
41906                emptyText: this.listEmptyText,
41907                deferEmptyText: false
41908            });
41909
41910            this.mon(this.view, {
41911                containerclick : this.onViewClick,
41912                click : this.onViewClick,
41913                scope :this
41914            });
41915
41916            this.bindStore(this.store, true);
41917
41918            if(this.resizable){
41919                this.resizer = new Ext.Resizable(this.list,  {
41920                   pinned:true, handles:'se'
41921                });
41922                this.mon(this.resizer, 'resize', function(r, w, h){
41923                    this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
41924                    this.listWidth = w;
41925                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
41926                    this.restrictHeight();
41927                }, this);
41928
41929                this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
41930            }
41931        }
41932    },
41933
41934    
41935    getListParent : function() {
41936        return document.body;
41937    },
41938
41939    
41940    getStore : function(){
41941        return this.store;
41942    },
41943
41944    
41945    bindStore : function(store, initial){
41946        if(this.store && !initial){
41947            if(this.store !== store && this.store.autoDestroy){
41948                this.store.destroy();
41949            }else{
41950                this.store.un('beforeload', this.onBeforeLoad, this);
41951                this.store.un('load', this.onLoad, this);
41952                this.store.un('exception', this.collapse, this);
41953            }
41954            if(!store){
41955                this.store = null;
41956                if(this.view){
41957                    this.view.bindStore(null);
41958                }
41959                if(this.pageTb){
41960                    this.pageTb.bindStore(null);
41961                }
41962            }
41963        }
41964        if(store){
41965            if(!initial) {
41966                this.lastQuery = null;
41967                if(this.pageTb) {
41968                    this.pageTb.bindStore(store);
41969                }
41970            }
41971
41972            this.store = Ext.StoreMgr.lookup(store);
41973            this.store.on({
41974                scope: this,
41975                beforeload: this.onBeforeLoad,
41976                load: this.onLoad,
41977                exception: this.collapse
41978            });
41979
41980            if(this.view){
41981                this.view.bindStore(store);
41982            }
41983        }
41984    },
41985
41986    reset : function(){
41987        if(this.clearFilterOnReset && this.mode == 'local'){
41988            this.store.clearFilter();
41989        }
41990        Ext.form.ComboBox.superclass.reset.call(this);
41991    },
41992
41993    
41994    initEvents : function(){
41995        Ext.form.ComboBox.superclass.initEvents.call(this);
41996
41997        
41998        this.keyNav = new Ext.KeyNav(this.el, {
41999            "up" : function(e){
42000                this.inKeyMode = true;
42001                this.selectPrev();
42002            },
42003
42004            "down" : function(e){
42005                if(!this.isExpanded()){
42006                    this.onTriggerClick();
42007                }else{
42008                    this.inKeyMode = true;
42009                    this.selectNext();
42010                }
42011            },
42012
42013            "enter" : function(e){
42014                this.onViewClick();
42015            },
42016
42017            "esc" : function(e){
42018                this.collapse();
42019            },
42020
42021            "tab" : function(e){
42022                if (this.forceSelection === true) {
42023                    this.collapse();
42024                } else {
42025                    this.onViewClick(false);
42026                }
42027                return true;
42028            },
42029
42030            scope : this,
42031
42032            doRelay : function(e, h, hname){
42033                if(hname == 'down' || this.scope.isExpanded()){
42034                    
42035                    var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
42036                    if(!Ext.isIE && Ext.EventManager.useKeydown){
42037                        
42038                        this.scope.fireKey(e);
42039                    }
42040                    return relay;
42041                }
42042                return true;
42043            },
42044
42045            forceKeyDown : true,
42046            defaultEventAction: 'stopEvent'
42047        });
42048        this.queryDelay = Math.max(this.queryDelay || 10,
42049                this.mode == 'local' ? 10 : 250);
42050        this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
42051        if(this.typeAhead){
42052            this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
42053        }
42054        if(!this.enableKeyEvents){
42055            this.mon(this.el, 'keyup', this.onKeyUp, this);
42056        }
42057    },
42058
42059
42060    
42061    onDestroy : function(){
42062        if (this.dqTask){
42063            this.dqTask.cancel();
42064            this.dqTask = null;
42065        }
42066        this.bindStore(null);
42067        Ext.destroy(
42068            this.resizer,
42069            this.view,
42070            this.pageTb,
42071            this.list
42072        );
42073        Ext.destroyMembers(this, 'hiddenField');
42074        Ext.form.ComboBox.superclass.onDestroy.call(this);
42075    },
42076
42077    
42078    fireKey : function(e){
42079        if (!this.isExpanded()) {
42080            Ext.form.ComboBox.superclass.fireKey.call(this, e);
42081        }
42082    },
42083
42084    
42085    onResize : function(w, h){
42086        Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
42087        if(!isNaN(w) && this.isVisible() && this.list){
42088            this.doResize(w);
42089        }else{
42090            this.bufferSize = w;
42091        }
42092    },
42093
42094    doResize: function(w){
42095        if(!Ext.isDefined(this.listWidth)){
42096            var lw = Math.max(w, this.minListWidth);
42097            this.list.setWidth(lw);
42098            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
42099        }
42100    },
42101
42102    
42103    onEnable : function(){
42104        Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
42105        if(this.hiddenField){
42106            this.hiddenField.disabled = false;
42107        }
42108    },
42109
42110    
42111    onDisable : function(){
42112        Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
42113        if(this.hiddenField){
42114            this.hiddenField.disabled = true;
42115        }
42116    },
42117
42118    
42119    onBeforeLoad : function(){
42120        if(!this.hasFocus){
42121            return;
42122        }
42123        this.innerList.update(this.loadingText ?
42124               '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
42125        this.restrictHeight();
42126        this.selectedIndex = -1;
42127    },
42128
42129    
42130    onLoad : function(){
42131        if(!this.hasFocus){
42132            return;
42133        }
42134        if(this.store.getCount() > 0 || this.listEmptyText){
42135            this.expand();
42136            this.restrictHeight();
42137            if(this.lastQuery == this.allQuery){
42138                if(this.editable){
42139                    this.el.dom.select();
42140                }
42141
42142                if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
42143                    this.select(0, true);
42144                }
42145            }else{
42146                if(this.autoSelect !== false){
42147                    this.selectNext();
42148                }
42149                if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
42150                    this.taTask.delay(this.typeAheadDelay);
42151                }
42152            }
42153        }else{
42154            this.collapse();
42155        }
42156
42157    },
42158
42159    
42160    onTypeAhead : function(){
42161        if(this.store.getCount() > 0){
42162            var r = this.store.getAt(0);
42163            var newValue = r.data[this.displayField];
42164            var len = newValue.length;
42165            var selStart = this.getRawValue().length;
42166            if(selStart != len){
42167                this.setRawValue(newValue);
42168                this.selectText(selStart, newValue.length);
42169            }
42170        }
42171    },
42172
42173    
42174    assertValue : function(){
42175        var val = this.getRawValue(),
42176            rec;
42177
42178        if(this.valueField && Ext.isDefined(this.value)){
42179            rec = this.findRecord(this.valueField, this.value);
42180        }
42181        if(!rec || rec.get(this.displayField) != val){
42182            rec = this.findRecord(this.displayField, val);
42183        }
42184        if(!rec && this.forceSelection){
42185            if(val.length > 0 && val != this.emptyText){
42186                this.el.dom.value = Ext.value(this.lastSelectionText, '');
42187                this.applyEmptyText();
42188            }else{
42189                this.clearValue();
42190            }
42191        }else{
42192            if(rec && this.valueField){
42193                
42194                
42195                
42196                if (this.value == val){
42197                    return;
42198                }
42199                val = rec.get(this.valueField || this.displayField);
42200            }
42201            this.setValue(val);
42202        }
42203    },
42204
42205    
42206    onSelect : function(record, index){
42207        if(this.fireEvent('beforeselect', this, record, index) !== false){
42208            this.setValue(record.data[this.valueField || this.displayField]);
42209            this.collapse();
42210            this.fireEvent('select', this, record, index);
42211        }
42212    },
42213
42214    
42215    getName: function(){
42216        var hf = this.hiddenField;
42217        return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
42218    },
42219
42220    
42221    getValue : function(){
42222        if(this.valueField){
42223            return Ext.isDefined(this.value) ? this.value : '';
42224        }else{
42225            return Ext.form.ComboBox.superclass.getValue.call(this);
42226        }
42227    },
42228
42229    
42230    clearValue : function(){
42231        if(this.hiddenField){
42232            this.hiddenField.value = '';
42233        }
42234        this.setRawValue('');
42235        this.lastSelectionText = '';
42236        this.applyEmptyText();
42237        this.value = '';
42238    },
42239
42240    
42241    setValue : function(v){
42242        var text = v;
42243        if(this.valueField){
42244            var r = this.findRecord(this.valueField, v);
42245            if(r){
42246                text = r.data[this.displayField];
42247            }else if(Ext.isDefined(this.valueNotFoundText)){
42248                text = this.valueNotFoundText;
42249            }
42250        }
42251        this.lastSelectionText = text;
42252        if(this.hiddenField){
42253            this.hiddenField.value = Ext.value(v, '');
42254        }
42255        Ext.form.ComboBox.superclass.setValue.call(this, text);
42256        this.value = v;
42257        return this;
42258    },
42259
42260    
42261    findRecord : function(prop, value){
42262        var record;
42263        if(this.store.getCount() > 0){
42264            this.store.each(function(r){
42265                if(r.data[prop] == value){
42266                    record = r;
42267                    return false;
42268                }
42269            });
42270        }
42271        return record;
42272    },
42273
42274    
42275    onViewMove : function(e, t){
42276        this.inKeyMode = false;
42277    },
42278
42279    
42280    onViewOver : function(e, t){
42281        if(this.inKeyMode){ 
42282            return;
42283        }
42284        var item = this.view.findItemFromChild(t);
42285        if(item){
42286            var index = this.view.indexOf(item);
42287            this.select(index, false);
42288        }
42289    },
42290
42291    
42292    onViewClick : function(doFocus){
42293        var index = this.view.getSelectedIndexes()[0],
42294            s = this.store,
42295            r = s.getAt(index);
42296        if(r){
42297            this.onSelect(r, index);
42298        }else {
42299            this.collapse();
42300        }
42301        if(doFocus !== false){
42302            this.el.focus();
42303        }
42304    },
42305
42306
42307    
42308    restrictHeight : function(){
42309        this.innerList.dom.style.height = '';
42310        var inner = this.innerList.dom,
42311            pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
42312            h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
42313            ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
42314            hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
42315            space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
42316
42317        h = Math.min(h, space, this.maxHeight);
42318
42319        this.innerList.setHeight(h);
42320        this.list.beginUpdate();
42321        this.list.setHeight(h+pad);
42322        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
42323        this.list.endUpdate();
42324    },
42325
42326    
42327    isExpanded : function(){
42328        return this.list && this.list.isVisible();
42329    },
42330
42331    
42332    selectByValue : function(v, scrollIntoView){
42333        if(!Ext.isEmpty(v, true)){
42334            var r = this.findRecord(this.valueField || this.displayField, v);
42335            if(r){
42336                this.select(this.store.indexOf(r), scrollIntoView);
42337                return true;
42338            }
42339        }
42340        return false;
42341    },
42342
42343    
42344    select : function(index, scrollIntoView){
42345        this.selectedIndex = index;
42346        this.view.select(index);
42347        if(scrollIntoView !== false){
42348            var el = this.view.getNode(index);
42349            if(el){
42350                this.innerList.scrollChildIntoView(el, false);
42351            }
42352        }
42353
42354    },
42355
42356    
42357    selectNext : function(){
42358        var ct = this.store.getCount();
42359        if(ct > 0){
42360            if(this.selectedIndex == -1){
42361                this.select(0);
42362            }else if(this.selectedIndex < ct-1){
42363                this.select(this.selectedIndex+1);
42364            }
42365        }
42366    },
42367
42368    
42369    selectPrev : function(){
42370        var ct = this.store.getCount();
42371        if(ct > 0){
42372            if(this.selectedIndex == -1){
42373                this.select(0);
42374            }else if(this.selectedIndex !== 0){
42375                this.select(this.selectedIndex-1);
42376            }
42377        }
42378    },
42379
42380    
42381    onKeyUp : function(e){
42382        var k = e.getKey();
42383        if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
42384
42385            this.lastKey = k;
42386            this.dqTask.delay(this.queryDelay);
42387        }
42388        Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
42389    },
42390
42391    
42392    validateBlur : function(){
42393        return !this.list || !this.list.isVisible();
42394    },
42395
42396    
42397    initQuery : function(){
42398        this.doQuery(this.getRawValue());
42399    },
42400
42401    
42402    beforeBlur : function(){
42403        this.assertValue();
42404    },
42405
42406    
42407    postBlur  : function(){
42408        Ext.form.ComboBox.superclass.postBlur.call(this);
42409        this.collapse();
42410        this.inKeyMode = false;
42411    },
42412
42413    
42414    doQuery : function(q, forceAll){
42415        q = Ext.isEmpty(q) ? '' : q;
42416        var qe = {
42417            query: q,
42418            forceAll: forceAll,
42419            combo: this,
42420            cancel:false
42421        };
42422        if(this.fireEvent('beforequery', qe)===false || qe.cancel){
42423            return false;
42424        }
42425        q = qe.query;
42426        forceAll = qe.forceAll;
42427        if(forceAll === true || (q.length >= this.minChars)){
42428            if(this.lastQuery !== q){
42429                this.lastQuery = q;
42430                if(this.mode == 'local'){
42431                    this.selectedIndex = -1;
42432                    if(forceAll){
42433                        this.store.clearFilter();
42434                    }else{
42435                        this.store.filter(this.displayField, q);
42436                    }
42437                    this.onLoad();
42438                }else{
42439                    this.store.baseParams[this.queryParam] = q;
42440                    this.store.load({
42441                        params: this.getParams(q)
42442                    });
42443                    this.expand();
42444                }
42445            }else{
42446                this.selectedIndex = -1;
42447                this.onLoad();
42448            }
42449        }
42450    },
42451
42452    
42453    getParams : function(q){
42454        var params = {},
42455            paramNames = this.store.paramNames;
42456        if(this.pageSize){
42457            params[paramNames.start] = 0;
42458            params[paramNames.limit] = this.pageSize;
42459        }
42460        return params;
42461    },
42462
42463    
42464    collapse : function(){
42465        if(!this.isExpanded()){
42466            return;
42467        }
42468        this.list.hide();
42469        Ext.getDoc().un('mousewheel', this.collapseIf, this);
42470        Ext.getDoc().un('mousedown', this.collapseIf, this);
42471        this.fireEvent('collapse', this);
42472    },
42473
42474    
42475    collapseIf : function(e){
42476        if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
42477            this.collapse();
42478        }
42479    },
42480
42481    
42482    expand : function(){
42483        if(this.isExpanded() || !this.hasFocus){
42484            return;
42485        }
42486
42487        if(this.title || this.pageSize){
42488            this.assetHeight = 0;
42489            if(this.title){
42490                this.assetHeight += this.header.getHeight();
42491            }
42492            if(this.pageSize){
42493                this.assetHeight += this.footer.getHeight();
42494            }
42495        }
42496
42497        if(this.bufferSize){
42498            this.doResize(this.bufferSize);
42499            delete this.bufferSize;
42500        }
42501        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
42502
42503        
42504        this.list.setZIndex(this.getZIndex());
42505        this.list.show();
42506        if(Ext.isGecko2){
42507            this.innerList.setOverflow('auto'); 
42508        }
42509        this.mon(Ext.getDoc(), {
42510            scope: this,
42511            mousewheel: this.collapseIf,
42512            mousedown: this.collapseIf
42513        });
42514        this.fireEvent('expand', this);
42515    },
42516
42517    
42518    
42519    
42520    onTriggerClick : function(){
42521        if(this.readOnly || this.disabled){
42522            return;
42523        }
42524        if(this.isExpanded()){
42525            this.collapse();
42526            this.el.focus();
42527        }else {
42528            this.onFocus({});
42529            if(this.triggerAction == 'all') {
42530                this.doQuery(this.allQuery, true);
42531            } else {
42532                this.doQuery(this.getRawValue());
42533            }
42534            this.el.focus();
42535        }
42536    }
42537
42538    
42539    
42540    
42541    
42542
42543});
42544Ext.reg('combo', Ext.form.ComboBox);
42545
42546Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
42547    
42548    focusClass : undefined,
42549    
42550    fieldClass : 'x-form-field',
42551    
42552    checked : false,
42553    
42554    boxLabel: '&#160;',
42555    
42556    defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
42557    
42558    
42559    
42560
42561    
42562    actionMode : 'wrap',
42563
42564	
42565    initComponent : function(){
42566        Ext.form.Checkbox.superclass.initComponent.call(this);
42567        this.addEvents(
42568            
42569            'check'
42570        );
42571    },
42572
42573    
42574    onResize : function(){
42575        Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
42576        if(!this.boxLabel && !this.fieldLabel){
42577            this.el.alignTo(this.wrap, 'c-c');
42578        }
42579    },
42580
42581    
42582    initEvents : function(){
42583        Ext.form.Checkbox.superclass.initEvents.call(this);
42584        this.mon(this.el, {
42585            scope: this,
42586            click: this.onClick,
42587            change: this.onClick
42588        });
42589    },
42590
42591    
42592    markInvalid : Ext.emptyFn,
42593    
42594    clearInvalid : Ext.emptyFn,
42595
42596    
42597    onRender : function(ct, position){
42598        Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
42599        if(this.inputValue !== undefined){
42600            this.el.dom.value = this.inputValue;
42601        }
42602        this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
42603        if(this.boxLabel){
42604            this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
42605        }
42606        if(this.checked){
42607            this.setValue(true);
42608        }else{
42609            this.checked = this.el.dom.checked;
42610        }
42611        
42612        if (Ext.isIE && !Ext.isStrict) {
42613            this.wrap.repaint();
42614        }
42615        this.resizeEl = this.positionEl = this.wrap;
42616    },
42617
42618    
42619    onDestroy : function(){
42620        Ext.destroy(this.wrap);
42621        Ext.form.Checkbox.superclass.onDestroy.call(this);
42622    },
42623
42624    
42625    initValue : function() {
42626        this.originalValue = this.getValue();
42627    },
42628
42629    
42630    getValue : function(){
42631        if(this.rendered){
42632            return this.el.dom.checked;
42633        }
42634        return this.checked;
42635    },
42636
42637	
42638    onClick : function(){
42639        if(this.el.dom.checked != this.checked){
42640            this.setValue(this.el.dom.checked);
42641        }
42642    },
42643
42644    
42645    setValue : function(v){
42646        var checked = this.checked,
42647            inputVal = this.inputValue;
42648            
42649        if (v === false) {
42650            this.checked = false;
42651        } else {
42652            this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
42653        }
42654        
42655        if(this.rendered){
42656            this.el.dom.checked = this.checked;
42657            this.el.dom.defaultChecked = this.checked;
42658        }
42659        if(checked != this.checked){
42660            this.fireEvent('check', this, this.checked);
42661            if(this.handler){
42662                this.handler.call(this.scope || this, this, this.checked);
42663            }
42664        }
42665        return this;
42666    }
42667});
42668Ext.reg('checkbox', Ext.form.Checkbox);
42669
42670Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
42671    
42672    
42673    columns : 'auto',
42674    
42675    vertical : false,
42676    
42677    allowBlank : true,
42678    
42679    blankText : "You must select at least one item in this group",
42680
42681    
42682    defaultType : 'checkbox',
42683
42684    
42685    groupCls : 'x-form-check-group',
42686
42687    
42688    initComponent: function(){
42689        this.addEvents(
42690            
42691            'change'
42692        );
42693        this.on('change', this.validate, this);
42694        Ext.form.CheckboxGroup.superclass.initComponent.call(this);
42695    },
42696
42697    
42698    onRender : function(ct, position){
42699        if(!this.el){
42700            var panelCfg = {
42701                autoEl: {
42702                    id: this.id
42703                },
42704                cls: this.groupCls,
42705                layout: 'column',
42706                renderTo: ct,
42707                bufferResize: false 
42708            };
42709            var colCfg = {
42710                xtype: 'container',
42711                defaultType: this.defaultType,
42712                layout: 'form',
42713                defaults: {
42714                    hideLabel: true,
42715                    anchor: '100%'
42716                }
42717            };
42718
42719            if(this.items[0].items){
42720
42721                
42722
42723                Ext.apply(panelCfg, {
42724                    layoutConfig: {columns: this.items.length},
42725                    defaults: this.defaults,
42726                    items: this.items
42727                });
42728                for(var i=0, len=this.items.length; i<len; i++){
42729                    Ext.applyIf(this.items[i], colCfg);
42730                }
42731
42732            }else{
42733
42734                
42735                
42736
42737                var numCols, cols = [];
42738
42739                if(typeof this.columns == 'string'){ 
42740                    this.columns = this.items.length;
42741                }
42742                if(!Ext.isArray(this.columns)){
42743                    var cs = [];
42744                    for(var i=0; i<this.columns; i++){
42745                        cs.push((100/this.columns)*.01); 
42746                    }
42747                    this.columns = cs;
42748                }
42749
42750                numCols = this.columns.length;
42751
42752                
42753                for(var i=0; i<numCols; i++){
42754                    var cc = Ext.apply({items:[]}, colCfg);
42755                    cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
42756                    if(this.defaults){
42757                        cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
42758                    }
42759                    cols.push(cc);
42760                };
42761
42762                
42763                if(this.vertical){
42764                    var rows = Math.ceil(this.items.length / numCols), ri = 0;
42765                    for(var i=0, len=this.items.length; i<len; i++){
42766                        if(i>0 && i%rows==0){
42767                            ri++;
42768                        }
42769                        if(this.items[i].fieldLabel){
42770                            this.items[i].hideLabel = false;
42771                        }
42772                        cols[ri].items.push(this.items[i]);
42773                    };
42774                }else{
42775                    for(var i=0, len=this.items.length; i<len; i++){
42776                        var ci = i % numCols;
42777                        if(this.items[i].fieldLabel){
42778                            this.items[i].hideLabel = false;
42779                        }
42780                        cols[ci].items.push(this.items[i]);
42781                    };
42782                }
42783
42784                Ext.apply(panelCfg, {
42785                    layoutConfig: {columns: numCols},
42786                    items: cols
42787                });
42788            }
42789
42790            this.panel = new Ext.Container(panelCfg);
42791            this.panel.ownerCt = this;
42792            this.el = this.panel.getEl();
42793
42794            if(this.forId && this.itemCls){
42795                var l = this.el.up(this.itemCls).child('label', true);
42796                if(l){
42797                    l.setAttribute('htmlFor', this.forId);
42798                }
42799            }
42800
42801            var fields = this.panel.findBy(function(c){
42802                return c.isFormField;
42803            }, this);
42804
42805            this.items = new Ext.util.MixedCollection();
42806            this.items.addAll(fields);
42807        }
42808        Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
42809    },
42810
42811    initValue : function(){
42812        if(this.value){
42813            this.setValue.apply(this, this.buffered ? this.value : [this.value]);
42814            delete this.buffered;
42815            delete this.value;
42816        }
42817    },
42818
42819    afterRender : function(){
42820        Ext.form.CheckboxGroup.superclass.afterRender.call(this);
42821        this.eachItem(function(item){
42822            item.on('check', this.fireChecked, this);
42823            item.inGroup = true;
42824        });
42825    },
42826
42827    
42828    doLayout: function(){
42829        
42830        if(this.rendered){
42831            this.panel.forceLayout = this.ownerCt.forceLayout;
42832            this.panel.doLayout();
42833        }
42834    },
42835
42836    
42837    fireChecked: function(){
42838        var arr = [];
42839        this.eachItem(function(item){
42840            if(item.checked){
42841                arr.push(item);
42842            }
42843        });
42844        this.fireEvent('change', this, arr);
42845    },
42846    
42847    
42848    getErrors: function() {
42849        var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
42850        
42851        if (!this.allowBlank) {
42852            var blank = true;
42853            
42854            this.eachItem(function(f){
42855                if (f.checked) {
42856                    return (blank = false);
42857                }
42858            });
42859            
42860            if (blank) errors.push(this.blankText);
42861        }
42862        
42863        return errors;
42864    },
42865
42866    
42867    isDirty: function(){
42868        
42869        if (this.disabled || !this.rendered) {
42870            return false;
42871        }
42872
42873        var dirty = false;
42874        
42875        this.eachItem(function(item){
42876            if(item.isDirty()){
42877                dirty = true;
42878                return false;
42879            }
42880        });
42881        
42882        return dirty;
42883    },
42884
42885    
42886    setReadOnly : function(readOnly){
42887        if(this.rendered){
42888            this.eachItem(function(item){
42889                item.setReadOnly(readOnly);
42890            });
42891        }
42892        this.readOnly = readOnly;
42893    },
42894
42895    
42896    onDisable : function(){
42897        this.eachItem(function(item){
42898            item.disable();
42899        });
42900    },
42901
42902    
42903    onEnable : function(){
42904        this.eachItem(function(item){
42905            item.enable();
42906        });
42907    },
42908
42909    
42910    onResize : function(w, h){
42911        this.panel.setSize(w, h);
42912        this.panel.doLayout();
42913    },
42914
42915    
42916    reset : function(){
42917        if (this.originalValue) {
42918            
42919            this.eachItem(function(c){
42920                if(c.setValue){
42921                    c.setValue(false);
42922                    c.originalValue = c.getValue();
42923                }
42924            });
42925            
42926            
42927            this.resetOriginal = true;
42928            this.setValue(this.originalValue);
42929            delete this.resetOriginal;
42930        } else {
42931            this.eachItem(function(c){
42932                if(c.reset){
42933                    c.reset();
42934                }
42935            });
42936        }
42937        
42938        
42939        (function() {
42940            this.clearInvalid();
42941        }).defer(50, this);
42942    },
42943
42944    
42945    setValue: function(){
42946        if(this.rendered){
42947            this.onSetValue.apply(this, arguments);
42948        }else{
42949            this.buffered = true;
42950            this.value = arguments;
42951        }
42952        return this;
42953    },
42954
42955    
42956    onSetValue: function(id, value){
42957        if(arguments.length == 1){
42958            if(Ext.isArray(id)){
42959                Ext.each(id, function(val, idx){
42960                    if (Ext.isObject(val) && val.setValue){ 
42961                        val.setValue(true);
42962                        if (this.resetOriginal === true) {
42963                            val.originalValue = val.getValue();
42964                        }
42965                    } else { 
42966                        var item = this.items.itemAt(idx);
42967                        if(item){
42968                            item.setValue(val);
42969                        }
42970                    }
42971                }, this);
42972            }else if(Ext.isObject(id)){
42973                
42974                for(var i in id){
42975                    var f = this.getBox(i);
42976                    if(f){
42977                        f.setValue(id[i]);
42978                    }
42979                }
42980            }else{
42981                this.setValueForItem(id);
42982            }
42983        }else{
42984            var f = this.getBox(id);
42985            if(f){
42986                f.setValue(value);
42987            }
42988        }
42989    },
42990
42991    
42992    beforeDestroy: function(){
42993        Ext.destroy(this.panel);
42994        if (!this.rendered) {
42995            Ext.destroy(this.items);
42996        }
42997        Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
42998
42999    },
43000
43001    setValueForItem : function(val){
43002        val = String(val).split(',');
43003        this.eachItem(function(item){
43004            if(val.indexOf(item.inputValue)>
43004 -1){
43005                item.setValue(true);
43006            }
43007        });
43008    },
43009
43010    
43011    getBox : function(id){
43012        var box = null;
43013        this.eachItem(function(f){
43014            if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
43015                box = f;
43016                return false;
43017            }
43018        });
43019        return box;
43020    },
43021
43022    
43023    getValue : function(){
43024        var out = [];
43025        this.eachItem(function(item){
43026            if(item.checked){
43027                out.push(item);
43028            }
43029        });
43030        return out;
43031    },
43032
43033    
43034    eachItem: function(fn, scope) {
43035        if(this.items && this.items.each){
43036            this.items.each(fn, scope || this);
43037        }
43038    },
43039
43040    
43041
43042    
43043    getRawValue : Ext.emptyFn,
43044
43045    
43046    setRawValue : Ext.emptyFn
43047
43048});
43049
43050Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
43051
43052Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
43053
43054    
43055    defaultMargins: '0 5 0 0',
43056
43057    
43058    skipLastItemMargin: true,
43059
43060    
43061    isComposite: true,
43062
43063    
43064    combineErrors: true,
43065    
43066    
43067    labelConnector: ', ',
43068    
43069    
43070
43071    
43072    
43073    initComponent: function() {
43074        var labels = [],
43075            items  = this.items,
43076            item;
43077
43078        for (var i=0, j = items.length; i < j; i++) {
43079            item = items[i];
43080            
43081            if (!Ext.isEmpty(item.ref)){
43082                item.ref = '../' + item.ref;
43083            }
43084
43085            labels.push(item.fieldLabel);
43086
43087            
43088            Ext.applyIf(item, this.defaults);
43089
43090            
43091            if (!(i == j - 1 && this.skipLastItemMargin)) {
43092                Ext.applyIf(item, {margins: this.defaultMargins});
43093            }
43094        }
43095
43096        this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
43097
43098        
43099        this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
43100            return item.field;
43101        });
43102
43103        this.fieldErrors.on({
43104            scope  : this,
43105            add    : this.updateInvalidMark,
43106            remove : this.updateInvalidMark,
43107            replace: this.updateInvalidMark
43108        });
43109
43110        Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
43111        
43112        this.innerCt = new Ext.Container({
43113            layout  : 'hbox',
43114            items   : this.items,
43115            cls     : 'x-form-composite',
43116            defaultMargins: '0 3 0 0',
43117            ownerCt: this
43118        });
43119        this.innerCt.ownerCt = undefined;
43120        
43121        var fields = this.innerCt.findBy(function(c) {
43122            return c.isFormField;
43123        }, this);
43124
43125        
43126        this.items = new Ext.util.MixedCollection();
43127        this.items.addAll(fields);
43128        
43129    },
43130
43131    
43132    onRender: function(ct, position) {
43133        if (!this.el) {
43134            
43135            var innerCt = this.innerCt;
43136            innerCt.render(ct);
43137
43138            this.el = innerCt.getEl();
43139
43140            
43141            
43142            if (this.combineErrors) {
43143                this.eachItem(function(field) {
43144                    Ext.apply(field, {
43145                        markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
43146                        clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
43147                    });
43148                });
43149            }
43150
43151            
43152            var l = this.el.parent().parent().child('label', true);
43153            if (l) {
43154                l.setAttribute('for', this.items.items[0].id);
43155            }
43156        }
43157
43158        Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
43159    },
43160
43161    
43162    onFieldMarkInvalid: function(field, message) {
43163        var name  = field.getName(),
43164            error = {
43165                field: name, 
43166                errorName: field.fieldLabel || name,
43167                error: message
43168            };
43169
43170        this.fieldErrors.replace(name, error);
43171
43172        if (!field.preventMark) {
43173            field.el.addClass(field.invalidClass);
43174        }
43175    },
43176
43177    
43178    onFieldClearInvalid: function(field) {
43179        this.fieldErrors.removeKey(field.getName());
43180
43181        field.el.removeClass(field.invalidClass);
43182    },
43183
43184    
43185    updateInvalidMark: function() {
43186        var ieStrict = Ext.isIE6 && Ext.isStrict;
43187
43188        if (this.fieldErrors.length == 0) {
43189            this.clearInvalid();
43190
43191            
43192            if (ieStrict) {
43193                this.clearInvalid.defer(50, this);
43194            }
43195        } else {
43196            var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
43197
43198            this.sortErrors();
43199            this.markInvalid(message);
43200
43201            
43202            if (ieStrict) {
43203                this.markInvalid(message);
43204            }
43205        }
43206    },
43207
43208    
43209    validateValue: function(value, preventMark) {
43210        var valid = true;
43211
43212        this.eachItem(function(field) {
43213            if (!field.isValid(preventMark)) {
43214                valid = false;
43215            }
43216        });
43217
43218        return valid;
43219    },
43220
43221    
43222    buildCombinedErrorMessage: function(errors) {
43223        var combined = [],
43224            error;
43225
43226        for (var i = 0, j = errors.length; i < j; i++) {
43227            error = errors[i];
43228
43229            combined.push(String.format("{0}: {1}", error.errorName, error.error));
43230        }
43231
43232        return combined.join("<br />");
43233    },
43234
43235    
43236    sortErrors: function() {
43237        var fields = this.items;
43238
43239        this.fieldErrors.sort("ASC", function(a, b) {
43240            var findByName = function(key) {
43241                return function(field) {
43242                    return field.getName() == key;
43243                };
43244            };
43245
43246            var aIndex = fields.findIndexBy(findByName(a.field)),
43247                bIndex = fields.findIndexBy(findByName(b.field));
43248
43249            return aIndex < bIndex ? -1 : 1;
43250        });
43251    },
43252
43253    
43254    reset: function() {
43255        this.eachItem(function(item) {
43256            item.reset();
43257        });
43258
43259        
43260        
43261        (function() {
43262            this.clearInvalid();
43263        }).defer(50, this);
43264    },
43265    
43266    
43267    clearInvalidChildren: function() {
43268        this.eachItem(function(item) {
43269            item.clearInvalid();
43270        });
43271    },
43272
43273    
43274    buildLabel: function(segments) {
43275        return Ext.clean(segments).join(this.labelConnector);
43276    },
43277
43278    
43279    isDirty: function(){
43280        
43281        if (this.disabled || !this.rendered) {
43282            return false;
43283        }
43284
43285        var dirty = false;
43286        this.eachItem(function(item){
43287            if(item.isDirty()){
43288                dirty = true;
43289                return false;
43290            }
43291        });
43292        return dirty;
43293    },
43294
43295    
43296    eachItem: function(fn, scope) {
43297        if(this.items && this.items.each){
43298            this.items.each(fn, scope || this);
43299        }
43300    },
43301
43302    
43303    onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
43304        var innerCt = this.innerCt;
43305
43306        if (this.rendered && innerCt.rendered) {
43307            innerCt.setSize(adjWidth, adjHeight);
43308        }
43309
43310        Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
43311    },
43312
43313    
43314    doLayout: function(shallow, force) {
43315        if (this.rendered) {
43316            var innerCt = this.innerCt;
43317
43318            innerCt.forceLayout = this.ownerCt.forceLayout;
43319            innerCt.doLayout(shallow, force);
43320        }
43321    },
43322
43323    
43324    beforeDestroy: function(){
43325        Ext.destroy(this.innerCt);
43326
43327        Ext.form.CompositeField.superclass.beforeDestroy.call(this);
43328    },
43329
43330    
43331    setReadOnly : function(readOnly) {
43332        if (readOnly == undefined) {
43333            readOnly = true;
43334        }
43335        readOnly = !!readOnly;
43336
43337        if(this.rendered){
43338            this.eachItem(function(item){
43339                item.setReadOnly(readOnly);
43340            });
43341        }
43342        this.readOnly = readOnly;
43343    },
43344
43345    onShow : function() {
43346        Ext.form.CompositeField.superclass.onShow.call(this);
43347        this.doLayout();
43348    },
43349
43350    
43351    onDisable : function(){
43352        this.eachItem(function(item){
43353            item.disable();
43354        });
43355    },
43356
43357    
43358    onEnable : function(){
43359        this.eachItem(function(item){
43360            item.enable();
43361        });
43362    }
43363});
43364
43365Ext.reg('compositefield', Ext.form.CompositeField);
43366Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
43367    inputType: 'radio',
43368
43369    
43370    markInvalid : Ext.emptyFn,
43371    
43372    clearInvalid : Ext.emptyFn,
43373
43374    
43375    getGroupValue : function(){
43376    	var p = this.el.up('form') || Ext.getBody();
43377        var c = p.child('input[name="'+this.el.dom.name+'"]:checked', true);
43378        return c ? c.value : null;
43379    },
43380
43381    
43382    setValue : function(v){
43383    	var checkEl,
43384            els,
43385            radio;
43386    	if (typeof v == 'boolean') {
43387            Ext.form.Radio.superclass.setValue.call(this, v);
43388        } else if (this.rendered) {
43389            checkEl = this.getCheckEl();
43390            radio = checkEl.child('input[name="' + this.el.dom.name + '"][value="' + v + '"]', true);
43391            if(radio){
43392                Ext.getCmp(radio.id).setValue(true);
43393            }
43394        }
43395        if(this.rendered && this.checked){
43396            checkEl = checkEl || this.getCheckEl();
43397            els = this.getCheckEl().select('input[name="' + this.el.dom.name + '"]');
43398			els.each(function(el){
43399				if(el.dom.id != this.id){
43400					Ext.getCmp(el.dom.id).setValue(false);
43401				}
43402			}, this);
43403        }
43404        return this;
43405    },
43406
43407    
43408    getCheckEl: function(){
43409        if(this.inGroup){
43410            return this.el.up('.x-form-radio-group');
43411        }
43412        return this.el.up('form') || Ext.getBody();
43413    }
43414});
43415Ext.reg('radio', Ext.form.Radio);
43416
43417Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
43418    
43419    
43420    allowBlank : true,
43421    
43422    blankText : 'You must select one item in this group',
43423    
43424    
43425    defaultType : 'radio',
43426    
43427    
43428    groupCls : 'x-form-radio-group',
43429    
43430    
43431    
43432    
43433    getValue : function(){
43434        var out = null;
43435        this.eachItem(function(item){
43436            if(item.checked){
43437                out = item;
43438                return false;
43439            }
43440        });
43441        return out;
43442    },
43443    
43444    
43445    onSetValue : function(id, value){
43446        if(arguments.length > 1){
43447            var f = this.getBox(id);
43448            if(f){
43449                f.setValue(value);
43450                if(f.checked){
43451                    this.eachItem(function(item){
43452                        if (item !== f){
43453                            item.setValue(false);
43454                        }
43455                    });
43456                }
43457            }
43458        }else{
43459            this.setValueForItem(id);
43460        }
43461    },
43462    
43463    setValueForItem : function(val){
43464        val = String(val).split(',')[0];
43465        this.eachItem(function(item){
43466            item.setValue(val == item.inputValue);
43467        });
43468    },
43469    
43470    
43471    fireChecked : function(){
43472        if(!this.checkTask){
43473            this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
43474        }
43475        this.checkTask.delay(10);
43476    },
43477    
43478    
43479    bufferChecked : function(){
43480        var out = null;
43481        this.eachItem(function(item){
43482            if(item.checked){
43483                out = item;
43484                return false;
43485            }
43486        });
43487        this.fireEvent('change', this, out);
43488    },
43489    
43490    onDestroy : function(){
43491        if(this.checkTask){
43492            this.checkTask.cancel();
43493            this.checkTask = null;
43494        }
43495        Ext.form.RadioGroup.superclass.onDestroy.call(this);
43496    }
43497
43498});
43499
43500Ext.reg('radiogroup', Ext.form.RadioGroup);
43501
43502Ext.form.Hidden = Ext.extend(Ext.form.Field, {
43503    
43504    inputType : 'hidden',
43505    
43506    shouldLayout: false,
43507
43508    
43509    onRender : function(){
43510        Ext.form.Hidden.superclass.onRender.apply(this, arguments);
43511    },
43512
43513    
43514    initEvents : function(){
43515        this.originalValue = this.getValue();
43516    },
43517
43518    
43519    setSize : Ext.emptyFn,
43520    setWidth : Ext.emptyFn,
43521    setHeight : Ext.emptyFn,
43522    setPosition : Ext.emptyFn,
43523    setPagePosition : Ext.emptyFn,
43524    markInvalid : Ext.emptyFn,
43525    clearInvalid : Ext.emptyFn
43526});
43527Ext.reg('hidden', Ext.form.Hidden);
43528Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
43529
43530    constructor: function(el, config){
43531        Ext.apply(this, config);
43532        if(Ext.isString(this.paramOrder)){
43533            this.paramOrder = this.paramOrder.split(/[\s,|]/);
43534        }
43535        
43536        this.items = new Ext.util.MixedCollection(false, function(o){
43537            return o.getItemId();
43538        });
43539        this.addEvents(
43540            
43541            'beforeaction',
43542            
43543            'actionfailed',
43544            
43545            'actioncomplete'
43546        );
43547
43548        if(el){
43549            this.initEl(el);
43550        }
43551        Ext.form.BasicForm.superclass.constructor.call(this);
43552    },
43553
43554    
43555    
43556    
43557    
43558    
43559    
43560    
43561    timeout: 30,
43562
43563    
43564
43565    
43566    paramOrder: undefined,
43567
43568    
43569    paramsAsHash: false,
43570
43571    
43572    waitTitle: 'Please Wait...',
43573
43574    
43575    activeAction : null,
43576
43577    
43578    trackResetOnLoad : false,
43579
43580    
43581    
43582
43583    
43584    initEl : function(el){
43585        this.el = Ext.get(el);
43586        this.id = this.el.id || Ext.id();
43587        if(!this.standardSubmit){
43588            this.el.on('submit', this.onSubmit, this);
43589        }
43590        this.el.addClass('x-form');
43591    },
43592
43593    
43594    getEl: function(){
43595        return this.el;
43596    },
43597
43598    
43599    onSubmit : function(e){
43600        e.stopEvent();
43601    },
43602
43603    
43604    destroy: function(bound){
43605        if(bound !== true){
43606            this.items.each(function(f){
43607                Ext.destroy(f);
43608            });
43609            Ext.destroy(this.el);
43610        }
43611        this.items.clear();
43612        this.purgeListeners();
43613    },
43614
43615    
43616    isValid : function(){
43617        var valid = true;
43618        this.items.each(function(f){
43619           if(!f.validate()){
43620               valid = false;
43621           }
43622        });
43623        return valid;
43624    },
43625
43626    
43627    isDirty : function(){
43628        var dirty = false;
43629        this.items.each(function(f){
43630           if(f.isDirty()){
43631               dirty = true;
43632               return false;
43633           }
43634        });
43635        return dirty;
43636    },
43637
43638    
43639    doAction : function(action, options){
43640        if(Ext.isString(action)){
43641            action = new Ext.form.Action.ACTION_TYPES[action](this, options);
43642        }
43643        if(this.fireEvent('beforeaction', this, action) !== false){
43644            this.beforeAction(action);
43645            action.run.defer(100, action);
43646        }
43647        return this;
43648    },
43649
43650    
43651    submit : function(options){
43652        options = options || {};
43653        if(this.standardSubmit){
43654            var v = options.clientValidation === false || this.isValid();
43655            if(v){
43656                var el = this.el.dom;
43657                if(this.url && Ext.isEmpty(el.action)){
43658                    el.action = this.url;
43659                }
43660                el.submit();
43661            }
43662            return v;
43663        }
43664        var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
43665        this.doAction(submitAction, options);
43666        return this;
43667    },
43668
43669    
43670    load : function(options){
43671        var loadAction = String.format('{0}load', this.api ? 'direct' : '');
43672        this.doAction(loadAction, options);
43673        return this;
43674    },
43675
43676    
43677    updateRecord : function(record){
43678        record.beginEdit();
43679        var fs = record.fields,
43680            field,
43681            value;
43682        fs.each(function(f){
43683            field = this.findField(f.name);
43684            if(field){
43685                value = field.getValue();
43686                if (Ext.type(value) !== false && value.getGroupValue) {
43687                    value = value.getGroupValue();
43688                } else if ( field.eachItem ) {
43689                    value = [];
43690                    field.eachItem(function(item){
43691                        value.push(item.getValue());
43692                    });
43693                }
43694                record.set(f.name, value);
43695            }
43696        }, this);
43697        record.endEdit();
43698        return this;
43699    },
43700
43701    
43702    loadRecord : function(record){
43703        this.setValues(record.data);
43704        return this;
43705    },
43706
43707    
43708    beforeAction : function(action){
43709        
43710        this.items.each(function(f){
43711            if(f.isFormField && f.syncValue){
43712                f.syncValue();
43713            }
43714        });
43715        var o = action.options;
43716        if(o.waitMsg){
43717            if(this.waitMsgTarget === true){
43718                this.el.mask(o.waitMsg, 'x-mask-loading');
43719            }else if(this.waitMsgTarget){
43720                this.waitMsgTarget = Ext.get(this.waitMsgTarget);
43721                this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
43722            }else{
43723                Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
43724            }
43725        }
43726    },
43727
43728    
43729    afterAction : function(action, success){
43730        this.activeAction = null;
43731        var o = action.options;
43732        if(o.waitMsg){
43733            if(this.waitMsgTarget === true){
43734                this.el.unmask();
43735            }else if(this.waitMsgTarget){
43736                this.waitMsgTarget.unmask();
43737            }else{
43738                Ext.MessageBox.updateProgress(1);
43739                Ext.MessageBox.hide();
43740            }
43741        }
43742        if(success){
43743            if(o.reset){
43744                this.reset();
43745            }
43746            Ext.callback(o.success, o.scope, [this, action]);
43747            this.fireEvent('actioncomplete', this, action);
43748        }else{
43749            Ext.callback(o.failure, o.scope, [this, action]);
43750            this.fireEvent('actionfailed', this, action);
43751        }
43752    },
43753
43754    
43755    findField : function(id) {
43756        var field = this.items.get(id);
43757
43758        if (!Ext.isObject(field)) {
43759            
43760            var findMatchingField = function(f) {
43761                if (f.isFormField) {
43762                    if (f.dataIndex == id || f.id == id || f.getName() == id) {
43763                        field = f;
43764                        return false;
43765                    } else if (f.isComposite) {
43766                        return f.items.each(findMatchingField);
43767                    } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
43768                        return f.eachItem(findMatchingField);
43769                    }
43770                }
43771            };
43772
43773            this.items.each(findMatchingField);
43774        }
43775        return field || null;
43776    },
43777
43778
43779    
43780    markInvalid : function(errors){
43781        if (Ext.isArray(errors)) {
43782            for(var i = 0, len = errors.length; i < len; i++){
43783                var fieldError = errors[i];
43784                var f = this.findField(fieldError.id);
43785                if(f){
43786                    f.markInvalid(fieldError.msg);
43787                }
43788            }
43789        } else {
43790            var field, id;
43791            for(id in errors){
43792                if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
43793                    field.markInvalid(errors[id]);
43794                }
43795            }
43796        }
43797
43798        return this;
43799    },
43800
43801    
43802    setValues : function(values){
43803        if(Ext.isArray(values)){ 
43804            for(var i = 0, len = values.length; i < len; i++){
43805                var v = values[i];
43806                var f = this.findField(v.id);
43807                if(f){
43808                    f.setValue(v.value);
43809                    if(this.trackResetOnLoad){
43810                        f.originalValue = f.getValue();
43811                    }
43812                }
43813            }
43814        }else{ 
43815            var field, id;
43816            for(id in values){
43817                if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
43818                    field.setValue(values[id]);
43819                    if(this.trackResetOnLoad){
43820                        field.originalValue = field.getValue();
43821                    }
43822                }
43823            }
43824        }
43825        return this;
43826    },
43827
43828    
43829    getValues : function(asString){
43830        var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
43831        if(asString === true){
43832            return fs;
43833        }
43834        return Ext.urlDecode(fs);
43835    },
43836
43837    
43838    getFieldValues : function(dirtyOnly){
43839        var o = {},
43840            n,
43841            key,
43842            val;
43843        this.items.each(function(f) {
43844            if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
43845                n = f.getName();
43846                key = o[n];
43847                val = f.getValue();
43848
43849                if(Ext.isDefined(key)){
43850                    if(Ext.isArray(key)){
43851                        o[n].push(val);
43852                    }else{
43853                        o[n] = [key, val];
43854                    }
43855                }else{
43856                    o[n] = val;
43857                }
43858            }
43859        });
43860        return o;
43861    },
43862
43863    
43864    clearInvalid : function(){
43865        this.items.each(function(f){
43866           f.clearInvalid();
43867        });
43868        return this;
43869    },
43870
43871    
43872    reset : function(){
43873        this.items.each(function(f){
43874            f.reset();
43875        });
43876        return this;
43877    },
43878
43879    
43880    add : function(){
43881        this.items.addAll(Array.prototype.slice.call(arguments, 0));
43882        return this;
43883    },
43884
43885    
43886    remove : function(field){
43887        this.items.remove(field);
43888        return this;
43889    },
43890
43891    
43892    cleanDestroyed : function() {
43893        this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
43894    },
43895
43896    
43897    render : function(){
43898        this.items.each(function(f){
43899            if(f.isFormField && !f.rendered && document.getElementById(f.id)){ 
43900                f.applyToMarkup(f.id);
43901            }
43902        });
43903        return this;
43904    },
43905
43906    
43907    applyToFields : function(o){
43908        this.items.each(function(f){
43909           Ext.apply(f, o);
43910        });
43911        return this;
43912    },
43913
43914    
43915    applyIfToFields : function(o){
43916        this.items.each(function(f){
43917           Ext.applyIf(f, o);
43918        });
43919        return this;
43920    },
43921
43922    callFieldMethod : function(fnName, args){
43923        args = args || [];
43924        this.items.each(function(f){
43925            if(Ext.isFunction(f[fnName])){
43926                f[fnName].apply(f, args);
43927            }
43928        });
43929        return this;
43930    }
43931});
43932
43933
43934Ext.BasicForm = Ext.form.BasicForm;
43935
43936Ext.FormPanel = Ext.extend(Ext.Panel, {
43937    
43938    
43939    
43940    
43941    
43942    
43943    
43944
43945
43946    
43947    minButtonWidth : 75,
43948
43949    
43950    labelAlign : 'left',
43951
43952    
43953    monitorValid : false,
43954
43955    
43956    monitorPoll : 200,
43957
43958    
43959    layout : 'form',
43960
43961    
43962    initComponent : function(){
43963        this.form = this.createForm();
43964        Ext.FormPanel.superclass.initComponent.call(this);
43965
43966        this.bodyCfg = {
43967            tag: 'form',
43968            cls: this.baseCls + '-body',
43969            method : this.method || 'POST',
43970            id : this.formId || Ext.id()
43971        };
43972        if(this.fileUpload) {
43973            this.bodyCfg.enctype = 'multipart/form-data';
43974        }
43975        this.initItems();
43976
43977        this.addEvents(
43978            
43979            'clientvalidation'
43980        );
43981
43982        this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
43983    },
43984
43985    
43986    createForm : function(){
43987        var config = Ext.applyIf({listeners: {}}, this.initialConfig);
43988        return new Ext.form.BasicForm(null, config);
43989    },
43990
43991    
43992    initFields : function(){
43993        var f = this.form;
43994        var formPanel = this;
43995        var fn = function(c){
43996            if(formPanel.isField(c)){
43997                f.add(c);
43998            }else if(c.findBy && c != formPanel){
43999                formPanel.applySettings(c);
44000                
44001                if(c.items && c.items.each){
44002                    c.items.each(fn, this);
44003                }
44004            }
44005        };
44006        this.items.each(fn, this);
44007    },
44008
44009    
44010    applySettings: function(c){
44011        var ct = c.ownerCt;
44012        Ext.applyIf(c, {
44013            labelAlign: ct.labelAlign,
44014            labelWidth: ct.labelWidth,
44015            itemCls: ct.itemCls
44016        });
44017    },
44018
44019    
44020    getLayoutTarget : function(){
44021        return this.form.el;
44022    },
44023
44024    
44025    getForm : function(){
44026        return this.form;
44027    },
44028
44029    
44030    onRender : function(ct, position){
44031        this.initFields();
44032        Ext.FormPanel.superclass.onRender.call(this, ct, position);
44033        this.form.initEl(this.body);
44034    },
44035
44036    
44037    beforeDestroy : function(){
44038        this.stopMonitoring();
44039        this.form.destroy(true);
44040        Ext.FormPanel.superclass.beforeDestroy.call(this);
44041    },
44042
44043    
44044    isField : function(c) {
44045        return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
44046    },
44047
44048    
44049    initEvents : function(){
44050        Ext.FormPanel.superclass.initEvents.call(this);
44051        
44052        this.on({
44053            scope: this,
44054            add: this.onAddEvent,
44055            remove: this.onRemoveEvent
44056        });
44057        if(this.monitorValid){ 
44058            this.startMonitoring();
44059        }
44060    },
44061
44062    
44063    onAdd: function(c){
44064        Ext.FormPanel.superclass.onAdd.call(this, c);
44065        this.processAdd(c);
44066    },
44067
44068    
44069    onAddEvent: function(ct, c){
44070        if(ct !== this){
44071            this.processAdd(c);
44072        }
44073    },
44074
44075    
44076    processAdd : function(c){
44077        
44078        if(this.isField(c)){
44079            this.form.add(c);
44080        
44081        }else if(c.findBy){
44082            this.applySettings(c);
44083            this.form.add.apply(this.form, c.findBy(this.isField));
44084        }
44085    },
44086
44087    
44088    onRemove: function(c){
44089        Ext.FormPanel.superclass.onRemove.call(this, c);
44090        this.processRemove(c);
44091    },
44092
44093    onRemoveEvent: function(ct, c){
44094        if(ct !== this){
44095            this.processRemove(c);
44096        }
44097    },
44098
44099    
44100    processRemove: function(c){
44101        if(!this.destroying){
44102            
44103            if(this.isField(c)){
44104                this.form.remove(c);
44105            
44106            }else if (c.findBy){
44107                Ext.each(c.findBy(this.isField), this.form.remove, this.form);
44108                
44109                this.form.cleanDestroyed();
44110            }
44111        }
44112    },
44113
44114    
44115    startMonitoring : function(){
44116        if(!this.validTask){
44117            this.validTask = new Ext.util.TaskRunner();
44118            this.validTask.start({
44119                run : this.bindHandler,
44120                interval : this.monitorPoll || 200,
44121                scope: this
44122            });
44123        }
44124    },
44125
44126    
44127    stopMonitoring : function(){
44128        if(this.validTask){
44129            this.validTask.stopAll();
44130            this.validTask = null;
44131        }
44132    },
44133
44134    
44135    load : function(){
44136        this.form.load.apply(this.form, arguments);
44137    },
44138
44139    
44140    onDisable : function(){
44141        Ext.FormPanel.superclass.onDisable.call(this);
44142        if(this.form){
44143            this.form.items.each(function(){
44144                 this.disable();
44145            });
44146        }
44147    },
44148
44149    
44150    onEnable : function(){
44151        Ext.FormPanel.superclass.onEnable.call(this);
44152        if(this.form){
44153            this.form.items.each(function(){
44154                 this.enable();
44155            });
44156        }
44157    },
44158
44159    
44160    bindHandler : function(){
44161        var valid = true;
44162        this.form.items.each(function(f){
44163            if(!f.isValid(true)){
44164                valid = false;
44165                return false;
44166            }
44167        });
44168        if(this.fbar){
44169            var fitems = this.fbar.items.items;
44170            for(var i = 0, len = fitems.length; i < len; i++){
44171                var btn = fitems[i];
44172                if(btn.formBind === true && btn.disabled === valid){
44173                    btn.setDisabled(!valid);
44174                }
44175            }
44176        }
44177        this.fireEvent('clientvalidation', this, valid);
44178    }
44179});
44180Ext.reg('form', Ext.FormPanel);
44181
44182Ext.form.FormPanel = Ext.FormPanel;
44183
44184Ext.form.FieldSet = Ext.extend(Ext.Panel, {
44185    
44186    
44187    
44188    
44189    
44190    
44191    baseCls : 'x-fieldset',
44192    
44193    layout : 'form',
44194    
44195    animCollapse : false,
44196
44197    
44198    onRender : function(ct, position){
44199        if(!this.el){
44200            this.el = document.createElement('fieldset');
44201            this.el.id = this.id;
44202            if (this.title || this.header || this.checkboxToggle) {
44203                this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
44204            }
44205        }
44206
44207        Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
44208
44209        if(this.checkboxToggle){
44210            var o = typeof this.checkboxToggle == 'object' ?
44211                    this.checkboxToggle :
44212                    {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
44213            this.checkbox = this.header.insertFirst(o);
44214            this.checkbox.dom.checked = !this.collapsed;
44215            this.mon(this.checkbox, 'click', this.onCheckClick, this);
44216        }
44217    },
44218
44219    
44220    onCollapse : function(doAnim, animArg){
44221        if(this.checkbox){
44222            this.checkbox.dom.checked = false;
44223        }
44224        Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
44225
44226    },
44227
44228    
44229    onExpand : function(doAnim, animArg){
44230        if(this.checkbox){
44231            this.checkbox.dom.checked = true;
44232        }
44233        Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
44234    },
44235
44236    
44237    onCheckClick : function(){
44238        this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
44239    }
44240
44241    
44242    
44243    
44244    
44245    
44246    
44247    
44248    
44249    
44250    
44251    
44252    
44253    
44254    
44255    
44256    
44257    
44258    
44259    
44260    
44261    
44262    
44263    
44264    
44265    
44266    
44267    
44268    
44269    
44270    
44271    
44272    
44273    
44274    
44275});
44276Ext.reg('fieldset', Ext.form.FieldSet);
44277
44278Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
44279    
44280    enableFormat : true,
44281    
44282    enableFontSize : true,
44283    
44284    enableColors : true,
44285    
44286    enableAlignments : true,
44287    
44288    enableLists : true,
44289    
44290    enableSourceEdit : true,
44291    
44292    enableLinks : true,
44293    
44294    enableFont : true,
44295    
44296    createLinkText : 'Please enter the URL for the link:',
44297    
44298    defaultLinkValue : 'http:/'+'/',
44299    
44300    fontFamilies : [
44301        'Arial',
44302        'Courier New',
44303        'Tahoma',
44304        'Times New Roman',
44305        'Verdana'
44306    ],
44307    defaultFont: 'tahoma',
44308    
44309    defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',
44310
44311    
44312    actionMode: 'wrap',
44313    validationEvent : false,
44314    deferHeight: true,
44315    initialized : false,
44316    activated : false,
44317    sourceEditMode : false,
44318    onFocus : Ext.emptyFn,
44319    iframePad:3,
44320    hideMode:'offsets',
44321    defaultAutoCreate : {
44322        tag: "textarea",
44323        style:"width:500px;height:300px;",
44324        autocomplete: "off"
44325    },
44326
44327    
44328    initComponent : function(){
44329        this.addEvents(
44330            
44331            'initialize',
44332            
44333            'activate',
44334             
44335            'beforesync',
44336             
44337            'beforepush',
44338             
44339            'sync',
44340             
44341            'push',
44342             
44343            'editmodechange'
44344        );
44345        Ext.form.HtmlEditor.superclass.initComponent.call(this);
44346    },
44347
44348    
44349    createFontOptions : function(){
44350        var buf = [], fs = this.fontFamilies, ff, lc;
44351        for(var i = 0, len = fs.length; i< len; i++){
44352            ff = fs[i];
44353            lc = ff.toLowerCase();
44354            buf.push(
44355                '<option value="',lc,'" style="font-family:',ff,';"',
44356                    (this.defaultFont == lc ? ' selected="true">' : '>'),
44357                    ff,
44358                '</option>'
44359            );
44360        }
44361        return buf.join('');
44362    },
44363
44364    
44365    createToolbar : function(editor){
44366        var items = [];
44367        var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
44368
44369
44370        function btn(id, toggle, handler){
44371            return {
44372                itemId : id,
44373                cls : 'x-btn-icon',
44374                iconCls: 'x-edit-'+id,
44375                enableToggle:toggle !== false,
44376                scope: editor,
44377                handler:handler||editor.relayBtnCmd,
44378                clickEvent:'mousedown',
44379                tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
44380                overflowText: editor.buttonTips[id].title || undefined,
44381                tabIndex:-1
44382            };
44383        }
44384
44385
44386        if(this.enableFont && !Ext.isSafari2){
44387            var fontSelectItem = new Ext.Toolbar.Item({
44388               autoEl: {
44389                    tag:'select',
44390                    cls:'x-font-select',
44391                    html: this.createFontOptions()
44392               }
44393            });
44394
44395            items.push(
44396                fontSelectItem,
44397                '-'
44398            );
44399        }
44400
44401        if(this.enableFormat){
44402            items.push(
44403                btn('bold'),
44404                btn('italic'),
44405                btn('underline')
44406            );
44407        }
44408
44409        if(this.enableFontSize){
44410            items.push(
44411                '-',
44412                btn('increasefontsize', false, this.adjustFont),
44413                btn('decreasefontsize', false, this.adjustFont)
44414            );
44415        }
44416
44417        if(this.enableColors){
44418            items.push(
44419                '-', {
44420                    itemId:'forecolor',
44421                    cls:'x-btn-icon',
44422                    iconCls: 'x-edit-forecolor',
44423                    clickEvent:'mousedown',
44424                    tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
44425                    tabIndex:-1,
44426                    menu : new Ext.menu.ColorMenu({
44427                        allowReselect: true,
44428                        focus: Ext.emptyFn,
44429                        value:'000000',
44430                        plain:true,
44431                        listeners: {
44432                            scope: this,
44433                            select: function(cp, color){
44434                                this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
44435                                this.deferFocus();
44436                            }
44437                        },
44438                        clickEvent:'mousedown'
44439                    })
44440                }, {
44441                    itemId:'backcolor',
44442                    cls:'x-btn-icon',
44443                    iconCls: 'x-edit-backcolor',
44444                    clickEvent:'mousedown',
44445                    tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
44446                    tabIndex:-1,
44447                    menu : new Ext.menu.ColorMenu({
44448                        focus: Ext.emptyFn,
44449                        value:'FFFFFF',
44450                        plain:true,
44451                        allowReselect: true,
44452                        listeners: {
44453                            scope: this,
44454                            select: function(cp, color){
44455                                if(Ext.isGecko){
44456                                    this.execCmd('useCSS', false);
44457                                    this.execCmd('hilitecolor', color);
44458                                    this.execCmd('useCSS', true);
44459                                    this.deferFocus();
44460                                }else{
44461                                    this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
44462                                    this.deferFocus();
44463                                }
44464                            }
44465                        },
44466                        clickEvent:'mousedown'
44467                    })
44468                }
44469            );
44470        }
44471
44472        if(this.enableAlignments){
44473            items.push(
44474                '-',
44475                btn('justifyleft'),
44476                btn('justifycenter'),
44477                btn('justifyright')
44478            );
44479        }
44480
44481        if(!Ext.isSafari2){
44482            if(this.enableLinks){
44483                items.push(
44484                    '-',
44485                    btn('createlink', false, this.createLink)
44486                );
44487            }
44488
44489            if(this.enableLists){
44490                items.push(
44491                    '-',
44492                    btn('insertorderedlist'),
44493                    btn('insertunorderedlist')
44494                );
44495            }
44496            if(this.enableSourceEdit){
44497                items.push(
44498                    '-',
44499                    btn('sourceedit', true, function(btn){
44500                        this.toggleSourceEdit(!this.sourceEditMode);
44501                    })
44502                );
44503            }
44504        }
44505
44506        
44507        var tb = new Ext.Toolbar({
44508            renderTo: this.wrap.dom.firstChild,
44509            items: items
44510        });
44511
44512        if (fontSelectItem) {
44513            this.fontSelect = fontSelectItem.el;
44514
44515            this.mon(this.fontSelect, 'change', function(){
44516                var font = this.fontSelect.dom.value;
44517                this.relayCmd('fontname', font);
44518                this.deferFocus();
44519            }, this);
44520        }
44521
44522        
44523        this.mon(tb.el, 'click', function(e){
44524            e.preventDefault();
44525        });
44526
44527        this.tb = tb;
44528        this.tb.doLayout();
44529    },
44530
44531    onDisable: function(){
44532        this.wrap.mask();
44533        Ext.form.HtmlEditor.superclass.onDisable.call(this);
44534    },
44535
44536    onEnable: function(){
44537        this.wrap.unmask();
44538        Ext.form.HtmlEditor.superclass.onEnable.call(this);
44539    },
44540
44541    setReadOnly: function(readOnly){
44542
44543        Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
44544        if(this.initialized){
44545            if(Ext.isIE){
44546                this.getEditorBody().contentEditable = !readOnly;
44547            }else{
44548                this.setDesignMode(!readOnly);
44549            }
44550            var bd = this.getEditorBody();
44551            if(bd){
44552                bd.style.cursor = this.readOnly ? 'default' : 'text';
44553            }
44554            this.disableItems(readOnly);
44555        }
44556    },
44557
44558    
44559    getDocMarkup : function(){
44560        var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
44561        return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
44562    },
44563
44564    
44565    getEditorBody : function(){
44566        var doc = this.getDoc();
44567        return doc.body || doc.documentElement;
44568    },
44569
44570    
44571    getDoc : function(){
44572        return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
44573    },
44574
44575    
44576    getWin : function(){
44577        return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
44578    },
44579
44580    
44581    onRender : function(ct, position){
44582        Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
44583        this.el.dom.style.border = '0 none';
44584        this.el.dom.setAttribute('tabIndex', -1);
44585        this.el.addClass('x-hidden');
44586        if(Ext.isIE){ 
44587            this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
44588        }
44589        this.wrap = this.el.wrap({
44590            cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
44591        });
44592
44593        this.createToolbar(this);
44594
44595        this.disableItems(true);
44596
44597        this.tb.doLayout();
44598
44599        this.createIFrame();
44600
44601        if(!this.width){
44602            var sz = this.el.getSize();
44603            this.setSize(sz.width, this.height || sz.height);
44604        }
44605        this.resizeEl = this.positionEl = this.wrap;
44606    },
44607
44608    createIFrame: function(){
44609        var iframe = document.createElement('iframe');
44610        iframe.name = Ext.id();
44611        iframe.frameBorder = '0';
44612        iframe.style.overflow = 'auto';
44613        iframe.src = Ext.SSL_SECURE_URL;
44614
44615        this.wrap.dom.appendChild(iframe);
44616        this.iframe = iframe;
44617
44618        this.monitorTask = Ext.TaskMgr.start({
44619            run: this.checkDesignMode,
44620            scope: this,
44621            interval:100
44622        });
44623    },
44624
44625    initFrame : function(){
44626        Ext.TaskMgr.stop(this.monitorTask);
44627        var doc = this.getDoc();
44628        this.win = this.getWin();
44629
44630        doc.open();
44631        doc.write(this.getDocMarkup());
44632        doc.close();
44633
44634        var task = { 
44635            run : function(){
44636                var doc = this.getDoc();
44637                if(doc.body || doc.readyState == 'complete'){
44638                    Ext.TaskMgr.stop(task);
44639                    this.setDesignMode(true);
44640                    this.initEditor.defer(10, this);
44641                }
44642            },
44643            interval : 10,
44644            duration:10000,
44645            scope: this
44646        };
44647        Ext.TaskMgr.start(task);
44648    },
44649
44650
44651    checkDesignMode : function(){
44652        if(this.wrap && this.wrap.dom.offsetWidth){
44653            var doc = this.getDoc();
44654            if(!doc){
44655                return;
44656            }
44657            if(!doc.editorInitialized || this.getDesignMode() != 'on'){
44658                this.initFrame();
44659            }
44660        }
44661    },
44662
44663    
44664    setDesignMode : function(mode){
44665        var doc = this.getDoc();
44666        if (doc) {
44667            if(this.readOnly){
44668                mode = false;
44669            }
44670            doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
44671        }
44672
44673    },
44674
44675    
44676    getDesignMode : function(){
44677        var doc = this.getDoc();
44678        if(!doc){ return ''; }
44679        return String(doc.designMode).toLowerCase();
44680
44681    },
44682
44683    disableItems: function(disabled){
44684        if(this.fontSelect){
44685            this.fontSelect.dom.disabled = disabled;
44686        }
44687        this.tb.items.each(function(item){
44688            if(item.getItemId() != 'sourceedit'){
44689                item.setDisabled(disabled);
44690            }
44691        });
44692    },
44693
44694    
44695    onResize : function(w, h){
44696        Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
44697        if(this.el && this.iframe){
44698            if(Ext.isNumber(w)){
44699                var aw = w - this.wrap.getFrameWidth('lr');
44700                this.el.setWidth(aw);
44701                this.tb.setWidth(aw);
44702                this.iframe.style.width = Math.max(aw, 0) + 'px';
44703            }
44704            if(Ext.isNumber(h)){
44705                var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
44706                this.el.setHeight(ah);
44707                this.iframe.style.height = Math.max(ah, 0) + 'px';
44708                var bd = this.getEditorBody();
44709                if(bd){
44710                    bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
44711                }
44712            }
44713        }
44714    },
44715
44716    
44717    toggleSourceEdit : function(sourceEditMode){
44718        var iframeHeight,
44719            elHeight;
44720
44721        if (sourceEditMode === undefined) {
44722            sourceEditMode = !this.sourceEditMode;
44723        }
44724        this.sourceEditMode = sourceEditMode === true;
44725        var btn = this.tb.getComponent('sourceedit');
44726
44727        if (btn.pressed !== this.sourceEditMode) {
44728            btn.toggle(this.sourceEditMode);
44729            if (!btn.xtbHidden) {
44730                return;
44731            }
44732        }
44733        if (this.sourceEditMode) {
44734            
44735            this.previousSize = this.getSize();
44736
44737            iframeHeight = Ext.get(this.iframe).getHeight();
44738
44739            this.disableItems(true);
44740            this.syncValue();
44741            this.iframe.className = 'x-hidden';
44742            this.el.removeClass('x-hidden');
44743            this.el.dom.removeAttribute('tabIndex');
44744            this.el.focus();
44745            this.el.dom.style.height = iframeHeight + 'px';
44746        }
44747        else {
44748            elHeight = parseInt(this.el.dom.style.height, 10);
44749            if (this.initialized) {
44750                this.disableItems(this.readOnly);
44751            }
44752            this.pushValue();
44753            this.iframe.className = '';
44754            this.el.addClass('x-hidden');
44755            this.el.dom.setAttribute('tabIndex', -1);
44756            this.deferFocus();
44757
44758            this.setSize(this.previousSize);
44759            delete this.previousSize;
44760            this.iframe.style.height = elHeight + 'px';
44761        }
44762        this.fireEvent('editmodechange', this, this.sourceEditMode);
44763    },
44764
44765    
44766    createLink : function() {
44767        var url = prompt(this.createLinkText, this.defaultLinkValue);
44768        if(url && url != 'http:/'+'/'){
44769            this.relayCmd('createlink', url);
44770        }
44771    },
44772
44773    
44774    initEvents : function(){
44775        this.originalValue = this.getValue();
44776    },
44777
44778    
44779    markInvalid : Ext.emptyFn,
44780
44781    
44782    clearInvalid : Ext.emptyFn,
44783
44784    
44785    setValue : function(v){
44786        Ext.form.HtmlEditor.superclass.setValue.call(this, v);
44787        this.pushValue();
44788        return this;
44789    },
44790
44791    
44792    cleanHtml: function(html) {
44793        html = String(html);
44794        if(Ext.isWebKit){ 
44795            html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
44796        }
44797
44798        
44799        if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
44800            html = html.substring(1);
44801        }
44802        return html;
44803    },
44804
44805    
44806    syncValue : function(){
44807        if(this.initialized){
44808            var bd = this.getEditorBody();
44809            var html = bd.innerHTML;
44810            if(Ext.isWebKit){
44811                var bs = bd.getAttribute('style'); 
44812                var m = bs.match(/text-align:(.*?);/i);
44813                if(m && m[1]){
44814                    html = '<div style="'+m[0]+'">' + html + '</div>';
44815                }
44816            }
44817            html = this.cleanHtml(html);
44818            if(this.fireEvent('beforesync', this, html) !== false){
44819                this.el.dom.value = html;
44820                this.fireEvent('sync', this, html);
44821            }
44822        }
44823    },
44824
44825    
44826    getValue : function() {
44827        this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
44828        return Ext.form.HtmlEditor.superclass.getValue.call(this);
44829    },
44830
44831    
44832    pushValue : function(){
44833        if(this.initialized){
44834            var v = this.el.dom.value;
44835            if(!this.activated && v.length < 1){
44836                v = this.defaultValue;
44837            }
44838            if(this.fireEvent('beforepush', this, v) !== false){
44839                this.getEditorBody().innerHTML = v;
44840                if(Ext.isGecko){
44841                    
44842                    this.setDesignMode(false);  
44843                    this.setDesignMode(true);
44844                }
44845                this.fireEvent('push', this, v);
44846            }
44847
44848        }
44849    },
44850
44851    
44852    deferFocus : function(){
44853        this.focus.defer(10, this);
44854    },
44855
44856    
44857    focus : function(){
44858        if(this.win && !this.sourceEditMode){
44859            this.win.focus();
44860        }else{
44861            this.el.focus();
44862        }
44863    },
44864
44865    
44866    initEditor : function(){
44867        
44868        try{
44869            var dbody = this.getEditorBody(),
44870                ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
44871                doc,
44872                fn;
44873
44874            ss['background-attachment'] = 'fixed'; 
44875            dbody.bgProperties = 'fixed'; 
44876
44877            Ext.DomHelper.applyStyles(dbody, ss);
44878
44879            doc = this.getDoc();
44880
44881            if(doc){
44882                try{
44883                    Ext.EventManager.removeAll(doc);
44884                }catch(e){}
44885            }
44886
44887            
44888            fn = this.onEditorEvent.createDelegate(this);
44889            Ext.EventManager.on(doc, {
44890                mousedown: fn,
44891                dblclick: fn,
44892                click: fn,
44893                keyup: fn,
44894                buffer:100
44895            });
44896
44897            if(Ext.isGecko){
44898                Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
44899            }
44900            if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
44901                Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
44902            }
44903            doc.editorInitialized = true;
44904            this.initialized = true;
44905            this.pushValue();
44906            this.setReadOnly(this.readOnly);
44907            this.fireEvent('initialize', this);
44908        }catch(e){}
44909    },
44910
44911    
44912    beforeDestroy : function(){
44913        if(this.monitorTask){
44914            Ext.TaskMgr.stop(this.monitorTask);
44915        }
44916        if(this.rendered){
44917            Ext.destroy(this.tb);
44918            var doc = this.getDoc();
44919            if(doc){
44920                try{
44921                    Ext.EventManager.removeAll(doc);
44922                    for (var prop in doc){
44923                        delete doc[prop];
44924                    }
44925                }catch(e){}
44926            }
44927            if(this.wrap){
44928                this.wrap.dom.innerHTML = '';
44929                this.wrap.remove();
44930            }
44931        }
44932        Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
44933    },
44934
44935    
44936    onFirstFocus : function(){
44937        this.activated = true;
44938        this.disableItems(this.readOnly);
44939        if(Ext.isGecko){ 
44940            this.win.focus();
44941            var s = this.win.getSelection();
44942            if(!s.focusNode || s.focusNode.nodeType != 3){
44943                var r = s.getRangeAt(0);
44944                r.selectNodeContents(this.getEditorBody());
44945                r.collapse(true);
44946                this.deferFocus();
44947            }
44948            try{
44949                this.execCmd('useCSS', true);
44950                this.execCmd('styleWithCSS', false);
44951            }catch(e){}
44952        }
44953        this.fireEvent('activate', this);
44954    },
44955
44956    
44957    adjustFont: function(btn){
44958        var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
44959            doc = this.getDoc(),
44960            v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
44961        if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
44962            
44963            
44964            if(v <= 10){
44965                v = 1 + adjust;
44966            }else if(v <= 13){
44967                v = 2 + adjust;
44968            }else if(v <= 16){
44969                v = 3 + adjust;
44970            }else if(v <= 18){
44971                v = 4 + adjust;
44972            }else if(v <= 24){
44973                v = 5 + adjust;
44974            }else {
44975                v = 6 + adjust;
44976            }
44977            v = v.constrain(1, 6);
44978        }else{
44979            if(Ext.isSafari){ 
44980                adjust *= 2;
44981            }
44982            v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
44983        }
44984        this.execCmd('FontSize', v);
44985    },
44986
44987    
44988    onEditorEvent : function(e){
44989        this.updateToolbar();
44990    },
44991
44992
44993    
44994    updateToolbar: function(){
44995
44996        if(this.readOnly){
44997            return;
44998        }
44999
45000        if(!this.activated){
45001            this.onFirstFocus();
45002            return;
45003        }
45004
45005        var btns = this.tb.items.map,
45006            doc = this.getDoc();
45007
45008        if(this.enableFont && !Ext.isSafari2){
45009            var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
45010            if(name != this.fontSelect.dom.value){
45011                this.fontSelect.dom.value = name;
45012            }
45013        }
45014        if(this.enableFormat){
45015            btns.bold.toggle(doc.queryCommandState('bold'));
45016            btns.italic.toggle(doc.queryCommandState('italic'));
45017            btns.underline.toggle(doc.queryCommandState('underline'));
45018        }
45019        if(this.enableAlignments){
45020            btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
45021            btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
45022            btns.justifyright.toggle(doc.queryCommandState('justifyright'));
45023        }
45024        if(!Ext.isSafari2 && this.enableLists){
45025            btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
45026            btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
45027        }
45028
45029        Ext.menu.MenuMgr.hideAll();
45030
45031        this.syncValue();
45032    },
45033
45034    
45035    relayBtnCmd : function(btn){
45036        this.relayCmd(btn.getItemId());
45037    },
45038
45039    
45040    relayCmd : function(cmd, value){
45041        (function(){
45042            this.focus();
45043            this.execCmd(cmd, value);
45044            this.updateToolbar();
45045        }).defer(10, this);
45046    },
45047
45048    
45049    execCmd : function(cmd, value){
45050        var doc = this.getDoc();
45051        doc.execCommand(cmd, false, value === undefined ? null : value);
45052        this.syncValue();
45053    },
45054
45055    
45056    applyCommand : function(e){
45057        if(e.ctrlKey){
45058            var c = e.getCharCode(), cmd;
45059            if(c > 0){
45060                c = String.fromCharCode(c);
45061                switch(c){
45062                    case 'b':
45063                        cmd = 'bold';
45064                    break;
45065                    case 'i':
45066                        cmd = 'italic';
45067                    break;
45068                    case 'u':
45069                        cmd = 'underline';
45070                    break;
45071                }
45072                if(cmd){
45073                    this.win.focus();
45074                    this.execCmd(cmd);
45075                    this.deferFocus();
45076                    e.preventDefault();
45077                }
45078            }
45079        }
45080    },
45081
45082    
45083    insertAtCursor : function(text){
45084        if(!this.activated){
45085            return;
45086        }
45087        if(Ext.isIE){
45088            this.win.focus();
45089            var doc = this.getDoc(),
45090                r = doc.selection.createRange();
45091            if(r){
45092                r.pasteHTML(text);
45093                this.syncValue();
45094                this.deferFocus();
45095            }
45096        }else{
45097            this.win.focus();
45098            this.execCmd('InsertHTML', text);
45099            this.deferFocus();
45100        }
45101    },
45102
45103    
45104    fixKeys : function(){ 
45105        if(Ext.isIE){
45106            return function(e){
45107                var k = e.getKey(),
45108                    doc = this.getDoc(),
45109                        r;
45110                if(k == e.TAB){
45111                    e.stopEvent();
45112                    r = doc.selection.createRange();
45113                    if(r){
45114                        r.collapse(true);
45115                        r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
45116                        this.deferFocus();
45117                    }
45118                }else if(k == e.ENTER){
45119                    r = doc.selection.createRange();
45120                    if(r){
45121                        var target = r.parentElement();
45122                        if(!target || target.tagName.toLowerCase() != 'li'){
45123                            e.stopEvent();
45124                            r.pasteHTML('<br />');
45125                            r.collapse(false);
45126                            r.select();
45127                        }
45128                    }
45129                }
45130            };
45131        }else if(Ext.isOpera){
45132            return function(e){
45133                var k = e.getKey();
45134                if(k == e.TAB){
45135                    e.stopEvent();
45136                    this.win.focus();
45137                    this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
45138                    this.deferFocus();
45139                }
45140            };
45141        }else if(Ext.isWebKit){
45142            return function(e){
45143                var k = e.getKey();
45144                if(k == e.TAB){
45145                    e.stopEvent();
45146                    this.execCmd('InsertText','\t');
45147                    this.deferFocus();
45148                }else if(k == e.ENTER){
45149                    e.stopEvent();
45150                    this.execCmd('InsertHtml','<br /><br />');
45151                    this.deferFocus();
45152                }
45153             };
45154        }
45155    }(),
45156
45157    
45158    getToolbar : function(){
45159        return this.tb;
45160    },
45161
45162    
45163    buttonTips : {
45164        bold : {
45165            title: 'Bold (Ctrl+B)',
45166            text: 'Make the selected text bold.',
45167            cls: 'x-html-editor-tip'
45168        },
45169        italic : {
45170            title: 'Italic (Ctrl+I)',
45171            text: 'Make the selected text italic.',
45172            cls: 'x-html-editor-tip'
45173        },
45174        underline : {
45175            title: 'Underline (Ctrl+U)',
45176            text: 'Underline the selected text.',
45177            cls: 'x-html-editor-tip'
45178        },
45179        increasefontsize : {
45180            title: 'Grow Text',
45181            text: 'Increase the font size.',
45182            cls: 'x-html-editor-tip'
45183        },
45184        decreasefontsize : {
45185            title: 'Shrink Text',
45186            text: 'Decrease the font size.',
45187            cls: 'x-html-editor-tip'
45188        },
45189        backcolor : {
45190            title: 'Text Highlight Color',
45191            text: 'Change the background color of the selected text.',
45192            cls: 'x-html-editor-tip'
45193        },
45194        forecolor : {
45195            title: 'Font Color',
45196            text: 'Change the color of the selected text.',
45197            cls: 'x-html-editor-tip'
45198        },
45199        justifyleft : {
45200            title: 'Align Text Left',
45201            text: 'Align text to the left.',
45202            cls: 'x-html-editor-tip'
45203        },
45204        justifycenter : {
45205            title: 'Center Text',
45206            text: 'Center text in the editor.',
45207            cls: 'x-html-editor-tip'
45208        },
45209        justifyright : {
45210            title: 'Align Text Right',
45211            text: 'Align text to the right.',
45212            cls: 'x-html-editor-tip'
45213        },
45214        insertunorderedlist : {
45215            title: 'Bullet List',
45216            text: 'Start a bulleted list.',
45217            cls: 'x-html-editor-tip'
45218        },
45219        insertorderedlist : {
45220            title: 'Numbered List',
45221            text: 'Start a numbered list.',
45222            cls: 'x-html-editor-tip'
45223        },
45224        createlink : {
45225            title: 'Hyperlink',
45226            text: 'Make the selected text a hyperlink.',
45227            cls: 'x-html-editor-tip'
45228        },
45229        sourceedit : {
45230            title: 'Source Edit',
45231            text: 'Switch to source editing mode.',
45232            cls: 'x-html-editor-tip'
45233        }
45234    }
45235
45236    
45237    
45238    
45239    
45240    
45241    
45242    
45243    
45244    
45245    
45246    
45247    
45248    
45249    
45250    
45251    
45252    
45253    
45254    
45255    
45256    
45257    
45258    
45259    
45260    
45261    
45262    
45263    
45264    
45265    
45266    
45267    
45268    
45269    
45270});
45271Ext.reg('htmleditor', Ext.form.HtmlEditor);
45272
45273Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
45274    
45275    minValue : undefined,
45276    
45277    maxValue : undefined,
45278    
45279    minText : "The time in this field must be equal to or after {0}",
45280    
45281    maxText : "The time in this field must be equal to or before {0}",
45282    
45283    invalidText : "{0} is not a valid time",
45284    
45285    format : "g:i A",
45286    
45287    altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
45288    
45289    increment: 15,
45290
45291    
45292    mode: 'local',
45293    
45294    triggerAction: 'all',
45295    
45296    typeAhead: false,
45297
45298    
45299    
45300    
45301    initDate: '1/1/2008',
45302
45303    initDateFormat: 'j/n/Y',
45304
45305    
45306    initComponent : function(){
45307        if(Ext.isDefined(this.minValue)){
45308            this.setMinValue(this.minValue, true);
45309        }
45310        if(Ext.isDefined(this.maxValue)){
45311            this.setMaxValue(this.maxValue, true);
45312        }
45313        if(!this.store){
45314            this.generateStore(true);
45315        }
45316        Ext.form.TimeField.superclass.initComponent.call(this);
45317    },
45318
45319    
45320    setMinValue: function(value,  initial){
45321        this.setLimit(value, true, initial);
45322        return this;
45323    },
45324
45325    
45326    setMaxValue: function(value,  initial){
45327        this.setLimit(value, false, initial);
45328        return this;
45329    },
45330
45331    
45332    generateStore: function(initial){
45333        var min = this.minValue || new Date(this.initDate).clearTime(),
45334            max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
45335            times = [];
45336
45337        while(min <= max){
45338            times.push(min.dateFormat(this.format));
45339            min = min.add('mi', this.increment);
45340        }
45341        this.bindStore(times, initial);
45342    },
45343
45344    
45345    setLimit: function(value, isMin, initial){
45346        var d;
45347        if(Ext.isString(value)){
45348            d = this.parseDate(value);
45349        }else if(Ext.isDate(value)){
45350            d = value;
45351        }
45352        if(d){
45353            var val = new Date(this.initDate).clearTime();
45354            val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
45355            this[isMin ? 'minValue' : 'maxValue'] = val;
45356            if(!initial){
45357                this.generateStore();
45358            }
45359        }
45360    },
45361
45362    
45363    getValue : function(){
45364        var v = Ext.form.TimeField.superclass.getValue.call(this);
45365        return this.formatDate(this.parseDate(v)) || '';
45366    },
45367
45368    
45369    setValue : function(value){
45370        return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
45371    },
45372
45373    
45374    validateValue : Ext.form.DateField.prototype.validateValue,
45375
45376    formatDate : Ext.form.DateField.prototype.formatDate,
45377
45378    parseDate: function(value) {
45379        if (!value || Ext.isDate(value)) {
45380            return value;
45381        }
45382
45383        var id = this.initDate + ' ',
45384            idf = this.initDateFormat + ' ',
45385            v = Date.parseDate(id + value, idf + this.format), 
45386            af = this.altFormats;
45387
45388        if (!v && af) {
45389            if (!this.altFormatsArray) {
45390                this.altFormatsArray = af.split("|");
45391            }
45392            for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
45393                v = Date.parseDate(id + value, idf + afa[i]);
45394            }
45395        }
45396
45397        return v;
45398    }
45399});
45400Ext.reg('timefield', Ext.form.TimeField);
45401Ext.form.SliderField = Ext.extend(Ext.form.Field, {
45402    
45403    
45404    useTips : true,
45405    
45406    
45407    tipText : null,
45408    
45409    
45410    actionMode: 'wrap',
45411    
45412    
45413    initComponent : function() {
45414        var cfg = Ext.copyTo({
45415            id: this.id + '-slider'
45416        }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
45417        
45418        
45419        if (this.useTips) {
45420            var plug = this.tipText ? {getText: this.tipText} : {};
45421            cfg.plugins = [new Ext.slider.Tip(plug)];
45422        }
45423        this.slider = new Ext.Slider(cfg);
45424        Ext.form.SliderField.superclass.initComponent.call(this);
45425    },    
45426    
45427    
45428    onRender : function(ct, position){
45429        this.autoCreate = {
45430            id: this.id,
45431            name: this.name,
45432            type: 'hidden',
45433            tag: 'input'    
45434        };
45435        Ext.form.SliderField.superclass.onRender.call(this, ct, position);
45436        this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
45437        this.resizeEl = this.positionEl = this.wrap;
45438        this.slider.render(this.wrap);
45439    },
45440    
45441    
45442    onResize : function(w, h, aw, ah){
45443        Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
45444        this.slider.setSize(w, h);    
45445    },
45446    
45447    
45448    initEvents : function(){
45449        Ext.form.SliderField.superclass.initEvents.call(this);
45450        this.slider.on('change', this.onChange, this);   
45451    },
45452    
45453    
45454    onChange : function(slider, v){
45455        this.setValue(v, undefined, true);
45456    },
45457    
45458    
45459    onEnable : function(){
45460        Ext.form.SliderField.superclass.onEnable.call(this);
45461        this.slider.enable();
45462    },
45463    
45464    
45465    onDisable : function(){
45466        Ext.form.SliderField.superclass.onDisable.call(this);
45467        this.slider.disable();    
45468    },
45469    
45470    
45471    beforeDestroy : function(){
45472        Ext.destroy(this.slider);
45473        Ext.form.SliderField.superclass.beforeDestroy.call(this);
45474    },
45475    
45476    
45477    alignErrorIcon : function(){
45478        this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
45479    },
45480    
45481    
45482    setMinValue : function(v){
45483        this.slider.setMinValue(v);
45484        return this;    
45485    },
45486    
45487    
45488    setMaxValue : function(v){
45489        this.slider.setMaxValue(v);
45490        return this;    
45491    },
45492    
45493    
45494    setValue : function(v, animate,  silent){
45495        
45496        
45497        if(!silent){
45498            this.slider.setValue(v, animate);
45499        }
45500        return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
45501    },
45502    
45503    
45504    getValue : function(){
45505        return this.slider.getValue();    
45506    }
45507});
45508
45509Ext.reg('sliderfield', Ext.form.SliderField);
45510Ext.form.Label = Ext.extend(Ext.BoxComponent, {
45511    
45512    
45513    
45514
45515    
45516    onRender : function(ct, position){
45517        if(!this.el){
45518            this.el = document.createElement('label');
45519            this.el.id = this.getId();
45520            this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
45521            if(this.forId){
45522                this.el.setAttribute('for', this.forId);
45523            }
45524        }
45525        Ext.form.Label.superclass.onRender.call(this, ct, position);
45526    },
45527
45528    
45529    setText : function(t, encode){
45530        var e = encode === false;
45531        this[!e ? 'text' : 'html'] = t;
45532        delete this[e ? 'text' : 'html'];
45533        if(this.rendered){
45534            this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
45535        }
45536        return this;
45537    }
45538});
45539
45540Ext.reg('label', Ext.form.Label);
45541Ext.form.Action = function(form, options){
45542    this.form = form;
45543    this.options = options || {};
45544};
45545
45546
45547Ext.form.Action.CLIENT_INVALID = 'client';
45548
45549Ext.form.Action.SERVER_INVALID = 'server';
45550
45551Ext.form.Action.CONNECT_FAILURE = 'connect';
45552
45553Ext.form.Action.LOAD_FAILURE = 'load';
45554
45555Ext.form.Action.prototype = {
45556
45557
45558
45559
45560
45561
45562
45563
45564
45565
45566
45567
45568
45569
45570    type : 'default',
45571
45572 
45573 
45574
45575    
45576    run : function(options){
45577
45578    },
45579
45580    
45581    success : function(response){
45582
45583    },
45584
45585    
45586    handleResponse : function(response){
45587
45588    },
45589
45590    
45591    failure : function(response){
45592        this.response = response;
45593        this.failureType = Ext.form.Action.CONNECT_FAILURE;
45594        this.form.afterAction(this, false);
45595    },
45596
45597    
45598    
45599    
45600    processResponse : function(response){
45601        this.response = response;
45602        if(!response.responseText && !response.responseXML){
45603            return true;
45604        }
45605        this.result = this.handleResponse(response);
45606        return this.result;
45607    },
45608    
45609    decodeResponse: function(response) {
45610        try {
45611            return Ext.decode(response.responseText);
45612        } catch(e) {
45613            return false;
45614        } 
45615    },
45616
45617    
45618    getUrl : function(appendParams){
45619        var url = this.options.url || this.form.url || this.form.el.dom.action;
45620        if(appendParams){
45621            var p = this.getParams();
45622            if(p){
45623                url = Ext.urlAppend(url, p);
45624            }
45625        }
45626        return url;
45627    },
45628
45629    
45630    getMethod : function(){
45631        return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
45632    },
45633
45634    
45635    getParams : function(){
45636        var bp = this.form.baseParams;
45637        var p = this.options.params;
45638        if(p){
45639            if(typeof p == "object"){
45640                p = Ext.urlEncode(Ext.applyIf(p, bp));
45641            }else if(typeof p == 'string' && bp){
45642                p += '&' + Ext.urlEncode(bp);
45643            }
45644        }else if(bp){
45645            p = Ext.urlEncode(bp);
45646        }
45647        return p;
45648    },
45649
45650    
45651    createCallback : function(opts){
45652        var opts = opts || {};
45653        return {
45654            success: this.success,
45655            failure: this.failure,
45656            scope: this,
45657            timeout: (opts.timeout*1000) || (this.form.timeout*1000),
45658            upload: this.form.fileUpload ? this.success : undefined
45659        };
45660    }
45661};
45662
45663
45664Ext.form.Action.Submit = function(form, options){
45665    Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
45666};
45667
45668Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
45669    
45670    
45671    type : 'submit',
45672
45673    
45674    run : function(){
45675        var o = this.options,
45676            method = this.getMethod(),
45677            isGet = method == 'GET';
45678        if(o.clientValidation === false || this.form.isValid()){
45679            if (o.submitEmptyText === false) {
45680                var fields = this.form.items,
45681                    emptyFields = [],
45682                    setupEmptyFields = function(f){
45683                        if (f.el.getValue() == f.emptyText) {
45684                            emptyFields.push(f);
45685                            f.el.dom.value = "";
45686                        }
45687                        if(f.isComposite && f.rendered){
45688                            f.items.each(setupEmptyFields);
45689                        }
45690                    };
45691                    
45692                fields.each(setupEmptyFields);
45693            }
45694            Ext.Ajax.request(Ext.apply(this.createCallback(o), {
45695                form:this.form.el.dom,
45696                url:this.getUrl(isGet),
45697                method: method,
45698                headers: o.headers,
45699                params:!isGet ? this.getParams() : null,
45700                isUpload: this.form.fileUpload
45701            }));
45702            if (o.submitEmptyText === false) {
45703                Ext.each(emptyFields, function(f) {
45704                    if (f.applyEmptyText) {
45705                        f.applyEmptyText();
45706                    }
45707                });
45708            }
45709        }else if (o.clientValidation !== false){ 
45710            this.failureType = Ext.form.Action.CLIENT_INVALID;
45711            this.form.afterAction(this, false);
45712        }
45713    },
45714
45715    
45716    success : function(response){
45717        var result = this.processResponse(response);
45718        if(result === true || result.success){
45719            this.form.afterAction(this, true);
45720            return;
45721        }
45722        if(result.errors){
45723            this.form.markInvalid(result.errors);
45724        }
45725        this.failureType = Ext.form.Action.SERVER_INVALID;
45726        this.form.afterAction(this, false);
45727    },
45728
45729    
45730    handleResponse : function(response){
45731        if(this.form.errorReader){
45732            var rs = this.form.errorReader.read(response);
45733            var errors = [];
45734            if(rs.records){
45735                for(var i = 0, len = rs.records.length; i < len; i++) {
45736                    var r = rs.records[i];
45737                    errors[i] = r.data;
45738                }
45739            }
45740            if(errors.length < 1){
45741                errors = null;
45742            }
45743            return {
45744                success : rs.success,
45745                errors : errors
45746            };
45747        }
45748        return this.decodeResponse(response);
45749    }
45750});
45751
45752
45753
45754Ext.form.Action.Load = function(form, options){
45755    Ext.form.Action.Load.superclass.constructor.call(this, form, options);
45756    this.reader = this.form.reader;
45757};
45758
45759Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
45760    
45761    type : 'load',
45762
45763    
45764    run : function(){
45765        Ext.Ajax.request(Ext.apply(
45766                this.createCallback(this.options), {
45767                    method:this.getMethod(),
45768                    url:this.getUrl(false),
45769                    headers: this.options.headers,
45770                    params:this.getParams()
45771        }));
45772    },
45773
45774    
45775    success : function(response){
45776        var result = this.processResponse(response);
45777        if(result === true || !result.success || !result.data){
45778            this.failureType = Ext.form.Action.LOAD_FAILURE;
45779            this.form.afterAction(this, false);
45780            return;
45781        }
45782        this.form.clearInvalid();
45783        this.form.setValues(result.data);
45784        this.form.afterAction(this, true);
45785    },
45786
45787    
45788    handleResponse : function(response){
45789        if(this.form.reader){
45790            var rs = this.form.reader.read(response);
45791            var data = rs.records && rs.records[0] ? rs.records[0].data : null;
45792            return {
45793                success : rs.success,
45794                data : data
45795            };
45796        }
45797        return this.decodeResponse(response);
45798    }
45799});
45800
45801
45802
45803
45804Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
45805    constructor: function(form, opts) {
45806        Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
45807    },
45808    type : 'directload',
45809
45810    run : function(){
45811        var args = this.getParams();
45812        args.push(this.success, this);
45813        this.form.api.load.apply(window, args);
45814    },
45815
45816    getParams : function() {
45817        var buf = [], o = {};
45818        var bp = this.form.baseParams;
45819        var p = this.options.params;
45820        Ext.apply(o, p, bp);
45821        var paramOrder = this.form.paramOrder;
45822        if(paramOrder){
45823            for(var i = 0, len = paramOrder.length; i < len; i++){
45824                buf.push(o[paramOrder[i]]);
45825            }
45826        }else if(this.form.paramsAsHash){
45827            buf.push(o);
45828        }
45829        return buf;
45830    },
45831    
45832    
45833    
45834    processResponse : function(result) {
45835        this.result = result;
45836        return result;
45837    },
45838
45839    success : function(response, trans){
45840        if(trans.type == Ext.Direct.exceptions.SERVER){
45841            response = {};
45842        }
45843        Ext.form.Action.DirectLoad.superclass.success.call(this, response);
45844    }
45845});
45846
45847
45848Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
45849    constructor : function(form, opts) {
45850        Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
45851    },
45852    type : 'directsubmit',
45853    
45854    run : function(){
45855        var o = this.options;
45856        if(o.clientValidation === false || this.form.isValid()){
45857            
45858            
45859            this.success.params = this.getParams();
45860            this.form.api.submit(this.form.el.dom, this.success, this);
45861        }else if (o.clientValidation !== false){ 
45862            this.failureType = Ext.form.Action.CLIENT_INVALID;
45863            this.form.afterAction(this, false);
45864        }
45865    },
45866
45867    getParams : function() {
45868        var o = {};
45869        var bp = this.form.baseParams;
45870        var p = this.options.params;
45871        Ext.apply(o, p, bp);
45872        return o;
45873    },
45874    
45875    
45876    
45877    processResponse : function(result) {
45878        this.result = result;
45879        return result;
45880    },
45881
45882    success : function(response, trans){
45883        if(trans.type == Ext.Direct.exceptions.SERVER){
45884            response = {};
45885        }
45886        Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
45887    }
45888});
45889
45890Ext.form.Action.ACTION_TYPES = {
45891    'load' : Ext.form.Action.Load,
45892    'submit' : Ext.form.Action.Submit,
45893    'directload' : Ext.form.Action.DirectLoad,
45894    'directsubmit' : Ext.form.Action.DirectSubmit
45895};
45896
45897Ext.form.VTypes = function(){
45898    
45899    var alpha = /^[a-zA-Z_]+$/,
45900        alphanum = /^[a-zA-Z0-9_]+$/,
45901        email = /^(\w+)([\-+.\'][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
45902        url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
45903
45904    
45905    return {
45906        
45907        'email' : function(v){
45908            return email.test(v);
45909        },
45910        
45911        'emailText' : 'This field should be an e-mail address in the format "[email protected]"',
45912        
45913        'emailMask' : /[a-z0-9_\.\-\+\'@]/i,
45914
45915        /**
45916         * The function used to validate URLs
45917         * @param {String} value The URL
45918         * @return {Boolean} true if the RegExp test passed, and false if not.
45919         */
45920        'url' : function(v){
45921            return url.test(v);
45922        },
45923        /**
45924         * The error text to display when the url validation function returns false.  Defaults to:
45925         * <tt>'This field should be a URL in the format "http:/'+'/www.example.com"'</tt>
45926         * @type String
45927         */
45928        'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
45929
45930        /**
45931         * The function used to validate alpha values
45932         * @param {String} value The value
45933         * @return {Boolean} true if the RegExp test passed, and false if not.
45934         */
45935        'alpha' : function(v){
45936            return alpha.test(v);
45937        },
45938        /**
45939         * The error text to display when the alpha validation function returns false.  Defaults to:
45940         * <tt>'This field should only contain letters and _'</tt>
45941         * @type String
45942         */
45943        'alphaText' : 'This field should only contain letters and _',
45944        /**
45945         * The keystroke filter mask to be applied on alpha input.  Defaults to:
45946         * <tt>/[a-z_]/i</tt>
45947         * @type RegExp
45948         */
45949        'alphaMask' : /[a-z_]/i,
45950
45951        /**
45952         * The function used to validate alphanumeric values
45953         * @param {String} value The value
45954         * @return {Boolean} true if the RegExp test passed, and false if not.
45955         */
45956        'alphanum' : function(v){
45957            return alphanum.test(v);
45958        },
45959        /**
45960         * The error text to display when the alphanumeric validation function returns false.  Defaults to:
45961         * <tt>'This field should only contain letters, numbers and _'</tt>
45962         * @type String
45963         */
45964        'alphanumText' : 'This field should only contain letters, numbers and _',
45965        /**
45966         * The keystroke filter mask to be applied on alphanumeric input.  Defaults to:
45967         * <tt>/[a-z0-9_]/i</tt>
45968         * @type RegExp
45969         */
45970        'alphanumMask' : /[a-z0-9_]/i
45971    };
45972}();
45973/**
45974 * @class Ext.grid.GridPanel
45975 * @extends Ext.Panel
45976 * <p>This class represents the primary interface of a component based grid control to represent data
45977 * in a tabular format of rows and columns. The GridPanel is composed of the following:</p>
45978 * <div class="mdetail-params"><ul>
45979 * <li><b>{@link Ext.data.Store Store}</b> : The Model holding the data records (rows)
45980 * <div class="sub-desc"></div></li>
45981 * <li><b>{@link Ext.grid.ColumnModel Column model}</b> : Column makeup
45982 * <div class="sub-desc"></div></li>
45983 * <li><b>{@link Ext.grid.GridView View}</b> : Encapsulates the user interface
45984 * <div class="sub-desc"></div></li>
45985 * <li><b>{@link Ext.grid.AbstractSelectionModel selection model}</b> : Selection behavior
45986 * <div class="sub-desc"></div></li>
45987 * </ul></div>
45988 * <p>Example usage:</p>
45989 * <pre><code>
45990var grid = new Ext.grid.GridPanel({
45991    {@link #store}: new {@link Ext.data.Store}({
45992        {@link Ext.data.Store#autoDestroy autoDestroy}: true,
45993        {@link Ext.data.Store#reader reader}: reader,
45994        {@link Ext.data.Store#data data}: xg.dummyData
45995    }),
45996    {@link #colModel}: new {@link Ext.grid.ColumnModel}({
45997        {@link Ext.grid.ColumnModel#defaults defaults}: {
45998            width: 120,
45999            sortable: true
46000        },
46001        {@link Ext.grid.ColumnModel#columns columns}: [
46002            {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
46003            {header: 'Price', renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
46004            {header: 'Change', dataIndex: 'change'},
46005            {header: '% Change', dataIndex: 'pctChange'},
46006            // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
46007            {
46008                header: 'Last Updated', width: 135, dataIndex: 'lastChange',
46009                xtype: 'datecolumn', format: 'M d, Y'
46010            }
46011        ]
46012    }),
46013    {@link #viewConfig}: {
46014        {@link Ext.grid.GridView#forceFit forceFit}: true,
46015
46016//      Return CSS class to apply to rows depending upon data values
46017        {@link Ext.grid.GridView#getRowClass getRowClass}: function(record, index) {
46018            var c = record.{@link Ext.data.Record#get get}('change');
46019            if (c < 0) {
46020                return 'price-fall';
46021            } else if (c > 0) {
46022                return 'price-rise';
46023            }
46024        }
46025    },
46026    {@link #sm}: new Ext.grid.RowSelectionModel({singleSelect:true}),
46027    width: 600,
46028    height: 300,
46029    frame: true,
46030    title: 'Framed with Row Selection and Horizontal Scrolling',
46031    iconCls: 'icon-grid'
46032});
46033 * </code></pre>
46034 * <p><b><u>Notes:</u></b></p>
46035 * <div class="mdetail-params"><ul>
46036 * <li>Although this class inherits many configuration options from base classes, some of them
46037 * (such as autoScroll, autoWidth, layout, items, etc) are not used by this class, and will
46038 * have no effect.</li>
46039 * <li>A grid <b>requires</b> a width in which to scroll its columns, and a height in which to
46040 * scroll its rows. These dimensions can either be set explicitly through the
46041 * <tt>{@link Ext.BoxComponent#height height}</tt> and <tt>{@link Ext.BoxComponent#width width}</tt>
46042 * configuration options or implicitly set by using the grid as a child item of a
46043 * {@link Ext.Container Container} which will have a {@link Ext.Container#layout layout manager}
46044 * provide the sizing of its child items (for example the Container of the Grid may specify
46045 * <tt>{@link Ext.Container#layout layout}:'fit'</tt>).</li>
46046 * <li>To access the data in a Grid, it is necessary to use the data model encapsulated
46047 * by the {@link #store Store}. See the {@link #cellclick} event for more details.</li>
46048 * </ul></div>
46049 * @constructor
46050 * @param {Object} config The config object
46051 * @xtype grid
46052 */
46053Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
46054    /**
46055     * @cfg {String} autoExpandColumn
46056     * <p>The <tt>{@link Ext.grid.Column#id id}</tt> of a {@link Ext.grid.Column column} in
46057     * this grid that should expand to fill unused space. This value specified here can not
46058     * be <tt>0</tt>.</p>
46059     * <br><p><b>Note</b>: If the Grid's {@link Ext.grid.GridView view} is configured with
46060     * <tt>{@link Ext.grid.GridView#forceFit forceFit}=true</tt> the <tt>autoExpandColumn</tt>
46061     * is ignored. See {@link Ext.grid.Column}.<tt>{@link Ext.grid.Column#width width}</tt>
46062     * for additional details.</p>
46063     * <p>See <tt>{@link #autoExpandMax}</tt> and <tt>{@link #autoExpandMin}</tt> also.</p>
46064     */
46065    autoExpandColumn : false,
46066    
46067    
46068    autoExpandMax : 1000,
46069    
46070    
46071    autoExpandMin : 50,
46072    
46073    
46074    columnLines : false,
46075    
46076    
46077    
46078    
46079    
46080    
46081    ddText : '{0} selected row{1}',
46082    
46083    
46084    deferRowRender : true,
46085    
46086    
46087    
46088    
46089    enableColumnHide : true,
46090    
46091    
46092    enableColumnMove : true,
46093    
46094    
46095    enableDragDrop : false,
46096    
46097    
46098    enableHdMenu : true,
46099    
46100    
46101    
46102    loadMask : false,
46103    
46104    
46105    
46106    minColumnWidth : 25,
46107    
46108    
46109    
46110    
46111    
46112    stripeRows : false,
46113    
46114    
46115    trackMouseOver : true,
46116    
46117    
46118    stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
46119    
46120    
46121    view : null,
46122
46123    
46124    bubbleEvents: [],
46125
46126    
46127
46128    
46129    rendered : false,
46130    
46131    
46132    viewReady : false,
46133
46134    
46135    initComponent : function() {
46136        Ext.grid.GridPanel.superclass.initComponent.call(this);
46137
46138        if (this.columnLines) {
46139            this.cls = (this.cls || '') + ' x-grid-with-col-lines';
46140        }
46141        
46142        
46143        this.autoScroll = false;
46144        this.autoWidth = false;
46145
46146        if(Ext.isArray(this.columns)){
46147            this.colModel = new Ext.grid.ColumnModel(this.columns);
46148            delete this.columns;
46149        }
46150
46151        
46152        if(this.ds){
46153            this.store = this.ds;
46154            delete this.ds;
46155        }
46156        if(this.cm){
46157            this.colModel = this.cm;
46158            delete this.cm;
46159        }
46160        if(this.sm){
46161            this.selModel = this.sm;
46162            delete this.sm;
46163        }
46164        this.store = Ext.StoreMgr.lookup(this.store);
46165
46166        this.addEvents(
46167            
46168            
46169            'click',
46170            
46171            'dblclick',
46172            
46173            'contextmenu',
46174            
46175            'mousedown',
46176            
46177            'mouseup',
46178            
46179            'mouseover',
46180            
46181            'mouseout',
46182            
46183            'keypress',
46184            
46185            'keydown',
46186
46187            
46188            
46189            'cellmousedown',
46190            
46191            'rowmousedown',
46192            
46193            'headermousedown',
46194
46195            
46196            'groupmousedown',
46197
46198            
46199            'rowbodymousedown',
46200
46201            
46202            'containermousedown',
46203
46204            
46205            'cellclick',
46206            
46207            'celldblclick',
46208            
46209            'rowclick',
46210            
46211            'rowdblclick',
46212            
46213            'headerclick',
46214            
46215            'headerdblclick',
46216            
46217            'groupclick',
46218            
46219            'groupdblclick',
46220            
46221            'containerclick',
46222            
46223            'containerdblclick',
46224
46225            
46226            'rowbodyclick',
46227            
46228            'rowbodydblclick',
46229
46230            
46231            'rowcontextmenu',
46232            
46233            'cellcontextmenu',
46234            
46235            'headercontextmenu',
46236            
46237            'groupcontextmenu',
46238            
46239            'containercontextmenu',
46240            
46241            'rowbodycontextmenu',
46242            
46243            'bodyscroll',
46244            
46245            'columnresize',
46246            
46247            'columnmove',
46248            
46249            'sortchange',
46250            
46251            'groupchange',
46252            
46253            'reconfigure',
46254            
46255            'viewready'
46256        );
46257    },
46258
46259    
46260    onRender : function(ct, position){
46261        Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
46262
46263        var c = this.getGridEl();
46264
46265        this.el.addClass('x-grid-panel');
46266
46267        this.mon(c, {
46268            scope: this,
46269            mousedown: this.onMouseDown,
46270            click: this.onClick,
46271            dblclick: this.onDblClick,
46272            contextmenu: this.onContextMenu
46273        });
46274
46275        this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
46276
46277        var view = this.getView();
46278        view.init(this);
46279        view.render();
46280        this.getSelectionModel().init(this);
46281    },
46282
46283    
46284    initEvents : function(){
46285        Ext.grid.GridPanel.superclass.initEvents.call(this);
46286
46287        if(this.loadMask){
46288            this.loadMask = new Ext.LoadMask(this.bwrap,
46289                    Ext.apply({store:this.store}, this.loadMask));
46290        }
46291    },
46292
46293    initStateEvents : function(){
46294        Ext.grid.GridPanel.superclass.initStateEvents.call(this);
46295        this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
46296    },
46297
46298    applyState : function(state){
46299        var cm = this.colModel,
46300            cs = state.columns,
46301            store = this.store,
46302            s,
46303            c,
46304            colIndex;
46305
46306        if(cs){
46307            for(var i = 0, len = cs.length; i < len; i++){
46308                s = cs[i];
46309                c = cm.getColumnById(s.id);
46310                if(c){
46311                    colIndex = cm.getIndexById(s.id);
46312                    cm.setState(colIndex, {
46313                        hidden: s.hidden,
46314                        width: s.width,
46315                        sortable: s.sortable
46316                    });
46317                    if(colIndex != i){
46318                        cm.moveColumn(colIndex, i);
46319                    }
46320                }
46321            }
46322        }
46323        if(store){
46324            s = state.sort;
46325            if(s){
46326                store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
46327            }
46328            s = state.group;
46329            if(store.groupBy){
46330                if(s){
46331                    store.groupBy(s);
46332                }else{
46333                    store.clearGrouping();
46334                }
46335            }
46336
46337        }
46338        var o = Ext.apply({}, state);
46339        delete o.columns;
46340        delete o.sort;
46341        Ext.grid.GridPanel.superclass.applyState.call(this, o);
46342    },
46343
46344    getState : function(){
46345        var o = {columns: []},
46346            store = this.store,
46347            ss,
46348            gs;
46349
46350        for(var i = 0, c; (c = this.colModel.config[i]); i++){
46351            o.columns[i] = {
46352                id: c.id,
46353                width: c.width
46354            };
46355            if(c.hidden){
46356                o.columns[i].hidden = true;
46357            }
46358            if(c.sortable){
46359                o.columns[i].sortable = true;
46360            }
46361        }
46362        if(store){
46363            ss = store.getSortState();
46364            if(ss){
46365                o.sort = ss;
46366            }
46367            if(store.getGroupState){
46368                gs = store.getGroupState();
46369                if(gs){
46370                    o.group = gs;
46371                }
46372            }
46373        }
46374        return o;
46375    },
46376
46377    
46378    afterRender : function(){
46379        Ext.grid.GridPanel.superclass.afterRender.call(this);
46380        var v = this.view;
46381        this.on('bodyresize', v.layout, v);
46382        v.layout(true);
46383        if(this.deferRowRender){
46384            if (!this.deferRowRenderTask){
46385                this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
46386            }
46387            this.deferRowRenderTask.delay(10);
46388        }else{
46389            v.afterRender();
46390        }
46391        this.viewReady = true;
46392    },
46393
46394    
46395    reconfigure : function(store, colModel){
46396        var rendered = this.rendered;
46397        if(rendered){
46398            if(this.loadMask){
46399                this.loadMask.destroy();
46400                this.loadMask = new Ext.LoadMask(this.bwrap,
46401                        Ext.apply({}, {store:store}, this.initialConfig.loadMask));
46402            }
46403        }
46404        if(this.view){
46405            this.view.initData(store, colModel);
46406        }
46407        this.store = store;
46408        this.colModel = colModel;
46409        if(rendered){
46410            this.view.refresh(true);
46411        }
46412        this.fireEvent('reconfigure', this, store, colModel);
46413    },
46414
46415    
46416    onDestroy : function(){
46417        if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
46418            this.deferRowRenderTask.cancel();
46419        }
46420        if(this.rendered){
46421            Ext.destroy(this.view, this.loadMask);
46422        }else if(this.store && this.store.autoDestroy){
46423            this.store.destroy();
46424        }
46425        Ext.destroy(this.colModel, this.selModel);
46426        this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
46427        Ext.grid.GridPanel.superclass.onDestroy.call(this);
46428    },
46429
46430    
46431    processEvent : function(name, e){
46432        this.view.processEvent(name, e);
46433    },
46434
46435    
46436    onClick : function(e){
46437        this.processEvent('click', e);
46438    },
46439
46440    
46441    onMouseDown : function(e){
46442        this.processEvent('mousedown', e);
46443    },
46444
46445    
46446    onContextMenu : function(e, t){
46447        this.processEvent('contextmenu', e);
46448    },
46449
46450    
46451    onDblClick : function(e){
46452        this.processEvent('dblclick', e);
46453    },
46454
46455    
46456    walkCells : function(row, col, step, fn, scope){
46457        var cm    = this.colModel,
46458            clen  = cm.getColumnCount(),
46459            ds    = this.store,
46460            rlen  = ds.getCount(),
46461            first = true;
46462
46463        if(step < 0){
46464            if(col < 0){
46465                row--;
46466                first = false;
46467            }
46468            while(row >= 0){
46469                if(!first){
46470                    col = clen-1;
46471                }
46472                first = false;
46473                while(col >= 0){
46474                    if(fn.call(scope || this, row, col, cm) === true){
46475                        return [row, col];
46476                    }
46477                    col--;
46478                }
46479                row--;
46480            }
46481        } else {
46482            if(col >= clen){
46483                row++;
46484                first = false;
46485            }
46486            while(row < rlen){
46487                if(!first){
46488                    col = 0;
46489                }
46490                first = false;
46491                while(col < clen){
46492                    if(fn.call(scope || this, row, col, cm) === true){
46493                        return [row, col];
46494                    }
46495                    col++;
46496                }
46497                row++;
46498            }
46499        }
46500        return null;
46501    },
46502
46503    
46504    getGridEl : function(){
46505        return this.body;
46506    },
46507
46508    
46509    stopEditing : Ext.emptyFn,
46510
46511    
46512    getSelectionModel : function(){
46513        if(!this.selModel){
46514            this.selModel = new Ext.grid.RowSelectionModel(
46515                    this.disableSelection ? {selectRow: Ext.emptyFn} : null);
46516        }
46517        return this.selModel;
46518    },
46519
46520    
46521    getStore : function(){
46522        return this.store;
46523    },
46524
46525    
46526    getColumnModel : function(){
46527        return this.colModel;
46528    },
46529
46530    
46531    getView : function() {
46532        if (!this.view) {
46533            this.view = new Ext.grid.GridView(this.viewConfig);
46534        }
46535        
46536        return this.view;
46537    },
46538    
46539    getDragDropText : function(){
46540        var count = this.selModel.getCount();
46541        return String.format(this.ddText, count, count == 1 ? '' : 's');
46542    }
46543
46544    
46545    
46546    
46547    
46548    
46549    
46550    
46551    
46552    
46553    
46554    
46555    
46556    
46557    
46558    
46559    
46560    
46561    
46562    
46563    
46564    
46565    
46566    
46567    
46568    
46569    
46570    
46571    
46572    
46573    
46574    
46575
46576
46577
46578    
46579    
46580    
46581    
46582    
46583    
46584    
46585    
46586    
46587    
46588    
46589    
46590    
46591    
46592    
46593    
46594});
46595Ext.reg('grid', Ext.grid.GridPanel);
46596Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {
46597    
46598    
46599    aggregator: 'sum',
46600    
46601    
46602    renderer: undefined,
46603    
46604    
46605    
46606    
46607    
46608    
46609    
46610    
46611    initComponent: function() {
46612        Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);
46613        
46614        this.initAxes();
46615        
46616        
46617        this.enableColumnResize = false;
46618        
46619        this.viewConfig = Ext.apply(this.viewConfig || {}, {
46620            forceFit: true
46621        });
46622        
46623        
46624        
46625        this.colModel = new Ext.grid.ColumnModel({});
46626    },
46627    
46628    
46629    getAggregator: function() {
46630        if (typeof this.aggregator == 'string') {
46631            return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
46632        } else {
46633            return this.aggregator;
46634        }
46635    },
46636    
46637    
46638    setAggregator: function(aggregator) {
46639        this.aggregator = aggregator;
46640    },
46641    
46642    
46643    setMeasure: function(measure) {
46644        this.measure = measure;
46645    },
46646    
46647    
46648    setLeftAxis: function(axis, refresh) {
46649        
46650        this.leftAxis = axis;
46651        
46652        if (refresh) {
46653            this.view.refresh();
46654        }
46655    },
46656    
46657    
46658    setTopAxis: function(axis, refresh) {
46659        
46660        this.topAxis = axis;
46661        
46662        if (refresh) {
46663            this.view.refresh();
46664        }
46665    },
46666    
46667    
46668    initAxes: function() {
46669        var PivotAxis = Ext.grid.PivotAxis;
46670        
46671        if (!(this.leftAxis instanceof PivotAxis)) {
46672            this.setLeftAxis(new PivotAxis({
46673                orientation: 'vertical',
46674                dimensions : this.leftAxis || [],
46675                store      : this.store
46676            }));
46677        };
46678        
46679        if (!(this.topAxis instanceof PivotAxis)) {
46680            this.setTopAxis(new PivotAxis({
46681                orientation: 'horizontal',
46682                dimensions : this.topAxis || [],
46683                store      : this.store
46684            }));
46685        };
46686    },
46687    
46688    
46689    extractData: function() {
46690        var records  = this.store.data.items,
46691            recCount = records.length,
46692            cells    = [],
46693            record, i, j, k;
46694        
46695        if (recCount == 0) {
46696            return [];
46697        }
46698        
46699        var leftTuples = this.leftAxis.getTuples(),
46700            leftCount  = leftTuples.length,
46701            topTuples  = this.topAxis.getTuples(),
46702            topCount   = topTuples.length,
46703            aggregator = this.getAggregator();
46704        
46705        for (i = 0; i < recCount; i++) {
46706            record = records[i];
46707            
46708            for (j = 0; j < leftCount; j++) {
46709                cells[j] = cells[j] || [];
46710                
46711                if (leftTuples[j].matcher(record) === true) {
46712                    for (k = 0; k < topCount; k++) {
46713                        cells[j][k] = cells[j][k] || [];
46714                        
46715                        if (topTuples[k].matcher(record)) {
46716                            cells[j][k].push(record);
46717                        }
46718                    }
46719                }
46720            }
46721        }
46722        
46723        var rowCount = cells.length,
46724            colCount, row;
46725        
46726        for (i = 0; i < rowCount; i++) {
46727            row = cells[i];
46728            colCount = row.length;
46729            
46730            for (j = 0; j < colCount; j++) {
46731                cells[i][j] = aggregator(cells[i][j], this.measure);
46732            }
46733        }
46734        
46735        return cells;
46736    },
46737    
46738    
46739    getView: function() {
46740        if (!this.view) {
46741            this.view = new Ext.grid.PivotGridView(this.viewConfig);
46742        }
46743        
46744        return this.view;
46745    }
46746});
46747
46748Ext.reg('pivotgrid', Ext.grid.PivotGrid);
46749
46750
46751Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();
46752
46753Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
46754    var length = records.length,
46755        total  = 0,
46756        i;
46757    
46758    for (i = 0; i < length; i++) {
46759        total += records[i].get(measure);
46760    }
46761    
46762    return total;
46763});
46764
46765Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
46766    var length = records.length,
46767        total  = 0,
46768        i;
46769    
46770    for (i = 0; i < length; i++) {
46771        total += records[i].get(measure);
46772    }
46773    
46774    return (total / length) || 'n/a';
46775});
46776
46777Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
46778    var data   = [],
46779        length = records.length,
46780        i;
46781    
46782    for (i = 0; i < length; i++) {
46783        data.push(records[i].get(measure));
46784    }
46785    
46786    return Math.min.apply(this, data) || 'n/a';
46787});
46788
46789Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
46790    var data   = [],
46791        length = records.length,
46792        i;
46793    
46794    for (i = 0; i < length; i++) {
46795        data.push(records[i].get(measure));
46796    }
46797    
46798    return Math.max.apply(this, data) || 'n/a';
46799});
46800
46801Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
46802    return records.length;
46803});
46804Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
46805    
46806
46807    
46808
46809    
46810
46811    
46812
46813    
46814
46815    
46816    deferEmptyText : true,
46817
46818    
46819    scrollOffset : undefined,
46820
46821    
46822    autoFill : false,
46823
46824    
46825    forceFit : false,
46826
46827    
46828    sortClasses : ['sort-asc', 'sort-desc'],
46829
46830    
46831    sortAscText : 'Sort Ascending',
46832
46833    
46834    sortDescText : 'Sort Descending',
46835
46836    
46837    columnsText : 'Columns',
46838
46839    
46840    selectedRowClass : 'x-grid3-row-selected',
46841
46842    
46843    borderWidth : 2,
46844    tdClass : 'x-grid3-cell',
46845    hdCls : 'x-grid3-hd',
46846    
46847    
46848    
46849    markDirty : true,
46850
46851    
46852    cellSelectorDepth : 4,
46853    
46854    
46855    rowSelectorDepth : 10,
46856
46857    
46858    rowBodySelectorDepth : 10,
46859
46860    
46861    cellSelector : 'td.x-grid3-cell',
46862    
46863    
46864    rowSelector : 'div.x-grid3-row',
46865
46866    
46867    rowBodySelector : 'div.x-grid3-row-body',
46868
46869    
46870    firstRowCls: 'x-grid3-row-first',
46871    lastRowCls: 'x-grid3-row-last',
46872    rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
46873    
46874    
46875    headerMenuOpenCls: 'x-grid3-hd-menu-open',
46876    
46877    
46878    rowOverCls: 'x-grid3-row-over',
46879
46880    constructor : function(config) {
46881        Ext.apply(this, config);
46882        
46883        
46884        this.addEvents(
46885            
46886            'beforerowremoved',
46887            
46888            
46889            'beforerowsinserted',
46890            
46891            
46892            'beforerefresh',
46893            
46894            
46895            'rowremoved',
46896            
46897            
46898            'rowsinserted',
46899            
46900            
46901            'rowupdated',
46902            
46903            
46904            'refresh'
46905        );
46906        
46907        Ext.grid.GridView.superclass.constructor.call(this);
46908    },
46909
46910    
46911    
46912    
46913    masterTpl: new Ext.Template(
46914        '<div class="x-grid3" hidefocus="true">',
46915            '<div class="x-grid3-viewport">',
46916                '<div class="x-grid3-header">',
46917                    '<div class="x-grid3-header-inner">',
46918                        '<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
46919                    '</div>',
46920                    '<div class="x-clear"></div>',
46921                '</div>',
46922                '<div class="x-grid3-scroller">',
46923                    '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
46924                    '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
46925                '</div>',
46926            '</div>',
46927            '<div class="x-grid3-resize-marker">&#160;</div>',
46928            '<div class="x-grid3-resize-proxy">&#160;</div>',
46929        '</div>'
46930    ),
46931    
46932    
46933    headerTpl: new Ext.Template(
46934        '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46935            '<thead>',
46936                '<tr class="x-grid3-hd-row">{cells}</tr>',
46937            '</thead>',
46938        '</table>'
46939    ),
46940    
46941    
46942    bodyTpl: new Ext.Template('{rows}'),
46943    
46944    
46945    cellTpl: new Ext.Template(
46946        '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
46947            '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
46948        '</td>'
46949    ),
46950    
46951    
46952    initTemplates : function() {
46953        var templates = this.templates || {},
46954            template, name,
46955            
46956            headerCellTpl = new Ext.Template(
46957                '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
46958                    '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
46959                        this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
46960                        '{value}',
46961                        '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
46962                    '</div>',
46963                '</td>'
46964            ),
46965        
46966            rowBodyText = [
46967                '<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
46968                    '<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
46969                        '<div class="x-grid3-row-body">{body}</div>',
46970                    '</td>',
46971                '</tr>'
46972            ].join(""),
46973        
46974            innerText = [
46975                '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46976                     '<tbody>',
46977                        '<tr>{cells}</tr>',
46978                        this.enableRowBody ? rowBodyText : '',
46979                     '</tbody>',
46980                '</table>'
46981            ].join("");
46982        
46983        Ext.applyIf(templates, {
46984            hcell   : headerCellTpl,
46985            cell    : this.cellTpl,
46986            body    : this.bodyTpl,
46987            header  : this.headerTpl,
46988            master  : this.masterTpl,
46989            row     : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
46990            rowInner: new Ext.Template(innerText)
46991        });
46992
46993        for (name in templates) {
46994            template = templates[name];
46995            
46996            if (template && Ext.isFunction(template.compile) && !template.compiled) {
46997                template.disableFormats = true;
46998                template.compile();
46999            }
47000        }
47001
47002        this.templates = templates;
47003        this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
47004    },
47005
47006    
47007    fly : function(el) {
47008        if (!this._flyweight) {
47009            this._flyweight = new Ext.Element.Flyweight(document.body);
47010        }
47011        this._flyweight.dom = el;
47012        return this._flyweight;
47013    },
47014
47015    
47016    getEditorParent : function() {
47017        return this.scroller.dom;
47018    },
47019
47020    
47021    initElements : function() {
47022        var Element  = Ext.Element,
47023            el       = Ext.get(this.grid.getGridEl().dom.firstChild),
47024            mainWrap = new Element(el.child('div.x-grid3-viewport')),
47025            mainHd   = new Element(mainWrap.child('div.x-grid3-header')),
47026            scroller = new Element(mainWrap.child('div.x-grid3-scroller'));
47027        
47028        if (this.grid.hideHeaders) {
47029            mainHd.setDisplayed(false);
47030        }
47031        
47032        if (this.forceFit) {
47033            scroller.setStyle('overflow-x', 'hidden');
47034        }
47035        
47036        
47037        
47038        Ext.apply(this, {
47039            el      : el,
47040            mainWrap: mainWrap,
47041            scroller: scroller,
47042            mainHd  : mainHd,
47043            innerHd : mainHd.child('div.x-grid3-header-inner').dom,
47044            mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
47045            focusEl : new Element(Element.fly(scroller).child('a')),
47046            
47047            resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
47048            resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
47049        });
47050        
47051        this.focusEl.swallowEvent('click', true);
47052    },
47053
47054    
47055    getRows : function() {
47056        return this.hasRows() ? this.mainBody.dom.childNodes : [];
47057    },
47058
47059    
47060
47061    
47062    findCell : function(el) {
47063        if (!el) {
47064            return false;
47065        }
47066        return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
47067    },
47068
47069    
47070    findCellIndex : function(el, requiredCls) {
47071        var cell = this.findCell(el),
47072            hasCls;
47073        
47074        if (cell) {
47075            hasCls = this.fly(cell).hasClass(requiredCls);
47076            if (!requiredCls || hasCls) {
47077                return this.getCellIndex(cell);
47078            }
47079        }
47080        return false;
47081    },
47082
47083    
47084    getCellIndex : function(el) {
47085        if (el) {
47086            var match = el.className.match(this.colRe);
47087            
47088            if (match && match[1]) {
47089                return this.cm.getIndexById(match[1]);
47090            }
47091        }
47092        return false;
47093    },
47094
47095    
47096    findHeaderCell : function(el) {
47097        var cell = this.findCell(el);
47098        return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
47099    },
47100
47101    
47102    findHeaderIndex : function(el){
47103        return this.findCellIndex(el, this.hdCls);
47104    },
47105
47106    
47107    findRow : function(el) {
47108        if (!el) {
47109            return false;
47110        }
47111        return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
47112    },
47113
47114    
47115    findRowIndex : function(el) {
47116        var row = this.findRow(el);
47117        return row ? row.rowIndex : false;
47118    },
47119
47120    
47121    findRowBody : function(el) {
47122        if (!el) {
47123            return false;
47124        }
47125        
47126        return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
47127    },
47128
47129    
47130
47131    
47132    getRow : function(row) {
47133        return this.getRows()[row];
47134    },
47135
47136    
47137    getCell : function(row, col) {
47138        return Ext.fly(this.getRow(row)).query(this.cellSelector)[col]; 
47139    },
47140
47141    
47142    getHeaderCell : function(index) {
47143        return this.mainHd.dom.getElementsByTagName('td')[index];
47144    },
47145
47146    
47147
47148    
47149    addRowClass : function(rowId, cls) {
47150        var row = this.getRow(rowId);
47151        if (row) {
47152            this.fly(row).addClass(cls);
47153        }
47154    },
47155
47156    
47157    removeRowClass : function(row, cls) {
47158        var r = this.getRow(row);
47159        if(r){
47160            this.fly(r).removeClass(cls);
47161        }
47162    },
47163
47164    
47165    removeRow : function(row) {
47166        Ext.removeNode(this.getRow(row));
47167        this.syncFocusEl(row);
47168    },
47169
47170    
47171    removeRows : function(firstRow, lastRow) {
47172        var bd = this.mainBody.dom,
47173            rowIndex;
47174            
47175        for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
47176            Ext.removeNode(bd.childNodes[firstRow]);
47177        }
47178        
47179        this.syncFocusEl(firstRow);
47180    },
47181
47182    
47183    
47184    
47185    getScrollState : function() {
47186        var sb = this.scroller.dom;
47187        
47188        return {
47189            left: sb.scrollLeft, 
47190            top : sb.scrollTop
47191        };
47192    },
47193
47194    
47195    restoreScroll : function(state) {
47196        var sb = this.scroller.dom;
47197        sb.scrollLeft = state.left;
47198        sb.scrollTop  = state.top;
47199    },
47200
47201    
47202    scrollToTop : function() {
47203        var dom = this.scroller.dom;
47204        
47205        dom.scrollTop  = 0;
47206        dom.scrollLeft = 0;
47207    },
47208
47209    
47210    syncScroll : function() {
47211        this.syncHeaderScroll();
47212        var mb = this.scroller.dom;
47213        this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
47214    },
47215
47216    
47217    syncHeaderScroll : function() {
47218        var innerHd    = this.innerHd,
47219            scrollLeft = this.scroller.dom.scrollLeft;
47220        
47221        innerHd.scrollLeft = scrollLeft;
47222        innerHd.scrollLeft = scrollLeft; 
47223    },
47224    
47225    
47226    updateSortIcon : function(col, dir) {
47227        var sortClasses = this.sortClasses,
47228            sortClass   = sortClasses[dir == "DESC" ? 1 : 0],
47229            headers     = this.mainHd.select('td').removeClass(sortClasses);
47230        
47231        headers.item(col).addClass(sortClass);
47232    },
47233
47234    
47235    updateAllColumnWidths : function() {
47236        var totalWidth = this.getTotalWidth(),
47237            colCount   = this.cm.getColumnCount(),
47238            rows       = this.getRows(),
47239            rowCount   = rows.length,
47240            widths     = [],
47241            row, rowFirstChild, trow, i, j;
47242        
47243        for (i = 0; i < colCount; i++) {
47244            widths[i] = this.getColumnWidth(i);
47245            this.getHeaderCell(i).style.width = widths[i];
47246        }
47247        
47248        this.updateHeaderWidth();
47249        
47250        for (i = 0; i < rowCount; i++) {
47251            row = rows[i];
47252            row.style.width = totalWidth;
47253            rowFirstChild = row.firstChild;
47254            
47255            if (rowFirstChild) {
47256                rowFirstChild.style.width = totalWidth;
47257                trow = rowFirstChild.rows[0];
47258                
47259                for (j = 0; j < colCount; j++) {
47260                    trow.childNodes[j].style.width = widths[j];
47261                }
47262            }
47263        }
47264        
47265        this.onAllColumnWidthsUpdated(widths, totalWidth);
47266    },
47267
47268    
47269    updateColumnWidth : function(column, width) {
47270        var columnWidth = this.getColumnWidth(column),
47271            totalWidth  = this.getTotalWidth(),
47272            headerCell  = this.getHeaderCell(column),
47273            nodes       = this.getRows(),
47274            nodeCount   = nodes.length,
47275            row, i, firstChild;
47276        
47277        this.updateHeaderWidth();
47278        headerCell.style.width = columnWidth;
47279        
47280        for (i = 0; i < nodeCount; i++) {
47281            row = nodes[i];
47282            firstChild = row.firstChild;
47283            
47284            row.style.width = totalWidth;
47285            if (firstChild) {
47286                firstChild.style.width = totalWidth;
47287                firstChild.rows[0].childNodes[column].style.width = columnWidth;
47288            }
47289        }
47290        
47291        this.onColumnWidthUpdated(column, columnWidth, totalWidth);
47292    },
47293    
47294    
47295    updateColumnHidden : function(col, hidden) {
47296        var totalWidth = this.getTotalWidth(),
47297            display    = hidden ? 'none' : '',
47298            headerCell = this.getHeaderCell(col),
47299            nodes      = this.getRows(),
47300            nodeCount  = nodes.length,
47301            row, rowFirstChild, i;
47302        
47303        this.updateHeaderWidth();
47304        headerCell.style.display = display;
47305        
47306        for (i = 0; i < nodeCount; i++) {
47307            row = nodes[i];
47308            row.style.width = totalWidth;
47309            rowFirstChild = row.firstChild;
47310            
47311            if (rowFirstChild) {
47312                rowFirstChild.style.width = totalWidth;
47313                rowFirstChild.rows[0].childNodes[col].style.display = display;
47314            }
47315        }
47316        
47317        this.onColumnHiddenUpdated(col, hidden, totalWidth);
47318        delete this.lastViewWidth; 
47319        this.layout();
47320    },
47321
47322    
47323    doRender : function(columns, records, store, startRow, colCount, stripe) {
47324        var templates = this.templates,
47325            cellTemplate = templates.cell,
47326            rowTemplate = templates.row,
47327            last = colCount - 1,
47328            tstyle = 'width:' + this.getTotalWidth() + ';',
47329            
47330            rowBuffer = [],
47331            colBuffer = [],
47332            rowParams = {tstyle: tstyle},
47333            meta = {},
47334            len  = records.length,
47335            alt,
47336            column,
47337            record, i, j, rowIndex;
47338
47339        
47340        for (j = 0; j < len; j++) {
47341            record    = records[j];
47342            colBuffer = [];
47343
47344            rowIndex = j + startRow;
47345
47346            
47347            for (i = 0; i < colCount; i++) {
47348                column = columns[i];
47349                
47350                meta.id    = column.id;
47351                meta.css   = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
47352                meta.attr  = meta.cellAttr = '';
47353                meta.style = column.style;
47354                meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
47355
47356                if (Ext.isEmpty(meta.value)) {
47357                    meta.value = '&#160;';
47358                }
47359
47360                if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
47361                    meta.css += ' x-grid3-dirty-cell';
47362                }
47363
47364                colBuffer[colBuffer.length] = cellTemplate.apply(meta);
47365            }
47366
47367            alt = [];
47368            
47369            if (stripe && ((rowIndex + 1) % 2 === 0)) {
47370                alt[0] = 'x-grid3-row-alt';
47371            }
47372
47373            if (record.dirty) {
47374                alt[1] = ' x-grid3-dirty-row';
47375            }
47376
47377            rowParams.cols = colCount;
47378
47379            if (this.getRowClass) {
47380                alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
47381            }
47382
47383            rowParams.alt   = alt.join(' ');
47384            rowParams.cells = colBuffer.join('');
47385
47386            rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
47387        }
47388
47389        return rowBuffer.join('');
47390    },
47391
47392    
47393    processRows : function(startRow, skipStripe) {
47394        if (!this.ds || this.ds.getCount() < 1) {
47395            return;
47396        }
47397
47398        var rows   = this.getRows(),
47399            length = rows.length,
47400            row, i;
47401
47402        skipStripe = skipStripe || !this.grid.stripeRows;
47403        startRow   = startRow   || 0;
47404
47405        for (i = 0; i < length; i++) {
47406            row = rows[i];
47407            if (row) {
47408                row.rowIndex = i;
47409                if (!skipStripe) {
47410                    row.className = row.className.replace(this.rowClsRe, ' ');
47411                    if ((i + 1) % 2 === 0){
47412                        row.className += ' x-grid3-row-alt';
47413                    }
47414                }
47415            }
47416        }
47417
47418        
47419        if (startRow === 0) {
47420            Ext.fly(rows[0]).addClass(this.firstRowCls);
47421        }
47422
47423        Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
47424    },
47425    
47426    
47427    afterRender : function() {
47428        if (!this.ds || !this.cm) {
47429            return;
47430        }
47431        
47432        this.mainBody.dom.innerHTML = this.renderBody() || '&#160;';
47433        this.processRows(0, true);
47434
47435        if (this.deferEmptyText !== true) {
47436            this.applyEmptyText();
47437        }
47438        
47439        this.grid.fireEvent('viewready', this.grid);
47440    },
47441    
47442    
47443    afterRenderUI: function() {
47444        var grid = this.grid;
47445        
47446        this.initElements();
47447
47448        
47449        Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
47450
47451        this.mainHd.on({
47452            scope    : this,
47453            mouseover: this.handleHdOver,
47454            mouseout : this.handleHdOut,
47455            mousemove: this.handleHdMove
47456        });
47457
47458        this.scroller.on('scroll', this.syncScroll,  this);
47459        
47460        if (grid.enableColumnResize !== false) {
47461            this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
47462        }
47463
47464        if (grid.enableColumnMove) {
47465            this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
47466            this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
47467        }
47468
47469        if (grid.enableHdMenu !== false) {
47470            this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'});
47471            this.hmenu.add(
47472                {itemId:'asc',  text: this.sortAscText,  cls: 'xg-hmenu-sort-asc'},
47473                {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
47474            );
47475
47476            if (grid.enableColumnHide !== false) {
47477                this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'});
47478                this.colMenu.on({
47479                    scope     : this,
47480                    beforeshow: this.beforeColMenuShow,
47481                    itemclick : this.handleHdMenuClick
47482                });
47483                this.hmenu.add('-', {
47484                    itemId:'columns',
47485                    hideOnClick: false,
47486                    text: this.columnsText,
47487                    menu: this.colMenu,
47488                    iconCls: 'x-cols-icon'
47489                });
47490            }
47491
47492            this.hmenu.on('itemclick', this.handleHdMenuClick, this);
47493        }
47494
47495        if (grid.trackMouseOver) {
47496            this.mainBody.on({
47497                scope    : this,
47498                mouseover: this.onRowOver,
47499                mouseout : this.onRowOut
47500            });
47501        }
47502
47503        if (grid.enableDragDrop || grid.enableDrag) {
47504            this.dragZone = new Ext.grid.GridDragZone(grid, {
47505                ddGroup : grid.ddGroup || 'GridDD'
47506            });
47507        }
47508
47509        this.updateHeaderSortState();
47510    },
47511
47512    
47513    renderUI : function() {
47514        var templates = this.templates;
47515
47516        return templates.master.apply({
47517            body  : templates.body.apply({rows:'&#160;'}),
47518            header: this.renderHeaders(),
47519            ostyle: 'width:' + this.getOffsetWidth() + ';',
47520            bstyle: 'width:' + this.getTotalWidth()  + ';'
47521        });
47522    },
47523
47524    
47525    processEvent : function(name, e) {
47526        var target = e.getTarget(),
47527            grid   = this.grid,
47528            header = this.findHeaderIndex(target),
47529            row, cell, col, body;
47530
47531        grid.fireEvent(name, e);
47532
47533        if (header !== false) {
47534            grid.fireEvent('header' + name, grid, header, e);
47535        } else {
47536            row = this.findRowIndex(target);
47537
47538
47539
47540
47541            if (row !== false) {
47542                cell = this.findCellIndex(target);
47543                if (cell !== false) {
47544                    col = grid.colModel.getColumnAt(cell);
47545                    if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
47546                        if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
47547                            grid.fireEvent('row' + name, grid, row, e);
47548                        }
47549                    }
47550                } else {
47551                    if (grid.fireEvent('row' + name, grid, row, e) !== false) {
47552                        (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
47553                    }
47554                }
47555            } else {
47556                grid.fireEvent('container' + name, grid, e);
47557            }
47558        }
47559    },
47560
47561    
47562    layout : function(initial) {
47563        if (!this.mainBody) {
47564            return; 
47565        }
47566
47567        var grid       = this.grid,
47568            gridEl     = grid.getGridEl(),
47569            gridSize   = gridEl.getSize(true),
47570            gridWidth  = gridSize.width,
47571            gridHeight = gridSize.height,
47572            scroller   = this.scroller,
47573            scrollStyle, headerHeight, scrollHeight;
47574        
47575        if (gridWidth < 20 || gridHeight < 20) {
47576            return;
47577        }
47578        
47579        if (grid.autoHeight) {
47580            scrollStyle = scroller.dom.style;
47581            scrollStyle.overflow = 'visible';
47582            
47583            if (Ext.isWebKit) {
47584                scrollStyle.position = 'static';
47585            }
47586        } else {
47587            this.el.setSize(gridWidth, gridHeight);
47588            
47589            headerHeight = this.mainHd.getHeight();
47590            scrollHeight = gridHeight - headerHeight;
47591            
47592            scroller.setSize(gridWidth, scrollHeight);
47593            
47594            if (this.innerHd) {
47595                this.innerHd.style.width = (gridWidth) + "px";
47596            }
47597        }
47598        
47599        if (this.forceFit || (initial === true && this.autoFill)) {
47600            if (this.lastViewWidth != gridWidth) {
47601                this.fitColumns(false, false);
47602                this.lastViewWidth = gridWidth;
47603            }
47604        } else {
47605            this.autoExpand();
47606            this.syncHeaderScroll();
47607        }
47608        
47609        this.onLayout(gridWidth, scrollHeight);
47610    },
47611
47612    
47613    
47614    onLayout : function(vw, vh) {
47615        
47616    },
47617
47618    onColumnWidthUpdated : function(col, w, tw) {
47619        
47620    },
47621
47622    onAllColumnWidthsUpdated : function(ws, tw) {
47623        
47624    },
47625
47626    onColumnHiddenUpdated : function(col, hidden, tw) {
47627        
47628    },
47629
47630    updateColumnText : function(col, text) {
47631        
47632    },
47633
47634    afterMove : function(colIndex) {
47635        
47636    },
47637
47638    
47639    
47640    init : function(grid) {
47641        this.grid = grid;
47642
47643        this.initTemplates();
47644        this.initData(grid.store, grid.colModel);
47645        this.initUI(grid);
47646    },
47647
47648    
47649    getColumnId : function(index){
47650        return this.cm.getColumnId(index);
47651    },
47652
47653    
47654    getOffsetWidth : function() {
47655        return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
47656    },
47657
47658    
47659    getScrollOffset: function() {
47660        return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
47661    },
47662
47663    
47664    renderHeaders : function() {
47665        var colModel   = this.cm,
47666            templates  = this.templates,
47667            headerTpl  = templates.hcell,
47668            properties = {},
47669            colCount   = colModel.getColumnCount(),
47670            last       = colCount - 1,
47671            cells      = [],
47672            i, cssCls;
47673        
47674        for (i = 0; i < colCount; i++) {
47675            if (i == 0) {
47676                cssCls = 'x-grid3-cell-first ';
47677            } else {
47678                cssCls = i == last ? 'x-grid3-cell-last ' : '';
47679            }
47680            
47681            properties = {
47682                id     : colModel.getColumnId(i),
47683                value  : colModel.getColumnHeader(i) || '',
47684                style  : this.getColumnStyle(i, true),
47685                css    : cssCls,
47686                tooltip: this.getColumnTooltip(i)
47687            };
47688            
47689            if (colModel.config[i].align == 'right') {
47690                properties.istyle = 'padding-right: 16px;';
47691            } else {
47692                delete properties.istyle;
47693            }
47694            
47695            cells[i] = headerTpl.apply(properties);
47696        }
47697        
47698        return templates.header.apply({
47699            cells : cells.join(""),
47700            tstyle: String.format("width: {0};", this.getTotalWidth())
47701        });
47702    },
47703
47704    
47705    getColumnTooltip : function(i) {
47706        var tooltip = this.cm.getColumnTooltip(i);
47707        if (tooltip) {
47708            if (Ext.QuickTips.isEnabled()) {
47709                return 'ext:qtip="' + tooltip + '"';
47710            } else {
47711                return 'title="' + tooltip + '"';
47712            }
47713        }
47714        
47715        return '';
47716    },
47717
47718    
47719    beforeUpdate : function() {
47720        this.grid.stopEditing(true);
47721    },
47722
47723    
47724    updateHeaders : function() {
47725        this.innerHd.firstChild.innerHTML = this.renderHeaders();
47726        
47727        this.updateHeaderWidth(false);
47728    },
47729    
47730    
47731    updateHeaderWidth: function(updateMain) {
47732        var innerHdChild = this.innerHd.firstChild,
47733            totalWidth   = this.getTotalWidth();
47734        
47735        innerHdChild.style.width = this.getOffsetWidth();
47736        innerHdChild.firstChild.style.width = totalWidth;
47737        
47738        if (updateMain !== false) {
47739            this.mainBody.dom.style.width = totalWidth;
47740        }
47741    },
47742
47743    
47744    focusRow : function(row) {
47745        this.focusCell(row, 0, false);
47746    },
47747
47748    
47749    focusCell : function(row, col, hscroll) {
47750        this.syncFocusEl(this.ensureVisible(row, col, hscroll));
47751        
47752        var focusEl = this.focusEl;
47753        
47754        if (Ext.isGecko) {
47755            focusEl.focus();
47756        } else {
47757            focusEl.focus.defer(1, focusEl);
47758        }
47759    },
47760
47761    
47762    resolveCell : function(row, col, hscroll) {
47763        if (!Ext.isNumber(row)) {
47764            row = row.rowIndex;
47765        }
47766        
47767        if (!this.ds) {
47768            return null;
47769        }
47770        
47771        if (row < 0 || row >= this.ds.getCount()) {
47772            return null;
47773        }
47774        col = (col !== undefined ? col : 0);
47775
47776        var rowEl    = this.getRow(row),
47777            colModel = this.cm,
47778            colCount = colModel.getColumnCount(),
47779            cellEl;
47780            
47781        if (!(hscroll === false && col === 0)) {
47782            while (col < colCount && colModel.isHidden(col)) {
47783                col++;
47784            }
47785            
47786            cellEl = this.getCell(row, col);
47787        }
47788
47789        return {row: rowEl, cell: cellEl};
47790    },
47791
47792    
47793    getResolvedXY : function(resolved) {
47794        if (!resolved) {
47795            return null;
47796        }
47797        
47798        var cell = resolved.cell,
47799            row  = resolved.row;
47800        
47801        if (cell) {
47802            return Ext.fly(cell).getXY();
47803        } else {
47804            return [this.el.getX(), Ext.fly(row).getY()];
47805        }
47806    },
47807
47808    
47809    syncFocusEl : function(row, col, hscroll) {
47810        var xy = row;
47811        
47812        if (!Ext.isArray(xy)) {
47813            row = Math.min(row, Math.max(0, this.getRows().length-1));
47814            
47815            if (isNaN(row)) {
47816                return;
47817            }
47818            
47819            xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
47820        }
47821        
47822        this.focusEl.setXY(xy || this.scroller.getXY());
47823    },
47824
47825    
47826    ensureVisible : function(row, col, hscroll) {
47827        var resolved = this.resolveCell(row, col, hscroll);
47828        
47829        if (!resolved || !resolved.row) {
47830            return null;
47831        }
47832
47833        var rowEl  = resolved.row,
47834            cellEl = resolved.cell,
47835            c = this.scroller.dom,
47836            p = rowEl,
47837            ctop = 0,
47838            stop = this.el.dom;
47839
47840        while (p && p != stop) {
47841            ctop += p.offsetTop;
47842            p = p.offsetParent;
47843        }
47844
47845        ctop -= this.mainHd.dom.offsetHeight;
47846        stop = parseInt(c.scrollTop, 10);
47847
47848        var cbot = ctop + rowEl.offsetHeight,
47849            ch = c.clientHeight,
47850            sbot = stop + ch;
47851
47852
47853        if (ctop < stop) {
47854          c.scrollTop = ctop;
47855        } else if(cbot > sbot) {
47856            c.scrollTop = cbot-ch;
47857        }
47858
47859        if (hscroll !== false) {
47860            var cleft  = parseInt(cellEl.offsetLeft, 10),
47861                cright = cleft + cellEl.offsetWidth,
47862                sleft  = parseInt(c.scrollLeft, 10),
47863                sright = sleft + c.clientWidth;
47864                
47865            if (cleft < sleft) {
47866                c.scrollLeft = cleft;
47867            } else if(cright > sright) {
47868                c.scrollLeft = cright-c.clientWidth;
47869            }
47870        }
47871        
47872        return this.getResolvedXY(resolved);
47873    },
47874
47875    
47876    insertRows : function(dm, firstRow, lastRow, isUpdate) {
47877        var last = dm.getCount() - 1;
47878        if( !isUpdate && firstRow === 0 && lastRow >= last) {
47879            this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
47880                this.refresh();
47881            this.fireEvent('rowsinserted', this, firstRow, lastRow);
47882        } else {
47883            if (!isUpdate) {
47884                this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
47885            }
47886            var html = this.renderRows(firstRow, lastRow),
47887                before = this.getRow(firstRow);
47888            if (before) {
47889                if(firstRow === 0){
47890                    Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
47891                }
47892                Ext.DomHelper.insertHtml('beforeBegin', before, html);
47893            } else {
47894                var r = this.getRow(last - 1);
47895                if(r){
47896                    Ext.fly(r).removeClass(this.lastRowCls);
47897                }
47898                Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
47899            }
47900            if (!isUpdate) {
47901                this.processRows(firstRow);
47902                this.fireEvent('rowsinserted', this, firstRow, lastRow);
47903            } else if (firstRow === 0 || firstRow >= last) {
47904                
47905                Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
47906            }
47907        }
47908        this.syncFocusEl(firstRow);
47909    },
47910
47911    
47912    deleteRows : function(dm, firstRow, lastRow) {
47913        if (dm.getRowCount() < 1) {
47914            this.refresh();
47915        } else {
47916            this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
47917
47918            this.removeRows(firstRow, lastRow);
47919
47920            this.processRows(firstRow);
47921            this.fireEvent('rowsdeleted', this, firstRow, lastRow);
47922        }
47923    },
47924
47925    
47926    getColumnStyle : function(colIndex, isHeader) {
47927        var colModel  = this.cm,
47928            colConfig = colModel.config,
47929            style     = isHeader ? '' : colConfig[colIndex].css || '',
47930            align     = colConfig[colIndex].align;
47931        
47932        style += String.format("width: {0};", this.getColumnWidth(colIndex));
47933        
47934        if (colModel.isHidden(colIndex)) {
47935            style += 'display: none; ';
47936        }
47937        
47938        if (align) {
47939            style += String.format("text-align: {0};", align);
47940        }
47941        
47942        return style;
47943    },
47944
47945    
47946    getColumnWidth : function(column) {
47947        var columnWidth = this.cm.getColumnWidth(column),
47948            borderWidth = this.borderWidth;
47949        
47950        if (Ext.isNumber(columnWidth)) {
47951            if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
47952                return columnWidth + "px";
47953            } else {
47954                return Math.max(columnWidth - borderWidth, 0) + "px";
47955            }
47956        } else {
47957            return columnWidth;
47958        }
47959    },
47960
47961    
47962    getTotalWidth : function() {
47963        return this.cm.getTotalWidth() + 'px';
47964    },
47965
47966    
47967    fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
47968        var grid          = this.grid,
47969            colModel      = this.cm,
47970            totalColWidth = colModel.getTotalWidth(false),
47971            gridWidth     = this.getGridInnerWidth(),
47972            extraWidth    = gridWidth - totalColWidth,
47973            columns       = [],
47974            extraCol      = 0,
47975            width         = 0,
47976            colWidth, fraction, i;
47977        
47978        
47979        if (gridWidth < 20 || extraWidth === 0) {
47980            return false;
47981        }
47982        
47983        var visibleColCount = colModel.getColumnCount(true),
47984            totalColCount   = colModel.getColumnCount(false),
47985            adjCount        = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);
47986        
47987        if (adjCount === 0) {
47988            adjCount = 1;
47989            omitColumn = undefined;
47990        }
47991        
47992        
47993        for (i = 0; i < totalColCount; i++) {
47994            if (!colModel.isFixed(i) && i !== omitColumn) {
47995                colWidth = colModel.getColumnWidth(i);
47996                columns.push(i, colWidth);
47997                
47998                if (!colModel.isHidden(i)) {
47999                    extraCol = i;
48000                    width += colWidth;
48001                }
48002            }
48003        }
48004        
48005        fraction = (gridWidth - colModel.getTotalWidth()) / width;
48006        
48007        while (columns.length) {
48008            colWidth = columns.pop();
48009            i        = columns.pop();
48010            
48011            colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
48012        }
48013        
48014        
48015        totalColWidth = colModel.getTotalWidth(false);
48016        
48017        if (totalColWidth > gridWidth) {
48018            var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
48019                newWidth  = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));
48020            
48021            colModel.setColumnWidth(adjustCol, newWidth, true);
48022        }
48023        
48024        if (preventRefresh !== true) {
48025            this.updateAllColumnWidths();
48026        }
48027        
48028        return true;
48029    },
48030
48031    
48032    autoExpand : function(preventUpdate) {
48033        var grid             = this.grid,
48034            colModel         = this.cm,
48035            gridWidth        = this.getGridInnerWidth(),
48036            totalColumnWidth = colModel.getTotalWidth(false),
48037            autoExpandColumn = grid.autoExpandColumn;
48038        
48039        if (!this.userResized && autoExpandColumn) {
48040            if (gridWidth != totalColumnWidth) {
48041                
48042                var colIndex     = colModel.getIndexById(autoExpandColumn),
48043                    currentWidth = colModel.getColumnWidth(colIndex),
48044                    desiredWidth = gridWidth - totalColumnWidth + currentWidth,
48045                    newWidth     = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);
48046                
48047                if (currentWidth != newWidth) {
48048                    colModel.setColumnWidth(colIndex, newWidth, true);
48049                    
48050                    if (preventUpdate !== true) {
48051                        this.updateColumnWidth(colIndex, newWidth);
48052                    }
48053                }
48054            }
48055        }
48056    },
48057    
48058    
48059    getGridInnerWidth: function() {
48060        return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
48061    },
48062
48063    
48064    getColumnData : function() {
48065        var columns  = [],
48066            colModel = this.cm,
48067            colCount = colModel.getColumnCount(),
48068            fields   = this.ds.fields,
48069            i, name;
48070        
48071        for (i = 0; i < colCount; i++) {
48072            name = colModel.getDataIndex(i);
48073            
48074            columns[i] = {
48075                name    : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
48076                renderer: colModel.getRenderer(i),
48077                scope   : colModel.getRendererScope(i),
48078                id      : colModel.getColumnId(i),
48079                style   : this.getColumnStyle(i)
48080            };
48081        }
48082        
48083        return columns;
48084    },
48085
48086    
48087    renderRows : function(startRow, endRow) {
48088        var grid     = this.grid,
48089            store    = grid.store,
48090            stripe   = grid.stripeRows,
48091            colModel = grid.colModel,
48092            colCount = colModel.getColumnCount(),
48093            rowCount = store.getCount(),
48094            records;
48095        
48096        if (rowCount < 1) {
48097            return '';
48098        }
48099        
48100        startRow = startRow || 0;
48101        endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
48102        records  = store.getRange(startRow, endRow);
48103        
48104        return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
48105    },
48106
48107    
48108    renderBody : function(){
48109        var markup = this.renderRows() || '&#160;';
48110        return this.templates.body.apply({rows: markup});
48111    },
48112
48113    
48114    refreshRow: function(record) {
48115        var store     = this.ds,
48116            colCount  = this.cm.getColumnCount(),
48117            columns   = this.getColumnData(),
48118            last      = colCount - 1,
48119            cls       = ['x-grid3-row'],
48120            rowParams = {
48121                tstyle: String.format("width: {0};", this.getTotalWidth())
48122            },
48123            colBuffer = [],
48124            cellTpl   = this.templates.cell,
48125            rowIndex, row, column, meta, css, i;
48126        
48127        if (Ext.isNumber(record)) {
48128            rowIndex = record;
48129            record   = store.getAt(rowIndex);
48130        } else {
48131            rowIndex = store.indexOf(record);
48132        }
48133        
48134        
48135        if (!record || rowIndex < 0) {
48136            return;
48137        }
48138        
48139        
48140        for (i = 0; i < colCount; i++) {
48141            column = columns[i];
48142            
48143            if (i == 0) {
48144                css = 'x-grid3-cell-first';
48145            } else {
48146                css = (i == last) ? 'x-grid3-cell-last ' : '';
48147            }
48148            
48149            meta = {
48150                id      : column.id,
48151                style   : column.style,
48152                css     : css,
48153                attr    : "",
48154                cellAttr: ""
48155            };
48156            
48157            meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
48158            
48159            if (Ext.isEmpty(meta.value)) {
48160                meta.value = '&#160;';
48161            }
48162            
48163            if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
48164                meta.css += ' x-grid3-dirty-cell';
48165            }
48166            
48167            colBuffer[i] = cellTpl.apply(meta);
48168        }
48169        
48170        row = this.getRow(rowIndex);
48171        row.className = '';
48172        
48173        if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
48174            cls.push('x-grid3-row-alt');
48175        }
48176        
48177        if (this.getRowClass) {
48178            rowParams.cols = colCount;
48179            cls.push(this.getRowClass(record, rowIndex, rowParams, store));
48180        }
48181        
48182        this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
48183        rowParams.cells = colBuffer.join("");
48184        row.innerHTML = this.templates.rowInner.apply(rowParams);
48185        
48186        this.fireEvent('rowupdated', this, rowIndex, record);
48187    },
48188
48189    
48190    refresh : function(headersToo) {
48191        this.fireEvent('beforerefresh', this);
48192        this.grid.stopEditing(true);
48193
48194        var result = this.renderBody();
48195        this.mainBody.update(result).setWidth(this.getTotalWidth());
48196        if (headersToo === true) {
48197            this.updateHeaders();
48198            this.updateHeaderSortState();
48199        }
48200        this.processRows(0, true);
48201        this.layout();
48202        this.applyEmptyText();
48203        this.fireEvent('refresh', this);
48204    },
48205
48206    
48207    applyEmptyText : function() {
48208        if (this.emptyText && !this.hasRows()) {
48209            this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
48210        }
48211    },
48212
48213    
48214    updateHeaderSortState : function() {
48215        var state = this.ds.getSortState();
48216        if (!state) {
48217            return;
48218        }
48219
48220        if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
48221            this.grid.fireEvent('sortchange', this.grid, state);
48222        }
48223
48224        this.sortState = state;
48225
48226        var sortColumn = this.cm.findColumnIndex(state.field);
48227        if (sortColumn != -1) {
48228            var sortDir = state.direction;
48229            this.updateSortIcon(sortColumn, sortDir);
48230        }
48231    },
48232
48233    
48234    clearHeaderSortState : function() {
48235        if (!this.sortState) {
48236            return;
48237        }
48238        this.grid.fireEvent('sortchange', this.grid, null);
48239        this.mainHd.select('td').removeClass(this.sortClasses);
48240        delete this.sortState;
48241    },
48242
48243    
48244    destroy : function() {
48245        var me              = this,
48246            grid            = me.grid,
48247            gridEl          = grid.getGridEl(),
48248            dragZone        = me.dragZone,
48249            splitZone       = me.splitZone,
48250            columnDrag      = me.columnDrag,
48251            columnDrop      = me.columnDrop,
48252            scrollToTopTask = me.scrollToTopTask,
48253            columnDragData,
48254            columnDragProxy;
48255        
48256        if (scrollToTopTask && scrollToTopTask.cancel) {
48257            scrollToTopTask.cancel();
48258        }
48259        
48260        Ext.destroyMembers(me, 'colMenu', 'hmenu');
48261
48262        me.initData(null, null);
48263        me.purgeListeners();
48264        
48265        Ext.fly(me.innerHd).un("click", me.handleHdDown, me);
48266
48267        if (grid.enableColumnMove) {
48268            columnDragData = columnDrag.dragData;
48269            columnDragProxy = columnDrag.proxy;
48270            Ext.destroy(
48271                columnDrag.el,
48272                columnDragProxy.ghost,
48273                columnDragProxy.el,
48274                columnDrop.el,
48275                columnDrop.proxyTop,
48276                columnDrop.proxyBottom,
48277                columnDragData.ddel,
48278                columnDragData.header
48279            );
48280            
48281            if (columnDragProxy.anim) {
48282                Ext.destroy(columnDragProxy.anim);
48283            }
48284            
48285            delete columnDragProxy.ghost;
48286            delete columnDragData.ddel;
48287            delete columnDragData.header;
48288            columnDrag.destroy();
48289            
48290            delete Ext.dd.DDM.locationCache[columnDrag.id];
48291            delete columnDrag._domRef;
48292
48293            delete columnDrop.proxyTop;
48294            delete columnDrop.proxyBottom;
48295            columnDrop.destroy();
48296            delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
48297            delete columnDrop._domRef;
48298            delete Ext.dd.DDM.ids[columnDrop.ddGroup];
48299        }
48300
48301        if (splitZone) { 
48302            splitZone.destroy();
48303            delete splitZone._domRef;
48304            delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
48305        }
48306
48307        Ext.fly(me.innerHd).removeAllListeners();
48308        Ext.removeNode(me.innerHd);
48309        delete me.innerHd;
48310
48311        Ext.destroy(
48312            me.el,
48313            me.mainWrap,
48314            me.mainHd,
48315            me.scroller,
48316            me.mainBody,
48317            me.focusEl,
48318            me.resizeMarker,
48319            me.resizeProxy,
48320            me.activeHdBtn,
48321            me._flyweight,
48322            dragZone,
48323            splitZone
48324        );
48325
48326        delete grid.container;
48327
48328        if (dragZone) {
48329            dragZone.destroy();
48330        }
48331
48332        Ext.dd.DDM.currentTarget = null;
48333        delete Ext.dd.DDM.locationCache[gridEl.id];
48334
48335        Ext.EventManager.removeResizeListener(me.onWindowResize, me);
48336    },
48337
48338    
48339    onDenyColumnHide : function() {
48340
48341    },
48342
48343    
48344    render : function() {
48345        if (this.autoFill) {
48346            var ct = this.grid.ownerCt;
48347            
48348            if (ct && ct.getLayout()) {
48349                ct.on('afterlayout', function() {
48350                    this.fitColumns(true, true);
48351                    this.updateHeaders();
48352                    this.updateHeaderSortState();
48353                }, this, {single: true});
48354            }
48355        } else if (this.forceFit) {
48356            this.fitColumns(true, false);
48357        } else if (this.grid.autoExpandColumn) {
48358            this.autoExpand(true);
48359        }
48360        
48361        this.grid.getGridEl().dom.innerHTML = this.renderUI();
48362        
48363        this.afterRenderUI();
48364    },
48365
48366    
48367    
48368    
48369    initData : function(newStore, newColModel) {
48370        var me = this;
48371        
48372        if (me.ds) {
48373            var oldStore = me.ds;
48374            
48375            oldStore.un('add', me.onAdd, me);
48376            oldStore.un('load', me.onLoad, me);
48377            oldStore.un('clear', me.onClear, me);
48378            oldStore.un('remove', me.onRemove, me);
48379            oldStore.un('update', me.onUpdate, me);
48380            oldStore.un('datachanged', me.onDataChange, me);
48381            
48382            if (oldStore !== newStore && oldStore.autoDestroy) {
48383                oldStore.destroy();
48384            }
48385        }
48386        
48387        if (newStore) {
48388            newStore.on({
48389                scope      : me,
48390                load       : me.onLoad,
48391                add        : me.onAdd,
48392                remove     : me.onRemove,
48393                update     : me.onUpdate,
48394                clear      : me.onClear,
48395                datachanged: me.onDataChange
48396            });
48397        }
48398        
48399        if (me.cm) {
48400            var oldColModel = me.cm;
48401            
48402            oldColModel.un('configchange', me.onColConfigChange, me);
48403            oldColModel.un('widthchange',  me.onColWidthChange, me);
48404            oldColModel.un('headerchange', me.onHeaderChange, me);
48405            oldColModel.un('hiddenchange', me.onHiddenChange, me);
48406            oldColModel.un('columnmoved',  me.onColumnMove, me);
48407        }
48408        
48409        if (newColModel) {
48410            delete me.lastViewWidth;
48411            
48412            newColModel.on({
48413                scope       : me,
48414                configchange: me.onColConfigChange,
48415                widthchange : me.onColWidthChange,
48416                headerchange: me.onHeaderChange,
48417                hiddenchange: me.onHiddenChange,
48418                columnmoved : me.onColumnMove
48419            });
48420        }
48421        
48422        me.ds = newStore;
48423        me.cm = newColModel;
48424    },
48425
48426    
48427    onDataChange : function(){
48428        this.refresh(true);
48429        this.updateHeaderSortState();
48430        this.syncFocusEl(0);
48431    },
48432
48433    
48434    onClear : function() {
48435        this.refresh();
48436        this.syncFocusEl(0);
48437    },
48438
48439    
48440    onUpdate : function(store, record) {
48441        this.refreshRow(record);
48442    },
48443
48444    
48445    onAdd : function(store, records, index) {
48446        this.insertRows(store, index, index + (records.length-1));
48447    },
48448
48449    
48450    onRemove : function(store, record, index, isUpdate) {
48451        if (isUpdate !== true) {
48452            this.fireEvent('beforerowremoved', this, index, record);
48453        }
48454        
48455        this.removeRow(index);
48456        
48457        if (isUpdate !== true) {
48458            this.processRows(index);
48459            this.applyEmptyText();
48460            this.fireEvent('rowremoved', this, index, record);
48461        }
48462    },
48463
48464    
48465    onLoad : function() {
48466        if (Ext.isGecko) {
48467            if (!this.scrollToTopTask) {
48468                this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
48469            }
48470            this.scrollToTopTask.delay(1);
48471        } else {
48472            this.scrollToTop();
48473        }
48474    },
48475
48476    
48477    onColWidthChange : function(cm, col, width) {
48478        this.updateColumnWidth(col, width);
48479    },
48480
48481    
48482    onHeaderChange : function(cm, col, text) {
48483        this.updateHeaders();
48484    },
48485
48486    
48487    onHiddenChange : function(cm, col, hidden) {
48488        this.updateColumnHidden(col, hidden);
48489    },
48490
48491    
48492    onColumnMove : function(cm, oldIndex, newIndex) {
48493        this.indexMap = null;
48494        this.refresh(true);
48495        this.restoreScroll(this.getScrollState());
48496        
48497        this.afterMove(newIndex);
48498        this.grid.fireEvent('columnmove', oldIndex, newIndex);
48499    },
48500
48501    
48502    onColConfigChange : function() {
48503        delete this.lastViewWidth;
48504        this.indexMap = null;
48505        this.refresh(true);
48506    },
48507
48508    
48509    
48510    initUI : function(grid) {
48511        grid.on('headerclick', this.onHeaderClick, this);
48512    },
48513
48514    
48515    initEvents : Ext.emptyFn,
48516
48517    
48518    onHeaderClick : function(g, index) {
48519        if (this.headersDisabled || !this.cm.isSortable(index)) {
48520            return;
48521        }
48522        g.stopEditing(true);
48523        g.store.sort(this.cm.getDataIndex(index));
48524    },
48525
48526    
48527    onRowOver : function(e, target) {
48528        var row = this.findRowIndex(target);
48529        
48530        if (row !== false) {
48531            this.addRowClass(row, this.rowOverCls);
48532        }
48533    },
48534
48535    
48536    onRowOut : function(e, target) {
48537        var row = this.findRowIndex(target);
48538        
48539        if (row !== false && !e.within(this.getRow(row), true)) {
48540            this.removeRowClass(row, this.rowOverCls);
48541        }
48542    },
48543
48544    
48545    onRowSelect : function(row) {
48546        this.addRowClass(row, this.selectedRowClass);
48547    },
48548
48549    
48550    onRowDeselect : function(row) {
48551        this.removeRowClass(row, this.selectedRowClass);
48552    },
48553
48554    
48555    onCellSelect : function(row, col) {
48556        var cell = this.getCell(row, col);
48557        if (cell) {
48558            this.fly(cell).addClass('x-grid3-cell-selected');
48559        }
48560    },
48561
48562    
48563    onCellDeselect : function(row, col) {
48564        var cell = this.getCell(row, col);
48565        if (cell) {
48566            this.fly(cell).removeClass('x-grid3-cell-selected');
48567        }
48568    },
48569
48570    
48571    handleWheel : function(e) {
48572        e.stopPropagation();
48573    },
48574
48575    
48576    onColumnSplitterMoved : function(cellIndex, width) {
48577        this.userResized = true;
48578        this.grid.colModel.setColumnWidth(cellIndex, width, true);
48579
48580        if (this.forceFit) {
48581            this.fitColumns(true, false, cellIndex);
48582            this.updateAllColumnWidths();
48583        } else {
48584            this.updateColumnWidth(cellIndex, width);
48585            this.syncHeaderScroll();
48586        }
48587
48588        this.grid.fireEvent('columnresize', cellIndex, width);
48589    },
48590
48591    
48592    beforeColMenuShow : function() {
48593        var colModel = this.cm,
48594            colCount = colModel.getColumnCount(),
48595            colMenu  = this.colMenu,
48596            i;
48597
48598        colMenu.removeAll();
48599
48600        for (i = 0; i < colCount; i++) {
48601            if (colModel.config[i].hideable !== false) {
48602                colMenu.add(new Ext.menu.CheckItem({
48603                    text       : colModel.getColumnHeader(i),
48604                    itemId     : 'col-' + colModel.getColumnId(i),
48605                    checked    : !colModel.isHidden(i),
48606                    disabled   : colModel.config[i].hideable === false,
48607                    hideOnClick: false
48608                }));
48609            }
48610        }
48611    },
48612    
48613    
48614    handleHdMenuClick : function(item) {
48615        var store     = this.ds,
48616            dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
48617
48618        switch (item.getItemId()) {
48619            case 'asc':
48620                store.sort(dataIndex, 'ASC');
48621                break;
48622            case 'desc':
48623                store.sort(dataIndex, 'DESC');
48624                break;
48625            default:
48626                this.handleHdMenuClickDefault(item);
48627        }
48628        return true;
48629    },
48630    
48631    
48632    handleHdMenuClickDefault: function(item) {
48633        var colModel = this.cm,
48634            itemId   = item.getItemId(),
48635            index    = colModel.getIndexById(itemId.substr(4));
48636
48637        if (index != -1) {
48638            if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
48639                this.onDenyColumnHide();
48640                return;
48641            }
48642            colModel.setHidden(index, item.checked);
48643        }
48644    },
48645
48646    
48647    handleHdDown : function(e, target) {
48648        if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
48649            e.stopEvent();
48650            
48651            var colModel  = this.cm,
48652                header    = this.findHeaderCell(target),
48653                index     = this.getCellIndex(header),
48654                sortable  = colModel.isSortable(index),
48655                menu      = this.hmenu,
48656                menuItems = menu.items,
48657                menuCls   = this.headerMenuOpenCls;
48658            
48659            this.hdCtxIndex = index;
48660            
48661            Ext.fly(header).addClass(menuCls);
48662            menuItems.get('asc').setDisabled(!sortable);
48663            menuItems.get('desc').setDisabled(!sortable);
48664            
48665            menu.on('hide', function() {
48666                Ext.fly(header).removeClass(menuCls);
48667            }, this, {single:true});
48668            
48669            menu.show(target, 'tl-bl?');
48670        }
48671    },
48672
48673    
48674    handleHdMove : function(e) {
48675        var header = this.findHeaderCell(this.activeHdRef);
48676        
48677        if (header && !this.headersDisabled) {
48678            var handleWidth  = this.splitHandleWidth || 5,
48679                activeRegion = this.activeHdRegion,
48680                headerStyle  = header.style,
48681                colModel     = this.cm,
48682                cursor       = '',
48683                pageX        = e.getPageX();
48684                
48685            if (this.grid.enableColumnResize !== false) {
48686                var activeHeaderIndex = this.activeHdIndex,
48687                    previousVisible   = this.getPreviousVisible(activeHeaderIndex),
48688                    currentResizable  = colModel.isResizable(activeHeaderIndex),
48689                    previousResizable = previousVisible && colModel.isResizable(previousVisible),
48690                    inLeftResizer     = pageX - activeRegion.left <= handleWidth,
48691                    inRightResizer    = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
48692                
48693                if (inLeftResizer && previousResizable) {
48694                    cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; 
48695                } else if (inRightResizer && currentResizable) {
48696                    cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
48697                }
48698            }
48699            
48700            headerStyle.cursor = cursor;
48701        }
48702    },
48703    
48704    
48705    getPreviousVisible: function(index) {
48706        while (index > 0) {
48707            if (!this.cm.isHidden(index - 1)) {
48708                return index;
48709            }
48710            index--;
48711        }
48712        return undefined;
48713    },
48714
48715    
48716    handleHdOver : function(e, target) {
48717        var header = this.findHeaderCell(target);
48718        
48719        if (header && !this.headersDisabled) {
48720            var fly = this.fly(header);
48721            
48722            this.activeHdRef = target;
48723            this.activeHdIndex = this.getCellIndex(header);
48724            this.activeHdRegion = fly.getRegion();
48725            
48726            if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
48727                fly.addClass('x-grid3-hd-over');
48728                this.activeHdBtn = fly.child('.x-grid3-hd-btn');
48729                
48730                if (this.activeHdBtn) {
48731                    this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
48732                }
48733            }
48734        }
48735    },
48736
48737    
48738    handleHdOut : function(e, target) {
48739        var header = this.findHeaderCell(target);
48740        
48741        if (header && (!Ext.isIE || !e.within(header, true))) {
48742            this.activeHdRef = null;
48743            this.fly(header).removeClass('x-grid3-hd-over');
48744            header.style.cursor = '';
48745        }
48746    },
48747    
48748    
48749    isMenuDisabled: function(cellIndex, el) {
48750        return this.cm.isMenuDisabled(cellIndex);
48751    },
48752
48753    
48754    hasRows : function() {
48755        var fc = this.mainBody.dom.firstChild;
48756        return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
48757    },
48758    
48759    
48760    isHideableColumn : function(c) {
48761        return !c.hidden;
48762    },
48763
48764    
48765    bind : function(d, c) {
48766        this.initData(d, c);
48767    }
48768});
48769
48770
48771
48772
48773Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
48774
48775    constructor: function(grid, hd){
48776        this.grid = grid;
48777        this.view = grid.getView();
48778        this.marker = this.view.resizeMarker;
48779        this.proxy = this.view.resizeProxy;
48780        Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
48781            'gridSplitters' + this.grid.getGridEl().id, {
48782            dragElId : Ext.id(this.proxy.dom), resizeFrame:false
48783        });
48784        this.scroll = false;
48785        this.hw = this.view.splitHandleWidth || 5;
48786    },
48787
48788    b4StartDrag : function(x, y){
48789        this.dragHeadersDisabled = this.view.headersDisabled;
48790        this.view.headersDisabled = true;
48791        var h = this.view.mainWrap.getHeight();
48792        this.marker.setHeight(h);
48793        this.marker.show();
48794        this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
48795        this.proxy.setHeight(h);
48796        var w = this.cm.getColumnWidth(this.cellIndex),
48797            minw = Math.max(w-this.grid.minColumnWidth, 0);
48798        this.resetConstraints();
48799        this.setXConstraint(minw, 1000);
48800        this.setYConstraint(0, 0);
48801        this.minX = x - minw;
48802        this.maxX = x + 1000;
48803        this.startPos = x;
48804        Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
48805    },
48806
48807    allowHeaderDrag : function(e){
48808        return true;
48809    },
48810
48811    handleMouseDown : function(e){
48812        var t = this.view.findHeaderCell(e.getTarget());
48813        if(t && this.allowHeaderDrag(e)){
48814            var xy = this.view.fly(t).getXY(), 
48815                x = xy[0],
48816                exy = e.getXY(), 
48817                ex = exy[0],
48818                w = t.offsetWidth, 
48819                adjust = false;
48820                
48821            if((ex - x) <= this.hw){
48822                adjust = -1;
48823            }else if((x+w) - ex <= this.hw){
48824                adjust = 0;
48825            }
48826            if(adjust !== false){
48827                this.cm = this.grid.colModel;
48828                var ci = this.view.getCellIndex(t);
48829                if(adjust == -1){
48830                  if (ci + adjust < 0) {
48831                    return;
48832                  }
48833                    while(this.cm.isHidden(ci+adjust)){
48834                        --adjust;
48835                        if(ci+adjust < 0){
48836                            return;
48837                        }
48838                    }
48839                }
48840                this.cellIndex = ci+adjust;
48841                this.split = t.dom;
48842                if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
48843                    Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
48844                }
48845            }else if(this.view.columnDrag){
48846                this.view.columnDrag.callHandleMouseDown(e);
48847            }
48848        }
48849    },
48850
48851    endDrag : function(e){
48852        this.marker.hide();
48853        var v = this.view,
48854            endX = Math.max(this.minX, e.getPageX()),
48855            diff = endX - this.startPos,
48856            disabled = this.dragHeadersDisabled;
48857            
48858        v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
48859        setTimeout(function(){
48860            v.headersDisabled = disabled;
48861        }, 50);
48862    },
48863
48864    autoOffset : function(){
48865        this.setDelta(0,0);
48866    }
48867});
48868
48869Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
48870    
48871    
48872    colHeaderCellCls: 'grid-hd-group-cell',
48873    
48874    
48875    title: '',
48876    
48877    
48878    
48879    
48880    getColumnHeaders: function() {
48881        return this.grid.topAxis.buildHeaders();;
48882    },
48883    
48884    
48885    getRowHeaders: function() {
48886        return this.grid.leftAxis.buildHeaders();
48887    },
48888    
48889    
48890    renderRows : function(startRow, endRow) {
48891        var grid          = this.grid,
48892            rows          = grid.extractData(),
48893            rowCount      = rows.length,
48894            templates     = this.templates,
48895            renderer      = grid.renderer,
48896            hasRenderer   = typeof renderer == 'function',
48897            getCellCls    = this.getCellCls,
48898            hasGetCellCls = typeof getCellCls == 'function',
48899            cellTemplate  = templates.cell,
48900            rowTemplate   = templates.row,
48901            rowBuffer     = [],
48902            meta          = {},
48903            tstyle        = 'width:' + this.getGridInnerWidth() + 'px;',
48904            colBuffer, colCount, column, i, row;
48905        
48906        startRow = startRow || 0;
48907        endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
48908        
48909        for (i = 0; i < rowCount; i++) {
48910            row = rows[i];
48911            colCount  = row.length;
48912            colBuffer = [];
48913            
48914            
48915            for (var j = 0; j < colCount; j++) {
48916                
48917                meta.id    = i + '-' + j;
48918                meta.css   = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
48919                meta.attr  = meta.cellAttr = '';
48920                meta.value = row[j];
48921
48922                if (Ext.isEmpty(meta.value)) {
48923                    meta.value = '&#160;';
48924                }
48925                
48926                if (hasRenderer) {
48927                    meta.value = renderer(meta.value);
48928                }
48929                
48930                if (hasGetCellCls) {
48931                    meta.css += getCellCls(meta.value) + ' ';
48932                }
48933
48934                colBuffer[colBuffer.length] = cellTemplate.apply(meta);
48935            }
48936            
48937            rowBuffer[rowBuffer.length] = rowTemplate.apply({
48938                tstyle: tstyle,
48939                cols  : colCount,
48940                cells : colBuffer.join(""),
48941                alt   : ''
48942            });
48943        }
48944        
48945        return rowBuffer.join("");
48946    },
48947    
48948    
48949    masterTpl: new Ext.Template(
48950        '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
48951            '<div class="x-grid3-viewport">',
48952                '<div class="x-grid3-header">',
48953                    '<div class="x-grid3-header-title"><span>{title}</span></div>',
48954                    '<div class="x-grid3-header-inner">',
48955                        '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
48956                    '</div>',
48957                    '<div class="x-clear"></div>',
48958                '</div>',
48959                '<div class="x-grid3-scroller">',
48960                    '<div class="x-grid3-row-headers"></div>',
48961                    '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
48962                    '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
48963                '</div>',
48964            '</div>',
48965            '<div class="x-grid3-resize-marker">&#160;</div>',
48966            '<div class="x-grid3-resize-proxy">&#160;</div>',
48967        '</div>'
48968    ),
48969    
48970    
48971    initTemplates: function() {
48972        Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
48973        
48974        var templates = this.templates || {};
48975        if (!templates.gcell) {
48976            templates.gcell = new Ext.XTemplate(
48977                '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
48978                    '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
48979                        this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
48980                    '</div>',
48981                '</td>'
48982            );
48983        }
48984        
48985        this.templates = templates;
48986        this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
48987    },
48988    
48989    
48990    initElements: function() {
48991        Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
48992        
48993        
48994        this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
48995        
48996        
48997        this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
48998    },
48999    
49000    
49001    getGridInnerWidth: function() {
49002        var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
49003        
49004        return previousWidth - this.getTotalRowHeaderWidth();
49005    },
49006    
49007    
49008    getTotalRowHeaderWidth: function() {
49009        var headers = this.getRowHeaders(),
49010            length  = headers.length,
49011            total   = 0,
49012            i;
49013        
49014        for (i = 0; i< length; i++) {
49015            total += headers[i].width;
49016        }
49017        
49018        return total;
49019    },
49020    
49021    
49022    getTotalColumnHeaderHeight: function() {
49023        return this.getColumnHeaders().length * 21;
49024    },
49025    
49026    
49027    getCellIndex : function(el) {
49028        if (el) {
49029            var match = el.className.match(this.colRe),
49030                data;
49031 
49032            if (match && (data = match[1])) {
49033                return parseInt(data.split('-')[1], 10);
49034            }
49035        }
49036        return false;
49037    },
49038    
49039    
49040    
49041    renderUI : function() {
49042        var templates  = this.templates,
49043            innerWidth = this.getGridInnerWidth();
49044            
49045        return templates.master.apply({
49046            body  : templates.body.apply({rows:'&#160;'}),
49047            ostyle: 'width:' + innerWidth + 'px',
49048            bstyle: 'width:' + innerWidth + 'px'
49049        });
49050    },
49051    
49052    
49053    onLayout: function(width, height) {
49054        Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
49055        
49056        var width = this.getGridInnerWidth();
49057        
49058        this.resizeColumnHeaders(width);
49059        this.resizeAllRows(width);
49060    },
49061    
49062    
49063    refresh : function(headersToo) {
49064        this.fireEvent('beforerefresh', this);
49065        this.grid.stopEditing(true);
49066        
49067        var result = this.renderBody();
49068        this.mainBody.update(result).setWidth(this.getGridInnerWidth());
49069        if (headersToo === true) {
49070            this.updateHeaders();
49071            this.updateHeaderSortState();
49072        }
49073        this.processRows(0, true);
49074        this.layout();
49075        this.applyEmptyText();
49076        this.fireEvent('refresh', this);
49077    },
49078    
49079    
49080    renderHeaders: Ext.emptyFn,
49081    
49082    
49083    fitColumns: Ext.emptyFn,
49084    
49085    
49086    resizeColumnHeaders: function(width) {
49087        var topAxis = this.grid.topAxis;
49088        
49089        if (topAxis.rendered) {
49090            topAxis.el.setWidth(width);
49091        }
49092    },
49093    
49094    
49095    resizeRowHeaders: function() {
49096        var rowHeaderWidth = this.getTotalRowHeaderWidth(),
49097            marginStyle    = String.format("margin-left: {0}px;", rowHeaderWidth);
49098        
49099        this.rowHeadersEl.setWidth(rowHeaderWidth);
49100        this.mainBody.applyStyles(marginStyle);
49101        Ext.fly(this.innerHd).applyStyles(marginStyle);
49102        
49103        this.headerTitleEl.setWidth(rowHeaderWidth);
49104        this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
49105    },
49106    
49107    
49108    resizeAllRows: function(width) {
49109        var rows   = this.getRows(),
49110            length = rows.length,
49111            i;
49112        
49113        for (i = 0; i < length; i++) {
49114            Ext.fly(rows[i]).setWidth(width);
49115            Ext.fly(rows[i]).child('table').setWidth(width);
49116        }
49117    },
49118    
49119    
49120    updateHeaders: function() {
49121        this.renderGroupRowHeaders();
49122        this.renderGroupColumnHeaders();
49123    },
49124    
49125    
49126    renderGroupRowHeaders: function() {
49127        var leftAxis = this.grid.leftAxis;
49128        
49129        this.resizeRowHeaders();
49130        leftAxis.rendered = false;
49131        leftAxis.render(this.rowHeadersEl);
49132        
49133        this.setTitle(this.title);
49134    },
49135    
49136    
49137    setTitle: function(title) {
49138        this.headerTitleEl.child('span').dom.innerHTML = title;
49139    },
49140    
49141    
49142    renderGroupColumnHeaders: function() {
49143        var topAxis = this.grid.topAxis;
49144        
49145        topAxis.rendered = false;
49146        topAxis.render(this.innerHd.firstChild);
49147    },
49148    
49149    
49150    isMenuDisabled: function(cellIndex, el) {
49151        return true;
49152    }
49153});
49154Ext.grid.PivotAxis = Ext.extend(Ext.Component, {
49155    
49156    orientation: 'horizontal',
49157    
49158    
49159    defaultHeaderWidth: 80,
49160    
49161    
49162    paddingWidth: 7,
49163    
49164    
49165    setDimensions: function(dimensions) {
49166        this.dimensions = dimensions;
49167    },
49168    
49169    
49170    onRender: function(ct, position) {
49171        var rows = this.orientation == 'horizontal'
49172                 ? this.renderHorizontalRows()
49173                 : this.renderVerticalRows();
49174        
49175        this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true);
49176    },
49177    
49178    
49179    renderHorizontalRows: function() {
49180        var headers  = this.buildHeaders(),
49181            rowCount = headers.length,
49182            rows     = [],
49183            cells, cols, colCount, i, j;
49184        
49185        for (i = 0; i < rowCount; i++) {
49186            cells = [];
49187            cols  = headers[i].items;
49188            colCount = cols.length;
49189
49190            for (j = 0; j < colCount; j++) {
49191                cells.push({
49192                    tag: 'td',
49193                    html: cols[j].header,
49194                    colspan: cols[j].span
49195                });
49196            }
49197
49198            rows[i] = {
49199                tag: 'tr',
49200                cn: cells
49201            };
49202        }
49203        
49204        return rows;
49205    },
49206    
49207    
49208    renderVerticalRows: function() {
49209        var headers  = this.buildHeaders(),
49210            colCount = headers.length,
49211            rowCells = [],
49212            rows     = [],
49213            rowCount, col, row, colWidth, i, j;
49214        
49215        for (i = 0; i < colCount; i++) {
49216            col = headers[i];
49217            colWidth = col.width || 80;
49218            rowCount = col.items.length;
49219            
49220            for (j = 0; j < rowCount; j++) {
49221                row = col.items[j];
49222                
49223                rowCells[row.start] = rowCells[row.start] || [];
49224                rowCells[row.start].push({
49225                    tag    : 'td',
49226                    html   : row.header,
49227                    rowspan: row.span,
49228                    width  : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
49229                });
49230            }
49231        }
49232        
49233        rowCount = rowCells.length;
49234        for (i = 0; i < rowCount; i++) {
49235            rows[i] = {
49236                tag: 'tr',
49237                cn : rowCells[i]
49238            };
49239        }
49240        
49241        return rows;
49242    },
49243    
49244    
49245    getTuples: function() {
49246        var newStore = new Ext.data.Store({});
49247        
49248        newStore.data = this.store.data.clone();
49249        newStore.fields = this.store.fields;
49250        
49251        var sorters    = [],
49252            dimensions = this.dimensions,
49253            length     = dimensions.length,
49254            i;
49255        
49256        for (i = 0; i < length; i++) {
49257            sorters.push({
49258                field    : dimensions[i].dataIndex,
49259                direction: dimensions[i].direction || 'ASC'
49260            });
49261        }
49262        
49263        newStore.sort(sorters);
49264        
49265        var records = newStore.data.items,
49266            hashes  = [],
49267            tuples  = [],
49268            recData, hash, info, data, key;
49269        
49270        length = records.length;
49271        
49272        for (i = 0; i < length; i++) {
49273            info = this.getRecordInfo(records[i]);
49274            data = info.data;
49275            hash = "";
49276            
49277            for (key in data) {
49278                hash += data[key] + '---';
49279            }
49280            
49281            if (hashes.indexOf(hash) == -1) {
49282                hashes.push(hash);
49283                tuples.push(info);
49284            }
49285        }
49286        
49287        newStore.destroy();
49288        
49289        return tuples;
49290    },
49291    
49292    
49293    getRecordInfo: function(record) {
49294        var dimensions = this.dimensions,
49295            length  = dimensions.length,
49296            data    = {},
49297            dimension, dataIndex, i;
49298        
49299        
49300        for (i = 0; i < length; i++) {
49301            dimension = dimensions[i];
49302            dataIndex = dimension.dataIndex;
49303            
49304            data[dataIndex] = record.get(dataIndex);
49305        }
49306        
49307        
49308        
49309        var createMatcherFunction = function(data) {
49310            return function(record) {
49311                for (var dataIndex in data) {
49312                    if (record.get(dataIndex) != data[dataIndex]) {
49313                        return false;
49314                    }
49315                }
49316                
49317                return true;
49318            };
49319        };
49320        
49321        return {
49322            data: data,
49323            matcher: createMatcherFunction(data)
49324        };
49325    },
49326    
49327    
49328    buildHeaders: function() {
49329        var tuples     = this.getTuples(),
49330            rowCount   = tuples.length,
49331            dimensions = this.dimensions,
49332            dimension,
49333            colCount   = dimensions.length,
49334            headers    = [],
49335            tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
49336        
49337        for (i = 0; i < colCount; i++) {
49338            dimension = dimensions[i];
49339            rows  = [];
49340            span  = 0;
49341            start = 0;
49342            
49343            for (j = 0; j < rowCount; j++) {
49344                tuple  = tuples[j];
49345                isLast = j == (rowCount - 1);
49346                currentHeader = tuple.data[dimension.dataIndex];
49347                
49348                
49349                changed = previousHeader != undefined && previousHeader != currentHeader;
49350                if (i > 0 && j > 0) {
49351                    changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
49352                }
49353                
49354                if (changed) {                    
49355                    rows.push({
49356                        header: previousHeader,
49357                        span  : span,
49358                        start : start
49359                    });
49360                    
49361                    start += span;
49362                    span = 0;
49363                }
49364                
49365                if (isLast) {
49366                    rows.push({
49367                        header: currentHeader,
49368                        span  : span + 1,
49369                        start : start
49370                    });
49371                    
49372                    start += span;
49373                    span = 0;
49374                }
49375                
49376                previousHeader = currentHeader;
49377                span++;
49378            }
49379            
49380            headers.push({
49381                items: rows,
49382                width: dimension.width || this.defaultHeaderWidth
49383            });
49384            
49385            previousHeader = undefined;
49386        }
49387        
49388        return headers;
49389    }
49390});
49391
49392
49393Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
49394    maxDragWidth: 120,
49395    
49396    constructor : function(grid, hd, hd2){
49397        this.grid = grid;
49398        this.view = grid.getView();
49399        this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
49400        Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
49401        if(hd2){
49402            this.setHandleElId(Ext.id(hd));
49403            this.setOuterHandleElId(Ext.id(hd2));
49404        }
49405        this.scroll = false;
49406    },
49407    
49408    getDragData : function(e){
49409        var t = Ext.lib.Event.getTarget(e),
49410            h = this.view.findHeaderCell(t);
49411        if(h){
49412            return {ddel: h.firstChild, header:h};
49413        }
49414        return false;
49415    },
49416
49417    onInitDrag : function(e){
49418        
49419        this.dragHeadersDisabled = this.view.headersDisabled;
49420        this.view.headersDisabled = true;
49421        var clone = this.dragData.ddel.cloneNode(true);
49422        clone.id = Ext.id();
49423        clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
49424        this.proxy.update(clone);
49425        return true;
49426    },
49427
49428    afterValidDrop : function(){
49429        this.completeDrop();
49430    },
49431
49432    afterInvalidDrop : function(){
49433        this.completeDrop();
49434    },
49435    
49436    completeDrop: function(){
49437        var v = this.view,
49438            disabled = this.dragHeadersDisabled;
49439        setTimeout(function(){
49440            v.headersDisabled = disabled;
49441        }, 50);
49442    }
49443});
49444
49445
49446
49447Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
49448    proxyOffsets : [-4, -9],
49449    fly: Ext.Element.fly,
49450    
49451    constructor : function(grid, hd, hd2){
49452        this.grid = grid;
49453        this.view = grid.getView();
49454        
49455        this.proxyTop = Ext.DomHelper.append(document.body, {
49456            cls:"col-move-top", html:"&#160;"
49457        }, true);
49458        this.proxyBottom = Ext.DomHelper.append(document.body, {
49459            cls:"col-move-bottom", html:"&#160;"
49460        }, true);
49461        this.proxyTop.hide = this.proxyBottom.hide = function(){
49462            this.setLeftTop(-100,-100);
49463            this.setStyle("visibility", "hidden");
49464        };
49465        this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
49466        
49467        
49468        Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
49469    },
49470
49471    getTargetFromEvent : function(e){
49472        var t = Ext.lib.Event.getTarget(e),
49473            cindex = this.view.findCellIndex(t);
49474        if(cindex !== false){
49475            return this.view.getHeaderCell(cindex);
49476        }
49477    },
49478
49479    nextVisible : function(h){
49480        var v = this.view, cm = this.grid.colModel;
49481        h = h.nextSibling;
49482        while(h){
49483            if(!cm.isHidden(v.getCellIndex(h))){
49484                return h;
49485            }
49486            h = h.nextSibling;
49487        }
49488        return null;
49489    },
49490
49491    prevVisible : function(h){
49492        var v = this.view, cm = this.grid.colModel;
49493        h = h.prevSibling;
49494        while(h){
49495            if(!cm.isHidden(v.getCellIndex(h))){
49496                return h;
49497            }
49498            h = h.prevSibling;
49499        }
49500        return null;
49501    },
49502
49503    positionIndicator : function(h, n, e){
49504        var x = Ext.lib.Event.getPageX(e),
49505            r = Ext.lib.Dom.getRegion(n.firstChild),
49506            px, 
49507            pt, 
49508            py = r.top + this.proxyOffsets[1];
49509        if((r.right - x) <= (r.right-r.left)/2){
49510            px = r.right+this.view.borderWidth;
49511            pt = "after";
49512        }else{
49513            px = r.left;
49514            pt = "before";
49515        }
49516
49517        if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
49518            return false;
49519        }
49520
49521        px +=  this.proxyOffsets[0];
49522        this.proxyTop.setLeftTop(px, py);
49523        this.proxyTop.show();
49524        if(!this.bottomOffset){
49525            this.bottomOffset = this.view.mainHd.getHeight();
49526        }
49527        this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
49528        this.proxyBottom.show();
49529        return pt;
49530    },
49531
49532    onNodeEnter : function(n, dd, e, data){
49533        if(data.header != n){
49534            this.positionIndicator(data.header, n, e);
49535        }
49536    },
49537
49538    onNodeOver : function(n, dd, e, data){
49539        var result = false;
49540        if(data.header != n){
49541            result = this.positionIndicator(data.header, n, e);
49542        }
49543        if(!result){
49544            this.proxyTop.hide();
49545            this.proxyBottom.hide();
49546        }
49547        return result ? this.dropAllowed : this.dropNotAllowed;
49548    },
49549
49550    onNodeOut : function(n, dd, e, data){
49551        this.proxyTop.hide();
49552        this.proxyBottom.hide();
49553    },
49554
49555    onNodeDrop : function(n, dd, e, data){
49556        var h = data.header;
49557        if(h != n){
49558            var cm = this.grid.colModel,
49559                x = Ext.lib.Event.getPageX(e),
49560                r = Ext.lib.Dom.getRegion(n.firstChild),
49561                pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
49562                oldIndex = this.view.getCellIndex(h),
49563                newIndex = this.view.getCellIndex(n);
49564            if(pt == "after"){
49565                newIndex++;
49566            }
49567            if(oldIndex < newIndex){
49568                newIndex--;
49569            }
49570            cm.moveColumn(oldIndex, newIndex);
49571            return true;
49572        }
49573        return false;
49574    }
49575});
49576
49577Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
49578    
49579    constructor : function(grid, hd){
49580        Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
49581        this.proxy.el.addClass('x-grid3-col-dd');
49582    },
49583    
49584    handleMouseDown : function(e){
49585    },
49586
49587    callHandleMouseDown : function(e){
49588        Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
49589    }
49590});
49591
49592Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
49593    fly: Ext.Element.fly,
49594    
49595    constructor : function(grid, hd, hd2){
49596        this.grid = grid;
49597        this.view = grid.getView();
49598        this.proxy = this.view.resizeProxy;
49599        Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
49600            "gridSplitters" + this.grid.getGridEl().id, {
49601            dragElId : Ext.id(this.proxy.dom), resizeFrame:false
49602        });
49603        this.setHandleElId(Ext.id(hd));
49604        this.setOuterHandleElId(Ext.id(hd2));
49605        this.scroll = false;
49606    },
49607
49608    b4StartDrag : function(x, y){
49609        this.view.headersDisabled = true;
49610        this.proxy.setHeight(this.view.mainWrap.getHeight());
49611        var w = this.cm.getColumnWidth(this.cellIndex);
49612        var minw = Math.max(w-this.grid.minColumnWidth, 0);
49613        this.resetConstraints();
49614        this.setXConstraint(minw, 1000);
49615        this.setYConstraint(0, 0);
49616        this.minX = x - minw;
49617        this.maxX = x + 1000;
49618        this.startPos = x;
49619        Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
49620    },
49621
49622
49623    handleMouseDown : function(e){
49624        var ev = Ext.EventObject.setEvent(e);
49625        var t = this.fly(ev.getTarget());
49626        if(t.hasClass("x-grid-split")){
49627            this.cellIndex = this.view.getCellIndex(t.dom);
49628            this.split = t.dom;
49629            this.cm = this.grid.colModel;
49630            if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
49631                Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
49632            }
49633        }
49634    },
49635
49636    endDrag : function(e){
49637        this.view.headersDisabled = false;
49638        var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
49639        var diff = endX - this.startPos;
49640        this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
49641    },
49642
49643    autoOffset : function(){
49644        this.setDelta(0,0);
49645    }
49646});
49647Ext.grid.GridDragZone = function(grid, config){
49648    this.view = grid.getView();
49649    Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
49650    this.scroll = false;
49651    this.grid = grid;
49652    this.ddel = document.createElement('div');
49653    this.ddel.className = 'x-grid-dd-wrap';
49654};
49655
49656Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
49657    ddGroup : "GridDD",
49658
49659    
49660    getDragData : function(e){
49661        var t = Ext.lib.Event.getTarget(e);
49662        var rowIndex = this.view.findRowIndex(t);
49663        if(rowIndex !== false){
49664            var sm = this.grid.selModel;
49665            if(!sm.isSelected(rowIndex) || e.hasModifier()){
49666                sm.handleMouseDown(this.grid, rowIndex, e);
49667            }
49668            return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
49669        }
49670        return false;
49671    },
49672
49673    
49674    onInitDrag : function(e){
49675        var data = this.dragData;
49676        this.ddel.innerHTML = this.grid.getDragDropText();
49677        this.proxy.update(this.ddel);
49678        
49679    },
49680
49681    
49682    afterRepair : function(){
49683        this.dragging = false;
49684    },
49685
49686    
49687    getRepairXY : function(e, data){
49688        return false;
49689    },
49690
49691    onEndDrag : function(data, e){
49692        
49693    },
49694
49695    onValidDrop : function(dd, e, id){
49696        
49697        this.hideProxy();
49698    },
49699
49700    beforeInvalidDrop : function(e, id){
49701
49702    }
49703});
49704
49705Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
49706    
49707    defaultWidth: 100,
49708
49709    
49710    defaultSortable: false,
49711
49712    
49713
49714    
49715
49716    constructor : function(config) {
49717        
49718	    if (config.columns) {
49719	        Ext.apply(this, config);
49720	        this.setConfig(config.columns, true);
49721	    } else {
49722	        this.setConfig(config, true);
49723	    }
49724	    
49725	    this.addEvents(
49726	        
49727	        "widthchange",
49728	        
49729	        
49730	        "headerchange",
49731	        
49732	        
49733	        "hiddenchange",
49734	        
49735	        
49736	        "columnmoved",
49737	        
49738	        
49739	        "configchange"
49740	    );
49741	    
49742	    Ext.grid.ColumnModel.superclass.constructor.call(this);
49743    },
49744
49745    
49746    getColumnId : function(index) {
49747        return this.config[index].id;
49748    },
49749
49750    getColumnAt : function(index) {
49751        return this.config[index];
49752    },
49753
49754    
49755    setConfig : function(config, initial) {
49756        var i, c, len;
49757        
49758        if (!initial) { 
49759            delete this.totalWidth;
49760            
49761            for (i = 0, len = this.config.length; i < len; i++) {
49762                c = this.config[i];
49763                
49764                if (c.setEditor) {
49765                    
49766                    c.setEditor(null);
49767                }
49768            }
49769        }
49770
49771        
49772        this.defaults = Ext.apply({
49773            width: this.defaultWidth,
49774            sortable: this.defaultSortable
49775        }, this.defaults);
49776
49777        this.config = config;
49778        this.lookup = {};
49779
49780        for (i = 0, len = config.length; i < len; i++) {
49781            c = Ext.applyIf(config[i], this.defaults);
49782            
49783            
49784            if (Ext.isEmpty(c.id)) {
49785                c.id = i;
49786            }
49787            
49788            if (!c.isColumn) {
49789                var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
49790                c = new Cls(c);
49791                config[i] = c;
49792            }
49793            
49794            this.lookup[c.id] = c;
49795        }
49796        
49797        if (!initial) {
49798            this.fireEvent('configchange', this);
49799        }
49800    },
49801
49802    
49803    getColumnById : function(id) {
49804        return this.lookup[id];
49805    },
49806
49807    
49808    getIndexById : function(id) {
49809        for (var i = 0, len = this.config.length; i < len; i++) {
49810            if (this.config[i].id == id) {
49811                return i;
49812            }
49813        }
49814        return -1;
49815    },
49816
49817    
49818    moveColumn : function(oldIndex, newIndex) {
49819        var config = this.config,
49820            c      = config[oldIndex];
49821            
49822        config.splice(oldIndex, 1);
49823        config.splice(newIndex, 0, c);
49824        this.dataMap = null;
49825        this.fireEvent("columnmoved", this, oldIndex, newIndex);
49826    },
49827
49828    
49829    getColumnCount : function(visibleOnly) {
49830        var length = this.config.length,
49831            c = 0,
49832            i;
49833        
49834        if (visibleOnly === true) {
49835            for (i = 0; i < length; i++) {
49836                if (!this.isHidden(i)) {
49837                    c++;
49838                }
49839            }
49840            
49841            return c;
49842        }
49843        
49844        return length;
49845    },
49846
49847    
49848    getColumnsBy : function(fn, scope) {
49849        var config = this.config,
49850            length = config.length,
49851            result = [],
49852            i, c;
49853            
49854        for (i = 0; i < length; i++){
49855            c = config[i];
49856            
49857            if (fn.call(scope || this, c, i) === true) {
49858                result[result.length] = c;
49859            }
49860        }
49861        
49862        return result;
49863    },
49864
49865    
49866    isSortable : function(col) {
49867        return !!this.config[col].sortable;
49868    },
49869
49870    
49871    isMenuDisabled : function(col) {
49872        return !!this.config[col].menuDisabled;
49873    },
49874
49875    
49876    getRenderer : function(col) {
49877        return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
49878    },
49879
49880    getRendererScope : function(col) {
49881        return this.config[col].scope;
49882    },
49883
49884    
49885    setRenderer : function(col, fn) {
49886        this.config[col].renderer = fn;
49887    },
49888
49889    
49890    getColumnWidth : function(col) {
49891        var width = this.config[col].width;
49892        if(typeof width != 'number'){
49893            width = this.defaultWidth;
49894        }
49895        return width;
49896    },
49897
49898    
49899    setColumnWidth : function(col, width, suppressEvent) {
49900        this.config[col].width = width;
49901        this.totalWidth = null;
49902        
49903        if (!suppressEvent) {
49904             this.fireEvent("widthchange", this, col, width);
49905        }
49906    },
49907
49908    
49909    getTotalWidth : function(includeHidden) {
49910        if (!this.totalWidth) {
49911            this.totalWidth = 0;
49912            for (var i = 0, len = this.config.length; i < len; i++) {
49913                if (includeHidden || !this.isHidden(i)) {
49914                    this.totalWidth += this.getColumnWidth(i);
49915                }
49916            }
49917        }
49918        return this.totalWidth;
49919    },
49920
49921    
49922    getColumnHeader : function(col) {
49923        return this.config[col].header;
49924    },
49925
49926    
49927    setColumnHeader : function(col, header) {
49928        this.config[col].header = header;
49929        this.fireEvent("headerchange", this, col, header);
49930    },
49931
49932    
49933    getColumnTooltip : function(col) {
49934            return this.config[col].tooltip;
49935    },
49936    
49937    setColumnTooltip : function(col, tooltip) {
49938            this.config[col].tooltip = tooltip;
49939    },
49940
49941    
49942    getDataIndex : function(col) {
49943        return this.config[col].dataIndex;
49944    },
49945
49946    
49947    setDataIndex : function(col, dataIndex) {
49948        this.config[col].dataIndex = dataIndex;
49949    },
49950
49951    
49952    findColumnIndex : function(dataIndex) {
49953        var c = this.config;
49954        for(var i = 0, len = c.length; i < len; i++){
49955            if(c[i].dataIndex == dataIndex){
49956                return i;
49957            }
49958        }
49959        return -1;
49960    },
49961
49962    
49963    isCellEditable : function(colIndex, rowIndex) {
49964        var c = this.config[colIndex],
49965            ed = c.editable;
49966
49967        
49968        return !!(ed || (!Ext.isDefined(ed) && c.editor));
49969    },
49970
49971    
49972    getCellEditor : function(colIndex, rowIndex) {
49973        return this.config[colIndex].getCellEditor(rowIndex);
49974    },
49975
49976    
49977    setEditable : function(col, editable) {
49978        this.config[col].editable = editable;
49979    },
49980
49981    
49982    isHidden : function(colIndex) {
49983        return !!this.config[colIndex].hidden; 
49984    },
49985
49986    
49987    isFixed : function(colIndex) {
49988        return !!this.config[colIndex].fixed;
49989    },
49990
49991    
49992    isResizable : function(colIndex) {
49993        return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
49994    },
49995    
49996    
49997    setHidden : function(colIndex, hidden) {
49998        var c = this.config[colIndex];
49999        if(c.hidden !== hidden){
50000            c.hidden = hidden;
50001            this.totalWidth = null;
50002            this.fireEvent("hiddenchange", this, colIndex, hidden);
50003        }
50004    },
50005
50006    
50007    setEditor : function(col, editor) {
50008        this.config[col].setEditor(editor);
50009    },
50010
50011    
50012    destroy : function() {
50013        var length = this.config.length,
50014            i = 0;
50015
50016        for (; i < length; i++){
50017            this.config[i].destroy(); 
50018        }
50019        delete this.config;
50020        delete this.lookup;
50021        this.purgeListeners();
50022    },
50023
50024    
50025    setState : function(col, state) {
50026        state = Ext.applyIf(state, this.defaults);
50027        Ext.apply(this.config[col], state);
50028    }
50029});
50030
50031
50032Ext.grid.ColumnModel.defaultRenderer = function(value) {
50033    if (typeof value == "string" && value.length < 1) {
50034        return "&#160;";
50035    }
50036    return value;
50037};
50038Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable,  {
50039    
50040
50041    constructor : function(){
50042        this.locked = false;
50043        Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
50044    },
50045
50046    
50047    init : function(grid){
50048        this.grid = grid;
50049        if(this.lockOnInit){
50050            delete this.lockOnInit;
50051            this.locked = false;
50052            this.lock();
50053        }
50054        this.initEvents();
50055    },
50056
50057    
50058    lock : function(){
50059        if(!this.locked){
50060            this.locked = true;
50061            
50062            var g = this.grid;
50063            if(g){
50064                g.getView().on({
50065                    scope: this,
50066                    beforerefresh: this.sortUnLock,
50067                    refresh: this.sortLock
50068                });
50069            }else{
50070                this.lockOnInit = true;
50071            }
50072        }
50073    },
50074
50075    
50076    sortLock : function() {
50077        this.locked = true;
50078    },
50079
50080    
50081    sortUnLock : function() {
50082        this.locked = false;
50083    },
50084
50085    
50086    unlock : function(){
50087        if(this.locked){
50088            this.locked = false;
50089            var g = this.grid,
50090                gv;
50091                
50092            
50093            if(g){
50094                gv = g.getView();
50095                gv.un('beforerefresh', this.sortUnLock, this);
50096                gv.un('refresh', this.sortLock, this);    
50097            }else{
50098                delete this.lockOnInit;
50099            }
50100        }
50101    },
50102
50103    
50104    isLocked : function(){
50105        return this.locked;
50106    },
50107
50108    destroy: function(){
50109        this.unlock();
50110        this.purgeListeners();
50111    }
50112});
50113Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
50114    
50115    singleSelect : false,
50116    
50117    constructor : function(config){
50118        Ext.apply(this, config);
50119        this.selections = new Ext.util.MixedCollection(false, function(o){
50120            return o.id;
50121        });
50122
50123        this.last = false;
50124        this.lastActive = false;
50125
50126        this.addEvents(
50127	        
50128	        'selectionchange',
50129	        
50130	        'beforerowselect',
50131	        
50132	        'rowselect',
50133	        
50134	        'rowdeselect'
50135        );
50136        Ext.grid.RowSelectionModel.superclass.constructor.call(this);
50137    },
50138
50139    
50140    
50141    initEvents : function(){
50142
50143        if(!this.grid.enableDragDrop && !this.grid.enableDrag){
50144            this.grid.on('rowmousedown', this.handleMouseDown, this);
50145        }
50146
50147        this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
50148            up: this.onKeyPress, 
50149            down: this.onKeyPress,
50150            scope: this
50151        });
50152
50153        this.grid.getView().on({
50154            scope: this,
50155            refresh: this.onRefresh,
50156            rowupdated: this.onRowUpdated,
50157            rowremoved: this.onRemove
50158        });
50159    },
50160    
50161    onKeyPress : function(e, name){
50162        var up = name == 'up',
50163            method = up ? 'selectPrevious' : 'selectNext',
50164            add = up ? -1 : 1,
50165            last;
50166        if(!e.shiftKey || this.singleSelect){
50167            this[method](false);
50168        }else if(this.last !== false && this.lastActive !== false){
50169            last = this.last;
50170            this.selectRange(this.last,  this.lastActive + add);
50171            this.grid.getView().focusRow(this.lastActive);
50172            if(last !== false){
50173                this.last = last;
50174            }
50175        }else{
50176           this.selectFirstRow();
50177        }
50178    },
50179
50180    
50181    onRefresh : function(){
50182        var ds = this.grid.store,
50183            s = this.getSelections(),
50184            i = 0,
50185            len = s.length, 
50186            index, r;
50187            
50188        this.silent = true;
50189        this.clearSelections(true);
50190        for(; i < len; i++){
50191            r = s[i];
50192            if((index = ds.indexOfId(r.id)) != -1){
50193                this.selectRow(index, true);
50194            }
50195        }
50196        if(s.length != this.selections.getCount()){
50197            this.fireEvent('selectionchange', this);
50198        }
50199        this.silent = false;
50200    },
50201
50202    
50203    onRemove : function(v, index, r){
50204        if(this.selections.remove(r) !== false){
50205            this.fireEvent('selectionchange', this);
50206        }
50207    },
50208
50209    
50210    onRowUpdated : function(v, index, r){
50211        if(this.isSelected(r)){
50212            v.onRowSelect(index);
50213        }
50214    },
50215
50216    
50217    selectRecords : function(records, keepExisting){
50218        if(!keepExisting){
50219            this.clearSelections();
50220        }
50221        var ds = this.grid.store,
50222            i = 0,
50223            len = records.length;
50224        for(; i < len; i++){
50225            this.selectRow(ds.indexOf(records[i]), true);
50226        }
50227    },
50228
50229    
50230    getCount : function(){
50231        return this.selections.length;
50232    },
50233
50234    
50235    selectFirstRow : function(){
50236        this.selectRow(0);
50237    },
50238
50239    
50240    selectLastRow : function(keepExisting){
50241        this.selectRow(this.grid.store.getCount() - 1, keepExisting);
50242    },
50243
50244    
50245    selectNext : function(keepExisting){
50246        if(this.hasNext()){
50247            this.selectRow(this.last+1, keepExisting);
50248            this.grid.getView().focusRow(this.last);
50249            return true;
50250        }
50251        return false;
50252    },
50253
50254    
50255    selectPrevious : function(keepExisting){
50256        if(this.hasPrevious()){
50257            this.selectRow(this.last-1, keepExisting);
50258            this.grid.getView().focusRow(this.last);
50259            return true;
50260        }
50261        return false;
50262    },
50263
50264    
50265    hasNext : function(){
50266        return this.last !== false && (this.last+1) < this.grid.store.getCount();
50267    },
50268
50269    
50270    hasPrevious : function(){
50271        return !!this.last;
50272    },
50273
50274
50275    
50276    getSelections : function(){
50277        return [].concat(this.selections.items);
50278    },
50279
50280    
50281    getSelected : function(){
50282        return this.selections.itemAt(0);
50283    },
50284
50285    
50286    each : function(fn, scope){
50287        var s = this.getSelections(),
50288            i = 0,
50289            len = s.length;
50290            
50291        for(; i < len; i++){
50292            if(fn.call(scope || this, s[i], i) === false){
50293                return false;
50294            }
50295        }
50296        return true;
50297    },
50298
50299    
50300    clearSelections : function(fast){
50301        if(this.isLocked()){
50302            return;
50303        }
50304        if(fast !== true){
50305            var ds = this.grid.store,
50306                s = this.selections;
50307            s.each(function(r){
50308                this.deselectRow(ds.indexOfId(r.id));
50309            }, this);
50310            s.clear();
50311        }else{
50312            this.selections.clear();
50313        }
50314        this.last = false;
50315    },
50316
50317
50318    
50319    selectAll : function(){
50320        if(this.isLocked()){
50321            return;
50322        }
50323        this.selections.clear();
50324        for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
50325            this.selectRow(i, true);
50326        }
50327    },
50328
50329    
50330    hasSelection : function(){
50331        return this.selections.length > 0;
50332    },
50333
50334    
50335    isSelected : function(index){
50336        var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
50337        return (r && this.selections.key(r.id) ? true : false);
50338    },
50339
50340    
50341    isIdSelected : function(id){
50342        return (this.selections.key(id) ? true : false);
50343    },
50344
50345    
50346    handleMouseDown : function(g, rowIndex, e){
50347        if(e.button !== 0 || this.isLocked()){
50348            return;
50349        }
50350        var view = this.grid.getView();
50351        if(e.shiftKey && !this.singleSelect && this.last !== false){
50352            var last = this.last;
50353            this.selectRange(last, rowIndex, e.ctrlKey);
50354            this.last = last; 
50355            view.focusRow(rowIndex);
50356        }else{
50357            var isSelected = this.isSelected(rowIndex);
50358            if(e.ctrlKey && isSelected){
50359                this.deselectRow(rowIndex);
50360            }else if(!isSelected || this.getCount() > 1){
50361                this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
50362                view.focusRow(rowIndex);
50363            }
50364        }
50365    },
50366
50367    
50368    selectRows : function(rows, keepExisting){
50369        if(!keepExisting){
50370            this.clearSelections();
50371        }
50372        for(var i = 0, len = rows.length; i < len; i++){
50373            this.selectRow(rows[i], true);
50374        }
50375    },
50376
50377    
50378    selectRange : function(startRow, endRow, keepExisting){
50379        var i;
50380        if(this.isLocked()){
50381            return;
50382        }
50383        if(!keepExisting){
50384            this.clearSelections();
50385        }
50386        if(startRow <= endRow){
50387            for(i = startRow; i <= endRow; i++){
50388                this.selectRow(i, true);
50389            }
50390        }else{
50391            for(i = startRow; i >= endRow; i--){
50392                this.selectRow(i, true);
50393            }
50394        }
50395    },
50396
50397    
50398    deselectRange : function(startRow, endRow, preventViewNotify){
50399        if(this.isLocked()){
50400            return;
50401        }
50402        for(var i = startRow; i <= endRow; i++){
50403            this.deselectRow(i, preventViewNotify);
50404        }
50405    },
50406
50407    
50408    selectRow : function(index, keepExisting, preventViewNotify){
50409        if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
50410            return;
50411        }
50412        var r = this.grid.store.getAt(index);
50413        if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
50414            if(!keepExisting || this.singleSelect){
50415                this.clearSelections();
50416            }
50417            this.selections.add(r);
50418            this.last = this.lastActive = index;
50419            if(!preventViewNotify){
50420                this.grid.getView().onRowSelect(index);
50421            }
50422            if(!this.silent){
50423                this.fireEvent('rowselect', this, index, r);
50424                this.fireEvent('selectionchange', this);
50425            }
50426        }
50427    },
50428
50429    
50430    deselectRow : function(index, preventViewNotify){
50431        if(this.isLocked()){
50432            return;
50433        }
50434        if(this.last == index){
50435            this.last = false;
50436        }
50437        if(this.lastActive == index){
50438            this.lastActive = false;
50439        }
50440        var r = this.grid.store.getAt(index);
50441        if(r){
50442            this.selections.remove(r);
50443            if(!preventViewNotify){
50444                this.grid.getView().onRowDeselect(index);
50445            }
50446            this.fireEvent('rowdeselect', this, index, r);
50447            this.fireEvent('selectionchange', this);
50448        }
50449    },
50450
50451    
50452    acceptsNav : function(row, col, cm){
50453        return !cm.isHidden(col) && cm.isCellEditable(col, row);
50454    },
50455
50456    
50457    onEditorKey : function(field, e){
50458        var k = e.getKey(), 
50459            newCell, 
50460            g = this.grid, 
50461            last = g.lastEdit,
50462            ed = g.activeEditor,
50463            shift = e.shiftKey,
50464            ae, last, r, c;
50465            
50466        if(k == e.TAB){
50467            e.stopEvent();
50468            ed.completeEdit();
50469            if(shift){
50470                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
50471            }else{
50472                newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
50473            }
50474        }else if(k == e.ENTER){
50475            if(this.moveEditorOnEnter !== false){
50476                if(shift){
50477                    newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
50478                }else{
50479                    newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
50480                }
50481            }
50482        }
50483        if(newCell){
50484            r = newCell[0];
50485            c = newCell[1];
50486
50487            this.onEditorSelect(r, last.row);
50488
50489            if(g.isEditor && g.editing){ 
50490                ae = g.activeEditor;
50491                if(ae && ae.field.triggerBlur){
50492                    
50493                    ae.field.triggerBlur();
50494                }
50495            }
50496            g.startEditing(r, c);
50497        }
50498    },
50499    
50500    onEditorSelect: function(row, lastRow){
50501        if(lastRow != row){
50502            this.selectRow(row); 
50503        }
50504    },
50505    
50506    destroy : function(){
50507        Ext.destroy(this.rowNav);
50508        this.rowNav = null;
50509        Ext.grid.RowSelectionModel.superclass.destroy.call(this);
50510    }
50511});
50512
50513Ext.grid.Column = Ext.extend(Ext.util.Observable, {
50514    
50515    
50516    
50517    
50518    
50519    
50520    
50521    
50522    
50523    
50524    
50525    
50526    
50527    
50528    
50529    
50530    
50531    
50532    
50533    
50534    
50535    
50536
50537    
50538    isColumn : true,
50539
50540    constructor : function(config){
50541        Ext.apply(this, config);
50542
50543        if(Ext.isString(this.renderer)){
50544            this.renderer = Ext.util.Format[this.renderer];
50545        }else if(Ext.isObject(this.renderer)){
50546            this.scope = this.renderer.scope;
50547            this.renderer = this.renderer.fn;
50548        }
50549        if(!this.scope){
50550            this.scope = this;
50551        }
50552
50553        var ed = this.editor;
50554        delete this.editor;
50555        this.setEditor(ed);
50556        this.addEvents(
50557            
50558            'click',
50559            
50560            'contextmenu',
50561            
50562            'dblclick',
50563            
50564            'mousedown'
50565        );
50566        Ext.grid.Column.superclass.constructor.call(this);
50567    },
50568
50569    
50570    processEvent : function(name, e, grid, rowIndex, colIndex){
50571        return this.fireEvent(name, this, grid, rowIndex, e);
50572    },
50573
50574    
50575    destroy: function() {
50576        if(this.setEditor){
50577            this.setEditor(null);
50578        }
50579        this.purgeListeners();
50580    },
50581
50582    
50583    renderer : function(value){
50584        return value;
50585    },
50586
50587    
50588    getEditor: function(rowIndex){
50589        return this.editable !== false ? this.editor : null;
50590    },
50591
50592    
50593    setEditor : function(editor){
50594        var ed = this.editor;
50595        if(ed){
50596            if(ed.gridEditor){
50597                ed.gridEditor.destroy();
50598                delete ed.gridEditor;
50599            }else{
50600                ed.destroy();
50601            }
50602        }
50603        this.editor = null;
50604        if(editor){
50605            
50606            if(!editor.isXType){
50607                editor = Ext.create(editor, 'textfield');
50608            }
50609            this.editor = editor;
50610        }
50611    },
50612
50613    
50614    getCellEditor: function(rowIndex){
50615        var ed = this.getEditor(rowIndex);
50616        if(ed){
50617            if(!ed.startEdit){
50618                if(!ed.gridEditor){
50619                    ed.gridEditor = new Ext.grid.GridEditor(ed);
50620                }
50621                ed = ed.gridEditor;
50622            }
50623        }
50624        return ed;
50625    }
50626});
50627
50628
50629Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
50630    
50631    trueText: 'true',
50632    
50633    falseText: 'false',
50634    
50635    undefinedText: '&#160;',
50636
50637    constructor: function(cfg){
50638        Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
50639        var t = this.trueText, f = this.falseText, u = this.undefinedText;
50640        this.renderer = function(v){
50641            if(v === undefined){
50642                return u;
50643            }
50644            if(!v || v === 'false'){
50645                return f;
50646            }
50647            return t;
50648        };
50649    }
50650});
50651
50652
50653Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
50654    
50655    format : '0,000.00',
50656    constructor: function(cfg){
50657        Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
50658        this.renderer = Ext.util.Format.numberRenderer(this.format);
50659    }
50660});
50661
50662
50663Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
50664    
50665    format : 'm/d/Y',
50666    constructor: function(cfg){
50667        Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
50668        this.renderer = Ext.util.Format.dateRenderer(this.format);
50669    }
50670});
50671
50672
50673Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
50674    
50675    constructor: function(cfg){
50676        Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
50677        var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
50678        this.renderer = function(value, p, r){
50679            return tpl.apply(r.data);
50680        };
50681        this.tpl = tpl;
50682    }
50683});
50684
50685
50686Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
50687    
50688    
50689    
50690    
50691    
50692    
50693    
50694    
50695    header: '&#160;',
50696
50697    actionIdRe: /x-action-col-(\d+)/,
50698    
50699    
50700    altText: '',
50701
50702    constructor: function(cfg) {
50703        var me = this,
50704            items = cfg.items || (me.items = [me]),
50705            l = items.length,
50706            i,
50707            item;
50708
50709        Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);
50710
50711
50712
50713        me.renderer = function(v, meta) {
50714
50715            v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
50716
50717            meta.css += ' x-action-col-cell';
50718            for (i = 0; i < l; i++) {
50719                item = items[i];
50720                v += '<img alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
50721                    '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
50722                    ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
50723                    ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
50724            }
50725            return v;
50726        };
50727    },
50728
50729    destroy: function() {
50730        delete this.items;
50731        delete this.renderer;
50732        return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
50733    },
50734
50735    
50736    processEvent : function(name, e, grid, rowIndex, colIndex){
50737        var m = e.getTarget().className.match(this.actionIdRe),
50738            item, fn;
50739        if (m && (item = this.items[parseInt(m[1], 10)])) {
50740            if (name == 'click') {
50741                (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
50742            } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
50743                return false;
50744            }
50745        }
50746        return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
50747    }
50748});
50749
50750
50751Ext.grid.Column.types = {
50752    gridcolumn : Ext.grid.Column,
50753    booleancolumn: Ext.grid.BooleanColumn,
50754    numbercolumn: Ext.grid.NumberColumn,
50755    datecolumn: Ext.grid.DateColumn,
50756    templatecolumn: Ext.grid.TemplateColumn,
50757    actioncolumn: Ext.grid.ActionColumn
50758};
50759Ext.grid.RowNumberer = Ext.extend(Object, {
50760    
50761    header: "",
50762    
50763    width: 23,
50764    
50765    sortable: false,
50766    
50767    constructor : function(config){
50768        Ext.apply(this, config);
50769        if(this.rowspan){
50770            this.renderer = this.renderer.createDelegate(this);
50771        }
50772    },
50773
50774    
50775    fixed:true,
50776    hideable: false,
50777    menuDisabled:true,
50778    dataIndex: '',
50779    id: 'numberer',
50780    rowspan: undefined,
50781
50782    
50783    renderer : function(v, p, record, rowIndex){
50784        if(this.rowspan){
50785            p.cellAttr = 'rowspan="'+this.rowspan+'"';
50786        }
50787        return rowIndex+1;
50788    }
50789});
50790Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
50791
50792    
50793    
50794    header : '<div class="x-grid3-hd-checker">&#160;</div>',
50795    
50796    width : 20,
50797    
50798    sortable : false,
50799
50800    
50801    menuDisabled : true,
50802    fixed : true,
50803    hideable: false,
50804    dataIndex : '',
50805    id : 'checker',
50806    isColumn: true, 
50807
50808    constructor : function(){
50809        Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
50810        if(this.checkOnly){
50811            this.handleMouseDown = Ext.emptyFn;
50812        }
50813    },
50814
50815    
50816    initEvents : function(){
50817        Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
50818        this.grid.on('render', function(){
50819            Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
50820        }, this);
50821    },
50822
50823    
50824    processEvent : function(name, e, grid, rowIndex, colIndex){
50825        if (name == 'mousedown') {
50826            this.onMouseDown(e, e.getTarget());
50827            return false;
50828        } else {
50829            return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
50830        }
50831    },
50832
50833    
50834    onMouseDown : function(e, t){
50835        if(e.button === 0 && t.className == 'x-grid3-row-checker'){ 
50836            e.stopEvent();
50837            var row = e.getTarget('.x-grid3-row');
50838            if(row){
50839                var index = row.rowIndex;
50840                if(this.isSelected(index)){
50841                    this.deselectRow(index);
50842                }else{
50843                    this.selectRow(index, true);
50844                    this.grid.getView().focusRow(index);
50845                }
50846            }
50847        }
50848    },
50849
50850    
50851    onHdMouseDown : function(e, t) {
50852        if(t.className == 'x-grid3-hd-checker'){
50853            e.stopEvent();
50854            var hd = Ext.fly(t.parentNode);
50855            var isChecked = hd.hasClass('x-grid3-hd-checker-on');
50856            if(isChecked){
50857                hd.removeClass('x-grid3-hd-checker-on');
50858                this.clearSelections();
50859            }else{
50860                hd.addClass('x-grid3-hd-checker-on');
50861                this.selectAll();
50862            }
50863        }
50864    },
50865
50866    
50867    renderer : function(v, p, record){
50868        return '<div class="x-grid3-row-checker">&#160;</div>';
50869    },
50870    
50871    onEditorSelect: function(row, lastRow){
50872        if(lastRow != row && !this.checkOnly){
50873            this.selectRow(row); 
50874        }
50875    }
50876});
50877Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
50878    
50879    constructor : function(config){
50880        Ext.apply(this, config);
50881
50882	    this.selection = null;
50883	
50884	    this.addEvents(
50885	        
50886	        "beforecellselect",
50887	        
50888	        "cellselect",
50889	        
50890	        "selectionchange"
50891	    );
50892	
50893	    Ext.grid.CellSelectionModel.superclass.constructor.call(this);
50894    },
50895
50896    
50897    initEvents : function(){
50898        this.grid.on('cellmousedown', this.handleMouseDown, this);
50899        this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
50900        this.grid.getView().on({
50901            scope: this,
50902            refresh: this.onViewChange,
50903            rowupdated: this.onRowUpdated,
50904            beforerowremoved: this.clearSelections,
50905            beforerowsinserted: this.clearSelections
50906        });
50907        if(this.grid.isEditor){
50908            this.grid.on('beforeedit', this.beforeEdit,  this);
50909        }
50910    },
50911
50912	
50913    beforeEdit : function(e){
50914        this.select(e.row, e.column, false, true, e.record);
50915    },
50916
50917	
50918    onRowUpdated : function(v, index, r){
50919        if(this.selection && this.selection.record == r){
50920            v.onCellSelect(index, this.selection.cell[1]);
50921        }
50922    },
50923
50924	
50925    onViewChange : function(){
50926        this.clearSelections(true);
50927    },
50928
50929	
50930    getSelectedCell : function(){
50931        return this.selection ? this.selection.cell : null;
50932    },
50933
50934    
50935    clearSelections : function(preventNotify){
50936        var s = this.selection;
50937        if(s){
50938            if(preventNotify !== true){
50939                this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
50940            }
50941            this.selection = null;
50942            this.fireEvent("selectionchange", this, null);
50943        }
50944    },
50945
50946    
50947    hasSelection : function(){
50948        return this.selection ? true : false;
50949    },
50950
50951    
50952    handleMouseDown : function(g, row, cell, e){
50953        if(e.button !== 0 || this.isLocked()){
50954            return;
50955        }
50956        this.select(row, cell);
50957    },
50958
50959    
50960    select : function(rowIndex, colIndex, preventViewNotify, preventFocus,  r){
50961        if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
50962            this.clearSelections();
50963            r = r || this.grid.store.getAt(rowIndex);
50964            this.selection = {
50965                record : r,
50966                cell : [rowIndex, colIndex]
50967            };
50968            if(!preventViewNotify){
50969                var v = this.grid.getView();
50970                v.onCellSelect(rowIndex, colIndex);
50971                if(preventFocus !== true){
50972                    v.focusCell(rowIndex, colIndex);
50973                }
50974            }
50975            this.fireEvent("cellselect", this, rowIndex, colIndex);
50976            this.fireEvent("selectionchange", this, this.selection);
50977        }
50978    },
50979
50980	
50981    isSelectable : function(rowIndex, colIndex, cm){
50982        return !cm.isHidden(colIndex);
50983    },
50984    
50985    
50986    onEditorKey: function(field, e){
50987        if(e.getKey() == e.TAB){
50988            this.handleKeyDown(e);
50989        }
50990    },
50991
50992    
50993    handleKeyDown : function(e){
50994        if(!e.isNavKeyPress()){
50995            return;
50996        }
50997        
50998        var k = e.getKey(),
50999            g = this.grid,
51000            s = this.selection,
51001            sm = this,
51002            walk = function(row, col, step){
51003                return g.walkCells(
51004                    row,
51005                    col,
51006                    step,
51007                    g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, 
51008                    sm
51009                );
51010            },
51011            cell, newCell, r, c, ae;
51012
51013        switch(k){
51014            case e.ESC:
51015            case e.PAGE_UP:
51016            case e.PAGE_DOWN:
51017                
51018                break;
51019            default:
51020                
51021                e.stopEvent();
51022                break;
51023        }
51024
51025        if(!s){
51026            cell = walk(0, 0, 1); 
51027            if(cell){
51028                this.select(cell[0], cell[1]);
51029            }
51030            return;
51031        }
51032
51033        cell = s.cell;  
51034        r = cell[0];    
51035        c = cell[1];    
51036        
51037        switch(k){
51038            case e.TAB:
51039                if(e.shiftKey){
51040                    newCell = walk(r, c - 1, -1);
51041                }else{
51042                    newCell = walk(r, c + 1, 1);
51043                }
51044                break;
51045            case e.DOWN:
51046                newCell = walk(r + 1, c, 1);
51047                break;
51048            case e.UP:
51049                newCell = walk(r - 1, c, -1);
51050                break;
51051            case e.RIGHT:
51052                newCell = walk(r, c + 1, 1);
51053                break;
51054            case e.LEFT:
51055                newCell = walk(r, c - 1, -1);
51056                break;
51057            case e.ENTER:
51058                if (g.isEditor && !g.editing) {
51059                    g.startEditing(r, c);
51060                    return;
51061                }
51062                break;
51063        }
51064
51065        if(newCell){
51066            
51067            r = newCell[0];
51068            c = newCell[1];
51069
51070            this.select(r, c); 
51071
51072            if(g.isEditor && g.editing){ 
51073                ae = g.activeEditor;
51074                if(ae && ae.field.triggerBlur){
51075                    
51076                    ae.field.triggerBlur();
51077                }
51078                g.startEditing(r, c);
51079            }
51080        }
51081    },
51082
51083    acceptsNav : function(row, col, cm){
51084        return !cm.isHidden(col) && cm.isCellEditable(col, row);
51085    }
51086});
51087Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
51088    
51089    clicksToEdit: 2,
51090
51091    
51092    forceValidation: false,
51093
51094    
51095    isEditor : true,
51096    
51097    detectEdit: false,
51098
51099    
51100    autoEncode : false,
51101
51102    
51103    
51104    trackMouseOver: false, 
51105
51106    
51107    initComponent : function(){
51108        Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
51109
51110        if(!this.selModel){
51111            
51112            this.selModel = new Ext.grid.CellSelectionModel();
51113        }
51114
51115        this.activeEditor = null;
51116
51117        this.addEvents(
51118            
51119            "beforeedit",
51120            
51121            "afteredit",
51122            
51123            "validateedit"
51124        );
51125    },
51126
51127    
51128    initEvents : function(){
51129        Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
51130
51131        this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
51132        this.on('columnresize', this.stopEditing, this, [true]);
51133
51134        if(this.clicksToEdit == 1){
51135            this.on("cellclick", this.onCellDblClick, this);
51136        }else {
51137            var view = this.getView();
51138            if(this.clicksToEdit == 'auto' && view.mainBody){
51139                view.mainBody.on('mousedown', this.onAutoEditClick, this);
51140            }
51141            this.on('celldblclick', this.onCellDblClick, this);
51142        }
51143    },
51144
51145    onResize : function(){
51146        Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
51147        var ae = this.activeEditor;
51148        if(this.editing && ae){
51149            ae.realign(true);
51150        }
51151    },
51152
51153    
51154    onCellDblClick : function(g, row, col){
51155        this.startEditing(row, col);
51156    },
51157
51158    
51159    onAutoEditClick : function(e, t){
51160        if(e.button !== 0){
51161            return;
51162        }
51163        var row = this.view.findRowIndex(t),
51164            col = this.view.findCellIndex(t);
51165        if(row !== false && col !== false){
51166            this.stopEditing();
51167            if(this.selModel.getSelectedCell){ 
51168                var sc = this.selModel.getSelectedCell();
51169                if(sc && sc[0] === row && sc[1] === col){
51170                    this.startEditing(row, col);
51171                }
51172            }else{
51173                if(this.selModel.isSelected(row)){
51174                    this.startEditing(row, col);
51175                }
51176            }
51177        }
51178    },
51179
51180    
51181    onEditComplete : function(ed, value, startValue){
51182        this.editing = false;
51183        this.lastActiveEditor = this.activeEditor;
51184        this.activeEditor = null;
51185
51186        var r = ed.record,
51187            field = this.colModel.getDataIndex(ed.col);
51188        value = this.postEditValue(value, startValue, r, field);
51189        if(this.forceValidation === true || String(value) !== String(startValue)){
51190            var e = {
51191                grid: this,
51192                record: r,
51193                field: field,
51194                originalValue: startValue,
51195                value: value,
51196                row: ed.row,
51197                column: ed.col,
51198                cancel:false
51199            };
51200            if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
51201                r.set(field, e.value);
51202                delete e.cancel;
51203                this.fireEvent("afteredit", e);
51204            }
51205        }
51206        this.view.focusCell(ed.row, ed.col);
51207    },
51208
51209    
51210    startEditing : function(row, col){
51211        this.stopEditing();
51212        if(this.colModel.isCellEditable(col, row)){
51213            this.view.ensureVisible(row, col, true);
51214            var r = this.store.getAt(row),
51215                field = this.colModel.getDataIndex(col),
51216                e = {
51217                    grid: this,
51218                    record: r,
51219                    field: field,
51220                    value: r.data[field],
51221                    row: row,
51222                    column: col,
51223                    cancel:false
51224                };
51225            if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
51226                this.editing = true;
51227                var ed = this.colModel.getCellEditor(col, row);
51228                if(!ed){
51229                    return;
51230                }
51231                if(!ed.rendered){
51232                    ed.parentEl = this.view.getEditorParent(ed);
51233                    ed.on({
51234                        scope: this,
51235                        render: {
51236                            fn: function(c){
51237                                c.field.focus(false, true);
51238                            },
51239                            single: true,
51240                            scope: this
51241                        },
51242                        specialkey: function(field, e){
51243                            this.getSelectionModel().onEditorKey(field, e);
51244                        },
51245                        complete: this.onEditComplete,
51246                        canceledit: this.stopEditing.createDelegate(this, [true])
51247                    });
51248                }
51249                Ext.apply(ed, {
51250                    row     : row,
51251                    col     : col,
51252                    record  : r
51253                });
51254                this.lastEdit = {
51255                    row: row,
51256                    col: col
51257                };
51258                this.activeEditor = ed;
51259                
51260                
51261                ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
51262                var v = this.preEditValue(r, field);
51263                ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
51264
51265                
51266                (function(){
51267                    delete ed.selectSameEditor;
51268                }).defer(50);
51269            }
51270        }
51271    },
51272
51273    
51274    preEditValue : function(r, field){
51275        var value = r.data[field];
51276        return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
51277    },
51278
51279    
51280    postEditValue : function(value, originalValue, r, field){
51281        return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
51282    },
51283
51284    
51285    stopEditing : function(cancel){
51286        if(this.editing){
51287            
51288            var ae = this.lastActiveEditor = this.activeEditor;
51289            if(ae){
51290                ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
51291                this.view.focusCell(ae.row, ae.col);
51292            }
51293            this.activeEditor = null;
51294        }
51295        this.editing = false;
51296    }
51297});
51298Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
51299
51300Ext.grid.GridEditor = function(field, config){
51301    Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
51302    field.monitorTab = false;
51303};
51304
51305Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
51306    alignment: "tl-tl",
51307    autoSize: "width",
51308    hideEl : false,
51309    cls: "x-small-editor x-grid-editor",
51310    shim:false,
51311    shadow:false
51312});
51313Ext.grid.PropertyRecord = Ext.data.Record.create([
51314    {name:'name',type:'string'}, 'value'
51315]);
51316
51317
51318Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
51319    
51320    constructor : function(grid, source){
51321        this.grid = grid;
51322        this.store = new Ext.data.Store({
51323            recordType : Ext.grid.PropertyRecord
51324        });
51325        this.store.on('update', this.onUpdate,  this);
51326        if(source){
51327            this.setSource(source);
51328        }
51329        Ext.grid.PropertyStore.superclass.constructor.call(this);    
51330    },
51331    
51332    
51333    setSource : function(o){
51334        this.source = o;
51335        this.store.removeAll();
51336        var data = [];
51337        for(var k in o){
51338            if(this.isEditableValue(o[k])){
51339                data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
51340            }
51341        }
51342        this.store.loadRecords({records: data}, {}, true);
51343    },
51344
51345    
51346    onUpdate : function(ds, record, type){
51347        if(type == Ext.data.Record.EDIT){
51348            var v = record.data.value;
51349            var oldValue = record.modified.value;
51350            if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
51351                this.source[record.id] = v;
51352                record.commit();
51353                this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
51354            }else{
51355                record.reject();
51356            }
51357        }
51358    },
51359
51360    
51361    getProperty : function(row){
51362       return this.store.getAt(row);
51363    },
51364
51365    
51366    isEditableValue: function(val){
51367        return Ext.isPrimitive(val) || Ext.isDate(val);
51368    },
51369
51370    
51371    setValue : function(prop, value, create){
51372        var r = this.getRec(prop);
51373        if(r){
51374            r.set('value', value);
51375            this.source[prop] = value;
51376        }else if(create){
51377            
51378            this.source[prop] = value;
51379            r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
51380            this.store.add(r);
51381
51382        }
51383    },
51384    
51385    
51386    remove : function(prop){
51387        var r = this.getRec(prop);
51388        if(r){
51389            this.store.remove(r);
51390            delete this.source[prop];
51391        }
51392    },
51393    
51394    
51395    getRec : function(prop){
51396        return this.store.getById(prop);
51397    },
51398
51399    
51400    getSource : function(){
51401        return this.source;
51402    }
51403});
51404
51405
51406Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
51407    
51408    nameText : 'Name',
51409    valueText : 'Value',
51410    dateFormat : 'm/j/Y',
51411    trueText: 'true',
51412    falseText: 'false',
51413    
51414    constructor : function(grid, store){
51415        var g = Ext.grid,
51416	        f = Ext.form;
51417	        
51418	    this.grid = grid;
51419	    g.PropertyColumnModel.superclass.constructor.call(this, [
51420	        {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
51421	        {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
51422	    ]);
51423	    this.store = store;
51424	
51425	    var bfield = new f.Field({
51426	        autoCreate: {tag: 'select', children: [
51427	            {tag: 'option', value: 'true', html: this.trueText},
51428	            {tag: 'option', value: 'false', html: this.falseText}
51429	        ]},
51430	        getValue : function(){
51431	            return this.el.dom.value == 'true';
51432	        }
51433	    });
51434	    this.editors = {
51435	        'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
51436	        'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
51437	        'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
51438	        'boolean' : new g.GridEditor(bfield, {
51439	            autoSize: 'both'
51440	        })
51441	    };
51442	    this.renderCellDelegate = this.renderCell.createDelegate(this);
51443	    this.renderPropDelegate = this.renderProp.createDelegate(this);
51444    },
51445
51446    
51447    renderDate : function(dateVal){
51448        return dateVal.dateFormat(this.dateFormat);
51449    },
51450
51451    
51452    renderBool : function(bVal){
51453        return this[bVal ? 'trueText' : 'falseText'];
51454    },
51455
51456    
51457    isCellEditable : function(colIndex, rowIndex){
51458        return colIndex == 1;
51459    },
51460
51461    
51462    getRenderer : function(col){
51463        return col == 1 ?
51464            this.renderCellDelegate : this.renderPropDelegate;
51465    },
51466
51467    
51468    renderProp : function(v){
51469        return this.getPropertyName(v);
51470    },
51471
51472    
51473    renderCell : function(val, meta, rec){
51474        var renderer = this.grid.customRenderers[rec.get('name')];
51475        if(renderer){
51476            return renderer.apply(this, arguments);
51477        }
51478        var rv = val;
51479        if(Ext.isDate(val)){
51480            rv = this.renderDate(val);
51481        }else if(typeof val == 'boolean'){
51482            rv = this.renderBool(val);
51483        }
51484        return Ext.util.Format.htmlEncode(rv);
51485    },
51486
51487    
51488    getPropertyName : function(name){
51489        var pn = this.grid.propertyNames;
51490        return pn && pn[name] ? pn[name] : name;
51491    },
51492
51493    
51494    getCellEditor : function(colIndex, rowIndex){
51495        var p = this.store.getProperty(rowIndex),
51496            n = p.data.name, 
51497            val = p.data.value;
51498        if(this.grid.customEditors[n]){
51499            return this.grid.customEditors[n];
51500        }
51501        if(Ext.isDate(val)){
51502            return this.editors.date;
51503        }else if(typeof val == 'number'){
51504            return this.editors.number;
51505        }else if(typeof val == 'boolean'){
51506            return this.editors['boolean'];
51507        }else{
51508            return this.editors.string;
51509        }
51510    },
51511
51512    
51513    destroy : function(){
51514        Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
51515        this.destroyEditors(this.editors);
51516        this.destroyEditors(this.grid.customEditors);
51517    },
51518    
51519    destroyEditors: function(editors){
51520        for(var ed in editors){
51521            Ext.destroy(editors[ed]);
51522        }
51523    }
51524});
51525
51526
51527Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
51528    
51529    
51530    
51531    
51532    
51533
51534    
51535    enableColumnMove:false,
51536    stripeRows:false,
51537    trackMouseOver: false,
51538    clicksToEdit:1,
51539    enableHdMenu : false,
51540    viewConfig : {
51541        forceFit:true
51542    },
51543
51544    
51545    initComponent : function(){
51546        this.customRenderers = this.customRenderers || {};
51547        this.customEditors = this.customEditors || {};
51548        this.lastEditRow = null;
51549        var store = new Ext.grid.PropertyStore(this);
51550        this.propStore = store;
51551        var cm = new Ext.grid.PropertyColumnModel(this, store);
51552        store.store.sort('name', 'ASC');
51553        this.addEvents(
51554            
51555            'beforepropertychange',
51556            
51557            'propertychange'
51558        );
51559        this.cm = cm;
51560        this.ds = store.store;
51561        Ext.grid.PropertyGrid.superclass.initComponent.call(this);
51562
51563		this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
51564            if(colIndex === 0){
51565                this.startEditing.defer(200, this, [rowIndex, 1]);
51566                return false;
51567            }
51568        }, this);
51569    },
51570
51571    
51572    onRender : function(){
51573        Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
51574
51575        this.getGridEl().addClass('x-props-grid');
51576    },
51577
51578    
51579    afterRender: function(){
51580        Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
51581        if(this.source){
51582            this.setSource(this.source);
51583        }
51584    },
51585
51586    
51587    setSource : function(source){
51588        this.propStore.setSource(source);
51589    },
51590
51591    
51592    getSource : function(){
51593        return this.propStore.getSource();
51594    },
51595    
51596    
51597    setProperty : function(prop, value, create){
51598        this.propStore.setValue(prop, value, create);    
51599    },
51600    
51601    
51602    removeProperty : function(prop){
51603        this.propStore.remove(prop);
51604    }
51605
51606    
51607    
51608    
51609    
51610});
51611Ext.reg("propertygrid", Ext.grid.PropertyGrid);
51612
51613Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
51614
51615    
51616    groupByText : 'Group By This Field',
51617    
51618    showGroupsText : 'Show in Groups',
51619    
51620    hideGroupedColumn : false,
51621    
51622    showGroupName : true,
51623    
51624    startCollapsed : false,
51625    
51626    enableGrouping : true,
51627    
51628    enableGroupingMenu : true,
51629    
51630    enableNoGroups : true,
51631    
51632    emptyGroupText : '(None)',
51633    
51634    ignoreAdd : false,
51635    
51636    groupTextTpl : '{text}',
51637
51638    
51639    groupMode: 'value',
51640
51641    
51642    
51643    
51644    cancelEditOnToggle: true,
51645
51646    
51647    initTemplates : function(){
51648        Ext.grid.GroupingView.superclass.initTemplates.call(this);
51649        this.state = {};
51650
51651        var sm = this.grid.getSelectionModel();
51652        sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
51653                this.onBeforeRowSelect, this);
51654
51655        if(!this.startGroup){
51656            this.startGroup = new Ext.XTemplate(
51657                '<div id="{groupId}" class="x-grid-group {cls}">',
51658                    '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
51659                    '<div id="{groupId}-bd" class="x-grid-group-body">'
51660            );
51661        }
51662        this.startGroup.compile();
51663
51664        if (!this.endGroup) {
51665            this.endGroup = '</div></div>';
51666        }
51667    },
51668
51669    
51670    findGroup : function(el){
51671        return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
51672    },
51673
51674    
51675    getGroups : function(){
51676        return this.hasRows() ? this.mainBody.dom.childNodes : [];
51677    },
51678
51679    
51680    onAdd : function(ds, records, index) {
51681        if (this.canGroup() && !this.ignoreAdd) {
51682            var ss = this.getScrollState();
51683            this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
51684            this.refresh();
51685            this.restoreScroll(ss);
51686            this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
51687        } else if (!this.canGroup()) {
51688            Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
51689        }
51690    },
51691
51692    
51693    onRemove : function(ds, record, index, isUpdate){
51694        Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
51695        var g = document.getElementById(record._groupId);
51696        if(g && g.childNodes[1].childNodes.length < 1){
51697            Ext.removeNode(g);
51698        }
51699        this.applyEmptyText();
51700    },
51701
51702    
51703    refreshRow : function(record){
51704        if(this.ds.getCount()==1){
51705            this.refresh();
51706        }else{
51707            this.isUpdating = true;
51708            Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
51709            this.isUpdating = false;
51710        }
51711    },
51712
51713    
51714    beforeMenuShow : function(){
51715        var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
51716        if((item = items.get('groupBy'))){
51717            item.setDisabled(disabled);
51718        }
51719        if((item = items.get('showGroups'))){
51720            item.setDisabled(disabled);
51721            item.setChecked(this.canGroup(), true);
51722        }
51723    },
51724
51725    
51726    renderUI : function(){
51727        var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);
51728
51729        if(this.enableGroupingMenu && this.hmenu){
51730            this.hmenu.add('-',{
51731                itemId:'groupBy',
51732                text: this.groupByText,
51733                handler: this.onGroupByClick,
51734                scope: this,
51735                iconCls:'x-group-by-icon'
51736            });
51737            if(this.enableNoGroups){
51738                this.hmenu.add({
51739                    itemId:'showGroups',
51740                    text: this.showGroupsText,
51741                    checked: true,
51742                    checkHandler: this.onShowGroupsClick,
51743                    scope: this
51744                });
51745            }
51746            this.hmenu.on('beforeshow', this.beforeMenuShow, this);
51747        }
51748        return markup;
51749    },
51750
51751    processEvent: function(name, e){
51752        Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
51753        var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
51754        if(hd){
51755            
51756            var field = this.getGroupField(),
51757                prefix = this.getPrefix(field),
51758                groupValue = hd.id.substring(prefix.length),
51759                emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
51760
51761            
51762            groupValue = groupValue.substr(0, groupValue.length - 3);
51763            
51764            
51765            if(groupValue || emptyRe.test(hd.id)){
51766                this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
51767            }
51768            if(name == 'mousedown' && e.button == 0){
51769                this.toggleGroup(hd.parentNode);
51770            }
51771        }
51772
51773    },
51774
51775    
51776    onGroupByClick : function(){
51777        var grid = this.grid;
51778        this.enableGrouping = true;
51779        grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
51780        grid.fireEvent('groupchange', grid, grid.store.getGroupState());
51781        this.beforeMenuShow(); 
51782        this.refresh();
51783    },
51784
51785    
51786    onShowGroupsClick : function(mi, checked){
51787        this.enableGrouping = checked;
51788        if(checked){
51789            this.onGroupByClick();
51790        }else{
51791            this.grid.store.clearGrouping();
51792            this.grid.fireEvent('groupchange', this, null);
51793        }
51794    },
51795
51796    
51797    toggleRowIndex : function(rowIndex, expanded){
51798        if(!this.canGroup()){
51799            return;
51800        }
51801        var row = this.getRow(rowIndex);
51802        if(row){
51803            this.toggleGroup(this.findGroup(row), expanded);
51804        }
51805    },
51806
51807    
51808    toggleGroup : function(group, expanded){
51809        var gel = Ext.get(group),
51810            id = Ext.util.Format.htmlEncode(gel.id);
51811 
51812        expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
51813        if(this.state[id] !== expanded){
51814            if (this.cancelEditOnToggle !== false) {
51815                this.grid.stopEditing(true);
51816            }
51817            this.state[id] = expanded;
51818            gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
51819        }
51820    },
51821
51822    
51823    toggleAllGroups : function(expanded){
51824        var groups = this.getGroups();
51825        for(var i = 0, len = groups.length; i < len; i++){
51826            this.toggleGroup(groups[i], expanded);
51827        }
51828    },
51829
51830    
51831    expandAllGroups : function(){
51832        this.toggleAllGroups(true);
51833    },
51834
51835    
51836    collapseAllGroups : function(){
51837        this.toggleAllGroups(false);
51838    },
51839
51840    
51841    getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
51842        var column = this.cm.config[colIndex],
51843            g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
51844        if(g === '' || g === '&#160;'){
51845            g = column.emptyGroupText || this.emptyGroupText;
51846        }
51847        return g;
51848    },
51849
51850    
51851    getGroupField : function(){
51852        return this.grid.store.getGroupState();
51853    },
51854
51855    
51856    afterRender : function(){
51857        if(!this.ds || !this.cm){
51858            return;
51859        }
51860        Ext.grid.GroupingView.superclass.afterRender.call(this);
51861        if(this.grid.deferRowRender){
51862            this.updateGroupWidths();
51863        }
51864    },
51865    
51866    afterRenderUI: function () {
51867        Ext.grid.GroupingView.superclass.afterRenderUI.call(this);
51868
51869        if (this.enableGroupingMenu && this.hmenu) {
51870            this.hmenu.add('-',{
51871                itemId:'groupBy',
51872                text: this.groupByText,
51873                handler: this.onGroupByClick,
51874                scope: this,
51875                iconCls:'x-group-by-icon'
51876            });
51877            
51878            if (this.enableNoGroups) {
51879                this.hmenu.add({
51880                    itemId:'showGroups',
51881                    text: this.showGroupsText,
51882                    checked: true,
51883                    checkHandler: this.onShowGroupsClick,
51884                    scope: this
51885                });
51886            }
51887            
51888            this.hmenu.on('beforeshow', this.beforeMenuShow, this);
51889        }
51890    },
51891
51892    
51893    renderRows : function(){
51894        var groupField = this.getGroupField();
51895        var eg = !!groupField;
51896        
51897        if(this.hideGroupedColumn) {
51898            var colIndex = this.cm.findColumnIndex(groupField),
51899                hasLastGroupField = Ext.isDefined(this.lastGroupField);
51900            if(!eg && hasLastGroupField){
51901                this.mainBody.update('');
51902                this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
51903                delete this.lastGroupField;
51904            }else if (eg && !hasLastGroupField){
51905                this.lastGroupField = groupField;
51906                this.cm.setHidden(colIndex, true);
51907            }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
51908                this.mainBody.update('');
51909                var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
51910                this.cm.setHidden(oldIndex, false);
51911                this.lastGroupField = groupField;
51912                this.cm.setHidden(colIndex, true);
51913            }
51914        }
51915        return Ext.grid.GroupingView.superclass.renderRows.apply(
51916                    this, arguments);
51917    },
51918
51919    
51920    doRender : function(cs, rs, ds, startRow, colCount, stripe){
51921        if(rs.length < 1){
51922            return '';
51923        }
51924
51925        if(!this.canGroup() || this.isUpdating){
51926            return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
51927        }
51928
51929        var groupField = this.getGroupField(),
51930            colIndex = this.cm.findColumnIndex(groupField),
51931            g,
51932            gstyle = 'width:' + this.getTotalWidth() + ';',
51933            cfg = this.cm.config[colIndex],
51934            groupRenderer = cfg.groupRenderer || cfg.renderer,
51935            prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
51936            groups = [],
51937            curGroup, i, len, gid;
51938
51939        for(i = 0, len = rs.length; i < len; i++){
51940            var rowIndex = startRow + i,
51941                r = rs[i],
51942                gvalue = r.data[groupField];
51943
51944                g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
51945            if(!curGroup || curGroup.group != g){
51946                gid = this.constructId(gvalue, groupField, colIndex);
51947                
51948                
51949                this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
51950                curGroup = {
51951                    group: g,
51952                    gvalue: gvalue,
51953                    text: prefix + g,
51954                    groupId: gid,
51955                    startRow: rowIndex,
51956                    rs: [r],
51957                    cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
51958                    style: gstyle
51959                };
51960                groups.push(curGroup);
51961            }else{
51962                curGroup.rs.push(r);
51963            }
51964            r._groupId = gid;
51965        }
51966
51967        var buf = [];
51968        for(i = 0, len = groups.length; i < len; i++){
51969            g = groups[i];
51970            this.doGroupStart(buf, g, cs, ds, colCount);
51971            buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
51972                    this, cs, g.rs, ds, g.startRow, colCount, stripe);
51973
51974            this.doGroupEnd(buf, g, cs, ds, colCount);
51975        }
51976        return buf.join('');
51977    },
51978
51979    
51980    getGroupId : function(value){
51981        var field = this.getGroupField();
51982        return this.constructId(value, field, this.cm.findColumnIndex(field));
51983    },
51984
51985    
51986    constructId : function(value, field, idx){
51987        var cfg = this.cm.config[idx],
51988            groupRenderer = cfg.groupRenderer || cfg.renderer,
51989            val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
51990
51991        return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
51992    },
51993
51994    
51995    canGroup  : function(){
51996        return this.enableGrouping && !!this.getGroupField();
51997    },
51998
51999    
52000    getPrefix: function(field){
52001        return this.grid.getGridEl().id + '-gp-' + field + '-';
52002    },
52003
52004    
52005    doGroupStart : function(buf, g, cs, ds, colCount){
52006        buf[buf.length] = this.startGroup.apply(g);
52007    },
52008
52009    
52010    doGroupEnd : function(buf, g, cs, ds, colCount){
52011        buf[buf.length] = this.endGroup;
52012    },
52013
52014    
52015    getRows : function(){
52016        if(!this.canGroup()){
52017            return Ext.grid.GroupingView.superclass.getRows.call(this);
52018        }
52019        var r = [],
52020            gs = this.getGroups(),
52021            g,
52022            i = 0,
52023            len = gs.length,
52024            j,
52025            jlen;
52026        for(; i < len; ++i){
52027            g = gs[i].childNodes[1];
52028            if(g){
52029                g = g.childNodes;
52030                for(j = 0, jlen = g.length; j < jlen; ++j){
52031                    r[r.length] = g[j];
52032                }
52033            }
52034        }
52035        return r;
52036    },
52037
52038    
52039    updateGroupWidths : function(){
52040        if(!this.canGroup() || !this.hasRows()){
52041            return;
52042        }
52043        var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
52044        var gs = this.getGroups();
52045        for(var i = 0, len = gs.length; i < len; i++){
52046            gs[i].firstChild.style.width = tw;
52047        }
52048    },
52049
52050    
52051    onColumnWidthUpdated : function(col, w, tw){
52052        Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
52053        this.updateGroupWidths();
52054    },
52055
52056    
52057    onAllColumnWidthsUpdated : function(ws, tw){
52058        Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
52059        this.updateGroupWidths();
52060    },
52061
52062    
52063    onColumnHiddenUpdated : function(col, hidden, tw){
52064        Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
52065        this.updateGroupWidths();
52066    },
52067
52068    
52069    onLayout : function(){
52070        this.updateGroupWidths();
52071    },
52072
52073    
52074    onBeforeRowSelect : function(sm, rowIndex){
52075        this.toggleRowIndex(rowIndex, true);
52076    }
52077});
52078
52079Ext.grid.GroupingView.GROUP_ID = 1000;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.