itat = function(){};if(typeof Ext !== "undefined"){
	Ext.namespace('Ext.ux');
	/**
	 * Image component for ExtJs
	 * 
	 * @author Charles Opute Odili (chalu)
	 * @version 1.0
	 * @licence GPLv3
	 */
	
	/**
	 * @class Ext.ux.Image
	 * @extends Ext.Component
	 *
	 * @constructor
	 * @param {Object} config The config object
	 */ 
	
	Ext.ux.Image = Ext.extend(Ext.Component, {
		/**
		 * @param {String} src the URL of an image to initiaize it with, 
		 * deafults to Ext.BLANK_IMAGE_URL
		 */
		src : Ext.BLANK_IMAGE_URL,
		
		/**
		 * @private
		 */
		autoEl : {
			tag : 'img',
			cls : 'tng-managed-image',
			src : Ext.BLANK_IMAGE_URL		
		},
		
		initComponent: function () {		
			Ext.ux.Image.superclass.initComponent.apply(this, arguments);
		},
		
		onRender: function(){
			Ext.ux.Image.superclass.onRender.apply(this, arguments);
			
			if(!Ext.isEmpty(this.src) && (this.src !== Ext.BLANK_IMAGE_URL)){
				this.setSrc(this.src);
			}		
		},
		
		/**
		 * Sets the src for the image component
		 * @param {String} src the new src
		 */
		setSrc: function (src) {
			this.el.dom.src = src;
		}
	});
	
	Ext.reg('image', Ext.ux.Image);
};itat.filebrowser_window = function(config){
	this.config = config;
	this.win = new Ext.Window({
		    title: 'Súborový manažér',
				minWidth: 700,
				minHeight: 300,
				width:920,
				height:400,
				y:100,
				cls: 'alwaystop0',
				center: true,
				modal: true,
				closeAction: 'close',
				layout: 'border',
				border: false,
				cfg: this.config,
				items:[
					this.config.browser.tree.panel,
					this.config.browser.view.panel,
					this.config.browser.detail.panel
				],
					buttons: [{
					text: 'OK',
					handler: this.config.browser.doCallback,
					scope: this.config.browser
				},{
					text: 'Storno',
					handler: function(){ this.win.close(); },
					scope: this
				}],
				keys: {
					key: 27, // Esc key
					handler: function(){ this.win.close(); },
					scope: this
				}
	});
};itat.filebrowser_store = function(config){
	this.config = config;
	this.store = new Ext.data.JsonStore({
			   	url:this.config.url,
			   	baseParams:{
			   		value: this.config.thumbsize
			   	},
			    root: 'files',
			    fields: [
			        'name', 'basefold','url','absurl','relurl','thumb',
			        {name:'size', type: 'float'},
			        {name:'lastmod', type:'date', dateFormat:'timestamp'}
			    ],
			    listeners: {
			    	'load': {fn:function(){ this.config.browser.view.view.select(0); }, scope:this, single:true}
			    }
	});
};itat.filebrowser_tree = function(config){
	this.config = config;
	this.conmenu = new Ext.menu.Menu({
		cfg: this.config,
		autoHeight:true,
		  	items: [{
					text: 'Nový adresár',
					iconCls: 'new_directory_button',
					handler: function(){this.ownerCt.cfg.browser.newdir(this.ownerCt.cfg.browser);}
				},
				{
					text: 'Vymazať adresár',
					iconCls: 'delete_directory_button',
					handler: function(){this.ownerCt.cfg.browser.deletedir(this.ownerCt.cfg.browser);}
				}]
		  });
		  
	this.tree = new Ext.tree.TreePanel({
				cfg : this.config,
				conmenu: this.conmenu,
				autoScroll: true,
				animate: true,
				containerScroll: true,
				border: false,
				autoHeight:true,
				enableDD: false,
				ddGroup : 'fileMove',
				loader: new Ext.tree.TreeLoader({
					dataUrl: this.config.dirurl
				}),
				root: new Ext.tree.AsyncTreeNode({
					text: 'Files',
					draggable: false,
					id: 'source',
					expanded: true
				}),
				listeners: {
					'click': function (node,e){
											this.cfg.browser.current_directory = node.attributes.url;
											if(this.cfg.browser.current_directory!='') {
												this.cfg.browser.view.toolbar.items.get(0).enable();
											} else {
												this.cfg.browser.view.toolbar.items.get(0).enable();
											};
											this.cfg.browser.store.store.reload({params:{dir:this.cfg.browser.current_directory,method:'POST'}});
											this.cfg.browser.view.view.refresh();
										},
					'contextmenu': function(node,e){
											node.select();
											this.cfg.browser.current_directory = node.attributes.url;
											this.conmenu.node = node;
											this.conmenu.zIndex=150000000000;
											this.conmenu.show(e.getTarget());
										}
				}
			});
	new Ext.tree.TreeSorter(this.tree, {folderSort: true});
	this.panel = new Ext.Panel({
					items: this.tree,
					tbar:this.menu,
					region: 'west',
					split: true,
					width: 150,
					minWidth: 150,
					maxWidth: 450
	});
};itat.filebrowser_view = function(config){
	this.config = config;
	this.toolbar = new Ext.Toolbar({
						cfg: this.config,
						autoHeight:true,
						items:[{
                    		text: 'Nahrať na server',
                    		tooltip: 'Nahrať nový súbor na server',
                    		iconCls: 'upload_button',
                    		disabled: true,
                    		handler: function(){this.ownerCt.cfg.browser.uploadfile(this.ownerCt.cfg.browser);}
                    		},{
                    			text: 'Vymazať súbor',
                    			tooltip: 'Vymazať vybraný súbor',
                    			iconCls: 'delete_button',
                    			disabled: true,
                    			handler: function(){this.ownerCt.cfg.browser.deletefile(this.ownerCt.cfg.browser);}
                    		},{
                    	text: 'Filter:'
                    },{
                    	xtype: 'textfield',
                    	selectOnFocus: true,
                    	width: 100,
                    	enableKeyEvents: true,
                    	listeners: {
												'keyup': {fn:function(e){
													this.ownerCt.cfg.browser.filter(this.ownerCt.cfg.browser);
												}}	                    	
	                    }
	                    }, ' ', '-', {
                    	text: 'Zoradiť podľa:'
                    }, {
                    	id: 'sortSelect',
                    	xtype: 'combo',
				        typeAhead: true,
				        triggerAction: 'all',
				        width: 100,
				        editable: false,
				        mode: 'local',
				        displayField: 'desc',
				        valueField: 'name',
				        lazyInit: false,
				        value: 'name',
				        store: new Ext.data.SimpleStore({
					        fields: ['name', 'desc'],
					        data : [['name', 'Názvu'],['size', 'Veľkosti súboru'],['lastmod', 'Poslednej zmeny']]
					    }),
					    listeners: {
								'select': function(){this.ownerCt.cfg.browser.sortfiles(this.ownerCt.cfg.browser);}
					    }
				    }]
				  });
	this.conmenu = new Ext.menu.Menu({
				cfg: this.config,
		  	id: 'file_context_menu',
		  	items: [{
		  			text: 'Vymazať súbor',
		  			iconCls: 'delete_button',
		  			handler: function(){this.ownerCt.cfg.browser.deletefile(this.ownerCt.cfg.browser);}
		  		}]	  
		  });

	
	
	this.view = new Ext.DataView({
				conmenu: this.conmenu,
				tpl: this.config.browser.thumbTemplate,
				singleSelect: true,
				overClass:'x-view-over',
				itemSelector: 'div.thumb-wrap',
				emptyText : '<div style="padding:10px;">No files match the specified filter</div>',
				store: this.config.browser.store.store,
				listeners: {
					'selectionchange': {fn:this.config.browser.showDetails.createDelegate(this.config.browser), scope:this.config.browser, buffer:100},
					'dblclick'       : {fn:this.config.browser.doCallback, scope:this.config.browser},
					'loadexception'  : {fn:this.config.browser.onLoadException, scope:this.config.browser},
					'beforeselect'   : {fn:function(view){
				        return this.store.getRange().length > 0;
				    }},
				  'contextmenu'		 : function(view,index,node,e){e.stopEvent();var coords = e.getXY();view.select(index);this.conmenu.showAt([coords[0], coords[1]]);}
				},
				prepareData: this.config.browser.formatData.createDelegate(this.config.browser)
			});
	this.panel = new Ext.Panel({
		region: 'center',
		autoScroll: true,
		bodyCssClass: 'img-chooser-view',
		height:300,
		width: 300,
		items: this.view,
		tbar: this.toolbar
		
	});
};itat.filebrowser_detail = function(config){
	this.config = config;
	this.panel = new Ext.Panel({
		region: 'east',
		bodyCssClass: 'img-chooser-dlg',
		split: true,
		width: 150,
		minWidth: 150,
		maxWidth: 250	
	});
};if(typeof Ext !== "undefined"){
	itat.filebrowser = function(config){
		config.browser = this;
		this.config = config;
		this.config.thumbsize = '120x120';
		this.current_directory = '';
		this.thumbTemplate = new Ext.XTemplate('<tpl for=".">',
 '<div class="thumb-wrap" id="{name}" name="{url}">',
 '<div class="thumb"><img src="{thumb}" title="{name}"></div>',
 '<span>{shortName}</span></div>',
'</tpl>');
		this.detailsTemplate = new Ext.XTemplate('<div class="details">',
 '<tpl for=".">',
 '<img src="{thumb}" style="width:120px;"><div class="details-info">',
 '<b>Názov:</b>',
 '<span>{name}</span>',
 '<b>Veľkosť:</b>',
 '<span>{sizeString}</span>',
 '<b>Posledná zmena:</b>',
 '<span>{dateString}</span></div>',
'</tpl>',
'</div>'); 
		this.store = new itat.filebrowser_store(this.config);
		this.tree = new itat.filebrowser_tree(this.config);
		this.view = new itat.filebrowser_view(this.config);
		this.detail = new itat.filebrowser_detail(this.config);
		this.win = new itat.filebrowser_window(this.config);
	};
	
	itat.filebrowser.prototype = {
		lookup: {},
		show: function(el, callback,callbackparams){
			this.rootel=el;
			this.callback = callback;
			this.callbackparams = callbackparams;
			this.store.store.load();
			this.initTemplates();
			this.win.win.show(el);
		},
		initTemplates : function(){
			this.thumbTemplate.compile();
			this.detailsTemplate.compile();
		},
		formatSize : function(data){if(data.size < 1024) {return data.size + " bytes";} else {return (Math.round(((data.size*10) / 1024))/10) + " KB";};},
	  formatData : function(data){if(data.name!==null)data.shortName = data.name.ellipse(15);data.sizeString = this.formatSize(data);data.dateString = new Date(data.lastmod).format("m/d/Y g:i a");this.lookup[data.name] = data;return data;},
	  showDetails : function(){
		    var selNode = this.view.view.getSelectedNodes();
		    if(this.detail.panel!=undefined){
					if(selNode && selNode.length > 0){
					 selNode = selNode[0];
						selectedNode = selNode;
							this.win.win.buttons[0].enable();
					    this.view.toolbar.items.get(1).enable();
					    var data = this.lookup[selNode.id];
			            this.detail.panel.body.hide();
			            this.detailsTemplate.overwrite(this.detail.panel.body, data);
			            this.detail.panel.body.slideIn('l', {stopFx:true,duration:.2});
						}else{
					    this.win.win.buttons[0].disable();
					    this.view.toolbar.items.get(1).disable();
					    this.detail.panel.body.update('');
					};
			};
		},
		deletefile: function(scope){
			Ext.MessageBox.confirm('Potvrdenie', 'Ste si istý, že chcete vymazať tento súbor?', function(reponse) {
			if (reponse == "yes") {
				var connection = new Ext.data.Connection().request({
				url:scope.config.deleteurl,
				method: "POST",
				params: {dir:scope.current_directory,value:selectedNode.id},
				success: function(o){
					scope.store.store.reload({params:{dir:scope.current_directory,method:'POST'}});
				},
				failure: function(o){
					Ext.Msg.show({title:"Chyba",msg:response.message,buttons:Ext.Msg.OK});
				}
				});
			};
			});
		},
		deletedir: function(scope){
			Ext.MessageBox.confirm('Potvrdenie', 'Ste si istý, že chcete vymazať tento adresár?', function(reponse) {
			if (reponse == "yes") {
				var connection = new Ext.data.Connection().request({
				url:scope.config.deldirurl,
				method: "POST",
				params: {dir:scope.current_directory},
				success: function(o){
					var response = Ext.util.JSON.decode(o.responseText);
					scope.tree.tree.getRootNode().reload();
					scope.tree.tree.getRootNode().expand();
					scope.store.store.reload({params:{dir:scope.current_directory,method:'POST'}});
				},
				failure: function(o){
					Ext.Msg.show({title:"Chyba",msg:response.message,buttons:Ext.Msg.OK});
				}
				});
				};
			});
		},
		newdir: function(scope) {
				Ext.MessageBox.prompt('Nový adresár', 'Názov nového adresára', function(reponse, text) {
					if (reponse == "ok") {
						var connection = new Ext.data.Connection().request({
							url: scope.config.newdirurl,
							method: "POST",
							params: {dir: scope.current_directory, value: text},
							success: function(o){
								var response = Ext.util.JSON.decode(o.responseText);
									scope.tree.tree.getRootNode().reload();
									scope.tree.tree.getRootNode().expand();
							},
							failure: function(o) {
								var response = Ext.util.JSON.decode(o.responseText);
								Ext.Msg.alert(response.message);
							}
						});
					};
				});
		},
		uploadfile: function(scope) {
			var upload_dialog = new Ext.ux.UploadDialog.Dialog({
				cfg: scope.config,
	 			title: 'Upload Files',
				url: scope.config.uploadurl,
				cls: 'alwaystop1',
				base_params: {'dir':scope.current_directory},
					minWidth: 400,
					minHeight: 200,
					width: 400,
					height: 350,
					reset_on_hide: false,
					modal:true,
					allow_close_on_upload: false
				});			
				
				upload_dialog.show('upload_button');
				upload_dialog.on("uploadcomplete", function() {
					this.cfg.browser.store.store.reload({params:{dir:this.cfg.browser.current_directory,method:'POST'}});
				});
		},
		sortfiles : function(scope){
				var v = scope.view.toolbar.items.get(7).getValue();
				//Ext.getCmp('sortSelect').getValue();
		    	scope.store.store.sort(v, v == 'name' ? 'asc' : 'desc');
		    	scope.view.view.select(0);
		},
		filter : function(scope){
			scope.store.store.filter('name', scope.view.toolbar.items.get(3).getValue());
			scope.view.view.select(0);
		},
		doCallback : function(){
	    var selNode = this.view.view.getSelectedRecords()[0];
			var callback = this.callback;
			var callbackparams = this.callbackparams;
			var lookup = this.lookup;
			var rootel=this.rootel;
			var iswin=this.win.win;
			var data = selNode.data;
			callback(data,rootel,iswin,callbackparams);
			//console.log(this.win);
			this.win.win.close();
			//this.win.destroy();
	   }
	};
};if(typeof Ext !== "undefined"){
	Ext.namespace('Ext.itat');
	Ext.itat.pictureField = function(config){
		if(config.imgwidth===undefined || config.imgwidth===null) config.imgwidth=100;
		if(config.imgheight===undefined || config.imgheight===null) config.imgheight=100;
		if(config.btnFunction===undefined || config.btnFunction===null) config.btnFunction=function(){};
		if(config.nopicture===undefined || config.nopicture===null || config.nopicture==="") config.nopicture='nopicture.jpg';
		config.rozmer = config.imgwidth + "x" + config.imgheight;
	  if(this.value=="" || this.value === undefined || this.value==null) this.value=config.nopicture;
		this.img = new Ext.ux.Image({width:config.imgwidth,height:config.imgheight,src:config.imgbasepath+config.rozmer+"/" + this.value});
		this.btn = new Ext.Button({width:config.imgwidth+10,style:'padding:5px;',text:config.btnText,handler:config.btnFunction.createDelegate(this)});
		Ext.itat.pictureField.superclass.constructor.call(this, config);
	};
	Ext.extend(Ext.itat.pictureField, Ext.form.Hidden, {
		onRender : function(ct, position){
					/* povodny onRender */
	        Ext.form.Hidden.superclass.onRender.apply(this, arguments);
	    		/* koniec povodneho onRender */
	    		var rozmer = this.imgwidth + "x" + this.imgheight;
	    		
	    		if(this.value=="" || this.value === undefined || this.value==null) this.value=this.nopicture;
					this.ownerCt.add(this.img);    		
	    		this.ownerCt.add(this.btn);    		
	    		this.ownerCt.doLayout();
	    },
	    changePicture: function(picture){
	    	this.setValue(picture);
	    	this.img.setSrc(this.imgbasepath+this.rozmer+"/" + this.baseDir + this.value);
	    },
	    setValue : function(v){
	        this.value = v;
	        if(this.rendered){
	            this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
	            this.validate();
	        }
	        this.img.setSrc(this.imgbasepath+this.rozmer+"/" + this.baseDir + this.value);
	        return this;
	    },
	});
	Ext.reg("picturefield",Ext.itat.pictureField);
}if(typeof Ext !== "undefined"){
	/*!
	 * Ext JS Library 3.1.0
	 * Copyright(c) 2006-2009 Ext JS, LLC
	 * licensing@extjs.com
	 * http://www.extjs.com/license
	 */
	Ext.ux.GroupTab = Ext.extend(Ext.Container, {
	    mainItem: 0,
	    
	    expanded: true,
	    
	    deferredRender: true,
	    
	    activeTab: null,
	    
	    idDelimiter: '__',
	    
	    headerAsText: false,
	    
	    frame: false,
	    
	    hideBorders: true,
	    
	    initComponent: function(config){
	        Ext.apply(this, config);
	        this.frame = false;
	        
	        Ext.ux.GroupTab.superclass.initComponent.call(this);
	        
	        this.addEvents('activate', 'deactivate', 'changemainitem', 'beforetabchange', 'tabchange');
	        
	        this.setLayout(new Ext.layout.CardLayout({
	            deferredRender: this.deferredRender
	        }));
	        
	        if (!this.stack) {
	            this.stack = Ext.TabPanel.AccessStack();
	        }
	        
	        this.initItems();
	        
	        this.on('beforerender', function(){
	            this.groupEl = this.ownerCt.getGroupEl(this);
	        }, this);
	        
	        this.on('add', this.onAdd, this, {
	            target: this
	        });
	        this.on('remove', this.onRemove, this, {
	            target: this
	        });
	        
	        if (this.mainItem !== undefined) {
	            var item = (typeof this.mainItem == 'object') ? this.mainItem : this.items.get(this.mainItem);
	            delete this.mainItem;
	            this.setMainItem(item);
	        }
	    },
	    
	    /**
	     * Sets the specified tab as the active tab. This method fires the {@link #beforetabchange} event which
	     * can return false to cancel the tab change.
	     * @param {String/Panel} tab The id or tab Panel to activate
	     */
	    setActiveTab : function(item){
	        item = this.getComponent(item);
	        if(!item){
	            return false;
	        }
	        if(!this.rendered){
	            this.activeTab = item;
	            return true;
	        }
	        if(this.activeTab != item && this.fireEvent('beforetabchange', this, item, this.activeTab) !== false){
	            if(this.activeTab && this.activeTab != this.mainItem){
	                var oldEl = this.getTabEl(this.activeTab);
	                if(oldEl){
	                    Ext.fly(oldEl).removeClass('x-grouptabs-strip-active');
	                }
	            }
	            var el = this.getTabEl(item);
	            Ext.fly(el).addClass('x-grouptabs-strip-active');
	            this.activeTab = item;
	            this.stack.add(item);
	
	            this.layout.setActiveItem(item);
	            if(this.layoutOnTabChange && item.doLayout){
	                item.doLayout();
	            }
	            if(this.scrolling){
	                this.scrollToTab(item, this.animScroll);
	            }
	
	            this.fireEvent('tabchange', this, item);
	            return true;
	        }
	        return false;
	    },
	    
	    getTabEl: function(item){
	        if (item == this.mainItem) {
	            return this.groupEl;
	        }
	        return Ext.TabPanel.prototype.getTabEl.call(this, item);
	    },
	    
	    onRender: function(ct, position){
	        Ext.ux.GroupTab.superclass.onRender.call(this, ct, position);
	        
	        this.strip = Ext.fly(this.groupEl).createChild({
	            tag: 'ul',
	            cls: 'x-grouptabs-sub'
	        });
	
	        this.tooltip = new Ext.ToolTip({
	           target: this.groupEl,
	           delegate: 'a.x-grouptabs-text',
	           trackMouse: true,
	           renderTo: document.body,
	           listeners: {
	               beforeshow: function(tip) {
	                   var item = (tip.triggerElement.parentNode === this.mainItem.tabEl)
	                       ? this.mainItem
	                       : this.findById(tip.triggerElement.parentNode.id.split(this.idDelimiter)[1]);
	
	                   if(!item.tabTip) {
	                       return false;
	                   }
	                   tip.body.dom.innerHTML = item.tabTip;
	               },
	               scope: this
	           }
	        });
	                
	        if (!this.itemTpl) {
	            var tt = new Ext.Template('<li class="{cls}" id="{id}">', '<a onclick="return false;" class="x-grouptabs-text {iconCls}">{text}</a>', '</li>');
	            tt.disableFormats = true;
	            tt.compile();
	            Ext.ux.GroupTab.prototype.itemTpl = tt;
	        }
	        
	        this.items.each(this.initTab, this);
	    },
	    
	    afterRender: function(){
	        Ext.ux.GroupTab.superclass.afterRender.call(this);
	        
	        if (this.activeTab !== undefined) {
	            var item = (typeof this.activeTab == 'object') ? this.activeTab : this.items.get(this.activeTab);
	            delete this.activeTab;
	            this.setActiveTab(item);
	        }
	    },
	    
	    // private
	    initTab: function(item, index){
	        var before = this.strip.dom.childNodes[index];
	        var p = Ext.TabPanel.prototype.getTemplateArgs.call(this, item);
	        
	        if (item === this.mainItem) {
	            item.tabEl = this.groupEl;
	            p.cls += ' x-grouptabs-main-item';
	        }
	        
	        var el = before ? this.itemTpl.insertBefore(before, p) : this.itemTpl.append(this.strip, p);
	        
	        item.tabEl = item.tabEl || el;
	                
	        item.on('disable', this.onItemDisabled, this);
	        item.on('enable', this.onItemEnabled, this);
	        item.on('titlechange', this.onItemTitleChanged, this);
	        item.on('iconchange', this.onItemIconChanged, this);
	        item.on('beforeshow', this.onBeforeShowItem, this);
	    },
	    
	    setMainItem: function(item){
	        item = this.getComponent(item);
	        if (!item || this.fireEvent('changemainitem', this, item, this.mainItem) === false) {
	            return;
	        }
	        
	        this.mainItem = item;
	    },
	    
	    getMainItem: function(){
	        return this.mainItem || null;
	    },
	    
	    // private
	    onBeforeShowItem: function(item){
	        if (item != this.activeTab) {
	            this.setActiveTab(item);
	            return false;
	        }
	    },
	    
	    // private
	    onAdd: function(gt, item, index){
	        if (this.rendered) {
	            this.initTab.call(this, item, index);
	        }
	    },
	    
	    // private
	    onRemove: function(tp, item){
	        Ext.destroy(Ext.get(this.getTabEl(item)));
	        this.stack.remove(item);
	        item.un('disable', this.onItemDisabled, this);
	        item.un('enable', this.onItemEnabled, this);
	        item.un('titlechange', this.onItemTitleChanged, this);
	        item.un('iconchange', this.onItemIconChanged, this);
	        item.un('beforeshow', this.onBeforeShowItem, this);
	        if (item == this.activeTab) {
	            var next = this.stack.next();
	            if (next) {
	                this.setActiveTab(next);
	            }
	            else if (this.items.getCount() > 0) {
	                this.setActiveTab(0);
	            }
	            else {
	                this.activeTab = null;
	            }
	        }
	    },
	    
	    // private
	    onBeforeAdd: function(item){
	        var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
	        if (existing) {
	            this.setActiveTab(item);
	            return false;
	        }
	        Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
	        var es = item.elements;
	        item.elements = es ? es.replace(',header', '') : es;
	        item.border = (item.border === true);
	    },
	    
	    // private
	    onItemDisabled: Ext.TabPanel.prototype.onItemDisabled,
	    onItemEnabled: Ext.TabPanel.prototype.onItemEnabled,
	    
	    // private
	    onItemTitleChanged: function(item){
	        var el = this.getTabEl(item);
	        if (el) {
	            Ext.fly(el).child('a.x-grouptabs-text', true).innerHTML = item.title;
	        }
	    },
	    
	    //private
	    onItemIconChanged: function(item, iconCls, oldCls){
	        var el = this.getTabEl(item);
	        if (el) {
	            Ext.fly(el).child('a.x-grouptabs-text').replaceClass(oldCls, iconCls);
	        }
	    },
	    
	    beforeDestroy: function(){
	        Ext.TabPanel.prototype.beforeDestroy.call(this);
	        this.tooltip.destroy();
	    }
	});
	
	Ext.reg('grouptab', Ext.ux.GroupTab);
};if(typeof Ext !== "undefined"){
	/*!
	 * Ext JS Library 3.1.0
	 * Copyright(c) 2006-2009 Ext JS, LLC
	 * licensing@extjs.com
	 * http://www.extjs.com/license
	 */
	Ext.ns('Ext.ux');
	
	Ext.ux.GroupTabPanel = Ext.extend(Ext.TabPanel, {
	    tabPosition: 'left',
	    
	    alternateColor: false,
	    
	    alternateCls: 'x-grouptabs-panel-alt',
	    
	    defaultType: 'grouptab',
	    
	    deferredRender: false,
	    
	    activeGroup : null,
	    
	    initComponent: function(){
	        Ext.ux.GroupTabPanel.superclass.initComponent.call(this);
	        
	        this.addEvents(
	            'beforegroupchange',
	            'groupchange'
	        );
	        this.elements = 'body,header';
	        this.stripTarget = 'header';
	        
	        this.tabPosition = this.tabPosition == 'right' ? 'right' : 'left';
	        
	        this.addClass('x-grouptabs-panel');
	        
	        if (this.tabStyle && this.tabStyle != '') {
	            this.addClass('x-grouptabs-panel-' + this.tabStyle);
	        }
	        
	        if (this.alternateColor) {
	            this.addClass(this.alternateCls);
	        }
	        
	        this.on('beforeadd', function(gtp, item, index){
	            this.initGroup(item, index);
	        });		     
	    },
	    
	    initEvents : function() {
	        this.mon(this.strip, 'mousedown', this.onStripMouseDown, this);
	    },
	        
	    onRender: function(ct, position){
	        Ext.TabPanel.superclass.onRender.call(this, ct, position);
	        if(this.plain){
	            var pos = this.tabPosition == 'top' ? 'header' : 'footer';
	            this[pos].addClass('x-tab-panel-'+pos+'-plain');
	        }
	
	        var st = this[this.stripTarget];
	
	        this.stripWrap = st.createChild({cls:'x-tab-strip-wrap ', cn:{
	            tag:'ul', cls:'x-grouptabs-strip x-grouptabs-tab-strip-'+this.tabPosition}});
	
	        var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
	        this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
	
			this.header.addClass('x-grouptabs-panel-header');
			this.bwrap.addClass('x-grouptabs-bwrap');
	        this.body.addClass('x-tab-panel-body-'+this.tabPosition + ' x-grouptabs-panel-body');
	
	        if (!this.groupTpl) {
	            var tt = new Ext.Template(
	                '<li class="{cls}" id="{id}">', 
	                '<a class="x-grouptabs-expand" onclick="return false;"></a>', 
	                '<a class="x-grouptabs-text {iconCls}" href="#" onclick="return false;">',
	                '<span>{text}</span></a>', 
	                '</li>'
	            );
	            tt.disableFormats = true;
	            tt.compile();
	            Ext.ux.GroupTabPanel.prototype.groupTpl = tt;
	        }
	        this.items.each(this.initGroup, this);
	    },
	    
	    afterRender: function(){
	        Ext.ux.GroupTabPanel.superclass.afterRender.call(this);
	        
	        this.tabJoint = Ext.fly(this.body.dom.parentNode).createChild({
	            cls: 'x-tab-joint'
	        });
	        
	        this.addClass('x-tab-panel-' + this.tabPosition);
	        this.header.setWidth(this.tabWidth);
	        
	        if (this.activeGroup !== undefined) {
	            var group = (typeof this.activeGroup == 'object') ? this.activeGroup : this.items.get(this.activeGroup);
	            delete this.activeGroup;
	            this.setActiveGroup(group);
	            group.setActiveTab(group.getMainItem());
	        }
	    },
	
	    getGroupEl : Ext.TabPanel.prototype.getTabEl,
	        
	    // private
	    findTargets: function(e){
	        var item = null,
	            itemEl = e.getTarget('li', this.strip);
	        if (itemEl) {
	            item = this.findById(itemEl.id.split(this.idDelimiter)[1]);
	            if (item.disabled) {
	                return {
	                    expand: null,
	                    item: null,
	                    el: null
	                };
	            }
	        }
	        return {
	            expand: e.getTarget('.x-grouptabs-expand', this.strip),
	            isGroup: !e.getTarget('ul.x-grouptabs-sub', this.strip),
	            item: item,
	            el: itemEl
	        };
	    },
	    
	    // private
	    onStripMouseDown: function(e){
	        if (e.button != 0) {
	            return;
	        }
	        e.preventDefault();
	        var t = this.findTargets(e);
	        if (t.expand) {
	            this.toggleGroup(t.el);
	        }
	        else if (t.item) {
	            if(t.isGroup) {
	                t.item.setActiveTab(t.item.getMainItem());
	            }
	            else {
	                t.item.ownerCt.setActiveTab(t.item);
	            }
	        }
	    },
	    
	    expandGroup: function(groupEl){
	        if(groupEl.isXType) {
	            groupEl = this.getGroupEl(groupEl);
	        }
	        Ext.fly(groupEl).addClass('x-grouptabs-expanded');
			this.syncTabJoint();
	    },
	    
	    toggleGroup: function(groupEl){
	        if(groupEl.isXType) {
	            groupEl = this.getGroupEl(groupEl);
	        }        
	        Ext.fly(groupEl).toggleClass('x-grouptabs-expanded');
			this.syncTabJoint();
	    },    
	
	    collapseGroup: function(groupEl){
	        if(groupEl.isXType) {
	            groupEl = this.getGroupEl(groupEl);
	        }
	        Ext.fly(groupEl).removeClass('x-grouptabs-expanded');
			this.syncTabJoint();
	    },
	        
	    syncTabJoint: function(groupEl){
	        if (!this.tabJoint) {
	            return;
	        }
	        
	        groupEl = groupEl || this.getGroupEl(this.activeGroup);
	        if(groupEl) {
	            this.tabJoint.setHeight(Ext.fly(groupEl).getHeight() - 2); 
				
	            var y = Ext.isGecko2 ? 0 : 1;
	            if (this.tabPosition == 'left'){
	                this.tabJoint.alignTo(groupEl, 'tl-tr', [-2,y]);
	            }
	            else {
	                this.tabJoint.alignTo(groupEl, 'tr-tl', [1,y]);
	            }           
	        }
	        else {
	            this.tabJoint.hide();
	        }
	    },
	    
	    getActiveTab : function() {
	        if(!this.activeGroup) return null;
	        return this.activeGroup.getTabEl(this.activeGroup.activeTab) || null;  
	    },
	    
	    onResize: function(){
	        Ext.ux.GroupTabPanel.superclass.onResize.apply(this, arguments);
	        this.syncTabJoint();
	    },
	    
	    createCorner: function(el, pos){
	        return Ext.fly(el).createChild({
	            cls: 'x-grouptabs-corner x-grouptabs-corner-' + pos
	        });
	    },
	    
	    initGroup: function(group, index){
	        var before = this.strip.dom.childNodes[index],   
	            p = this.getTemplateArgs(group);
	        if (index === 0) {
	            p.cls += ' x-tab-first';
	        }
	        p.cls += ' x-grouptabs-main';
	        p.text = group.getMainItem().title;
	        
	        var el = before ? this.groupTpl.insertBefore(before, p) : this.groupTpl.append(this.strip, p),
	            tl = this.createCorner(el, 'top-' + this.tabPosition),
	            bl = this.createCorner(el, 'bottom-' + this.tabPosition);
	
	        group.tabEl = el;
	        if (group.expanded) {
	            this.expandGroup(el);
	        }
	
	        if (Ext.isIE6 || (Ext.isIE && !Ext.isStrict)){
	            bl.setLeft('-10px');
	            bl.setBottom('-5px');
	            tl.setLeft('-10px');
	            tl.setTop('-5px');
	        }
	
	        this.mon(group, {
	            scope: this,
	            changemainitem: this.onGroupChangeMainItem,
	            beforetabchange: this.onGroupBeforeTabChange
	        });
	    },
	    
	    setActiveGroup : function(group) {
	        group = this.getComponent(group);
	        if(!group){
	            return false;
	        }
	        if(!this.rendered){
	            this.activeGroup = group;
	            return true;
	        }
	        if(this.activeGroup != group && this.fireEvent('beforegroupchange', this, group, this.activeGroup) !== false){
	            if(this.activeGroup){
	                var oldEl = this.getGroupEl(this.activeGroup);
	                if(oldEl){
	                    Ext.fly(oldEl).removeClass('x-grouptabs-strip-active');
	                }
	            }
	
	            var groupEl = this.getGroupEl(group);
	            Ext.fly(groupEl).addClass('x-grouptabs-strip-active');
	                        
	            this.activeGroup = group;
	            this.stack.add(group);
	
	            this.layout.setActiveItem(group);
	            this.syncTabJoint(groupEl);
	
	            this.fireEvent('groupchange', this, group);
	            return true;
	        }
	        return false; 
	    },
	    
	    onGroupBeforeTabChange: function(group, newTab, oldTab){
	        if(group !== this.activeGroup || newTab !== oldTab) {
	            this.strip.select('.x-grouptabs-sub > li.x-grouptabs-strip-active', true).removeClass('x-grouptabs-strip-active');
	        } 
	        this.expandGroup(this.getGroupEl(group));
	        if(group !== this.activeGroup) {
	            return this.setActiveGroup(group);
	        }        
	    },
	    
	    getFrameHeight: function(){
	        var h = this.el.getFrameWidth('tb');
	        h += (this.tbar ? this.tbar.getHeight() : 0) +
	        (this.bbar ? this.bbar.getHeight() : 0);
	        
	        return h;
	    },
	    
	    adjustBodyWidth: function(w){
	        return w - this.tabWidth;
	    }
	});
	
	Ext.reg('grouptabpanel', Ext.ux.GroupTabPanel);
};if(typeof Ext !== "undefined"){
	/**
	 * @class Ext.ux.TreeCheckNodeUI
	 * @extends Ext.tree.TreeNodeUI
	 *
	 * Some extends features available:
	 * (1) single check model (allow only one treeNode checked)
	 *		usage:  checkModel: "single" 
	 * (2) cascade check model (suport asyn's node loads situation)
	 *		usage1:  checkModel: "cascade" (check/uncheck childrenNodes and parentNodes)
	 *		usage2:  checkModel: "parentCascade" (check/uncheck parentNodes)
	 *		usage3:  checkModel: "childCascade" (check/uncheck childrenNodes)
	 * (3) only leaf node can check model
	 *		only when the node's attribute leaf is true,then the node has checkbox
	 *		usage:  onlyLeafCheckable: true  , default is false,all nodes have checkbox
	 *
	 * checkModel default is 'multiple' , that's mean all node with checkbox can checked
	 *
	 * Supported events:
	 * check (when the node's checkbox value change, will fire this event)
	 *
	 * usage:
	 *    just add attribute  baseAttrs: { uiProvider: Ext.ux.TreeCheckNodeUI }  to tree's loader
	 *
	 * example:
	 *
	 *   var tree = new Ext.tree.TreePanel({
	 *		el:'tree-ct',
	 *		width:568,
	 *		height:300,
	 *		checkModel: 'cascade',   // cascade check
	 *		onlyLeafCheckable: false,// all node have checkbox
	 *		animate: false,
	 *		rootVisible: false,
	 *		autoScroll:true,
	 *		loader: new Tree.TreeLoader({
	 *			dataUrl:'get-nodes.php'
	 *			baseAttrs: { uiProvider: Ext.ux.TreeCheckNodeUI } //add uiProvider attribute
	 *		}),
	 *		root: new Ext.tree.AsyncTreeNode({ id:'0' })
	 *	});
	 *	tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); 
	 *	tree.render();
	 */
	
	
	Ext.ux.TreeCheckNodeUI = function() {
		//'multiple': multiple check model; 
		//'single': single check model; 
		//'cascade':cascade check model(check/uncheck childrenNodes and parentNodes);
		//'parentCascade':check/uncheck parentNodes;
		//'childCascade':check/uncheck childrenNodes
		this.checkModel = 'multiple';
		
		//only leaf can checked
		this.onlyLeafCheckable = false;
		
		Ext.ux.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
	};
	
	Ext.extend(Ext.ux.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {
	
	    renderElements : function(n, a, targetNode, bulkRender){
	    	var tree = n.getOwnerTree();
			this.checkModel = tree.checkModel || this.checkModel;
			this.onlyLeafCheckable = tree.onlyLeafCheckable || false;
	    	
	        // add some indent caching, this helps performance when rendering a large tree
	        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
	
	        //var cb = typeof a.checked == 'boolean';
			var cb = (!this.onlyLeafCheckable || a.leaf);
	        var href = a.href ? a.href : Ext.isGecko ? "" : "#";
	        var 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">',
	            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
	            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
	            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
	            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
	            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
	             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
	            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
	            "</li>"].join('');
	
	        var nel;
	        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
	            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
	        }else{
	            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
	        }
	        
	        this.elNode = this.wrap.childNodes[0];
	        this.ctNode = this.wrap.childNodes[1];
	        var cs = this.elNode.childNodes;
	        this.indentNode = cs[0];
	        this.ecNode = cs[1];
	        this.iconNode = cs[2];
	        var index = 3;
	        if(cb){
	            this.checkbox = cs[3];
	            Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
	            index++;
	        }
	        this.anchor = cs[index];
	        this.textNode = cs[index].firstChild;
	    },
	    
	    // private
	    check : function(checked){
	        var n = this.node;
			var tree = n.getOwnerTree();
			this.checkModel = tree.checkModel || this.checkModel;
			
			if( checked === null ) {
				checked = this.checkbox.checked;
			} else {
				this.checkbox.checked = checked;
			}
			
			n.attributes.checked = checked;
			tree.fireEvent('check', n, checked);
			
			if(!this.onlyLeafCheckable){
				if(this.checkModel == 'cascade' || this.checkModel == 'parentCascade'){
					var parentNode = n.parentNode;
					if(parentNode !== null) {
						this.parentCheck(parentNode,checked);
					}
				}
				if(this.checkModel == 'cascade' || this.checkModel == 'childCascade'){
					if( !n.expanded && !n.childrenRendered ) {
						n.expand(false,false,this.childCheck);
					}else {
						this.childCheck(n);  
					}
				}
			} else if(this.checkModel == 'single'){
				var checkedNodes = tree.getChecked();
				for(var i=0;i<checkedNodes.length;i++){
					var node = checkedNodes[i];
					if(node.id != n.id){
						node.getUI().checkbox.checked = false;
						node.attributes.checked = false;
						tree.fireEvent('check', node, false);
					}
				}
			}
		},
	
	    
	    // private
		childCheck : function(node){
			var a = node.attributes;
			if(!a.leaf) {
				var cs = node.childNodes;
				var csui;
				for(var i = 0; i < cs.length; i++) {
					csui = cs[i].getUI();
					if(csui.checkbox.checked ^ a.checked)
						csui.check(a.checked);
				}
			}
		},
		
		// private
		parentCheck : function(node ,checked){
			var checkbox = node.getUI().checkbox;
			if(typeof checkbox == 'undefined')return ;
			if(!(checked ^ checkbox.checked))return;
			if(!checked && this.childHasChecked(node))return;
			checkbox.checked = checked;
			node.attributes.checked = checked;
			node.getOwnerTree().fireEvent('check', node, checked);
			
			var parentNode = node.parentNode;
			if( parentNode !== null){
				this.parentCheck(parentNode,checked);
			}
		},
		
		// private
		childHasChecked : function(node){
			var childNodes = node.childNodes;
			if(childNodes || childNodes.length>0){
				for(var i=0;i<childNodes.length;i++){
					if(childNodes[i].getUI().checkbox.checked)
						return true;
				}
			}
			return false;
		},
		
	    toggleCheck : function(value){
	    	var cb = this.checkbox;
	        if(cb){
	            var checked = (value === undefined ? !cb.checked : value);
	            this.check(checked);
	        }
	    }
	});
};if(typeof Ext !== "undefined"){
// Ext.ux.grid.GridSummary.js
// summary plugin for Grid

Ext.ns('Ext.ux.grid');

Ext.ux.grid.GridSummary = function(config) {
        Ext.apply(this, config);
};

Ext.extend(Ext.ux.grid.GridSummary, Ext.util.Observable, {
    init : function(grid) {
        this.grid = grid;
        this.cm = grid.getColumnModel();
        this.view = grid.getView();

        var v = this.view;

        // override GridView's onLayout() method
        v.onLayout = this.onLayout;

        v.afterMethod('render', this.refreshSummary, this);
        v.afterMethod('refresh', this.refreshSummary, this);
        v.afterMethod('syncScroll', this.syncSummaryScroll, this);
        v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
        v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
        v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);

        // update summary row on store's add/remove/clear/update events
        grid.store.on({
            add: this.refreshSummary,
            remove: this.refreshSummary,
            clear: this.refreshSummary,
            update: this.refreshSummary,
            scope: this
        });

        if (!this.rowTpl) {
            this.rowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row x-grid3-gridsummary-row-offset">',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr>{cells}</tr></tbody>',
                    '</table>',
                '</div>'
            );
            this.rowTpl.disableFormats = true;
        }
        this.rowTpl.compile();

        if (!this.cellTpl) {
            this.cellTpl = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
                    '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
                "</td>"
            );
            this.cellTpl.disableFormats = true;
        }
        this.cellTpl.compile();
    },

    calculate : function(rs, cm) {
        var data = {}, cfg = cm.config;
        for (var i = 0, len = cfg.length; i < len; i++) { // loop through all columns in ColumnModel
            var cf = cfg[i], // get column's configuration
                cname = cf.dataIndex; // get column dataIndex

            // initialise grid summary row data for
            // the current column being worked on
            data[cname] = 0;

            if (cf.summaryType) {
                for (var j = 0, jlen = rs.length; j < jlen; j++) {
                    var r = rs[j]; // get a single Record
                    data[cname] = Ext.ux.grid.GridSummary.Calculations[cf.summaryType](r.get(cname), r, cname, data, j);
                }
            }
        }

        return data;
    },

    onLayout : function(vw, vh) {
        if (Ext.type(vh) != 'number') { // handles grid's height:'auto' config
            return;
        }
        // note: this method is scoped to the GridView
        if (!this.grid.getGridEl().hasClass('x-grid-hide-gridsummary')) {
            // readjust gridview's height only if grid summary row is visible
            this.scroller.setHeight(vh - this.summary.getHeight());
        }
    },

    syncSummaryScroll : function() {
        var mb = this.view.scroller.dom;

        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft;
        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
    },

    doWidth : function(col, w, tw) {
        var s = this.view.summary.dom;

        s.firstChild.style.width = tw;
        s.firstChild.rows[0].childNodes[col].style.width = w;
    },

    doAllWidths : function(ws, tw) {
        var s = this.view.summary.dom, wlen = ws.length;

        s.firstChild.style.width = tw;

        var cells = s.firstChild.rows[0].childNodes;

        for (var j = 0; j < wlen; j++) {
            cells[j].style.width = ws[j];
        }
    },

    doHidden : function(col, hidden, tw) {
        var s = this.view.summary.dom,
            display = hidden ? 'none' : '';

        s.firstChild.style.width = tw;
        s.firstChild.rows[0].childNodes[col].style.display = display;
    },

    renderSummary : function(o, cs, cm) {
        cs = cs || this.view.getColumnData();
        var cfg = cm.config,
            buf = [],
            last = cs.length - 1;

        for (var i = 0, len = cs.length; i < len; i++) {
            var c = cs[i], cf = cfg[i], p = {};

            p.id = c.id;
            p.style = c.style;
            p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');

            if (cf.summaryType || cf.summaryRenderer) {
                p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
            } else {
                p.value = '';
            }
            if (p.value == undefined || p.value === "") p.value = "&#160;";
            buf[buf.length] = this.cellTpl.apply(p);
        }

        return this.rowTpl.apply({
            tstyle: 'width:' + this.view.getTotalWidth() + ';',
            cells: buf.join('')
        });
    },

    refreshSummary : function() {
        var g = this.grid, ds = g.store,
            cs = this.view.getColumnData(),
            cm = this.cm,
            rs = ds.getRange(),
            data = this.calculate(rs, cm),
            buf = this.renderSummary({data: data}, cs, cm);

        if (!this.view.summaryWrap) {
            this.view.summaryWrap = Ext.DomHelper.insertAfter(this.view.scroller, {
                tag: 'div',
                cls: 'x-grid3-gridsummary-row-inner'
            }, true);
        }
        this.view.summary = this.view.summaryWrap.update(buf).first();
    },

    toggleSummary : function(visible) { // true to display summary row
        var el = this.grid.getGridEl();

        if (el) {
            if (visible === undefined) {
                visible = el.hasClass('x-grid-hide-gridsummary');
            }
            el[visible ? 'removeClass' : 'addClass']('x-grid-hide-gridsummary');

            this.view.layout(); // readjust gridview height
        }
    },

    getSummaryNode : function() {
        return this.view.summary
    }
});
Ext.reg('gridsummary', Ext.ux.grid.GridSummary);

}if(typeof Ext !== "undefined"){
Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, {

    lockText : 'Lock',

    unlockText : 'Unlock',

    rowBorderWidth : 1,

    lockedBorderWidth : 1,

    /*

     * This option ensures that height between the rows is synchronized

     * between the locked and unlocked sides. This option only needs to be used

     * when the row heights isn't predictable.

     */

    syncHeights: false,

    initTemplates : function(){

        var ts = this.templates || {};

        if(!ts.master){

            ts.master = new Ext.Template(

                '<div class="x-grid3" hidefocus="true">',

                    '<div class="x-grid3-locked">',

                        '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{lstyle}">{lockedHeader}</div></div><div class="x-clear"></div></div>',

                        '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',

                    '</div>',

                    '<div class="x-grid3-viewport x-grid3-unlocked">',

                        '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',

                        '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',

                    '</div>',

                    '<div class="x-grid3-resize-marker">&#160;</div>',

                    '<div class="x-grid3-resize-proxy">&#160;</div>',

                '</div>'

            );

        }

        this.templates = ts;

        Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this);

    },

    getEditorParent : function(ed){

        return this.el.dom;

    },

    initElements : function(){

        var E = Ext.Element;

        var el = this.grid.getGridEl().dom.firstChild;

        var cs = el.childNodes;

        this.el = new E(el);

        this.lockedWrap = new E(cs[0]);

        this.lockedHd = new E(this.lockedWrap.dom.firstChild);

        this.lockedInnerHd = this.lockedHd.dom.firstChild;

        this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]);

        this.lockedBody = new E(this.lockedScroller.dom.firstChild);

        this.mainWrap = new E(cs[1]);

        this.mainHd = new E(this.mainWrap.dom.firstChild);

        if(this.grid.hideHeaders){

            this.lockedHd.setDisplayed(false);

            this.mainHd.setDisplayed(false);

        }

        this.innerHd = this.mainHd.dom.firstChild;

        this.scroller = new E(this.mainWrap.dom.childNodes[1]);

        if(this.forceFit){

            this.scroller.setStyle('overflow-x', 'hidden');

        }

        this.mainBody = new E(this.scroller.dom.firstChild);

        this.focusEl = new E(this.scroller.dom.childNodes[1]);

        this.focusEl.swallowEvent('click', true);

        this.resizeMarker = new E(cs[2]);

        this.resizeProxy = new E(cs[3]);

    },

    

    getLockedRows : function(){

        return this.hasRows() ? this.lockedBody.dom.childNodes : [];

    },

    

    getLockedRow : function(row){

        return this.getLockedRows()[row];

    },

    

    getCell : function(row, col){

        var llen = this.cm.getLockedCount();

        if(col < llen){

            return this.getLockedRow(row).getElementsByTagName('td')[col];

        }

        return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen);

    },

    

    getHeaderCell : function(index){

        var llen = this.cm.getLockedCount();

        if(index < llen){

            return this.lockedHd.dom.getElementsByTagName('td')[index];

        }

        return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen);

    },

    

    addRowClass : function(row, cls){

        var r = this.getLockedRow(row);

        if(r){

            this.fly(r).addClass(cls);

        }

        Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);

    },

    

    removeRowClass : function(row, cls){

        var r = this.getLockedRow(row);

        if(r){

            this.fly(r).removeClass(cls);

        }

        Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls);

    },

    

    removeRow : function(row) {

        Ext.removeNode(this.getLockedRow(row));

        Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row);

    },

    

    removeRows : function(firstRow, lastRow){

        var bd = this.lockedBody.dom;

        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){

            Ext.removeNode(bd.childNodes[firstRow]);

        }

        Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow);

    },

    

    syncScroll : function(e){

        var mb = this.scroller.dom;

        this.lockedScroller.dom.scrollTop = mb.scrollTop;

        Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);

    },

    

    updateSortIcon : function(col, dir){

        var sc = this.sortClasses,

            lhds = this.lockedHd.select('td').removeClass(sc),

            hds = this.mainHd.select('td').removeClass(sc),

            llen = this.cm.getLockedCount(),

            cls = sc[dir == 'DESC' ? 1 : 0];

        if(col < llen){

            lhds.item(col).addClass(cls);

        }else{

            hds.item(col - llen).addClass(cls);

        }

    },

    

    updateAllColumnWidths : function(){

        var tw = this.getTotalWidth(),

            clen = this.cm.getColumnCount(),

            lw = this.getLockedWidth(),

            llen = this.cm.getLockedCount(),

            ws = [], len, i;

        this.updateLockedWidth();

        for(i = 0; i < clen; i++){

            ws[i] = this.getColumnWidth(i);

            var hd = this.getHeaderCell(i);

            hd.style.width = ws[i];

        }

        var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j;

        for(i = 0, len = ns.length; i < len; i++){

            row = lns[i];

            row.style.width = lw;

            if(row.firstChild){

                row.firstChild.style.width = lw;

                trow = row.firstChild.rows[0];

                for (j = 0; j < llen; j++) {

                   trow.childNodes[j].style.width = ws[j];

                }

            }

            row = ns[i];

            row.style.width = tw;

            if(row.firstChild){

                row.firstChild.style.width = tw;

                trow = row.firstChild.rows[0];

                for (j = llen; j < clen; j++) {

                   trow.childNodes[j - llen].style.width = ws[j];

                }

            }

        }

        this.onAllColumnWidthsUpdated(ws, tw);

        this.syncHeaderHeight();

    },

    

    updateColumnWidth : function(col, width){

        var w = this.getColumnWidth(col),

            llen = this.cm.getLockedCount(),

            ns, rw, c, row;

        this.updateLockedWidth();

        if(col < llen){

            ns = this.getLockedRows();

            rw = this.getLockedWidth();

            c = col;

        }else{

            ns = this.getRows();

            rw = this.getTotalWidth();

            c = col - llen;

        }

        var hd = this.getHeaderCell(col);

        hd.style.width = w;

        for(var i = 0, len = ns.length; i < len; i++){

            row = ns[i];

            row.style.width = rw;

            if(row.firstChild){

                row.firstChild.style.width = rw;

                row.firstChild.rows[0].childNodes[c].style.width = w;

            }

        }

        this.onColumnWidthUpdated(col, w, this.getTotalWidth());

        this.syncHeaderHeight();

    },

    

    updateColumnHidden : function(col, hidden){

        var llen = this.cm.getLockedCount(),

            ns, rw, c, row,

            display = hidden ? 'none' : '';

        this.updateLockedWidth();

        if(col < llen){

            ns = this.getLockedRows();

            rw = this.getLockedWidth();

            c = col;

        }else{

            ns = this.getRows();

            rw = this.getTotalWidth();

            c = col - llen;

        }

        var hd = this.getHeaderCell(col);

        hd.style.display = display;

        for(var i = 0, len = ns.length; i < len; i++){

            row = ns[i];

            row.style.width = rw;

            if(row.firstChild){

                row.firstChild.style.width = rw;

                row.firstChild.rows[0].childNodes[c].style.display = display;

            }

        }

        this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth());

        delete this.lastViewWidth;

        this.layout();

    },

    

    doRender : function(cs, rs, ds, startRow, colCount, stripe){

        var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1,

            tstyle = 'width:'+this.getTotalWidth()+';',

            lstyle = 'width:'+this.getLockedWidth()+';',

            buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r;

        for(var j = 0, len = rs.length; j < len; j++){

            r = rs[j]; cb = []; lcb = [];

            var rowIndex = (j+startRow);

            for(var i = 0; i < colCount; i++){

                c = cs[i];

                p.id = c.id;

                p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +

                    (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : '');

                p.attr = p.cellAttr = '';

                p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);

                p.style = c.style;

                if(Ext.isEmpty(p.value)){

                    p.value = '&#160;';

                }

                if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){

                    p.css += ' x-grid3-dirty-cell';

                }

                if(c.locked){

                    lcb[lcb.length] = ct.apply(p);

                }else{

                    cb[cb.length] = ct.apply(p);

                }

            }

            var alt = [];

            if(stripe && ((rowIndex+1) % 2 === 0)){

                alt[0] = 'x-grid3-row-alt';

            }

            if(r.dirty){

                alt[1] = ' x-grid3-dirty-row';

            }

            rp.cols = colCount;

            if(this.getRowClass){

                alt[2] = this.getRowClass(r, rowIndex, rp, ds);

            }

            rp.alt = alt.join(' ');

            rp.cells = cb.join('');

            rp.tstyle = tstyle;

            buf[buf.length] = rt.apply(rp);

            rp.cells = lcb.join('');

            rp.tstyle = lstyle;

            lbuf[lbuf.length] = rt.apply(rp);

        }

        return [buf.join(''), lbuf.join('')];

    },

    processRows : function(startRow, skipStripe){

        if(!this.ds || this.ds.getCount() < 1){

            return;

        }

        var rows = this.getRows(),

            lrows = this.getLockedRows(),

            row, lrow;

        skipStripe = skipStripe || !this.grid.stripeRows;

        startRow = startRow || 0;

        for(var i = 0, len = rows.length; i < len; ++i){

            row = rows[i];

            lrow = lrows[i];

            row.rowIndex = i;

            lrow.rowIndex = i;

            if(!skipStripe){

                row.className = row.className.replace(this.rowClsRe, ' ');

                lrow.className = lrow.className.replace(this.rowClsRe, ' ');

                if ((i + 1) % 2 === 0){

                    row.className += ' x-grid3-row-alt';

                    lrow.className += ' x-grid3-row-alt';

                }

            }

            if(this.syncHeights){

                var el1 = Ext.get(row),

                    el2 = Ext.get(lrow),

                    h1 = el1.getHeight(),

                    h2 = el2.getHeight();

                

                if(h1 > h2){

                    el2.setHeight(h1);    

                }else if(h2 > h1){

                    el1.setHeight(h2);

                }

            }

        }

        if(startRow === 0){

            Ext.fly(rows[0]).addClass(this.firstRowCls);

            Ext.fly(lrows[0]).addClass(this.firstRowCls);

        }

        Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);

        Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls);

    },

    

    afterRender : function(){

        if(!this.ds || !this.cm){

            return;

        }

        var bd = this.renderRows() || ['&#160;', '&#160;'];

        this.mainBody.dom.innerHTML = bd[0];

        this.lockedBody.dom.innerHTML = bd[1];

        this.processRows(0, true);

        if(this.deferEmptyText !== true){

            this.applyEmptyText();

        }

    },

    

    renderUI : function(){

        var header = this.renderHeaders();

        var body = this.templates.body.apply({rows:'&#160;'});

        var html = this.templates.master.apply({

            body: body,

            header: header[0],

            ostyle: 'width:'+this.getOffsetWidth()+';',

            bstyle: 'width:'+this.getTotalWidth()+';',

            lockedBody: body,

            lockedHeader: header[1],

            lstyle: 'width:'+this.getLockedWidth()+';'

        });

        var g = this.grid;

        g.getGridEl().dom.innerHTML = html;

        this.initElements();

        Ext.fly(this.innerHd).on('click', this.handleHdDown, this);

        Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this);

        this.mainHd.on({

            scope: this,

            mouseover: this.handleHdOver,

            mouseout: this.handleHdOut,

            mousemove: this.handleHdMove

        });

        this.lockedHd.on({

            scope: this,

            mouseover: this.handleHdOver,

            mouseout: this.handleHdOut,

            mousemove: this.handleHdMove

        });

        this.scroller.on('scroll', this.syncScroll,  this);

        if(g.enableColumnResize !== false){

            this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);

            this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));

            this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));

        }

        if(g.enableColumnMove){

            this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);

            this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));

            this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));

            this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);

        }

        if(g.enableHdMenu !== false){

            this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});

            this.hmenu.add(

                {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},

                {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}

            );

            if(this.grid.enableColLock !== false){

                this.hmenu.add('-',

                    {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'},

                    {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'}

                );

            }

            if(g.enableColumnHide !== false){

                this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});

                this.colMenu.on({

                    scope: this,

                    beforeshow: this.beforeColMenuShow,

                    itemclick: this.handleHdMenuClick

                });

                this.hmenu.add('-', {

                    itemId:'columns',

                    hideOnClick: false,

                    text: this.columnsText,

                    menu: this.colMenu,

                    iconCls: 'x-cols-icon'

                });

            }

            this.hmenu.on('itemclick', this.handleHdMenuClick, this);

        }

        if(g.trackMouseOver){

            this.mainBody.on({

                scope: this,

                mouseover: this.onRowOver,

                mouseout: this.onRowOut

            });

            this.lockedBody.on({

                scope: this,

                mouseover: this.onRowOver,

                mouseout: this.onRowOut

            });

        }

        

        if(g.enableDragDrop || g.enableDrag){

            this.dragZone = new Ext.grid.GridDragZone(g, {

                ddGroup : g.ddGroup || 'GridDD'

            });

        }

        this.updateHeaderSortState();

    },

    

    layout : function(){

        if(!this.mainBody){

            return;

        }

        var g = this.grid;

        var c = g.getGridEl();

        var csize = c.getSize(true);

        var vw = csize.width;

        if(!g.hideHeaders && (vw < 20 || csize.height < 20)){

            return;

        }

        this.syncHeaderHeight();

        if(g.autoHeight){

            this.scroller.dom.style.overflow = 'visible';

            this.lockedScroller.dom.style.overflow = 'visible';

            if(Ext.isWebKit){

                this.scroller.dom.style.position = 'static';

                this.lockedScroller.dom.style.position = 'static';

            }

        }else{

            this.el.setSize(csize.width, csize.height);

            var hdHeight = this.mainHd.getHeight();

            var vh = csize.height - (hdHeight);

        }

        this.updateLockedWidth();

        if(this.forceFit){

            if(this.lastViewWidth != vw){

                this.fitColumns(false, false);

                this.lastViewWidth = vw;

            }

        }else {

            this.autoExpand();

            this.syncHeaderScroll();

        }

        this.onLayout(vw, vh);

    },

    

    getOffsetWidth : function() {

        return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px';

    },

    

    renderHeaders : function(){

        var cm = this.cm,

            ts = this.templates,

            ct = ts.hcell,

            cb = [], lcb = [],

            p = {},

            len = cm.getColumnCount(),

            last = len - 1;

        for(var i = 0; i < len; i++){

            p.id = cm.getColumnId(i);

            p.value = cm.getColumnHeader(i) || '';

            p.style = this.getColumnStyle(i, true);

            p.tooltip = this.getColumnTooltip(i);

            p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +

                (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : '');

            if(cm.config[i].align == 'right'){

                p.istyle = 'padding-right:16px';

            } else {

                delete p.istyle;

            }

            if(cm.isLocked(i)){

                lcb[lcb.length] = ct.apply(p);

            }else{

                cb[cb.length] = ct.apply(p);

            }

        }

        return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}),

                ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})];

    },

    

    updateHeaders : function(){

        var hd = this.renderHeaders();

        this.innerHd.firstChild.innerHTML = hd[0];

        this.innerHd.firstChild.style.width = this.getOffsetWidth();

        this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();

        this.lockedInnerHd.firstChild.innerHTML = hd[1];

        var lw = this.getLockedWidth();

        this.lockedInnerHd.firstChild.style.width = lw;

        this.lockedInnerHd.firstChild.firstChild.style.width = lw;

    },

    

    getResolvedXY : function(resolved){

        if(!resolved){

            return null;

        }

        var c = resolved.cell, r = resolved.row;

        return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()];

    },

    

    syncFocusEl : function(row, col, hscroll){

        Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);

    },

    

    ensureVisible : function(row, col, hscroll){

        return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);

    },

    

    insertRows : function(dm, firstRow, lastRow, isUpdate){

        var last = dm.getCount() - 1;

        if(!isUpdate && firstRow === 0 && lastRow >= last){

            this.refresh();

        }else{

            if(!isUpdate){

                this.fireEvent('beforerowsinserted', this, firstRow, lastRow);

            }

            var html = this.renderRows(firstRow, lastRow),

                before = this.getRow(firstRow);

            if(before){

                if(firstRow === 0){

                    this.removeRowClass(0, this.firstRowCls);

                }

                Ext.DomHelper.insertHtml('beforeBegin', before, html[0]);

                before = this.getLockedRow(firstRow);

                Ext.DomHelper.insertHtml('beforeBegin', before, html[1]);

            }else{

                this.removeRowClass(last - 1, this.lastRowCls);

                Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]);

                Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]);

            }

            if(!isUpdate){

                this.fireEvent('rowsinserted', this, firstRow, lastRow);

                this.processRows(firstRow);

            }else if(firstRow === 0 || firstRow >= last){

                this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls);

            }

        }

        this.syncFocusEl(firstRow);

    },

    

    getColumnStyle : function(col, isHeader){

        var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || '';

        style += 'width:'+this.getColumnWidth(col)+';';

        if(this.cm.isHidden(col)){

            style += 'display:none;';

        }

        var align = this.cm.config[col].align;

        if(align){

            style += 'text-align:'+align+';';

        }

        return style;

    },

    

    getLockedWidth : function() {

        return this.cm.getTotalLockedWidth() + 'px';

    },

    

    getTotalWidth : function() {

        return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px';

    },

    

    getColumnData : function(){

        var cs = [], cm = this.cm, colCount = cm.getColumnCount();

        for(var i = 0; i < colCount; i++){

            var name = cm.getDataIndex(i);

            cs[i] = {

                name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),

                renderer : cm.getRenderer(i),

                id : cm.getColumnId(i),

                style : this.getColumnStyle(i),

                locked : cm.isLocked(i)

            };

        }

        return cs;

    },

    

    renderBody : function(){

        var markup = this.renderRows() || ['&#160;', '&#160;'];

        return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})];

    },

    

    refreshRow : function(record){

        Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record);

        var index = Ext.isNumber(record) ? record : this.ds.indexOf(record);

        this.getLockedRow(index).rowIndex = index;

    },

    

    refresh : function(headersToo){

        this.fireEvent('beforerefresh', this);

        this.grid.stopEditing(true);

        var result = this.renderBody();

        this.mainBody.update(result[0]).setWidth(this.getTotalWidth());

        this.lockedBody.update(result[1]).setWidth(this.getLockedWidth());

        if(headersToo === true){

            this.updateHeaders();

            this.updateHeaderSortState();

        }

        this.processRows(0, true);

        this.layout();

        this.applyEmptyText();

        this.fireEvent('refresh', this);

    },

    

    onDenyColumnLock : function(){



    },

    

    initData : function(ds, cm){

        if(this.cm){

            this.cm.un('columnlockchange', this.onColumnLock, this);

        }

        Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm);

        if(this.cm){

            this.cm.on('columnlockchange', this.onColumnLock, this);

        }

    },

    

    onColumnLock : function(){

        this.refresh(true);

    },

    

    handleHdMenuClick : function(item){

        var index = this.hdCtxIndex,

            cm = this.cm,

            id = item.getItemId(),

            llen = cm.getLockedCount();

        switch(id){

            case 'lock':

                if(cm.getColumnCount(true) <= llen + 1){

                    this.onDenyColumnLock();

                    return;

                }

                if(llen != index){

                    cm.setLocked(index, true, true);

                    cm.moveColumn(index, llen);

                    this.grid.fireEvent('columnmove', index, llen);

                }else{

                    cm.setLocked(index, true);

                }

            break;

            case 'unlock':

                if(llen - 1 != index){

                    cm.setLocked(index, false, true);

                    cm.moveColumn(index, llen - 1);

                    this.grid.fireEvent('columnmove', index, llen - 1);

                }else{

                    cm.setLocked(index, false);

                }

            break;

            default:

                return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item);

        }

        return true;

    },

    

    handleHdDown : function(e, t){

        Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t);

        if(this.grid.enableColLock !== false){

            if(Ext.fly(t).hasClass('x-grid3-hd-btn')){

                var hd = this.findHeaderCell(t),

                    index = this.getCellIndex(hd),

                    ms = this.hmenu.items, cm = this.cm;

                ms.get('lock').setDisabled(cm.isLocked(index));

                ms.get('unlock').setDisabled(!cm.isLocked(index));

            }

        }

    },

    

    syncHeaderHeight: function(){

        this.innerHd.firstChild.firstChild.style.height = 'auto';

        this.lockedInnerHd.firstChild.firstChild.style.height = 'auto';

        var hd = this.innerHd.firstChild.firstChild.offsetHeight,

            lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight,

            height = (lhd > hd ? lhd : hd) + 'px';

        this.innerHd.firstChild.firstChild.style.height = height;

        this.lockedInnerHd.firstChild.firstChild.style.height = height;

    },

    

    updateLockedWidth: function(){

        var lw = this.cm.getTotalLockedWidth(),

            tw = this.cm.getTotalWidth() - lw,

            csize = this.grid.getGridEl().getSize(true),

            lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth,

            rp = Ext.isBorderBox ? 0 : this.rowBorderWidth,

            vw = (csize.width - lw - lp - rp) + 'px',

            so = this.getScrollOffset();

        if(!this.grid.autoHeight){

            var vh = (csize.height - this.mainHd.getHeight()) + 'px';

            this.lockedScroller.dom.style.height = vh;

            this.scroller.dom.style.height = vh;

        }

        this.lockedWrap.dom.style.width = (lw + rp) + 'px';

        this.scroller.dom.style.width = vw;

        this.mainWrap.dom.style.left = (lw + lp + rp) + 'px';

        if(this.innerHd){

            this.lockedInnerHd.firstChild.style.width = lw + 'px';

            this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px';

            this.innerHd.style.width = vw;

            this.innerHd.firstChild.style.width = (tw + rp + so) + 'px';

            this.innerHd.firstChild.firstChild.style.width = tw + 'px';

        }

        if(this.mainBody){

            this.lockedBody.dom.style.width = (lw + rp) + 'px';

            this.mainBody.dom.style.width = (tw + rp) + 'px';

        }

    }

});
}if(typeof Ext !== "undefined"){
Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, {

    isLocked : function(colIndex){

        return this.config[colIndex].locked === true;

    },

    

    setLocked : function(colIndex, value, suppressEvent){

        if(this.isLocked(colIndex) == value){

            return;

        }

        this.config[colIndex].locked = value;

        if(!suppressEvent){

            this.fireEvent('columnlockchange', this, colIndex, value);

        }

    },

    

    getTotalLockedWidth : function(){

        var totalWidth = 0;

        for(var i = 0, len = this.config.length; i < len; i++){

            if(this.isLocked(i) && !this.isHidden(i)){

                totalWidth += this.getColumnWidth(i);

            }

        }

        return totalWidth;

    },

    

    getLockedCount : function(){

        for(var i = 0, len = this.config.length; i < len; i++){

            if(!this.isLocked(i)){

                return i;

            }

        }

    },

    

    moveColumn : function(oldIndex, newIndex){

        if(oldIndex < newIndex && this.isLocked(oldIndex) && !this.isLocked(newIndex)){

            this.setLocked(oldIndex, false, true);

        }else if(oldIndex > newIndex && !this.isLocked(oldIndex) && this.isLocked(newIndex)){

            this.setLocked(oldIndex, true, true);

        }

        Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments);

    }

});
}if(typeof Ext !== "undefined"){
/** ************************************************************
	Ext.ux.TinyMCE v0.8.6
	ExtJS form field containing TinyMCE v3.4.x.
	
	Author: Andrew Mayorov et al.
	http://blogs.byte-force.com/xor
	
	Copyright (c)2008-2011 BYTE-force
	www.byte-force.com
	
	License: LGPLv2.1 or later
*/

(function() {

	Ext.namespace("Ext.ux");

	var tmceInitialized = false;

	// Lazy references to classes. To be filled in the initTinyMCE method.
	var WindowManager;
	var ControlManager;

	// Create a new Windows Group for the dialogs
	/*var windowGroup = new Ext.WindowGroup();
	windowGroup.zseed = 12000;*/


	/** ----------------------------------------------------------
	Ext.ux.TinyMCE
	*/
	Ext.ux.TinyMCE = Ext.extend( Ext.form.Field, {

		// TinyMCE Settings specified for this instance of the editor.
		tinymceSettings: null,

		// Validation properties
		allowBlank: true,
		invalidText: "The value in this field is invalid",
		invalidClass: "invalid-content-body",
		minLengthText : 'The minimum length for this field is {0}',
		maxLengthText : 'The maximum length for this field is {0}',
		blankText : 'This field is required',

		// HTML markup for this field
		hideMode: 'offsets',
		defaultAutoCreate: {
			tag: "textarea",
			style: "width:1px;height:1px;",
			autocomplete: "off"
		},

		/** ----------------------------------------------------------
		*/
		constructor: function(cfg) {

			var config = {
				tinymceSettings: {
					accessibility_focus: false
				}
			};

			Ext.apply(config, cfg);

			// Add events
			this.addEvents({
				"editorcreated": true
			});

			Ext.ux.TinyMCE.superclass.constructor.call(this, config);
		},

		/** ----------------------------------------------------------
		*/
		initComponent: function() {
			this.tinymceSettings = this.tinymceSettings || {};
			Ext.ux.TinyMCE.initTinyMCE({ language: this.tinymceSettings.language , baseURL: this.tinymceSettings.baseURL});
		},

		/** ----------------------------------------------------------
		*/
		initEvents: function() {
			this.originalValue = this.getValue();
		},

		/** ----------------------------------------------------------
		*/
		onRender: function(ct, position) {
			Ext.ux.TinyMCE.superclass.onRender.call(this, ct, position);

			// Fix size if it was specified in config
			this.width=500;
			this.height=500;
			if (Ext.type(this.width) == "number") {
				this.tinymceSettings.width = this.width;
			}
			if (Ext.type(this.height) == "number") {
				this.tinymceSettings.height = this.height;
			}

			//this.el.dom.style.border = '0 none';
			this.el.dom.setAttribute('tabIndex', -1);
			this.el.addClass('x-hidden');
			
			// Wrap textarea into DIV
			this.textareaEl = this.el;
			var wrapElStyle = { overflow: "hidden" };
			if( Ext.isIE ) { // fix IE 1px bogus margin
				wrapElStyle["margin-top"] = "-1px";
				wrapElStyle["margin-bottom"] = "-1px";
			}
			this.wrapEl = this.el.wrap({ style: wrapElStyle });
			this.actionMode = "wrapEl"; // Set action element to the new wrapper
			this.positionEl = this.wrapEl;
			
			var id = this.getId();

			// Create TinyMCE editor.
			this.ed = new tinymce.Editor(id, this.tinymceSettings);
			
			// Validate value onKeyPress
			var validateContentTask = new Ext.util.DelayedTask( this.validate, this );
			this.ed.onKeyPress.add(function(ed, controlManager) {
				validateContentTask.delay( 250 );
			} .createDelegate(this));

			// Set up editor events' handlers
			this.ed.onBeforeRenderUI.add(function(ed, controlManager) {
				// Replace control manager
				ed.controlManager = new ControlManager(this, ed);
			} .createDelegate(this));

			this.ed.onPostRender.add(function(ed, controlManager) {
				var s = ed.settings;

				// Modify markup.
				var tbar = Ext.get(Ext.DomQuery.selectNode("#" + this.ed.id + "_tbl td.mceToolbar"));
				if( tbar != null ) {
					// If toolbar is present
					var tbars = tbar.select("table.mceToolbar");
					Ext.DomHelper
						.append( tbar,
							{ tag: "div", cls: "_tbar-wrap", style: { overflow: "hidden"} }
							, true )
						.appendChild(tbars);
				}
				
				// Change window manager
				ed.windowManager = new WindowManager({
					control: this,
					editor: this.ed,
					manager: this.manager
				});
				// Patch css-style for validation body like ExtJS
				Ext.get(ed.getContentAreaContainer()).addClass('patch-content-body');

				// Event of focused body
				Ext.Element.fly(s.content_editable ? ed.getBody() : ed.getWin())
					.on("focus", this.onFocus, this);

				// Event of blur body
				Ext.Element.fly(s.content_editable ? ed.getBody() : ed.getWin())
					.on("blur", this.onBlur, this,
						this.inEditor && Ext.isWindows && Ext.isGecko ? { buffer: 10} : null
					);

			} .createDelegate(this));

			// Set event handler on editor init.
			//this.ed.onInit.add(function() {
			//} .createDelegate(this));

			// Wire events
			var fireChangeEvent = function(ed, level) {
				this.fireEvent("change", this, level.content);
			} .createDelegate(this)

			this.ed.onChange.add( fireChangeEvent );
			this.ed.onUndo.add( fireChangeEvent );
			this.ed.onRedo.add( fireChangeEvent );

			this.ed.onKeyDown.add(function(ed, e) {
				this.fireEvent("keydown", this, Ext.EventObject );
			} .createDelegate(this));

			this.ed.onKeyUp.add(function(ed, e) {
				this.fireEvent("keyup", this, Ext.EventObject );
			} .createDelegate(this));

			this.ed.onKeyPress.add(function(ed, e) {
				this.fireEvent("keypress", this, Ext.EventObject );
			} .createDelegate(this));

			// Render the editor
			this.ed.render();
			
			// Fix editor size when control will be visible
			(function fixEditorSize() {
			
				// If element is not visible yet, wait.
				if( !this.isVisible() ) {
					arguments.callee.defer( 50, this );
					return;
				}
				
				var size = this.getSize();
				this.withEd( function() {
					this._setEditorSize( size.width, size.height );
					
					// Indicate that editor is created
					this.fireEvent("editorcreated");
				});
			}).call( this );
		},

		/** ----------------------------------------------------------
		*/
		getResizeEl: function() {
			return this.wrapEl;
		},

		/** ----------------------------------------------------------
		* Returns the name attribute of the field if available
		* @return {String} name The field name
		*/
		getName: function() {
			return this.rendered && this.textareaEl.dom.name
				? this.textareaEl.dom.name : (this.name || '');
		},

		/** ----------------------------------------------------------
		*/
		initValue: function() {

			if (!this.rendered)
				Ext.ux.TinyMCE.superclass.initValue.call(this);
			else {
				if (this.value !== undefined) {
					this.setValue(this.value);
				}
				else {
					var v = this.textareaEl.value; 
					if ( v )
						this.setValue( v );
				}
			}
		},

		/** ----------------------------------------------------------
		*/
		beforeDestroy: function() {
			if( this.ed ) {
				this.ed.remove();
			}
			if( this.wrapEl ) Ext.destroy( this.wrapEl );
			Ext.ux.TinyMCE.superclass.beforeDestroy.call( this );
		},

		/** ----------------------------------------------------------
		*/
		getRawValue : function(){

			if( !this.rendered || !this.ed.initialized )
				return Ext.value( this.value, '' );
				
			var v = this.ed.getContent();
			if(v === this.emptyText){
				v = '';
			}
			return v;
		},

		/** ----------------------------------------------------------
		*/
		getValue: function() {

			if( !this.rendered || !this.ed.initialized )
				return Ext.value( this.value, '' );

			var v = this.ed.getContent();
			if( v === this.emptyText || v === undefined ){
				v = '';
			}
			return v;
		},

		/** ----------------------------------------------------------
		*/
		setRawValue: function(v) {
			this.value = v;
			if (this.rendered)
				this.withEd(function() {
					this.ed.undoManager.clear();
					this.ed.setContent(v === null || v === undefined ? '' : v);
					this.ed.startContent = this.ed.getContent({ format: 'raw' });
				});
		},

		/** ----------------------------------------------------------
		*/
		setValue: function(v) {
			this.value = v;
			if (this.rendered)
				this.withEd(function() {
					this.ed.undoManager.clear();
					this.ed.setContent(v === null || v === undefined ? '' : v);
					this.ed.startContent = this.ed.getContent({ format: 'raw' });
					this.validate();
					//this.ed.resizeToContent();
				});
		},

		/** ----------------------------------------------------------
		*/
		isDirty: function() {
			if (this.disabled || !this.rendered) {
				return false;
			}
			return this.ed && this.ed.initialized && this.ed.isDirty();
		},

		/** ----------------------------------------------------------
		*/
		syncValue: function() {
			if (this.rendered && this.ed.initialized)
				this.ed.save();
		},

		/** ----------------------------------------------------------
		*/
		getEd: function() {
			return this.ed;
		},

		/** ----------------------------------------------------------
		*/
		disable: function() {
			this.withEd(function() {
				var bodyEl = this.ed.getBody();
				bodyEl = Ext.get(bodyEl);

				if (bodyEl.hasClass('mceContentBody')) {
					bodyEl.removeClass('mceContentBody');
					bodyEl.addClass('mceNonEditable');
				}
			});
			Ext.ux.TinyMCE.superclass.disable.call( this );
		},

		/** ----------------------------------------------------------
		*/
		enable: function() {
			this.withEd(function() {
				var bodyEl = this.ed.getBody();
				bodyEl = Ext.get(bodyEl);

				if (bodyEl.hasClass('mceNonEditable')) {
					bodyEl.removeClass('mceNonEditable');
					bodyEl.addClass('mceContentBody');
				}
			});
			Ext.ux.TinyMCE.superclass.enable.call( this );
		},

		/** ----------------------------------------------------------
		*/
		onResize: function(aw, ah) {
			if( Ext.type( aw ) != "number" ){
				aw = this.getWidth();
			}
			if( Ext.type(ah) != "number" ){
				ah = this.getHeight();
			}
			if (aw == 0 || ah == 0)
				return;

			if( this.rendered && this.isVisible() ) {
				this.withEd(function() { this._setEditorSize( aw, ah ); });
			}
		},
		
		/** ----------------------------------------------------------
			Sets control size to the given width and height
		*/
		_setEditorSize: function( width, height ) {
		
			// We currently support only advanced theme resize
			if( !this.ed.theme.AdvancedTheme ) return;
		
			// Minimal width and height for advanced theme
			if( width < 100 ) width = 100;
			if( height < 129 ) height = 129;
			
			// Set toolbar div width
			var edTable = Ext.get(this.ed.id + "_tbl"), 
				edIframe = Ext.get(this.ed.id + "_ifr"),
				edToolbar = edTable.child( "._tbar-wrap" );
			
			var toolbarWidth = width;
			if( edTable ) 
				toolbarWidth = width - edTable.getFrameWidth( "lr" );		
			
			var toolbarHeight = 0;
			if( edToolbar ) {
				toolbarHeight = edToolbar.getHeight();
				var toolbarTd = edToolbar.findParent( "td", 5, true );
				toolbarHeight += toolbarTd.getFrameWidth( "tb" );
				edToolbar.setWidth( toolbarWidth );
			}
			
			var edStatusbarTd = edTable.child( ".mceStatusbar" );
			var statusbarHeight = 0;
			if( edStatusbarTd ) {
				statusbarHeight += edStatusbarTd.getHeight();
			}
			
			var iframeHeight = height - toolbarHeight - statusbarHeight;
			var iframeTd = edIframe.findParent( "td", 5, true );
			if( iframeTd )
				iframeHeight -= iframeTd.getFrameWidth( "tb" );
				
			// Resize iframe and container
			edTable.setSize( width, height );
			edIframe.setSize( toolbarWidth, iframeHeight );
		},

		/** ----------------------------------------------------------
		*/
		focus: function(selectText, delay) {
			if (delay) {
				this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
				return;
			}

			this.withEd(function() {
				this.ed.focus();
				/*if (selectText === true) {
				// TODO: Select editor's content
				}*/
			});

			return this;
		},

		/** ----------------------------------------------------------
		*/
		processValue : function( value ){
			return Ext.util.Format.stripTags( value );
		},
		
		/** ----------------------------------------------------------
		*/
		validateValue: function( value ) {
			if(Ext.isFunction(this.validator)){
				var msg = this.validator(value);
				if(msg !== true){
					this.markInvalid(msg);
					return false;
				}
			}
			if(value.length < 1 || value === this.emptyText){ // if it's blank
				 if(this.allowBlank){
					 this.clearInvalid();
					 return true;
				 }else{
					 this.markInvalid(this.blankText);
					 return false;
				 }
			}
			if(value.length < this.minLength){
				this.markInvalid(String.format(this.minLengthText, this.minLength));
				return false;
			}
			if(value.length > this.maxLength){
				this.markInvalid(String.format(this.maxLengthText, this.maxLength));
				return false;
			}	
			if(this.vtype){
				var vt = Ext.form.VTypes;
				if(!vt[this.vtype](value, this)){
					this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
					return false;
				}
			}
			if(this.regex && !this.regex.test(value)){
				this.markInvalid(this.regexText);
				return false;
			}
			return true;
		},

		/** ----------------------------------------------------------
		If ed (local editor instance) is already initilized, calls
		specified function directly. Otherwise - adds it to ed.onInit event.
		*/
		withEd: function(func) {

			// If editor is not created yet, reschedule this call.
			if (!this.ed) this.on(
				"editorcreated",
				function() { this.withEd(func); },
				this);

			// Else if editor is created and initialized
			else if (this.ed.initialized) func.call(this);

			// Else if editor is created but not initialized yet.
			else this.ed.onInit.add(function() { func.defer(10, this); } .createDelegate(this));
		},

		/** ----------------------------------------------------------
			internal
			Unbind blur and focus events coming from DOM node. Used while opening aux windows.
		*/
		_unbindBlurAndFocus: function() {
			//this.onBlur = Ext.emptyFn;
			/*this.mun( this.el, 'focus' );
			this.mun( this.el, 'blur' );*/
			Ext.util.Observable.capture( this, function() { return false; } );
		},

		/** ----------------------------------------------------------
			internal
			Bind blur and focus events coming from DOM. Used to return back normal blur and focus opearaions.
			Code is copied from initEvents method.
		*/
		_bindBlurAndFocus: function() {
			this.ed.focus();
			Ext.util.Observable.releaseCapture( this );
			
			/*this.mon(this.el, 'focus', this.onFocus, this);

			// standardise buffer across all browsers + OS-es for consistent event order.
			// (the 10ms buffer for Editors fixes a weird FF/Win editor issue when changing OS window focus)
			this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);*/
		}
	});

	// Add static members
	Ext.apply(Ext.ux.TinyMCE, {

		/**
		Static field with all the plugins that should be loaded by TinyMCE.
		Should be set before first component would be created.
		@static
		*/
		tinymcePlugins: "pagebreak,style,layer,table,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,template",

		/** ----------------------------------------------------------
			Inits TinyMCE and other necessary dependencies.
		*/
		initTinyMCE: function(settings) {
			console.log(settings);
			if (!tmceInitialized) {

				// Create lazy classes
				/** ----------------------------------------------------------
				WindowManager
				*/
				
				WindowManager = Ext.extend( tinymce.WindowManager, {

					// Reference to ExtJS control Ext.ux.TinyMCE.
					control: null,

					/** ----------------------------------------------------------
						Config parameters:
						control - reference to Ext.ux.TinyMCE control
						editor - reference to TinyMCE intstance.
						mangager - WindowGroup to use for the popup window. Could be empty.
					*/
					constructor: function( cfg ) {
						WindowManager.superclass.constructor.call(this, cfg.editor);

						// Set reference to host control
						this.control = cfg.control;

						// Set window group
						this.manager = cfg.manager;  
					},

					/** ----------------------------------------------------------
					*/
					alert: function(txt, cb, s) {
						Ext.MessageBox.alert("", this.editor.getLang(txt,txt), function() {
							if (!Ext.isEmpty(cb)) {
								cb.call(this);
							}
						}, s);
					},

					/** ----------------------------------------------------------
					*/
					confirm: function(txt, cb, s) {
						Ext.MessageBox.confirm("", this.editor.getLang(txt,txt), function(btn) {
							if (!Ext.isEmpty(cb)) {
								cb.call(this, btn == "yes");
							}
						}, s);
					},

					/** ----------------------------------------------------------
					*/
					open: function(s, p) {

						this.control._unbindBlurAndFocus();

						s = s || {};
						p = p || {};

						if (!s.type)
							this.bookmark = this.editor.selection.getBookmark('simple');

						s.width = parseInt(s.width || 320);
						s.height = parseInt(s.height || 240) + (tinymce.isIE ? 8 : 0);
						s.min_width = parseInt(s.min_width || 150);
						s.min_height = parseInt(s.min_height || 100);
						s.max_width = parseInt(s.max_width || 2000);
						s.max_height = parseInt(s.max_height || 2000);
						s.movable = true;
						s.resizable = true;
						p.mce_width = s.width;
						p.mce_height = s.height;
						p.mce_inline = true;

						this.features = s;
						this.params = p;

						var win = new Ext.Window(
						{
							title: s.name,
							width: s.width,
							height: s.height,
							minWidth: s.min_width,
							minHeight: s.min_height,
							resizable: true,
							maximizable: s.maximizable,
							minimizable: s.minimizable,
							modal: true,
							stateful: false,
							constrain: true,
							manager: this.manager,
							layout: "fit",
							items: [
								new Ext.BoxComponent({
									autoEl: {
										tag: 'iframe',
										src: s.url || s.file
									},
									style : 'border-width: 0px;'
								})
							],
							listeners: {
								beforeclose: function() {
									this.control._bindBlurAndFocus();
								},
								scope: this
							}
						});

						p.mce_window_id = win.getId();

						win.show(null,
							function() {
								if (s.left && s.top)
									win.setPagePosition(s.left, s.top);
								var pos = win.getPosition();
								s.left = pos[0];
								s.top = pos[1];
								this.onOpen.dispatch(this, s, p);
							},
							this
						);

						return win;
					},

					/** ----------------------------------------------------------
					*/
					close: function(win) {

						// Probably not inline
						if (!win.tinyMCEPopup || !win.tinyMCEPopup.id) {
							WindowManager.superclass.close.call(this, win);
							return;
						}

						var w = Ext.getCmp(win.tinyMCEPopup.id);
						if (w) {
							this.onClose.dispatch(this);
							w.close();
						}
					},

					/** ----------------------------------------------------------
					*/
					setTitle: function(win, ti) {

						// Probably not inline
						if (!win.tinyMCEPopup || !win.tinyMCEPopup.id) {
							WindowManager.superclass.setTitle.call(this, win, ti);
							return;
						}

						var w = Ext.getCmp(win.tinyMCEPopup.id);
						if (w) w.setTitle(ti);
					},

					/** ----------------------------------------------------------
					*/
					resizeBy: function(dw, dh, id) {

						var w = Ext.getCmp(id);
						if (w) {
							var size = w.getSize();
							w.setSize(size.width + dw, size.height + dh);
						}
					},

					/** ----------------------------------------------------------
					*/
					focus: function(id) {
						var w = Ext.getCmp(id);
						if (w) w.setActive(true);
					}
					
				});

				/** ----------------------------------------------------------
				ControlManager
				*/
				ControlManager = Ext.extend( tinymce.ControlManager, {

					// Reference to ExtJS control Ext.ux.TinyMCE.
					control: null,

					/** ----------------------------------------------------------
					*/
					constructor: function(control, ed, s) {
						this.control = control;
						ControlManager.superclass.constructor.call(this, ed, s);
					},

					/** ----------------------------------------------------------
					*/
					createDropMenu: function(id, s) {
						// Call base method
						var res = ControlManager.superclass.createDropMenu.call(this, id, s);

						// Modify returned result
						var orig = res.showMenu;
						res.showMenu = function(x, y, px) {
							orig.call(this, x, y, px);
							Ext.fly('menu_' + this.id).setStyle("z-index", 200001);
						};

						return res;
					},

					/** ----------------------------------------------------------
					*/
					createColorSplitButton: function(id, s) {
						// Call base method
						var res = ControlManager.superclass.createColorSplitButton.call(this, id, s);

						// Modify returned result
						var orig = res.showMenu;
						res.showMenu = function(x, y, px) {
							orig.call(this, x, y, px);
							Ext.fly(this.id + '_menu').setStyle("z-index", 200001);
						};

						return res;
					}
				});

				// Init TinyMCE
				var s = {
					mode: "none",
					plugins: Ext.ux.TinyMCE.tinymcePlugins,
					theme: "advanced"
				};
				
				Ext.apply(s, settings);
				console.log(settings);
				if (!tinymce.dom.Event.domLoaded)
					tinymce.dom.Event._pageInit();
				if(s.baseURL !== undefined){
					tinyMCE.baseURL = s.baseURL;
				}
				tinyMCE.init(s);
				tmceInitialized = true;
			}
		}
	});
	Ext.ComponentMgr.registerType("tinymce", Ext.ux.TinyMCE);
	//Ext.reg("tinymce", Ext.ux.TinyMCE);
})();
}
