roojs-bootstrap.js
authoredward <edward@roojs.com>
Fri, 18 Sep 2015 04:23:05 +0000 (12:23 +0800)
committeredward <edward@roojs.com>
Fri, 18 Sep 2015 04:23:05 +0000 (12:23 +0800)
roojs-bootstrap-debug.js

roojs-bootstrap-debug.js
roojs-bootstrap.js

index da8b5f2..d1ef85f 100644 (file)
@@ -7814,3 +7814,14380 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
 });
 
  
+/*
+ * - LGPL
+ *
+ * Input
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TextArea
+ * @extends Roo.bootstrap.Input
+ * Bootstrap TextArea class
+ * @cfg {Number} cols Specifies the visible width of a text area
+ * @cfg {Number} rows Specifies the visible number of lines in a text area
+ * @cfg {string} wrap (soft|hard)Specifies how the text in a text area is to be wrapped when submitted in a form
+ * @cfg {string} resize (none|both|horizontal|vertical|inherit|initial)
+ * @cfg {string} html text
+ * 
+ * @constructor
+ * Create a new TextArea
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TextArea = function(config){
+    Roo.bootstrap.TextArea.superclass.constructor.call(this, config);
+   
+};
+
+Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
+     
+    cols : false,
+    rows : 5,
+    readOnly : false,
+    warp : 'soft',
+    resize : false,
+    value: false,
+    html: false,
+    
+    getAutoCreate : function(){
+        
+        var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
+        
+        var id = Roo.id();
+        
+        var cfg = {};
+        
+        var input =  {
+            tag: 'textarea',
+            id : id,
+            warp : this.warp,
+            rows : this.rows,
+            value : this.value || '',
+            html: this.html || '',
+            cls : 'form-control',
+            placeholder : this.placeholder || '' 
+            
+        };
+        
+        if(this.maxLength && this.maxLength != Number.MAX_VALUE){
+            input.maxLength = this.maxLength;
+        }
+        
+        if(this.resize){
+            input.style = (typeof(input.style) == 'undefined') ? 'resize:' + this.resize : input.style + 'resize:' + this.resize;
+        }
+        
+        if(this.cols){
+            input.cols = this.cols;
+        }
+        
+        if (this.readOnly) {
+            input.readonly = true;
+        }
+        
+        if (this.name) {
+            input.name = this.name;
+        }
+        
+        if (this.size) {
+            input.cls = (typeof(input.cls) == 'undefined') ? 'input-' + this.size : input.cls + ' input-' + this.size;
+        }
+        
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        var inputblock = input;
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            inputblock.cn.push(input);
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        }
+        
+        if (align ==='left' && this.fieldLabel.length) {
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label col-sm-' + this.labelWidth,
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-sm-" + (12 - this.labelWidth), 
+                        cn: [
+                            inputblock
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                 cfg.cn = [
+                   
+                    {
+                        tag: 'label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    inputblock
+                    
+                ];
+
+        } else {
+            
+                   Roo.log(" no label && no align");
+                cfg.cn = [
+                    
+                        inputblock
+                    
+                ];
+                
+                
+        }
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        return cfg;
+        
+    },
+    /**
+     * return the real textarea element.
+     */
+    inputEl: function ()
+    {
+        return this.el.select('textarea.form-control',true).first();
+    }
+});
+
+/*
+ * - LGPL
+ *
+ * trigger field - base class for combo..
+ * 
+ */
+/**
+ * @class Roo.bootstrap.TriggerField
+ * @extends Roo.bootstrap.Input
+ * Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).
+ * The trigger has no default action, so you must assign a function to implement the trigger click handler by
+ * overriding {@link #onTriggerClick}. You can create a TriggerField directly, as it renders exactly like a combobox
+ * for which you can provide a custom implementation.  For example:
+ * <pre><code>
+var trigger = new Roo.bootstrap.TriggerField();
+trigger.onTriggerClick = myTriggerFn;
+trigger.applyTo('my-field');
+</code></pre>
+ *
+ * However, in general you will most likely want to use TriggerField as the base class for a reusable component.
+ * {@link Roo.bootstrap.DateField} and {@link Roo.bootstrap.ComboBox} are perfect examples of this.
+ * @cfg {String} triggerClass An additional CSS class used to style the trigger button.  The trigger will always get the
+ * class 'x-form-trigger' by default and triggerClass will be <b>appended</b> if specified.
+ * @cfg {String} caret (search|calendar) a fontawesome for the trigger icon see http://fortawesome.github.io/Font-Awesome/icons/
+
+ * @constructor
+ * Create a new TriggerField.
+ * @param {Object} config Configuration options (valid {@Roo.bootstrap.Input} config options will also be applied
+ * to the base TextField)
+ */
+Roo.bootstrap.TriggerField = function(config){
+    this.mimicing = false;
+    Roo.bootstrap.TriggerField.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
+    /**
+     * @cfg {String} triggerClass A CSS class to apply to the trigger
+     */
+     /**
+     * @cfg {Boolean} hideTrigger True to hide the trigger element and display only the base text field (defaults to false)
+     */
+    hideTrigger:false,
+
+    /** @cfg {Boolean} grow @hide */
+    /** @cfg {Number} growMin @hide */
+    /** @cfg {Number} growMax @hide */
+
+    /**
+     * @hide 
+     * @method
+     */
+    autoSize: Roo.emptyFn,
+    // private
+    monitorTab : true,
+    // private
+    deferHeight : true,
+
+    
+    actionMode : 'wrap',
+    
+    caret : false,
+    
+    
+    getAutoCreate : function(){
+       
+        var align = this.labelAlign || this.parentLabelAlign();
+        
+        var id = Roo.id();
+        
+        var cfg = {
+            cls: 'form-group' //input-group
+        };
+        
+        
+        var input =  {
+            tag: 'input',
+            id : id,
+            type : this.inputType,
+            cls : 'form-control',
+            autocomplete: 'false',
+            placeholder : this.placeholder || '' 
+            
+        };
+        if (this.name) {
+            input.name = this.name;
+        }
+        if (this.size) {
+            input.cls += ' input-' + this.size;
+        }
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        var inputblock = input;
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            inputblock.cn.push(input);
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        };
+        
+        var box = {
+            tag: 'div',
+            cn: [
+                {
+                    tag: 'input',
+                    type : 'hidden',
+                    cls: 'form-hidden-field'
+                },
+                inputblock
+            ]
+            
+        };
+        
+        if(this.multiple){
+            Roo.log('multiple');
+            
+            box = {
+                tag: 'div',
+                cn: [
+                    {
+                        tag: 'input',
+                        type : 'hidden',
+                        cls: 'form-hidden-field'
+                    },
+                    {
+                        tag: 'ul',
+                        cls: 'select2-choices',
+                        cn:[
+                            {
+                                tag: 'li',
+                                cls: 'select2-search-field',
+                                cn: [
+
+                                    inputblock
+                                ]
+                            }
+                        ]
+                    }
+                ]
+            }
+        };
+        
+        var combobox = {
+            cls: 'select2-container input-group',
+            cn: [
+                box
+//                {
+//                    tag: 'ul',
+//                    cls: 'typeahead typeahead-long dropdown-menu',
+//                    style: 'display:none'
+//                }
+            ]
+        };
+        
+        if(!this.multiple && this.showToggleBtn){
+            
+            var caret = {
+                        tag: 'span',
+                        cls: 'caret'
+             };
+            if (this.caret != false) {
+                caret = {
+                     tag: 'i',
+                     cls: 'fa fa-' + this.caret
+                };
+                
+            }
+            
+            combobox.cn.push({
+                tag :'span',
+                cls : 'input-group-addon btn dropdown-toggle',
+                cn : [
+                    caret,
+                    {
+                        tag: 'span',
+                        cls: 'combobox-clear',
+                        cn  : [
+                            {
+                                tag : 'i',
+                                cls: 'icon-remove'
+                            }
+                        ]
+                    }
+                ]
+
+            })
+        }
+        
+        if(this.multiple){
+            combobox.cls += ' select2-container-multi';
+        }
+        
+        if (align ==='left' && this.fieldLabel.length) {
+            
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label col-sm-' + this.labelWidth,
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-sm-" + (12 - this.labelWidth), 
+                        cn: [
+                            combobox
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                 cfg.cn = [
+                   
+                    {
+                        tag: 'label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    combobox
+                    
+                ];
+
+        } else {
+            
+                Roo.log(" no label && no align");
+                cfg = combobox
+                     
+                
+        }
+         
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        return cfg;
+        
+    },
+    
+    
+    
+    // private
+    onResize : function(w, h){
+//        Roo.bootstrap.TriggerField.superclass.onResize.apply(this, arguments);
+//        if(typeof w == 'number'){
+//            var x = w - this.trigger.getWidth();
+//            this.inputEl().setWidth(this.adjustWidth('input', x));
+//            this.trigger.setStyle('left', x+'px');
+//        }
+    },
+
+    // private
+    adjustSize : Roo.BoxComponent.prototype.adjustSize,
+
+    // private
+    getResizeEl : function(){
+        return this.inputEl();
+    },
+
+    // private
+    getPositionEl : function(){
+        return this.inputEl();
+    },
+
+    // private
+    alignErrorIcon : function(){
+        this.errorIcon.alignTo(this.inputEl(), 'tl-tr', [2, 0]);
+    },
+
+    // private
+    initEvents : function(){
+        
+        this.createList();
+        
+        Roo.bootstrap.TriggerField.superclass.initEvents.call(this);
+        //this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
+        if(!this.multiple && this.showToggleBtn){
+            this.trigger = this.el.select('span.dropdown-toggle',true).first();
+            if(this.hideTrigger){
+                this.trigger.setDisplayed(false);
+            }
+            this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
+        }
+        
+        if(this.multiple){
+            this.inputEl().on("click", this.onTriggerClick, this, {preventDefault:true});
+        }
+        
+        //this.trigger.addClassOnOver('x-form-trigger-over');
+        //this.trigger.addClassOnClick('x-form-trigger-click');
+        
+        //if(!this.width){
+        //    this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
+        //}
+    },
+    
+    createList : function()
+    {
+        this.list = Roo.get(document.body).createChild({
+            tag: 'ul',
+            cls: 'typeahead typeahead-long dropdown-menu',
+            style: 'display:none'
+        });
+        
+        this.list.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';;
+        
+    },
+
+    // private
+    initTrigger : function(){
+       
+    },
+
+    // private
+    onDestroy : function(){
+        if(this.trigger){
+            this.trigger.removeAllListeners();
+          //  this.trigger.remove();
+        }
+        //if(this.wrap){
+        //    this.wrap.remove();
+        //}
+        Roo.bootstrap.TriggerField.superclass.onDestroy.call(this);
+    },
+
+    // private
+    onFocus : function(){
+        Roo.bootstrap.TriggerField.superclass.onFocus.call(this);
+        /*
+        if(!this.mimicing){
+            this.wrap.addClass('x-trigger-wrap-focus');
+            this.mimicing = true;
+            Roo.get(Roo.isIE ? document.body : document).on("mousedown", this.mimicBlur, this);
+            if(this.monitorTab){
+                this.el.on("keydown", this.checkTab, this);
+            }
+        }
+        */
+    },
+
+    // private
+    checkTab : function(e){
+        if(e.getKey() == e.TAB){
+            this.triggerBlur();
+        }
+    },
+
+    // private
+    onBlur : function(){
+        // do nothing
+    },
+
+    // private
+    mimicBlur : function(e, t){
+        /*
+        if(!this.wrap.contains(t) && this.validateBlur()){
+            this.triggerBlur();
+        }
+        */
+    },
+
+    // private
+    triggerBlur : function(){
+        this.mimicing = false;
+        Roo.get(Roo.isIE ? document.body : document).un("mousedown", this.mimicBlur);
+        if(this.monitorTab){
+            this.el.un("keydown", this.checkTab, this);
+        }
+        //this.wrap.removeClass('x-trigger-wrap-focus');
+        Roo.bootstrap.TriggerField.superclass.onBlur.call(this);
+    },
+
+    // private
+    // This should be overriden by any subclass that needs to check whether or not the field can be blurred.
+    validateBlur : function(e, t){
+        return true;
+    },
+
+    // private
+    onDisable : function(){
+        this.inputEl().dom.disabled = true;
+        //Roo.bootstrap.TriggerField.superclass.onDisable.call(this);
+        //if(this.wrap){
+        //    this.wrap.addClass('x-item-disabled');
+        //}
+    },
+
+    // private
+    onEnable : function(){
+        this.inputEl().dom.disabled = false;
+        //Roo.bootstrap.TriggerField.superclass.onEnable.call(this);
+        //if(this.wrap){
+        //    this.el.removeClass('x-item-disabled');
+        //}
+    },
+
+    // private
+    onShow : function(){
+        var ae = this.getActionEl();
+        
+        if(ae){
+            ae.dom.style.display = '';
+            ae.dom.style.visibility = 'visible';
+        }
+    },
+
+    // private
+    
+    onHide : function(){
+        var ae = this.getActionEl();
+        ae.dom.style.display = 'none';
+    },
+
+    /**
+     * The function that should handle the trigger's click event.  This method does nothing by default until overridden
+     * by an implementing function.
+     * @method
+     * @param {EventObject} e
+     */
+    onTriggerClick : Roo.emptyFn
+});
+ /*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+
+/**
+ * @class Roo.data.SortTypes
+ * @singleton
+ * Defines the default sorting (casting?) comparison functions used when sorting data.
+ */
+Roo.data.SortTypes = {
+    /**
+     * Default sort that does nothing
+     * @param {Mixed} s The value being converted
+     * @return {Mixed} The comparison value
+     */
+    none : function(s){
+        return s;
+    },
+    
+    /**
+     * The regular expression used to strip tags
+     * @type {RegExp}
+     * @property
+     */
+    stripTagsRE : /<\/?[^>]+>/gi,
+    
+    /**
+     * Strips all HTML tags to sort on text only
+     * @param {Mixed} s The value being converted
+     * @return {String} The comparison value
+     */
+    asText : function(s){
+        return String(s).replace(this.stripTagsRE, "");
+    },
+    
+    /**
+     * Strips all HTML tags to sort on text only - Case insensitive
+     * @param {Mixed} s The value being converted
+     * @return {String} The comparison value
+     */
+    asUCText : function(s){
+        return String(s).toUpperCase().replace(this.stripTagsRE, "");
+    },
+    
+    /**
+     * Case insensitive string
+     * @param {Mixed} s The value being converted
+     * @return {String} The comparison value
+     */
+    asUCString : function(s) {
+       return String(s).toUpperCase();
+    },
+    
+    /**
+     * Date sorting
+     * @param {Mixed} s The value being converted
+     * @return {Number} The comparison value
+     */
+    asDate : function(s) {
+        if(!s){
+            return 0;
+        }
+        if(s instanceof Date){
+            return s.getTime();
+        }
+       return Date.parse(String(s));
+    },
+    
+    /**
+     * Float sorting
+     * @param {Mixed} s The value being converted
+     * @return {Float} The comparison value
+     */
+    asFloat : function(s) {
+       var val = parseFloat(String(s).replace(/,/g, ""));
+        if(isNaN(val)) val = 0;
+       return val;
+    },
+    
+    /**
+     * Integer sorting
+     * @param {Mixed} s The value being converted
+     * @return {Number} The comparison value
+     */
+    asInt : function(s) {
+        var val = parseInt(String(s).replace(/,/g, ""));
+        if(isNaN(val)) val = 0;
+       return val;
+    }
+};/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+* @class Roo.data.Record
+ * Instances of this class encapsulate both record <em>definition</em> information, and record
+ * <em>value</em> information for use in {@link Roo.data.Store} objects, or any code which needs
+ * to access Records cached in an {@link Roo.data.Store} object.<br>
+ * <p>
+ * Constructors for this class are generated by passing an Array of field definition objects to {@link #create}.
+ * Instances are usually only created by {@link Roo.data.Reader} implementations when processing unformatted data
+ * objects.<br>
+ * <p>
+ * Record objects generated by this constructor inherit all the methods of Roo.data.Record listed below.
+ * @constructor
+ * This constructor should not be used to create Record objects. Instead, use the constructor generated by
+ * {@link #create}. The parameters are the same.
+ * @param {Array} data An associative Array of data values keyed by the field name.
+ * @param {Object} id (Optional) The id of the record. This id should be unique, and is used by the
+ * {@link Roo.data.Store} object which owns the Record to index its collection of Records. If
+ * not specified an integer id is generated.
+ */
+Roo.data.Record = function(data, id){
+    this.id = (id || id === 0) ? id : ++Roo.data.Record.AUTO_ID;
+    this.data = data;
+};
+
+/**
+ * Generate a constructor for a specific record layout.
+ * @param {Array} o An Array of field definition objects which specify field names, and optionally,
+ * data types, and a mapping for an {@link Roo.data.Reader} to extract the field's value from a data object.
+ * Each field definition object may contain the following properties: <ul>
+ * <li><b>name</b> : String<p style="margin-left:1em">The name by which the field is referenced within the Record. This is referenced by,
+ * for example the <em>dataIndex</em> property in column definition objects passed to {@link Roo.grid.ColumnModel}</p></li>
+ * <li><b>mapping</b> : String<p style="margin-left:1em">(Optional) A path specification for use by the {@link Roo.data.Reader} implementation
+ * that is creating the Record to access the data value from the data object. If an {@link Roo.data.JsonReader}
+ * is being used, then this is a string containing the javascript expression to reference the data relative to 
+ * the record item's root. If an {@link Roo.data.XmlReader} is being used, this is an {@link Roo.DomQuery} path
+ * to the data item relative to the record element. If the mapping expression is the same as the field name,
+ * this may be omitted.</p></li>
+ * <li><b>type</b> : String<p style="margin-left:1em">(Optional) The data type for conversion to displayable value. Possible values are
+ * <ul><li>auto (Default, implies no conversion)</li>
+ * <li>string</li>
+ * <li>int</li>
+ * <li>float</li>
+ * <li>boolean</li>
+ * <li>date</li></ul></p></li>
+ * <li><b>sortType</b> : Mixed<p style="margin-left:1em">(Optional) A member of {@link Roo.data.SortTypes}.</p></li>
+ * <li><b>sortDir</b> : String<p style="margin-left:1em">(Optional) Initial direction to sort. "ASC" or "DESC"</p></li>
+ * <li><b>convert</b> : Function<p style="margin-left:1em">(Optional) A function which converts the value provided
+ * by the Reader into an object that will be stored in the Record. It is passed the
+ * following parameters:<ul>
+ * <li><b>v</b> : Mixed<p style="margin-left:1em">The data value as read by the Reader.</p></li>
+ * </ul></p></li>
+ * <li><b>dateFormat</b> : String<p style="margin-left:1em">(Optional) A format String for the Date.parseDate function.</p></li>
+ * </ul>
+ * <br>usage:<br><pre><code>
+var TopicRecord = Roo.data.Record.create(
+    {name: 'title', mapping: 'topic_title'},
+    {name: 'author', mapping: 'username'},
+    {name: 'totalPosts', mapping: 'topic_replies', type: 'int'},
+    {name: 'lastPost', mapping: 'post_time', type: 'date'},
+    {name: 'lastPoster', mapping: 'user2'},
+    {name: 'excerpt', mapping: 'post_text'}
+);
+
+var myNewRecord = new TopicRecord({
+    title: 'Do my job please',
+    author: 'noobie',
+    totalPosts: 1,
+    lastPost: new Date(),
+    lastPoster: 'Animal',
+    excerpt: 'No way dude!'
+});
+myStore.add(myNewRecord);
+</code></pre>
+ * @method create
+ * @static
+ */
+Roo.data.Record.create = function(o){
+    var f = function(){
+        f.superclass.constructor.apply(this, arguments);
+    };
+    Roo.extend(f, Roo.data.Record);
+    var p = f.prototype;
+    p.fields = new Roo.util.MixedCollection(false, function(field){
+        return field.name;
+    });
+    for(var i = 0, len = o.length; i < len; i++){
+        p.fields.add(new Roo.data.Field(o[i]));
+    }
+    f.getField = function(name){
+        return p.fields.get(name);  
+    };
+    return f;
+};
+
+Roo.data.Record.AUTO_ID = 1000;
+Roo.data.Record.EDIT = 'edit';
+Roo.data.Record.REJECT = 'reject';
+Roo.data.Record.COMMIT = 'commit';
+
+Roo.data.Record.prototype = {
+    /**
+     * Readonly flag - true if this record has been modified.
+     * @type Boolean
+     */
+    dirty : false,
+    editing : false,
+    error: null,
+    modified: null,
+
+    // private
+    join : function(store){
+        this.store = store;
+    },
+
+    /**
+     * Set the named field to the specified value.
+     * @param {String} name The name of the field to set.
+     * @param {Object} value The value to set the field to.
+     */
+    set : function(name, value){
+        if(this.data[name] == value){
+            return;
+        }
+        this.dirty = true;
+        if(!this.modified){
+            this.modified = {};
+        }
+        if(typeof this.modified[name] == 'undefined'){
+            this.modified[name] = this.data[name];
+        }
+        this.data[name] = value;
+        if(!this.editing && this.store){
+            this.store.afterEdit(this);
+        }       
+    },
+
+    /**
+     * Get the value of the named field.
+     * @param {String} name The name of the field to get the value of.
+     * @return {Object} The value of the field.
+     */
+    get : function(name){
+        return this.data[name]; 
+    },
+
+    // private
+    beginEdit : function(){
+        this.editing = true;
+        this.modified = {}; 
+    },
+
+    // private
+    cancelEdit : function(){
+        this.editing = false;
+        delete this.modified;
+    },
+
+    // private
+    endEdit : function(){
+        this.editing = false;
+        if(this.dirty && this.store){
+            this.store.afterEdit(this);
+        }
+    },
+
+    /**
+     * Usually called by the {@link Roo.data.Store} which owns the Record.
+     * Rejects all changes made to the Record since either creation, or the last commit operation.
+     * Modified fields are reverted to their original values.
+     * <p>
+     * Developers should subscribe to the {@link Roo.data.Store#update} event to have their code notified
+     * of reject operations.
+     */
+    reject : function(){
+        var m = this.modified;
+        for(var n in m){
+            if(typeof m[n] != "function"){
+                this.data[n] = m[n];
+            }
+        }
+        this.dirty = false;
+        delete this.modified;
+        this.editing = false;
+        if(this.store){
+            this.store.afterReject(this);
+        }
+    },
+
+    /**
+     * Usually called by the {@link Roo.data.Store} which owns the Record.
+     * Commits all changes made to the Record since either creation, or the last commit operation.
+     * <p>
+     * Developers should subscribe to the {@link Roo.data.Store#update} event to have their code notified
+     * of commit operations.
+     */
+    commit : function(){
+        this.dirty = false;
+        delete this.modified;
+        this.editing = false;
+        if(this.store){
+            this.store.afterCommit(this);
+        }
+    },
+
+    // private
+    hasError : function(){
+        return this.error != null;
+    },
+
+    // private
+    clearError : function(){
+        this.error = null;
+    },
+
+    /**
+     * Creates a copy of this record.
+     * @param {String} id (optional) A new record id if you don't want to use this record's id
+     * @return {Record}
+     */
+    copy : function(newId) {
+        return new this.constructor(Roo.apply({}, this.data), newId || this.id);
+    }
+};/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+
+
+/**
+ * @class Roo.data.Store
+ * @extends Roo.util.Observable
+ * The Store class encapsulates a client side cache of {@link Roo.data.Record} objects which provide input data
+ * for widgets such as the Roo.grid.Grid, or the Roo.form.ComboBox.<br>
+ * <p>
+ * A Store object uses an implementation of {@link Roo.data.DataProxy} to access a data object unless you call loadData() directly and pass in your data. The Store object
+ * has no knowledge of the format of the data returned by the Proxy.<br>
+ * <p>
+ * A Store object uses its configured implementation of {@link Roo.data.DataReader} to create {@link Roo.data.Record}
+ * instances from the data object. These records are cached and made available through accessor functions.
+ * @constructor
+ * Creates a new Store.
+ * @param {Object} config A config object containing the objects needed for the Store to access data,
+ * and read the data into Records.
+ */
+Roo.data.Store = function(config){
+    this.data = new Roo.util.MixedCollection(false);
+    this.data.getKey = function(o){
+        return o.id;
+    };
+    this.baseParams = {};
+    // private
+    this.paramNames = {
+        "start" : "start",
+        "limit" : "limit",
+        "sort" : "sort",
+        "dir" : "dir",
+        "multisort" : "_multisort"
+    };
+
+    if(config && config.data){
+        this.inlineData = config.data;
+        delete config.data;
+    }
+
+    Roo.apply(this, config);
+    
+    if(this.reader){ // reader passed
+        this.reader = Roo.factory(this.reader, Roo.data);
+        this.reader.xmodule = this.xmodule || false;
+        if(!this.recordType){
+            this.recordType = this.reader.recordType;
+        }
+        if(this.reader.onMetaChange){
+            this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
+        }
+    }
+
+    if(this.recordType){
+        this.fields = this.recordType.prototype.fields;
+    }
+    this.modified = [];
+
+    this.addEvents({
+        /**
+         * @event datachanged
+         * Fires when the data cache has changed, and a widget which is using this Store
+         * as a Record cache should refresh its view.
+         * @param {Store} this
+         */
+        datachanged : true,
+        /**
+         * @event metachange
+         * Fires when this store's reader provides new metadata (fields). This is currently only support for JsonReaders.
+         * @param {Store} this
+         * @param {Object} meta The JSON metadata
+         */
+        metachange : true,
+        /**
+         * @event add
+         * Fires when Records have been added to the Store
+         * @param {Store} this
+         * @param {Roo.data.Record[]} records The array of Records added
+         * @param {Number} index The index at which the record(s) were added
+         */
+        add : true,
+        /**
+         * @event remove
+         * Fires when a Record has been removed from the Store
+         * @param {Store} this
+         * @param {Roo.data.Record} record The Record that was removed
+         * @param {Number} index The index at which the record was removed
+         */
+        remove : true,
+        /**
+         * @event update
+         * Fires when a Record has been updated
+         * @param {Store} this
+         * @param {Roo.data.Record} record The Record that was updated
+         * @param {String} operation The update operation being performed.  Value may be one of:
+         * <pre><code>
+ Roo.data.Record.EDIT
+ Roo.data.Record.REJECT
+ Roo.data.Record.COMMIT
+         * </code></pre>
+         */
+        update : true,
+        /**
+         * @event clear
+         * Fires when the data cache has been cleared.
+         * @param {Store} this
+         */
+        clear : true,
+        /**
+         * @event beforeload
+         * Fires before a request is made for a new data object.  If the beforeload handler returns false
+         * the load action will be canceled.
+         * @param {Store} this
+         * @param {Object} options The loading options that were specified (see {@link #load} for details)
+         */
+        beforeload : true,
+        /**
+         * @event beforeloadadd
+         * Fires after a new set of Records has been loaded.
+         * @param {Store} this
+         * @param {Roo.data.Record[]} records The Records that were loaded
+         * @param {Object} options The loading options that were specified (see {@link #load} for details)
+         */
+        beforeloadadd : true,
+        /**
+         * @event load
+         * Fires after a new set of Records has been loaded, before they are added to the store.
+         * @param {Store} this
+         * @param {Roo.data.Record[]} records The Records that were loaded
+         * @param {Object} options The loading options that were specified (see {@link #load} for details)
+         * @params {Object} return from reader
+         */
+        load : true,
+        /**
+         * @event loadexception
+         * Fires if an exception occurs in the Proxy during loading.
+         * Called with the signature of the Proxy's "loadexception" event.
+         * If you return Json { data: [] , success: false, .... } then this will be thrown with the following args
+         * 
+         * @param {Proxy} 
+         * @param {Object} return from JsonData.reader() - success, totalRecords, records
+         * @param {Object} load options 
+         * @param {Object} jsonData from your request (normally this contains the Exception)
+         */
+        loadexception : true
+    });
+    
+    if(this.proxy){
+        this.proxy = Roo.factory(this.proxy, Roo.data);
+        this.proxy.xmodule = this.xmodule || false;
+        this.relayEvents(this.proxy,  ["loadexception"]);
+    }
+    this.sortToggle = {};
+    this.sortOrder = []; // array of order of sorting - updated by grid if multisort is enabled.
+
+    Roo.data.Store.superclass.constructor.call(this);
+
+    if(this.inlineData){
+        this.loadData(this.inlineData);
+        delete this.inlineData;
+    }
+};
+
+Roo.extend(Roo.data.Store, Roo.util.Observable, {
+     /**
+    * @cfg {boolean} isLocal   flag if data is locally available (and can be always looked up
+    * without a remote query - used by combo/forms at present.
+    */
+    
+    /**
+    * @cfg {Roo.data.DataProxy} proxy The Proxy object which provides access to a data object.
+    */
+    /**
+    * @cfg {Array} data Inline data to be loaded when the store is initialized.
+    */
+    /**
+    * @cfg {Roo.data.Reader} reader The Reader object which processes the data object and returns
+    * an Array of Roo.data.record objects which are cached keyed by their <em>id</em> property.
+    */
+    /**
+    * @cfg {Object} baseParams An object containing properties which are to be sent as parameters
+    * on any HTTP request
+    */
+    /**
+    * @cfg {Object} sortInfo A config object in the format: {field: "fieldName", direction: "ASC|DESC"}
+    */
+    /**
+    * @cfg {Boolean} multiSort enable multi column sorting (sort is based on the order of columns, remote only at present)
+    */
+    multiSort: false,
+    /**
+    * @cfg {boolean} remoteSort True if sorting is to be handled by requesting the Proxy to provide a refreshed
+    * version of the data object in sorted order, as opposed to sorting the Record cache in place (defaults to false).
+    */
+    remoteSort : false,
+
+    /**
+    * @cfg {boolean} pruneModifiedRecords True to clear all modified record information each time the store is
+     * loaded or when a record is removed. (defaults to false).
+    */
+    pruneModifiedRecords : false,
+
+    // private
+    lastOptions : null,
+
+    /**
+     * Add Records to the Store and fires the add event.
+     * @param {Roo.data.Record[]} records An Array of Roo.data.Record objects to add to the cache.
+     */
+    add : function(records){
+        records = [].concat(records);
+        for(var i = 0, len = records.length; i < len; i++){
+            records[i].join(this);
+        }
+        var index = this.data.length;
+        this.data.addAll(records);
+        this.fireEvent("add", this, records, index);
+    },
+
+    /**
+     * Remove a Record from the Store and fires the remove event.
+     * @param {Ext.data.Record} record The Roo.data.Record object to remove from the cache.
+     */
+    remove : function(record){
+        var index = this.data.indexOf(record);
+        this.data.removeAt(index);
+        if(this.pruneModifiedRecords){
+            this.modified.remove(record);
+        }
+        this.fireEvent("remove", this, record, index);
+    },
+
+    /**
+     * Remove all Records from the Store and fires the clear event.
+     */
+    removeAll : function(){
+        this.data.clear();
+        if(this.pruneModifiedRecords){
+            this.modified = [];
+        }
+        this.fireEvent("clear", this);
+    },
+
+    /**
+     * Inserts Records to the Store at the given index and fires the add event.
+     * @param {Number} index The start index at which to insert the passed Records.
+     * @param {Roo.data.Record[]} records An Array of Roo.data.Record objects to add to the cache.
+     */
+    insert : function(index, records){
+        records = [].concat(records);
+        for(var i = 0, len = records.length; i < len; i++){
+            this.data.insert(index, records[i]);
+            records[i].join(this);
+        }
+        this.fireEvent("add", this, records, index);
+    },
+
+    /**
+     * Get the index within the cache of the passed Record.
+     * @param {Roo.data.Record} record The Roo.data.Record object to to find.
+     * @return {Number} The index of the passed Record. Returns -1 if not found.
+     */
+    indexOf : function(record){
+        return this.data.indexOf(record);
+    },
+
+    /**
+     * Get the index within the cache of the Record with the passed id.
+     * @param {String} id The id of the Record to find.
+     * @return {Number} The index of the Record. Returns -1 if not found.
+     */
+    indexOfId : function(id){
+        return this.data.indexOfKey(id);
+    },
+
+    /**
+     * Get the Record with the specified id.
+     * @param {String} id The id of the Record to find.
+     * @return {Roo.data.Record} The Record with the passed id. Returns undefined if not found.
+     */
+    getById : function(id){
+        return this.data.key(id);
+    },
+
+    /**
+     * Get the Record at the specified index.
+     * @param {Number} index The index of the Record to find.
+     * @return {Roo.data.Record} The Record at the passed index. Returns undefined if not found.
+     */
+    getAt : function(index){
+        return this.data.itemAt(index);
+    },
+
+    /**
+     * Returns a range of Records between specified indices.
+     * @param {Number} startIndex (optional) The starting index (defaults to 0)
+     * @param {Number} endIndex (optional) The ending index (defaults to the last Record in the Store)
+     * @return {Roo.data.Record[]} An array of Records
+     */
+    getRange : function(start, end){
+        return this.data.getRange(start, end);
+    },
+
+    // private
+    storeOptions : function(o){
+        o = Roo.apply({}, o);
+        delete o.callback;
+        delete o.scope;
+        this.lastOptions = o;
+    },
+
+    /**
+     * Loads the Record cache from the configured Proxy using the configured Reader.
+     * <p>
+     * If using remote paging, then the first load call must specify the <em>start</em>
+     * and <em>limit</em> properties in the options.params property to establish the initial
+     * position within the dataset, and the number of Records to cache on each read from the Proxy.
+     * <p>
+     * <strong>It is important to note that for remote data sources, loading is asynchronous,
+     * and this call will return before the new data has been loaded. Perform any post-processing
+     * in a callback function, or in a "load" event handler.</strong>
+     * <p>
+     * @param {Object} options An object containing properties which control loading options:<ul>
+     * <li>params {Object} An object containing properties to pass as HTTP parameters to a remote data source.</li>
+     * <li>callback {Function} A function to be called after the Records have been loaded. The callback is
+     * passed the following arguments:<ul>
+     * <li>r : Roo.data.Record[]</li>
+     * <li>options: Options object from the load call</li>
+     * <li>success: Boolean success indicator</li></ul></li>
+     * <li>scope {Object} Scope with which to call the callback (defaults to the Store object)</li>
+     * <li>add {Boolean} indicator to append loaded records rather than replace the current cache.</li>
+     * </ul>
+     */
+    load : function(options){
+        options = options || {};
+        if(this.fireEvent("beforeload", this, options) !== false){
+            this.storeOptions(options);
+            var p = Roo.apply(options.params || {}, this.baseParams);
+            // if meta was not loaded from remote source.. try requesting it.
+            if (!this.reader.metaFromRemote) {
+                p._requestMeta = 1;
+            }
+            if(this.sortInfo && this.remoteSort){
+                var pn = this.paramNames;
+                p[pn["sort"]] = this.sortInfo.field;
+                p[pn["dir"]] = this.sortInfo.direction;
+            }
+            if (this.multiSort) {
+                var pn = this.paramNames;
+                p[pn["multisort"]] = Roo.encode( { sort : this.sortToggle, order: this.sortOrder });
+            }
+            
+            this.proxy.load(p, this.reader, this.loadRecords, this, options);
+        }
+    },
+
+    /**
+     * Reloads the Record cache from the configured Proxy using the configured Reader and
+     * the options from the last load operation performed.
+     * @param {Object} options (optional) An object containing properties which may override the options
+     * used in the last load operation. See {@link #load} for details (defaults to null, in which case
+     * the most recently used options are reused).
+     */
+    reload : function(options){
+        this.load(Roo.applyIf(options||{}, this.lastOptions));
+    },
+
+    // private
+    // Called as a callback by the Reader during a load operation.
+    loadRecords : function(o, options, success){
+        if(!o || success === false){
+            if(success !== false){
+                this.fireEvent("load", this, [], options, o);
+            }
+            if(options.callback){
+                options.callback.call(options.scope || this, [], options, false);
+            }
+            return;
+        }
+        // if data returned failure - throw an exception.
+        if (o.success === false) {
+            // show a message if no listener is registered.
+            if (!this.hasListener('loadexception') && typeof(o.raw.errorMsg) != 'undefined') {
+                    Roo.MessageBox.alert("Error loading",o.raw.errorMsg);
+            }
+            // loadmask wil be hooked into this..
+            this.fireEvent("loadexception", this, o, options, o.raw.errorMsg);
+            return;
+        }
+        var r = o.records, t = o.totalRecords || r.length;
+        
+        this.fireEvent("beforeloadadd", this, r, options, o);
+        
+        if(!options || options.add !== true){
+            if(this.pruneModifiedRecords){
+                this.modified = [];
+            }
+            for(var i = 0, len = r.length; i < len; i++){
+                r[i].join(this);
+            }
+            if(this.snapshot){
+                this.data = this.snapshot;
+                delete this.snapshot;
+            }
+            this.data.clear();
+            this.data.addAll(r);
+            this.totalLength = t;
+            this.applySort();
+            this.fireEvent("datachanged", this);
+        }else{
+            this.totalLength = Math.max(t, this.data.length+r.length);
+            this.add(r);
+        }
+        this.fireEvent("load", this, r, options, o);
+        if(options.callback){
+            options.callback.call(options.scope || this, r, options, true);
+        }
+    },
+
+
+    /**
+     * Loads data from a passed data block. A Reader which understands the format of the data
+     * must have been configured in the constructor.
+     * @param {Object} data The data block from which to read the Records.  The format of the data expected
+     * is dependent on the type of Reader that is configured and should correspond to that Reader's readRecords parameter.
+     * @param {Boolean} append (Optional) True to append the new Records rather than replace the existing cache.
+     */
+    loadData : function(o, append){
+        var r = this.reader.readRecords(o);
+        this.loadRecords(r, {add: append}, true);
+    },
+
+    /**
+     * Gets the number of cached records.
+     * <p>
+     * <em>If using paging, this may not be the total size of the dataset. If the data object
+     * used by the Reader contains the dataset size, then the getTotalCount() function returns
+     * the data set size</em>
+     */
+    getCount : function(){
+        return this.data.length || 0;
+    },
+
+    /**
+     * Gets the total number of records in the dataset as returned by the server.
+     * <p>
+     * <em>If using paging, for this to be accurate, the data object used by the Reader must contain
+     * the dataset size</em>
+     */
+    getTotalCount : function(){
+        return this.totalLength || 0;
+    },
+
+    /**
+     * Returns the sort state of the Store as an object with two properties:
+     * <pre><code>
+ field {String} The name of the field by which the Records are sorted
+ direction {String} The sort order, "ASC" or "DESC"
+     * </code></pre>
+     */
+    getSortState : function(){
+        return this.sortInfo;
+    },
+
+    // private
+    applySort : function(){
+        if(this.sortInfo && !this.remoteSort){
+            var s = this.sortInfo, f = s.field;
+            var st = this.fields.get(f).sortType;
+            var fn = function(r1, r2){
+                var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
+                return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+            };
+            this.data.sort(s.direction, fn);
+            if(this.snapshot && this.snapshot != this.data){
+                this.snapshot.sort(s.direction, fn);
+            }
+        }
+    },
+
+    /**
+     * Sets the default sort column and order to be used by the next load operation.
+     * @param {String} fieldName The name of the field to sort by.
+     * @param {String} dir (optional) The sort order, "ASC" or "DESC" (defaults to "ASC")
+     */
+    setDefaultSort : function(field, dir){
+        this.sortInfo = {field: field, direction: dir ? dir.toUpperCase() : "ASC"};
+    },
+
+    /**
+     * Sort the Records.
+     * If remote sorting is used, the sort is performed on the server, and the cache is
+     * reloaded. If local sorting is used, the cache is sorted internally.
+     * @param {String} fieldName The name of the field to sort by.
+     * @param {String} dir (optional) The sort order, "ASC" or "DESC" (defaults to "ASC")
+     */
+    sort : function(fieldName, dir){
+        var f = this.fields.get(fieldName);
+        if(!dir){
+            this.sortToggle[f.name] = this.sortToggle[f.name] || f.sortDir;
+            
+            if(this.multiSort || (this.sortInfo && this.sortInfo.field == f.name) ){ // toggle sort dir
+                dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
+            }else{
+                dir = f.sortDir;
+            }
+        }
+        this.sortToggle[f.name] = dir;
+        this.sortInfo = {field: f.name, direction: dir};
+        if(!this.remoteSort){
+            this.applySort();
+            this.fireEvent("datachanged", this);
+        }else{
+            this.load(this.lastOptions);
+        }
+    },
+
+    /**
+     * Calls the specified function for each of the Records in the cache.
+     * @param {Function} fn The function to call. The Record is passed as the first parameter.
+     * Returning <em>false</em> aborts and exits the iteration.
+     * @param {Object} scope (optional) The scope in which to call the function (defaults to the Record).
+     */
+    each : function(fn, scope){
+        this.data.each(fn, scope);
+    },
+
+    /**
+     * Gets all records modified since the last commit.  Modified records are persisted across load operations
+     * (e.g., during paging).
+     * @return {Roo.data.Record[]} An array of Records containing outstanding modifications.
+     */
+    getModifiedRecords : function(){
+        return this.modified;
+    },
+
+    // private
+    createFilterFn : function(property, value, anyMatch){
+        if(!value.exec){ // not a regex
+            value = String(value);
+            if(value.length == 0){
+                return false;
+            }
+            value = new RegExp((anyMatch === true ? '' : '^') + Roo.escapeRe(value), "i");
+        }
+        return function(r){
+            return value.test(r.data[property]);
+        };
+    },
+
+    /**
+     * Sums the value of <i>property</i> for each record between start and end and returns the result.
+     * @param {String} property A field on your records
+     * @param {Number} start The record index to start at (defaults to 0)
+     * @param {Number} end The last record index to include (defaults to length - 1)
+     * @return {Number} The sum
+     */
+    sum : function(property, start, end){
+        var rs = this.data.items, v = 0;
+        start = start || 0;
+        end = (end || end === 0) ? end : rs.length-1;
+
+        for(var i = start; i <= end; i++){
+            v += (rs[i].data[property] || 0);
+        }
+        return v;
+    },
+
+    /**
+     * Filter the records by a specified property.
+     * @param {String} field A field on your records
+     * @param {String/RegExp} value Either a string that the field
+     * should start with or a RegExp to test against the field
+     * @param {Boolean} anyMatch True to match any part not just the beginning
+     */
+    filter : function(property, value, anyMatch){
+        var fn = this.createFilterFn(property, value, anyMatch);
+        return fn ? this.filterBy(fn) : this.clearFilter();
+    },
+
+    /**
+     * Filter by a function. The specified function will be called with each
+     * record in this data source. If the function returns true the record is included,
+     * otherwise it is filtered.
+     * @param {Function} fn The function to be called, it will receive 2 args (record, id)
+     * @param {Object} scope (optional) The scope of the function (defaults to this)
+     */
+    filterBy : function(fn, scope){
+        this.snapshot = this.snapshot || this.data;
+        this.data = this.queryBy(fn, scope||this);
+        this.fireEvent("datachanged", this);
+    },
+
+    /**
+     * Query the records by a specified property.
+     * @param {String} field A field on your records
+     * @param {String/RegExp} value Either a string that the field
+     * should start with or a RegExp to test against the field
+     * @param {Boolean} anyMatch True to match any part not just the beginning
+     * @return {MixedCollection} Returns an Roo.util.MixedCollection of the matched records
+     */
+    query : function(property, value, anyMatch){
+        var fn = this.createFilterFn(property, value, anyMatch);
+        return fn ? this.queryBy(fn) : this.data.clone();
+    },
+
+    /**
+     * Query by a function. The specified function will be called with each
+     * record in this data source. If the function returns true the record is included
+     * in the results.
+     * @param {Function} fn The function to be called, it will receive 2 args (record, id)
+     * @param {Object} scope (optional) The scope of the function (defaults to this)
+      @return {MixedCollection} Returns an Roo.util.MixedCollection of the matched records
+     **/
+    queryBy : function(fn, scope){
+        var data = this.snapshot || this.data;
+        return data.filterBy(fn, scope||this);
+    },
+
+    /**
+     * Collects unique values for a particular dataIndex from this store.
+     * @param {String} dataIndex The property to collect
+     * @param {Boolean} allowNull (optional) Pass true to allow null, undefined or empty string values
+     * @param {Boolean} bypassFilter (optional) Pass true to collect from all records, even ones which are filtered
+     * @return {Array} An array of the unique values
+     **/
+    collect : function(dataIndex, allowNull, bypassFilter){
+        var d = (bypassFilter === true && this.snapshot) ?
+                this.snapshot.items : this.data.items;
+        var v, sv, r = [], l = {};
+        for(var i = 0, len = d.length; i < len; i++){
+            v = d[i].data[dataIndex];
+            sv = String(v);
+            if((allowNull || !Roo.isEmpty(v)) && !l[sv]){
+                l[sv] = true;
+                r[r.length] = v;
+            }
+        }
+        return r;
+    },
+
+    /**
+     * Revert to a view of the Record cache with no filtering applied.
+     * @param {Boolean} suppressEvent If true the filter is cleared silently without notifying listeners
+     */
+    clearFilter : function(suppressEvent){
+        if(this.snapshot && this.snapshot != this.data){
+            this.data = this.snapshot;
+            delete this.snapshot;
+            if(suppressEvent !== true){
+                this.fireEvent("datachanged", this);
+            }
+        }
+    },
+
+    // private
+    afterEdit : function(record){
+        if(this.modified.indexOf(record) == -1){
+            this.modified.push(record);
+        }
+        this.fireEvent("update", this, record, Roo.data.Record.EDIT);
+    },
+    
+    // private
+    afterReject : function(record){
+        this.modified.remove(record);
+        this.fireEvent("update", this, record, Roo.data.Record.REJECT);
+    },
+
+    // private
+    afterCommit : function(record){
+        this.modified.remove(record);
+        this.fireEvent("update", this, record, Roo.data.Record.COMMIT);
+    },
+
+    /**
+     * Commit all Records with outstanding changes. To handle updates for changes, subscribe to the
+     * Store's "update" event, and perform updating when the third parameter is Roo.data.Record.COMMIT.
+     */
+    commitChanges : function(){
+        var m = this.modified.slice(0);
+        this.modified = [];
+        for(var i = 0, len = m.length; i < len; i++){
+            m[i].commit();
+        }
+    },
+
+    /**
+     * Cancel outstanding changes on all changed records.
+     */
+    rejectChanges : function(){
+        var m = this.modified.slice(0);
+        this.modified = [];
+        for(var i = 0, len = m.length; i < len; i++){
+            m[i].reject();
+        }
+    },
+
+    onMetaChange : function(meta, rtype, o){
+        this.recordType = rtype;
+        this.fields = rtype.prototype.fields;
+        delete this.snapshot;
+        this.sortInfo = meta.sortInfo || this.sortInfo;
+        this.modified = [];
+        this.fireEvent('metachange', this, this.reader.meta);
+    },
+    
+    moveIndex : function(data, type)
+    {
+        var index = this.indexOf(data);
+        
+        var newIndex = index + type;
+        
+        this.remove(data);
+        
+        this.insert(newIndex, data);
+        
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.data.SimpleStore
+ * @extends Roo.data.Store
+ * Small helper class to make creating Stores from Array data easier.
+ * @cfg {Number} id The array index of the record id. Leave blank to auto generate ids.
+ * @cfg {Array} fields An array of field definition objects, or field name strings.
+ * @cfg {Array} data The multi-dimensional array of data
+ * @constructor
+ * @param {Object} config
+ */
+Roo.data.SimpleStore = function(config){
+    Roo.data.SimpleStore.superclass.constructor.call(this, {
+        isLocal : true,
+        reader: new Roo.data.ArrayReader({
+                id: config.id
+            },
+            Roo.data.Record.create(config.fields)
+        ),
+        proxy : new Roo.data.MemoryProxy(config.data)
+    });
+    this.load();
+};
+Roo.extend(Roo.data.SimpleStore, Roo.data.Store);/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+/**
+ * @extends Roo.data.Store
+ * @class Roo.data.JsonStore
+ * Small helper class to make creating Stores for JSON data easier. <br/>
+<pre><code>
+var store = new Roo.data.JsonStore({
+    url: 'get-images.php',
+    root: 'images',
+    fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
+});
+</code></pre>
+ * <b>Note: Although they are not listed, this class inherits all of the config options of Store,
+ * JsonReader and HttpProxy (unless inline data is provided).</b>
+ * @cfg {Array} fields An array of field definition objects, or field name strings.
+ * @constructor
+ * @param {Object} config
+ */
+Roo.data.JsonStore = function(c){
+    Roo.data.JsonStore.superclass.constructor.call(this, Roo.apply(c, {
+        proxy: !c.data ? new Roo.data.HttpProxy({url: c.url}) : undefined,
+        reader: new Roo.data.JsonReader(c, c.fields)
+    }));
+};
+Roo.extend(Roo.data.JsonStore, Roo.data.Store);/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+Roo.data.Field = function(config){
+    if(typeof config == "string"){
+        config = {name: config};
+    }
+    Roo.apply(this, config);
+    
+    if(!this.type){
+        this.type = "auto";
+    }
+    
+    var st = Roo.data.SortTypes;
+    // named sortTypes are supported, here we look them up
+    if(typeof this.sortType == "string"){
+        this.sortType = st[this.sortType];
+    }
+    
+    // set default sortType for strings and dates
+    if(!this.sortType){
+        switch(this.type){
+            case "string":
+                this.sortType = st.asUCString;
+                break;
+            case "date":
+                this.sortType = st.asDate;
+                break;
+            default:
+                this.sortType = st.none;
+        }
+    }
+
+    // define once
+    var stripRe = /[\$,%]/g;
+
+    // prebuilt conversion function for this field, instead of
+    // switching every time we're reading a value
+    if(!this.convert){
+        var cv, dateFormat = this.dateFormat;
+        switch(this.type){
+            case "":
+            case "auto":
+            case undefined:
+                cv = function(v){ return v; };
+                break;
+            case "string":
+                cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
+                break;
+            case "int":
+                cv = function(v){
+                    return v !== undefined && v !== null && v !== '' ?
+                           parseInt(String(v).replace(stripRe, ""), 10) : '';
+                    };
+                break;
+            case "float":
+                cv = function(v){
+                    return v !== undefined && v !== null && v !== '' ?
+                           parseFloat(String(v).replace(stripRe, ""), 10) : ''; 
+                    };
+                break;
+            case "bool":
+            case "boolean":
+                cv = function(v){ return v === true || v === "true" || v == 1; };
+                break;
+            case "date":
+                cv = function(v){
+                    if(!v){
+                        return '';
+                    }
+                    if(v instanceof Date){
+                        return v;
+                    }
+                    if(dateFormat){
+                        if(dateFormat == "timestamp"){
+                            return new Date(v*1000);
+                        }
+                        return Date.parseDate(v, dateFormat);
+                    }
+                    var parsed = Date.parse(v);
+                    return parsed ? new Date(parsed) : null;
+                };
+             break;
+            
+        }
+        this.convert = cv;
+    }
+};
+
+Roo.data.Field.prototype = {
+    dateFormat: null,
+    defaultValue: "",
+    mapping: null,
+    sortType : null,
+    sortDir : "ASC"
+};/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+// Base class for reading structured data from a data source.  This class is intended to be
+// extended (see ArrayReader, JsonReader and XmlReader) and should not be created directly.
+
+/**
+ * @class Roo.data.DataReader
+ * Base class for reading structured data from a data source.  This class is intended to be
+ * extended (see {Roo.data.ArrayReader}, {Roo.data.JsonReader} and {Roo.data.XmlReader}) and should not be created directly.
+ */
+
+Roo.data.DataReader = function(meta, recordType){
+    
+    this.meta = meta;
+    
+    this.recordType = recordType instanceof Array ? 
+        Roo.data.Record.create(recordType) : recordType;
+};
+
+Roo.data.DataReader.prototype = {
+     /**
+     * Create an empty record
+     * @param {Object} data (optional) - overlay some values
+     * @return {Roo.data.Record} record created.
+     */
+    newRow :  function(d) {
+        var da =  {};
+        this.recordType.prototype.fields.each(function(c) {
+            switch( c.type) {
+                case 'int' : da[c.name] = 0; break;
+                case 'date' : da[c.name] = new Date(); break;
+                case 'float' : da[c.name] = 0.0; break;
+                case 'boolean' : da[c.name] = false; break;
+                default : da[c.name] = ""; break;
+            }
+            
+        });
+        return new this.recordType(Roo.apply(da, d));
+    }
+    
+};/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.data.DataProxy
+ * @extends Roo.data.Observable
+ * This class is an abstract base class for implementations which provide retrieval of
+ * unformatted data objects.<br>
+ * <p>
+ * DataProxy implementations are usually used in conjunction with an implementation of Roo.data.DataReader
+ * (of the appropriate type which knows how to parse the data object) to provide a block of
+ * {@link Roo.data.Records} to an {@link Roo.data.Store}.<br>
+ * <p>
+ * Custom implementations must implement the load method as described in
+ * {@link Roo.data.HttpProxy#load}.
+ */
+Roo.data.DataProxy = function(){
+    this.addEvents({
+        /**
+         * @event beforeload
+         * Fires before a network request is made to retrieve a data object.
+         * @param {Object} This DataProxy object.
+         * @param {Object} params The params parameter to the load function.
+         */
+        beforeload : true,
+        /**
+         * @event load
+         * Fires before the load method's callback is called.
+         * @param {Object} This DataProxy object.
+         * @param {Object} o The data object.
+         * @param {Object} arg The callback argument object passed to the load function.
+         */
+        load : true,
+        /**
+         * @event loadexception
+         * Fires if an Exception occurs during data retrieval.
+         * @param {Object} This DataProxy object.
+         * @param {Object} o The data object.
+         * @param {Object} arg The callback argument object passed to the load function.
+         * @param {Object} e The Exception.
+         */
+        loadexception : true
+    });
+    Roo.data.DataProxy.superclass.constructor.call(this);
+};
+
+Roo.extend(Roo.data.DataProxy, Roo.util.Observable);
+
+    /**
+     * @cfg {void} listeners (Not available) Constructor blocks listeners from being set
+     */
+/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.data.MemoryProxy
+ * An implementation of Roo.data.DataProxy that simply passes the data specified in its constructor
+ * to the Reader when its load method is called.
+ * @constructor
+ * @param {Object} data The data object which the Reader uses to construct a block of Roo.data.Records.
+ */
+Roo.data.MemoryProxy = function(data){
+    if (data.data) {
+        data = data.data;
+    }
+    Roo.data.MemoryProxy.superclass.constructor.call(this);
+    this.data = data;
+};
+
+Roo.extend(Roo.data.MemoryProxy, Roo.data.DataProxy, {
+    /**
+     * Load data from the requested source (in this case an in-memory
+     * data object passed to the constructor), read the data object into
+     * a block of Roo.data.Records using the passed Roo.data.DataReader implementation, and
+     * process that block using the passed callback.
+     * @param {Object} params This parameter is not used by the MemoryProxy class.
+     * @param {Roo.data.DataReader} reader The Reader object which converts the data
+     * object into a block of Roo.data.Records.
+     * @param {Function} callback The function into which to pass the block of Roo.data.records.
+     * The function must be passed <ul>
+     * <li>The Record block object</li>
+     * <li>The "arg" argument from the load function</li>
+     * <li>A boolean success indicator</li>
+     * </ul>
+     * @param {Object} scope The scope in which to call the callback
+     * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
+     */
+    load : function(params, reader, callback, scope, arg){
+        params = params || {};
+        var result;
+        try {
+            result = reader.readRecords(this.data);
+        }catch(e){
+            this.fireEvent("loadexception", this, arg, null, e);
+            callback.call(scope, null, arg, false);
+            return;
+        }
+        callback.call(scope, result, arg, true);
+    },
+    
+    // private
+    update : function(params, records){
+        
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.data.HttpProxy
+ * @extends Roo.data.DataProxy
+ * An implementation of {@link Roo.data.DataProxy} that reads a data object from an {@link Roo.data.Connection} object
+ * configured to reference a certain URL.<br><br>
+ * <p>
+ * <em>Note that this class cannot be used to retrieve data from a domain other than the domain
+ * from which the running page was served.<br><br>
+ * <p>
+ * For cross-domain access to remote data, use an {@link Roo.data.ScriptTagProxy}.</em><br><br>
+ * <p>
+ * Be aware that to enable the browser to parse an XML document, the server must set
+ * the Content-Type header in the HTTP response to "text/xml".
+ * @constructor
+ * @param {Object} conn Connection config options to add to each request (e.g. {url: 'foo.php'} or
+ * an {@link Roo.data.Connection} object.  If a Connection config is passed, the singleton {@link Roo.Ajax} object
+ * will be used to make the request.
+ */
+Roo.data.HttpProxy = function(conn){
+    Roo.data.HttpProxy.superclass.constructor.call(this);
+    // is conn a conn config or a real conn?
+    this.conn = conn;
+    this.useAjax = !conn || !conn.events;
+  
+};
+
+Roo.extend(Roo.data.HttpProxy, Roo.data.DataProxy, {
+    // thse are take from connection...
+    
+    /**
+     * @cfg {String} url (Optional) The default URL to be used for requests to the server. (defaults to undefined)
+     */
+    /**
+     * @cfg {Object} extraParams (Optional) An object containing properties which are used as
+     * extra parameters to each request made by this object. (defaults to undefined)
+     */
+    /**
+     * @cfg {Object} defaultHeaders (Optional) An object containing request headers which are added
+     *  to each request made by this object. (defaults to undefined)
+     */
+    /**
+     * @cfg {String} method (Optional) The default HTTP method to be used for requests. (defaults to undefined; if not set but parms are present will use POST, otherwise GET)
+     */
+    /**
+     * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000)
+     */
+     /**
+     * @cfg {Boolean} autoAbort (Optional) Whether this request should abort any pending requests. (defaults to false)
+     * @type Boolean
+     */
+  
+
+    /**
+     * @cfg {Boolean} disableCaching (Optional) True to add a unique cache-buster param to GET requests. (defaults to true)
+     * @type Boolean
+     */
+    /**
+     * Return the {@link Roo.data.Connection} object being used by this Proxy.
+     * @return {Connection} The Connection object. This object may be used to subscribe to events on
+     * a finer-grained basis than the DataProxy events.
+     */
+    getConnection : function(){
+        return this.useAjax ? Roo.Ajax : this.conn;
+    },
+
+    /**
+     * Load data from the configured {@link Roo.data.Connection}, read the data object into
+     * a block of Roo.data.Records using the passed {@link Roo.data.DataReader} implementation, and
+     * process that block using the passed callback.
+     * @param {Object} params An object containing properties which are to be used as HTTP parameters
+     * for the request to the remote server.
+     * @param {Roo.data.DataReader} reader The Reader object which converts the data
+     * object into a block of Roo.data.Records.
+     * @param {Function} callback The function into which to pass the block of Roo.data.Records.
+     * The function must be passed <ul>
+     * <li>The Record block object</li>
+     * <li>The "arg" argument from the load function</li>
+     * <li>A boolean success indicator</li>
+     * </ul>
+     * @param {Object} scope The scope in which to call the callback
+     * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
+     */
+    load : function(params, reader, callback, scope, arg){
+        if(this.fireEvent("beforeload", this, params) !== false){
+            var  o = {
+                params : params || {},
+                request: {
+                    callback : callback,
+                    scope : scope,
+                    arg : arg
+                },
+                reader: reader,
+                callback : this.loadResponse,
+                scope: this
+            };
+            if(this.useAjax){
+                Roo.applyIf(o, this.conn);
+                if(this.activeRequest){
+                    Roo.Ajax.abort(this.activeRequest);
+                }
+                this.activeRequest = Roo.Ajax.request(o);
+            }else{
+                this.conn.request(o);
+            }
+        }else{
+            callback.call(scope||this, null, arg, false);
+        }
+    },
+
+    // private
+    loadResponse : function(o, success, response){
+        delete this.activeRequest;
+        if(!success){
+            this.fireEvent("loadexception", this, o, response);
+            o.request.callback.call(o.request.scope, null, o.request.arg, false);
+            return;
+        }
+        var result;
+        try {
+            result = o.reader.read(response);
+        }catch(e){
+            this.fireEvent("loadexception", this, o, response, e);
+            o.request.callback.call(o.request.scope, null, o.request.arg, false);
+            return;
+        }
+        
+        this.fireEvent("load", this, o, o.request.arg);
+        o.request.callback.call(o.request.scope, result, o.request.arg, true);
+    },
+
+    // private
+    update : function(dataSet){
+
+    },
+
+    // private
+    updateResponse : function(dataSet){
+
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.data.ScriptTagProxy
+ * An implementation of Roo.data.DataProxy that reads a data object from a URL which may be in a domain
+ * other than the originating domain of the running page.<br><br>
+ * <p>
+ * <em>Note that if you are retrieving data from a page that is in a domain that is NOT the same as the originating domain
+ * of the running page, you must use this class, rather than DataProxy.</em><br><br>
+ * <p>
+ * The content passed back from a server resource requested by a ScriptTagProxy is executable JavaScript
+ * source code that is used as the source inside a &lt;script> tag.<br><br>
+ * <p>
+ * In order for the browser to process the returned data, the server must wrap the data object
+ * with a call to a callback function, the name of which is passed as a parameter by the ScriptTagProxy.
+ * Below is a Java example for a servlet which returns data for either a ScriptTagProxy, or an HttpProxy
+ * depending on whether the callback name was passed:
+ * <p>
+ * <pre><code>
+boolean scriptTag = false;
+String cb = request.getParameter("callback");
+if (cb != null) {
+    scriptTag = true;
+    response.setContentType("text/javascript");
+} else {
+    response.setContentType("application/x-json");
+}
+Writer out = response.getWriter();
+if (scriptTag) {
+    out.write(cb + "(");
+}
+out.print(dataBlock.toJsonString());
+if (scriptTag) {
+    out.write(");");
+}
+</pre></code>
+ *
+ * @constructor
+ * @param {Object} config A configuration object.
+ */
+Roo.data.ScriptTagProxy = function(config){
+    Roo.data.ScriptTagProxy.superclass.constructor.call(this);
+    Roo.apply(this, config);
+    this.head = document.getElementsByTagName("head")[0];
+};
+
+Roo.data.ScriptTagProxy.TRANS_ID = 1000;
+
+Roo.extend(Roo.data.ScriptTagProxy, Roo.data.DataProxy, {
+    /**
+     * @cfg {String} url The URL from which to request the data object.
+     */
+    /**
+     * @cfg {Number} timeout (Optional) The number of milliseconds to wait for a response. Defaults to 30 seconds.
+     */
+    timeout : 30000,
+    /**
+     * @cfg {String} callbackParam (Optional) The name of the parameter to pass to the server which tells
+     * the server the name of the callback function set up by the load call to process the returned data object.
+     * Defaults to "callback".<p>The server-side processing must read this parameter value, and generate
+     * javascript output which calls this named function passing the data object as its only parameter.
+     */
+    callbackParam : "callback",
+    /**
+     *  @cfg {Boolean} nocache (Optional) Defaults to true. Disable cacheing by adding a unique parameter
+     * name to the request.
+     */
+    nocache : true,
+
+    /**
+     * Load data from the configured URL, read the data object into
+     * a block of Roo.data.Records using the passed Roo.data.DataReader implementation, and
+     * process that block using the passed callback.
+     * @param {Object} params An object containing properties which are to be used as HTTP parameters
+     * for the request to the remote server.
+     * @param {Roo.data.DataReader} reader The Reader object which converts the data
+     * object into a block of Roo.data.Records.
+     * @param {Function} callback The function into which to pass the block of Roo.data.Records.
+     * The function must be passed <ul>
+     * <li>The Record block object</li>
+     * <li>The "arg" argument from the load function</li>
+     * <li>A boolean success indicator</li>
+     * </ul>
+     * @param {Object} scope The scope in which to call the callback
+     * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
+     */
+    load : function(params, reader, callback, scope, arg){
+        if(this.fireEvent("beforeload", this, params) !== false){
+
+            var p = Roo.urlEncode(Roo.apply(params, this.extraParams));
+
+            var url = this.url;
+            url += (url.indexOf("?") != -1 ? "&" : "?") + p;
+            if(this.nocache){
+                url += "&_dc=" + (new Date().getTime());
+            }
+            var transId = ++Roo.data.ScriptTagProxy.TRANS_ID;
+            var trans = {
+                id : transId,
+                cb : "stcCallback"+transId,
+                scriptId : "stcScript"+transId,
+                params : params,
+                arg : arg,
+                url : url,
+                callback : callback,
+                scope : scope,
+                reader : reader
+            };
+            var conn = this;
+
+            window[trans.cb] = function(o){
+                conn.handleResponse(o, trans);
+            };
+
+            url += String.format("&{0}={1}", this.callbackParam, trans.cb);
+
+            if(this.autoAbort !== false){
+                this.abort();
+            }
+
+            trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
+
+            var script = document.createElement("script");
+            script.setAttribute("src", url);
+            script.setAttribute("type", "text/javascript");
+            script.setAttribute("id", trans.scriptId);
+            this.head.appendChild(script);
+
+            this.trans = trans;
+        }else{
+            callback.call(scope||this, null, arg, false);
+        }
+    },
+
+    // private
+    isLoading : function(){
+        return this.trans ? true : false;
+    },
+
+    /**
+     * Abort the current server request.
+     */
+    abort : function(){
+        if(this.isLoading()){
+            this.destroyTrans(this.trans);
+        }
+    },
+
+    // private
+    destroyTrans : function(trans, isLoaded){
+        this.head.removeChild(document.getElementById(trans.scriptId));
+        clearTimeout(trans.timeoutId);
+        if(isLoaded){
+            window[trans.cb] = undefined;
+            try{
+                delete window[trans.cb];
+            }catch(e){}
+        }else{
+            // if hasn't been loaded, wait for load to remove it to prevent script error
+            window[trans.cb] = function(){
+                window[trans.cb] = undefined;
+                try{
+                    delete window[trans.cb];
+                }catch(e){}
+            };
+        }
+    },
+
+    // private
+    handleResponse : function(o, trans){
+        this.trans = false;
+        this.destroyTrans(trans, true);
+        var result;
+        try {
+            result = trans.reader.readRecords(o);
+        }catch(e){
+            this.fireEvent("loadexception", this, o, trans.arg, e);
+            trans.callback.call(trans.scope||window, null, trans.arg, false);
+            return;
+        }
+        this.fireEvent("load", this, o, trans.arg);
+        trans.callback.call(trans.scope||window, result, trans.arg, true);
+    },
+
+    // private
+    handleFailure : function(trans){
+        this.trans = false;
+        this.destroyTrans(trans, false);
+        this.fireEvent("loadexception", this, null, trans.arg);
+        trans.callback.call(trans.scope||window, null, trans.arg, false);
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.data.JsonReader
+ * @extends Roo.data.DataReader
+ * Data reader class to create an Array of Roo.data.Record objects from a JSON response
+ * based on mappings in a provided Roo.data.Record constructor.
+ * 
+ * The default behaviour of a store is to send ?_requestMeta=1, unless the class has recieved 'metaData' property
+ * in the reply previously. 
+ * 
+ * <p>
+ * Example code:
+ * <pre><code>
+var RecordDef = Roo.data.Record.create([
+    {name: 'name', mapping: 'name'},     // "mapping" property not needed if it's the same as "name"
+    {name: 'occupation'}                 // This field will use "occupation" as the mapping.
+]);
+var myReader = new Roo.data.JsonReader({
+    totalProperty: "results",    // The property which contains the total dataset size (optional)
+    root: "rows",                // The property which contains an Array of row objects
+    id: "id"                     // The property within each row object that provides an ID for the record (optional)
+}, RecordDef);
+</code></pre>
+ * <p>
+ * This would consume a JSON file like this:
+ * <pre><code>
+{ 'results': 2, 'rows': [
+    { 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
+    { 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' } ]
+}
+</code></pre>
+ * @cfg {String} totalProperty Name of the property from which to retrieve the total number of records
+ * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
+ * paged from the remote server.
+ * @cfg {String} successProperty Name of the property from which to retrieve the success attribute used by forms.
+ * @cfg {String} root name of the property which contains the Array of row objects.
+ * @cfg {String} id Name of the property within a row object that contains a record identifier value.
+ * @constructor
+ * Create a new JsonReader
+ * @param {Object} meta Metadata configuration options
+ * @param {Object} recordType Either an Array of field definition objects,
+ * or an {@link Roo.data.Record} object created using {@link Roo.data.Record#create}.
+ */
+Roo.data.JsonReader = function(meta, recordType){
+    
+    meta = meta || {};
+    // set some defaults:
+    Roo.applyIf(meta, {
+        totalProperty: 'total',
+        successProperty : 'success',
+        root : 'data',
+        id : 'id'
+    });
+    
+    Roo.data.JsonReader.superclass.constructor.call(this, meta, recordType||meta.fields);
+};
+Roo.extend(Roo.data.JsonReader, Roo.data.DataReader, {
+    
+    /**
+     * @prop {Boolean} metaFromRemote  - if the meta data was loaded from the remote source.
+     * Used by Store query builder to append _requestMeta to params.
+     * 
+     */
+    metaFromRemote : false,
+    /**
+     * This method is only used by a DataProxy which has retrieved data from a remote server.
+     * @param {Object} response The XHR object which contains the JSON data in its responseText.
+     * @return {Object} data A data block which is used by an Roo.data.Store object as
+     * a cache of Roo.data.Records.
+     */
+    read : function(response){
+        var json = response.responseText;
+       
+        var o = /* eval:var:o */ eval("("+json+")");
+        if(!o) {
+            throw {message: "JsonReader.read: Json object not found"};
+        }
+        
+        if(o.metaData){
+            
+            delete this.ef;
+            this.metaFromRemote = true;
+            this.meta = o.metaData;
+            this.recordType = Roo.data.Record.create(o.metaData.fields);
+            this.onMetaChange(this.meta, this.recordType, o);
+        }
+        return this.readRecords(o);
+    },
+
+    // private function a store will implement
+    onMetaChange : function(meta, recordType, o){
+
+    },
+
+    /**
+        * @ignore
+        */
+    simpleAccess: function(obj, subsc) {
+       return obj[subsc];
+    },
+
+       /**
+        * @ignore
+        */
+    getJsonAccessor: function(){
+        var re = /[\[\.]/;
+        return function(expr) {
+            try {
+                return(re.test(expr))
+                    ? new Function("obj", "return obj." + expr)
+                    : function(obj){
+                        return obj[expr];
+                    };
+            } catch(e){}
+            return Roo.emptyFn;
+        };
+    }(),
+
+    /**
+     * Create a data block containing Roo.data.Records from an XML document.
+     * @param {Object} o An object which contains an Array of row objects in the property specified
+     * in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
+     * which contains the total size of the dataset.
+     * @return {Object} data A data block which is used by an Roo.data.Store object as
+     * a cache of Roo.data.Records.
+     */
+    readRecords : function(o){
+        /**
+         * After any data loads, the raw JSON data is available for further custom processing.
+         * @type Object
+         */
+        this.o = o;
+        var s = this.meta, Record = this.recordType,
+            f = Record ? Record.prototype.fields : null, fi = f ? f.items : [], fl = f ? f.length : 0;
+
+//      Generate extraction functions for the totalProperty, the root, the id, and for each field
+        if (!this.ef) {
+            if(s.totalProperty) {
+                   this.getTotal = this.getJsonAccessor(s.totalProperty);
+               }
+               if(s.successProperty) {
+                   this.getSuccess = this.getJsonAccessor(s.successProperty);
+               }
+               this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
+               if (s.id) {
+                       var g = this.getJsonAccessor(s.id);
+                       this.getId = function(rec) {
+                               var r = g(rec);  
+                               return (r === undefined || r === "") ? null : r;
+                       };
+               } else {
+                       this.getId = function(){return null;};
+               }
+            this.ef = [];
+            for(var jj = 0; jj < fl; jj++){
+                f = fi[jj];
+                var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
+                this.ef[jj] = this.getJsonAccessor(map);
+            }
+        }
+
+       var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
+       if(s.totalProperty){
+            var vt = parseInt(this.getTotal(o), 10);
+            if(!isNaN(vt)){
+                totalRecords = vt;
+            }
+        }
+        if(s.successProperty){
+            var vs = this.getSuccess(o);
+            if(vs === false || vs === 'false'){
+                success = false;
+            }
+        }
+        var records = [];
+        for(var i = 0; i < c; i++){
+                var n = root[i];
+            var values = {};
+            var id = this.getId(n);
+            for(var j = 0; j < fl; j++){
+                f = fi[j];
+            var v = this.ef[j](n);
+            if (!f.convert) {
+                Roo.log('missing convert for ' + f.name);
+                Roo.log(f);
+                continue;
+            }
+            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
+            }
+            var record = new Record(values, id);
+            record.json = n;
+            records[i] = record;
+        }
+        return {
+            raw : o,
+            success : success,
+            records : records,
+            totalRecords : totalRecords
+        };
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.data.ArrayReader
+ * @extends Roo.data.DataReader
+ * Data reader class to create an Array of Roo.data.Record objects from an Array.
+ * Each element of that Array represents a row of data fields. The
+ * fields are pulled into a Record object using as a subscript, the <em>mapping</em> property
+ * of the field definition if it exists, or the field's ordinal position in the definition.<br>
+ * <p>
+ * Example code:.
+ * <pre><code>
+var RecordDef = Roo.data.Record.create([
+    {name: 'name', mapping: 1},         // "mapping" only needed if an "id" field is present which
+    {name: 'occupation', mapping: 2}    // precludes using the ordinal position as the index.
+]);
+var myReader = new Roo.data.ArrayReader({
+    id: 0                     // The subscript within row Array that provides an ID for the Record (optional)
+}, RecordDef);
+</code></pre>
+ * <p>
+ * This would consume an Array like this:
+ * <pre><code>
+[ [1, 'Bill', 'Gardener'], [2, 'Ben', 'Horticulturalist'] ]
+  </code></pre>
+ * @cfg {String} id (optional) The subscript within row Array that provides an ID for the Record
+ * @constructor
+ * Create a new JsonReader
+ * @param {Object} meta Metadata configuration options.
+ * @param {Object} recordType Either an Array of field definition objects
+ * as specified to {@link Roo.data.Record#create},
+ * or an {@link Roo.data.Record} object
+ * created using {@link Roo.data.Record#create}.
+ */
+Roo.data.ArrayReader = function(meta, recordType){
+    Roo.data.ArrayReader.superclass.constructor.call(this, meta, recordType);
+};
+
+Roo.extend(Roo.data.ArrayReader, Roo.data.JsonReader, {
+    /**
+     * Create a data block containing Roo.data.Records from an XML document.
+     * @param {Object} o An Array of row objects which represents the dataset.
+     * @return {Object} data A data block which is used by an Roo.data.Store object as
+     * a cache of Roo.data.Records.
+     */
+    readRecords : function(o){
+        var sid = this.meta ? this.meta.id : null;
+       var recordType = this.recordType, fields = recordType.prototype.fields;
+       var records = [];
+       var root = o;
+           for(var i = 0; i < root.length; i++){
+                   var n = root[i];
+               var values = {};
+               var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
+               for(var j = 0, jlen = fields.length; j < jlen; j++){
+                var f = fields.items[j];
+                var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
+                var v = n[k] !== undefined ? n[k] : f.defaultValue;
+                v = f.convert(v);
+                values[f.name] = v;
+            }
+               var record = new recordType(values, id);
+               record.json = n;
+               records[records.length] = record;
+           }
+           return {
+               records : records,
+               totalRecords : records.length
+           };
+    }
+});/*
+ * - LGPL
+ * * 
+ */
+
+/**
+ * @class Roo.bootstrap.ComboBox
+ * @extends Roo.bootstrap.TriggerField
+ * A combobox control with support for autocomplete, remote-loading, paging and many other features.
+ * @cfg {Boolean} append (true|false) default false
+ * @cfg {Boolean} autoFocus (true|false) auto focus the first item, default true
+ * @cfg {Boolean} tickable ComboBox with tickable selections (true|false), default false
+ * @cfg {Boolean} triggerList trigger show the list or not (true|false) default true
+ * @cfg {Boolean} showToggleBtn show toggle button or not (true|false) default true
+ * @cfg {String} btnPosition set the position of the trigger button (left | right) default right
+ * @constructor
+ * Create a new ComboBox.
+ * @param {Object} config Configuration options
+ */
+Roo.bootstrap.ComboBox = function(config){
+    Roo.bootstrap.ComboBox.superclass.constructor.call(this, config);
+    this.addEvents({
+        /**
+         * @event expand
+         * Fires when the dropdown list is expanded
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            */
+        'expand' : true,
+        /**
+         * @event collapse
+         * Fires when the dropdown list is collapsed
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            */
+        'collapse' : true,
+        /**
+         * @event beforeselect
+         * Fires before a list item is selected. Return false to cancel the selection.
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            * @param {Roo.data.Record} record The data record returned from the underlying store
+            * @param {Number} index The index of the selected item in the dropdown list
+            */
+        'beforeselect' : true,
+        /**
+         * @event select
+         * Fires when a list item is selected
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            * @param {Roo.data.Record} record The data record returned from the underlying store (or false on clear)
+            * @param {Number} index The index of the selected item in the dropdown list
+            */
+        'select' : true,
+        /**
+         * @event beforequery
+         * Fires before all queries are processed. Return false to cancel the query or set cancel to true.
+         * The event object passed has these properties:
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            * @param {String} query The query
+            * @param {Boolean} forceAll true to force "all" query
+            * @param {Boolean} cancel true to cancel the query
+            * @param {Object} e The query event object
+            */
+        'beforequery': true,
+         /**
+         * @event add
+         * Fires when the 'add' icon is pressed (add a listener to enable add button)
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            */
+        'add' : true,
+        /**
+         * @event edit
+         * Fires when the 'edit' icon is pressed (add a listener to enable add button)
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            * @param {Roo.data.Record|false} record The data record returned from the underlying store (or false on nothing selected)
+            */
+        'edit' : true,
+        /**
+         * @event remove
+         * Fires when the remove value from the combobox array
+            * @param {Roo.bootstrap.ComboBox} combo This combo box
+            */
+        'remove' : true
+        
+    });
+    
+    this.item = [];
+    this.tickItems = [];
+    
+    this.selectedIndex = -1;
+    if(this.mode == 'local'){
+        if(config.queryDelay === undefined){
+            this.queryDelay = 10;
+        }
+        if(config.minChars === undefined){
+            this.minChars = 0;
+        }
+    }
+};
+
+Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
+     
+    /**
+     * @cfg {Boolean} lazyRender True to prevent the ComboBox from rendering until requested (should always be used when
+     * rendering into an Roo.Editor, defaults to false)
+     */
+    /**
+     * @cfg {Boolean/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to:
+     * {tag: "input", type: "text", size: "24", autocomplete: "off"})
+     */
+    /**
+     * @cfg {Roo.data.Store} store The data store to which this combo is bound (defaults to undefined)
+     */
+    /**
+     * @cfg {String} title If supplied, a header element is created containing this text and added into the top of
+     * the dropdown list (defaults to undefined, with no header element)
+     */
+
+     /**
+     * @cfg {String/Roo.Template} tpl The template to use to render the output
+     */
+     
+     /**
+     * @cfg {Number} listWidth The width in pixels of the dropdown list (defaults to the width of the ComboBox field)
+     */
+    listWidth: undefined,
+    /**
+     * @cfg {String} displayField The underlying data field name to bind to this CombBox (defaults to undefined if
+     * mode = 'remote' or 'text' if mode = 'local')
+     */
+    displayField: undefined,
+    /**
+     * @cfg {String} valueField The underlying data value name to bind to this CombBox (defaults to undefined if
+     * mode = 'remote' or 'value' if mode = 'local'). 
+     * Note: use of a valueField requires the user make a selection
+     * in order for a value to be mapped.
+     */
+    valueField: undefined,
+    
+    
+    /**
+     * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the
+     * field's data value (defaults to the underlying DOM element's name)
+     */
+    hiddenName: undefined,
+    /**
+     * @cfg {String} listClass CSS class to apply to the dropdown list element (defaults to '')
+     */
+    listClass: '',
+    /**
+     * @cfg {String} selectedClass CSS class to apply to the selected item in the dropdown list (defaults to 'x-combo-selected')
+     */
+    selectedClass: 'active',
+    
+    /**
+     * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop" for bottom-right
+     */
+    shadow:'sides',
+    /**
+     * @cfg {String} listAlign A valid anchor position value. See {@link Roo.Element#alignTo} for details on supported
+     * anchor positions (defaults to 'tl-bl')
+     */
+    listAlign: 'tl-bl?',
+    /**
+     * @cfg {Number} maxHeight The maximum height in pixels of the dropdown list before scrollbars are shown (defaults to 300)
+     */
+    maxHeight: 300,
+    /**
+     * @cfg {String} triggerAction The action to execute when the trigger field is activated.  Use 'all' to run the
+     * query specified by the allQuery config option (defaults to 'query')
+     */
+    triggerAction: 'query',
+    /**
+     * @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and typeahead activate
+     * (defaults to 4, does not apply if editable = false)
+     */
+    minChars : 4,
+    /**
+     * @cfg {Boolean} typeAhead True to populate and autoselect the remainder of the text being typed after a configurable
+     * delay (typeAheadDelay) if it matches a known value (defaults to false)
+     */
+    typeAhead: false,
+    /**
+     * @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and sending the
+     * query to filter the dropdown list (defaults to 500 if mode = 'remote' or 10 if mode = 'local')
+     */
+    queryDelay: 500,
+    /**
+     * @cfg {Number} pageSize If greater than 0, a paging toolbar is displayed in the footer of the dropdown list and the
+     * filter queries will execute with page start and limit parameters.  Only applies when mode = 'remote' (defaults to 0)
+     */
+    pageSize: 0,
+    /**
+     * @cfg {Boolean} selectOnFocus True to select any existing text in the field immediately on focus.  Only applies
+     * when editable = true (defaults to false)
+     */
+    selectOnFocus:false,
+    /**
+     * @cfg {String} queryParam Name of the query as it will be passed on the querystring (defaults to 'query')
+     */
+    queryParam: 'query',
+    /**
+     * @cfg {String} loadingText The text to display in the dropdown list while data is loading.  Only applies
+     * when mode = 'remote' (defaults to 'Loading...')
+     */
+    loadingText: 'Loading...',
+    /**
+     * @cfg {Boolean} resizable True to add a resize handle to the bottom of the dropdown list (defaults to false)
+     */
+    resizable: false,
+    /**
+     * @cfg {Number} handleHeight The height in pixels of the dropdown list resize handle if resizable = true (defaults to 8)
+     */
+    handleHeight : 8,
+    /**
+     * @cfg {Boolean} editable False to prevent the user from typing text directly into the field, just like a
+     * traditional select (defaults to true)
+     */
+    editable: true,
+    /**
+     * @cfg {String} allQuery The text query to send to the server to return all records for the list with no filtering (defaults to '')
+     */
+    allQuery: '',
+    /**
+     * @cfg {String} mode Set to 'local' if the ComboBox loads local data (defaults to 'remote' which loads from the server)
+     */
+    mode: 'remote',
+    /**
+     * @cfg {Number} minListWidth The minimum width of the dropdown list in pixels (defaults to 70, will be ignored if
+     * listWidth has a higher value)
+     */
+    minListWidth : 70,
+    /**
+     * @cfg {Boolean} forceSelection True to restrict the selected value to one of the values in the list, false to
+     * allow the user to set arbitrary text into the field (defaults to false)
+     */
+    forceSelection:false,
+    /**
+     * @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
+     * if typeAhead = true (defaults to 250)
+     */
+    typeAheadDelay : 250,
+    /**
+     * @cfg {String} valueNotFoundText When using a name/value combo, if the value passed to setValue is not found in
+     * the store, valueNotFoundText will be displayed as the field text if defined (defaults to undefined)
+     */
+    valueNotFoundText : undefined,
+    /**
+     * @cfg {Boolean} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
+     */
+    blockFocus : false,
+    
+    /**
+     * @cfg {Boolean} disableClear Disable showing of clear button.
+     */
+    disableClear : false,
+    /**
+     * @cfg {Boolean} alwaysQuery  Disable caching of results, and always send query
+     */
+    alwaysQuery : false,
+    
+    /**
+     * @cfg {Boolean} multiple  (true|false) ComboBobArray, default false
+     */
+    multiple : false,
+    
+    //private
+    addicon : false,
+    editicon: false,
+    
+    page: 0,
+    hasQuery: false,
+    append: false,
+    loadNext: false,
+    autoFocus : true,
+    tickable : false,
+    btnPosition : 'right',
+    triggerList : true,
+    showToggleBtn : true,
+    // element that contains real text value.. (when hidden is used..)
+    
+    getAutoCreate : function()
+    {
+        var cfg = false;
+        
+        /*
+         *  Normal ComboBox
+         */
+        if(!this.tickable){
+            cfg = Roo.bootstrap.ComboBox.superclass.getAutoCreate.call(this);
+            return cfg;
+        }
+        
+        /*
+         *  ComboBox with tickable selections
+         */
+             
+        var align = this.labelAlign || this.parentLabelAlign();
+        
+        cfg = {
+            cls : 'form-group roo-combobox-tickable' //input-group
+        };
+        
+        
+        var buttons = {
+            tag : 'div',
+            cls : 'tickable-buttons',
+            cn : [
+                {
+                    tag : 'button',
+                    type : 'button',
+                    cls : 'btn btn-link btn-edit pull-' + this.btnPosition,
+                    html : 'Edit'
+                },
+                {
+                    tag : 'button',
+                    type : 'button',
+                    name : 'ok',
+                    cls : 'btn btn-link btn-ok pull-' + this.btnPosition,
+                    html : 'Done'
+                },
+                {
+                    tag : 'button',
+                    type : 'button',
+                    name : 'cancel',
+                    cls : 'btn btn-link btn-cancel pull-' + this.btnPosition,
+                    html : 'Cancel'
+                }
+            ]
+        };
+        
+        var _this = this;
+        Roo.each(buttons.cn, function(c){
+            if (_this.size) {
+                c.cls += ' btn-' + _this.size;
+            }
+
+            if (_this.disabled) {
+                c.disabled = true;
+            }
+        });
+        
+        var box = {
+            tag: 'div',
+            cn: [
+                {
+                    tag: 'input',
+                    type : 'hidden',
+                    cls: 'form-hidden-field'
+                },
+                {
+                    tag: 'ul',
+                    cls: 'select2-choices',
+                    cn:[
+                        {
+                            tag: 'li',
+                            cls: 'select2-search-field',
+                            cn: [
+
+                                buttons
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+        
+        var combobox = {
+            cls: 'select2-container input-group select2-container-multi',
+            cn: [
+                box
+//                {
+//                    tag: 'ul',
+//                    cls: 'typeahead typeahead-long dropdown-menu',
+//                    style: 'display:none; max-height:' + this.maxHeight + 'px;'
+//                }
+            ]
+        };
+        
+        if (align ==='left' && this.fieldLabel.length) {
+            
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label col-sm-' + this.labelWidth,
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-sm-" + (12 - this.labelWidth), 
+                        cn: [
+                            combobox
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                 cfg.cn = [
+                   
+                    {
+                        tag: 'label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    combobox
+                    
+                ];
+
+        } else {
+            
+                Roo.log(" no label && no align");
+                cfg = combobox
+                     
+                
+        }
+         
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        return cfg;
+        
+    },
+    
+    // private
+    initEvents: function()
+    {
+        
+        if (!this.store) {
+            throw "can not find store for combo";
+        }
+        this.store = Roo.factory(this.store, Roo.data);
+        
+        if(this.tickable){
+            this.initTickableEvents();
+            return;
+        }
+        
+        Roo.bootstrap.ComboBox.superclass.initEvents.call(this);
+        
+        if(this.hiddenName){
+            
+            this.hiddenField = this.el.select('input.form-hidden-field',true).first();
+            
+            this.hiddenField.dom.value =
+                this.hiddenValue !== undefined ? this.hiddenValue :
+                this.value !== undefined ? this.value : '';
+
+            // prevent input submission
+            this.el.dom.removeAttribute('name');
+            this.hiddenField.dom.setAttribute('name', this.hiddenName);
+             
+             
+        }
+        //if(Roo.isGecko){
+        //    this.el.dom.setAttribute('autocomplete', 'off');
+        //}
+        
+        var cls = 'x-combo-list';
+        
+        //this.list = new Roo.Layer({
+        //    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
+        //});
+        
+        var _this = this;
+        
+        (function(){
+            var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
+            _this.list.setWidth(lw);
+        }).defer(100);
+        
+        this.list.on('mouseover', this.onViewOver, this);
+        this.list.on('mousemove', this.onViewMove, this);
+        
+        this.list.on('scroll', this.onViewScroll, this);
+        
+        /*
+        this.list.swallowEvent('mousewheel');
+        this.assetHeight = 0;
+
+        if(this.title){
+            this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
+            this.assetHeight += this.header.getHeight();
+        }
+
+        this.innerList = this.list.createChild({cls:cls+'-inner'});
+        this.innerList.on('mouseover', this.onViewOver, this);
+        this.innerList.on('mousemove', this.onViewMove, this);
+        this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
+        
+        if(this.allowBlank && !this.pageSize && !this.disableClear){
+            this.footer = this.list.createChild({cls:cls+'-ft'});
+            this.pageTb = new Roo.Toolbar(this.footer);
+           
+        }
+        if(this.pageSize){
+            this.footer = this.list.createChild({cls:cls+'-ft'});
+            this.pageTb = new Roo.PagingToolbar(this.footer, this.store,
+                    {pageSize: this.pageSize});
+            
+        }
+        
+        if (this.pageTb && this.allowBlank && !this.disableClear) {
+            var _this = this;
+            this.pageTb.add(new Roo.Toolbar.Fill(), {
+                cls: 'x-btn-icon x-btn-clear',
+                text: '&#160;',
+                handler: function()
+                {
+                    _this.collapse();
+                    _this.clearValue();
+                    _this.onSelect(false, -1);
+                }
+            });
+        }
+        if (this.footer) {
+            this.assetHeight += this.footer.getHeight();
+        }
+        */
+            
+        if(!this.tpl){
+            this.tpl = '<li><a href="#">{' + this.displayField + '}</a></li>';
+        }
+
+        this.view = new Roo.View(this.list, this.tpl, {
+            singleSelect:true, store: this.store, selectedClass: this.selectedClass
+        });
+        //this.view.wrapEl.setDisplayed(false);
+        this.view.on('click', this.onViewClick, this);
+        
+        
+        
+        this.store.on('beforeload', this.onBeforeLoad, this);
+        this.store.on('load', this.onLoad, this);
+        this.store.on('loadexception', this.onLoadException, this);
+        /*
+        if(this.resizable){
+            this.resizer = new Roo.Resizable(this.list,  {
+               pinned:true, handles:'se'
+            });
+            this.resizer.on('resize', function(r, w, h){
+                this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
+                this.listWidth = w;
+                this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
+                this.restrictHeight();
+            }, this);
+            this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
+        }
+        */
+        if(!this.editable){
+            this.editable = true;
+            this.setEditable(false);
+        }
+        
+        /*
+        
+        if (typeof(this.events.add.listeners) != 'undefined') {
+            
+            this.addicon = this.wrap.createChild(
+                {tag: 'img', src: Roo.BLANK_IMAGE_URL, cls: 'x-form-combo-add' });  
+       
+            this.addicon.on('click', function(e) {
+                this.fireEvent('add', this);
+            }, this);
+        }
+        if (typeof(this.events.edit.listeners) != 'undefined') {
+            
+            this.editicon = this.wrap.createChild(
+                {tag: 'img', src: Roo.BLANK_IMAGE_URL, cls: 'x-form-combo-edit' });  
+            if (this.addicon) {
+                this.editicon.setStyle('margin-left', '40px');
+            }
+            this.editicon.on('click', function(e) {
+                
+                // we fire even  if inothing is selected..
+                this.fireEvent('edit', this, this.lastData );
+                
+            }, this);
+        }
+        */
+        
+        this.keyNav = new Roo.KeyNav(this.inputEl(), {
+            "up" : function(e){
+                this.inKeyMode = true;
+                this.selectPrev();
+            },
+
+            "down" : function(e){
+                if(!this.isExpanded()){
+                    this.onTriggerClick();
+                }else{
+                    this.inKeyMode = true;
+                    this.selectNext();
+                }
+            },
+
+            "enter" : function(e){
+//                this.onViewClick();
+                //return true;
+                this.collapse();
+                
+                if(this.fireEvent("specialkey", this, e)){
+                    this.onViewClick(false);
+                }
+                
+                return true;
+            },
+
+            "esc" : function(e){
+                this.collapse();
+            },
+
+            "tab" : function(e){
+                this.collapse();
+                
+                if(this.fireEvent("specialkey", this, e)){
+                    this.onViewClick(false);
+                }
+                
+                return true;
+            },
+
+            scope : this,
+
+            doRelay : function(foo, bar, hname){
+                if(hname == 'down' || this.scope.isExpanded()){
+                   return Roo.KeyNav.prototype.doRelay.apply(this, arguments);
+                }
+                return true;
+            },
+
+            forceKeyDown: true
+        });
+        
+        
+        this.queryDelay = Math.max(this.queryDelay || 10,
+                this.mode == 'local' ? 10 : 250);
+        
+        
+        this.dqTask = new Roo.util.DelayedTask(this.initQuery, this);
+        
+        if(this.typeAhead){
+            this.taTask = new Roo.util.DelayedTask(this.onTypeAhead, this);
+        }
+        if(this.editable !== false){
+            this.inputEl().on("keyup", this.onKeyUp, this);
+        }
+        if(this.forceSelection){
+            this.inputEl().on('blur', this.doForce, this);
+        }
+        
+        if(this.multiple){
+            this.choices = this.el.select('ul.select2-choices', true).first();
+            this.searchField = this.el.select('ul li.select2-search-field', true).first();
+        }
+    },
+    
+    initTickableEvents: function()
+    {   
+        this.createList();
+        
+        if(this.hiddenName){
+            
+            this.hiddenField = this.el.select('input.form-hidden-field',true).first();
+            
+            this.hiddenField.dom.value =
+                this.hiddenValue !== undefined ? this.hiddenValue :
+                this.value !== undefined ? this.value : '';
+
+            // prevent input submission
+            this.el.dom.removeAttribute('name');
+            this.hiddenField.dom.setAttribute('name', this.hiddenName);
+             
+             
+        }
+        
+//        this.list = this.el.select('ul.dropdown-menu',true).first();
+        
+        this.choices = this.el.select('ul.select2-choices', true).first();
+        this.searchField = this.el.select('ul li.select2-search-field', true).first();
+        if(this.triggerList){
+            this.searchField.on("click", this.onSearchFieldClick, this, {preventDefault:true});
+        }
+         
+        this.trigger = this.el.select('.tickable-buttons > .btn-edit', true).first();
+        this.trigger.on("click", this.onTickableTriggerClick, this, {preventDefault:true});
+        
+        this.okBtn = this.el.select('.tickable-buttons > .btn-ok', true).first();
+        this.cancelBtn = this.el.select('.tickable-buttons > .btn-cancel', true).first();
+        
+        this.okBtn.on('click', this.onTickableFooterButtonClick, this, this.okBtn);
+        this.cancelBtn.on('click', this.onTickableFooterButtonClick, this, this.cancelBtn);
+        
+        this.trigger.setVisibilityMode(Roo.Element.DISPLAY);
+        this.okBtn.setVisibilityMode(Roo.Element.DISPLAY);
+        this.cancelBtn.setVisibilityMode(Roo.Element.DISPLAY);
+        
+        this.okBtn.hide();
+        this.cancelBtn.hide();
+        
+        var _this = this;
+        
+        (function(){
+            var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
+            _this.list.setWidth(lw);
+        }).defer(100);
+        
+        this.list.on('mouseover', this.onViewOver, this);
+        this.list.on('mousemove', this.onViewMove, this);
+        
+        this.list.on('scroll', this.onViewScroll, this);
+        
+        if(!this.tpl){
+            this.tpl = '<li class="select2-result"><div class="checkbox"><input id="{roo-id}" type="checkbox" {roo-data-checked}><label for="{roo-id}"><b>{' + this.displayField + '}</b></label></li>';
+        }
+
+        this.view = new Roo.View(this.list, this.tpl, {
+            singleSelect:true, tickable:true, parent:this, store: this.store, selectedClass: this.selectedClass
+        });
+        
+        //this.view.wrapEl.setDisplayed(false);
+        this.view.on('click', this.onViewClick, this);
+        
+        
+        
+        this.store.on('beforeload', this.onBeforeLoad, this);
+        this.store.on('load', this.onLoad, this);
+        this.store.on('loadexception', this.onLoadException, this);
+        
+//        this.keyNav = new Roo.KeyNav(this.inputEl(), {
+//            "up" : function(e){
+//                this.inKeyMode = true;
+//                this.selectPrev();
+//            },
+//
+//            "down" : function(e){
+//                if(!this.isExpanded()){
+//                    this.onTriggerClick();
+//                }else{
+//                    this.inKeyMode = true;
+//                    this.selectNext();
+//                }
+//            },
+//
+//            "enter" : function(e){
+////                this.onViewClick();
+//                //return true;
+//                this.collapse();
+//                
+//                if(this.fireEvent("specialkey", this, e)){
+//                    this.onViewClick(false);
+//                }
+//                
+//                return true;
+//            },
+//
+//            "esc" : function(e){
+//                this.collapse();
+//            },
+//
+//            "tab" : function(e){
+//                this.collapse();
+//                
+//                if(this.fireEvent("specialkey", this, e)){
+//                    this.onViewClick(false);
+//                }
+//                
+//                return true;
+//            },
+//
+//            scope : this,
+//
+//            doRelay : function(foo, bar, hname){
+//                if(hname == 'down' || this.scope.isExpanded()){
+//                   return Roo.KeyNav.prototype.doRelay.apply(this, arguments);
+//                }
+//                return true;
+//            },
+//
+//            forceKeyDown: true
+//        });
+        
+        
+        this.queryDelay = Math.max(this.queryDelay || 10,
+                this.mode == 'local' ? 10 : 250);
+        
+        
+        this.dqTask = new Roo.util.DelayedTask(this.initQuery, this);
+        
+        if(this.typeAhead){
+            this.taTask = new Roo.util.DelayedTask(this.onTypeAhead, this);
+        }
+        
+    },
+
+    onDestroy : function(){
+        if(this.view){
+            this.view.setStore(null);
+            this.view.el.removeAllListeners();
+            this.view.el.remove();
+            this.view.purgeListeners();
+        }
+        if(this.list){
+            this.list.dom.innerHTML  = '';
+        }
+        
+        if(this.store){
+            this.store.un('beforeload', this.onBeforeLoad, this);
+            this.store.un('load', this.onLoad, this);
+            this.store.un('loadexception', this.onLoadException, this);
+        }
+        Roo.bootstrap.ComboBox.superclass.onDestroy.call(this);
+    },
+
+    // private
+    fireKey : function(e){
+        if(e.isNavKeyPress() && !this.list.isVisible()){
+            this.fireEvent("specialkey", this, e);
+        }
+    },
+
+    // private
+    onResize: function(w, h){
+//        Roo.bootstrap.ComboBox.superclass.onResize.apply(this, arguments);
+//        
+//        if(typeof w != 'number'){
+//            // we do not handle it!?!?
+//            return;
+//        }
+//        var tw = this.trigger.getWidth();
+//       // tw += this.addicon ? this.addicon.getWidth() : 0;
+//       // tw += this.editicon ? this.editicon.getWidth() : 0;
+//        var x = w - tw;
+//        this.inputEl().setWidth( this.adjustWidth('input', x));
+//            
+//        //this.trigger.setStyle('left', x+'px');
+//        
+//        if(this.list && this.listWidth === undefined){
+//            var lw = Math.max(x + this.trigger.getWidth(), this.minListWidth);
+//            this.list.setWidth(lw);
+//            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
+//        }
+        
+    
+        
+    },
+
+    /**
+     * Allow or prevent the user from directly editing the field text.  If false is passed,
+     * the user will only be able to select from the items defined in the dropdown list.  This method
+     * is the runtime equivalent of setting the 'editable' config option at config time.
+     * @param {Boolean} value True to allow the user to directly edit the field text
+     */
+    setEditable : function(value){
+        if(value == this.editable){
+            return;
+        }
+        this.editable = value;
+        if(!value){
+            this.inputEl().dom.setAttribute('readOnly', true);
+            this.inputEl().on('mousedown', this.onTriggerClick,  this);
+            this.inputEl().addClass('x-combo-noedit');
+        }else{
+            this.inputEl().dom.setAttribute('readOnly', false);
+            this.inputEl().un('mousedown', this.onTriggerClick,  this);
+            this.inputEl().removeClass('x-combo-noedit');
+        }
+    },
+
+    // private
+    
+    onBeforeLoad : function(combo,opts){
+        if(!this.hasFocus){
+            return;
+        }
+         if (!opts.add) {
+            this.list.dom.innerHTML = '<li class="loading-indicator">'+(this.loadingText||'loading')+'</li>' ;
+         }
+        this.restrictHeight();
+        this.selectedIndex = -1;
+    },
+
+    // private
+    onLoad : function(){
+        
+        this.hasQuery = false;
+        
+        if(!this.hasFocus){
+            return;
+        }
+        
+        if(typeof(this.loading) !== 'undefined' && this.loading !== null){
+            this.loading.hide();
+        }
+        
+        if(this.store.getCount() > 0){
+            this.expand();
+//            this.restrictHeight();
+            if(this.lastQuery == this.allQuery){
+                if(this.editable && !this.tickable){
+                    this.inputEl().dom.select();
+                }
+                
+                if(
+                    !this.selectByValue(this.value, true) &&
+                    this.autoFocus && (typeof(this.store.lastOptions.add) == 'undefined' || 
+                    this.store.lastOptions.add != true)
+                ){
+                    this.select(0, true);
+                }
+            }else{
+                if(this.autoFocus){
+                    this.selectNext();
+                }
+                if(this.typeAhead && this.lastKey != Roo.EventObject.BACKSPACE && this.lastKey != Roo.EventObject.DELETE){
+                    this.taTask.delay(this.typeAheadDelay);
+                }
+            }
+        }else{
+            this.onEmptyResults();
+        }
+        
+        //this.el.focus();
+    },
+    // private
+    onLoadException : function()
+    {
+        this.hasQuery = false;
+        
+        if(typeof(this.loading) !== 'undefined' && this.loading !== null){
+            this.loading.hide();
+        }
+        
+        this.collapse();
+        Roo.log(this.store.reader.jsonData);
+        if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+            // fixme
+            //Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+        }
+        
+        
+    },
+    // private
+    onTypeAhead : function(){
+        if(this.store.getCount() > 0){
+            var r = this.store.getAt(0);
+            var newValue = r.data[this.displayField];
+            var len = newValue.length;
+            var selStart = this.getRawValue().length;
+            
+            if(selStart != len){
+                this.setRawValue(newValue);
+                this.selectText(selStart, newValue.length);
+            }
+        }
+    },
+
+    // private
+    onSelect : function(record, index){
+        
+        if(this.fireEvent('beforeselect', this, record, index) !== false){
+        
+            this.setFromData(index > -1 ? record.data : false);
+            
+            this.collapse();
+            this.fireEvent('select', this, record, index);
+        }
+    },
+
+    /**
+     * Returns the currently selected field value or empty string if no value is set.
+     * @return {String} value The selected value
+     */
+    getValue : function(){
+        
+        if(this.multiple){
+            return (this.hiddenField) ? this.hiddenField.dom.value : this.value;
+        }
+        
+        if(this.valueField){
+            return typeof this.value != 'undefined' ? this.value : '';
+        }else{
+            return Roo.bootstrap.ComboBox.superclass.getValue.call(this);
+        }
+    },
+
+    /**
+     * Clears any text/value currently set in the field
+     */
+    clearValue : function(){
+        if(this.hiddenField){
+            this.hiddenField.dom.value = '';
+        }
+        this.value = '';
+        this.setRawValue('');
+        this.lastSelectionText = '';
+        
+    },
+
+    /**
+     * Sets the specified value into the field.  If the value finds a match, the corresponding record text
+     * will be displayed in the field.  If the value does not match the data value of an existing item,
+     * and the valueNotFoundText config option is defined, it will be displayed as the default field text.
+     * Otherwise the field will be blank (although the value will still be set).
+     * @param {String} value The value to match
+     */
+    setValue : function(v){
+        if(this.multiple){
+            this.syncValue();
+            return;
+        }
+        
+        var text = v;
+        if(this.valueField){
+            var r = this.findRecord(this.valueField, v);
+            if(r){
+                text = r.data[this.displayField];
+            }else if(this.valueNotFoundText !== undefined){
+                text = this.valueNotFoundText;
+            }
+        }
+        this.lastSelectionText = text;
+        if(this.hiddenField){
+            this.hiddenField.dom.value = v;
+        }
+        Roo.bootstrap.ComboBox.superclass.setValue.call(this, text);
+        this.value = v;
+    },
+    /**
+     * @property {Object} the last set data for the element
+     */
+    
+    lastData : false,
+    /**
+     * Sets the value of the field based on a object which is related to the record format for the store.
+     * @param {Object} value the value to set as. or false on reset?
+     */
+    setFromData : function(o){
+        
+        if(this.multiple){
+            this.addItem(o);
+            return;
+        }
+            
+        var dv = ''; // display value
+        var vv = ''; // value value..
+        this.lastData = o;
+        if (this.displayField) {
+            dv = !o || typeof(o[this.displayField]) == 'undefined' ? '' : o[this.displayField];
+        } else {
+            // this is an error condition!!!
+            Roo.log('no  displayField value set for '+ (this.name ? this.name : this.id));
+        }
+        
+        if(this.valueField){
+            vv = !o || typeof(o[this.valueField]) == 'undefined' ? dv : o[this.valueField];
+        }
+        
+        if(this.hiddenField){
+            this.hiddenField.dom.value = vv;
+            
+            this.lastSelectionText = dv;
+            Roo.bootstrap.ComboBox.superclass.setValue.call(this, dv);
+            this.value = vv;
+            return;
+        }
+        // no hidden field.. - we store the value in 'value', but still display
+        // display field!!!!
+        this.lastSelectionText = dv;
+        Roo.bootstrap.ComboBox.superclass.setValue.call(this, dv);
+        this.value = vv;
+        
+        
+    },
+    // private
+    reset : function(){
+        // overridden so that last data is reset..
+        this.setValue(this.originalValue);
+        this.clearInvalid();
+        this.lastData = false;
+        if (this.view) {
+            this.view.clearSelections();
+        }
+    },
+    // private
+    findRecord : function(prop, value){
+        var record;
+        if(this.store.getCount() > 0){
+            this.store.each(function(r){
+                if(r.data[prop] == value){
+                    record = r;
+                    return false;
+                }
+                return true;
+            });
+        }
+        return record;
+    },
+    
+    getName: function()
+    {
+        // returns hidden if it's set..
+        if (!this.rendered) {return ''};
+        return !this.hiddenName && this.inputEl().dom.name  ? this.inputEl().dom.name : (this.hiddenName || '');
+        
+    },
+    // private
+    onViewMove : function(e, t){
+        this.inKeyMode = false;
+    },
+
+    // private
+    onViewOver : function(e, t){
+        if(this.inKeyMode){ // prevent key nav and mouse over conflicts
+            return;
+        }
+        var item = this.view.findItemFromChild(t);
+        
+        if(item){
+            var index = this.view.indexOf(item);
+            this.select(index, false);
+        }
+    },
+
+    // private
+    onViewClick : function(view, doFocus, el, e)
+    {
+        var index = this.view.getSelectedIndexes()[0];
+        
+        var r = this.store.getAt(index);
+        
+        if(this.tickable){
+            
+            if(e.getTarget().nodeName.toLowerCase() != 'input'){
+                return;
+            }
+            
+            var rm = false;
+            var _this = this;
+            
+            Roo.each(this.tickItems, function(v,k){
+                
+                if(typeof(v) != 'undefined' && v[_this.valueField] == r.data[_this.valueField]){
+                    _this.tickItems.splice(k, 1);
+                    rm = true;
+                    return;
+                }
+            });
+            
+            if(rm){
+                return;
+            }
+            
+            this.tickItems.push(r.data);
+            return;
+        }
+        
+        if(r){
+            this.onSelect(r, index);
+        }
+        if(doFocus !== false && !this.blockFocus){
+            this.inputEl().focus();
+        }
+    },
+
+    // private
+    restrictHeight : function(){
+        //this.innerList.dom.style.height = '';
+        //var inner = this.innerList.dom;
+        //var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
+        //this.innerList.setHeight(h < this.maxHeight ? 'auto' : this.maxHeight);
+        //this.list.beginUpdate();
+        //this.list.setHeight(this.innerList.getHeight()+this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight);
+        this.list.alignTo(this.inputEl(), this.listAlign);
+        this.list.alignTo(this.inputEl(), this.listAlign);
+        //this.list.endUpdate();
+    },
+
+    // private
+    onEmptyResults : function(){
+        this.collapse();
+    },
+
+    /**
+     * Returns true if the dropdown list is expanded, else false.
+     */
+    isExpanded : function(){
+        return this.list.isVisible();
+    },
+
+    /**
+     * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
+     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+     * @param {String} value The data value of the item to select
+     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+     * selected item if it is not currently in view (defaults to true)
+     * @return {Boolean} True if the value matched an item in the list, else false
+     */
+    selectByValue : function(v, scrollIntoView){
+        if(v !== undefined && v !== null){
+            var r = this.findRecord(this.valueField || this.displayField, v);
+            if(r){
+                this.select(this.store.indexOf(r), scrollIntoView);
+                return true;
+            }
+        }
+        return false;
+    },
+
+    /**
+     * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
+     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+     * @param {Number} index The zero-based index of the list item to select
+     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+     * selected item if it is not currently in view (defaults to true)
+     */
+    select : function(index, scrollIntoView){
+        this.selectedIndex = index;
+        this.view.select(index);
+        if(scrollIntoView !== false){
+            var el = this.view.getNode(index);
+            if(el && !this.multiple && !this.tickable){
+                this.list.scrollChildIntoView(el, false);
+            }
+        }
+    },
+
+    // private
+    selectNext : function(){
+        var ct = this.store.getCount();
+        if(ct > 0){
+            if(this.selectedIndex == -1){
+                this.select(0);
+            }else if(this.selectedIndex < ct-1){
+                this.select(this.selectedIndex+1);
+            }
+        }
+    },
+
+    // private
+    selectPrev : function(){
+        var ct = this.store.getCount();
+        if(ct > 0){
+            if(this.selectedIndex == -1){
+                this.select(0);
+            }else if(this.selectedIndex != 0){
+                this.select(this.selectedIndex-1);
+            }
+        }
+    },
+
+    // private
+    onKeyUp : function(e){
+        if(this.editable !== false && !e.isSpecialKey()){
+            this.lastKey = e.getKey();
+            this.dqTask.delay(this.queryDelay);
+        }
+    },
+
+    // private
+    validateBlur : function(){
+        return !this.list || !this.list.isVisible();   
+    },
+
+    // private
+    initQuery : function(){
+        this.doQuery(this.getRawValue());
+    },
+
+    // private
+    doForce : function(){
+        if(this.inputEl().dom.value.length > 0){
+            this.inputEl().dom.value =
+                this.lastSelectionText === undefined ? '' : this.lastSelectionText;
+             
+        }
+    },
+
+    /**
+     * Execute a query to filter the dropdown list.  Fires the beforequery event prior to performing the
+     * query allowing the query action to be canceled if needed.
+     * @param {String} query The SQL query to execute
+     * @param {Boolean} forceAll True to force the query to execute even if there are currently fewer characters
+     * in the field than the minimum specified by the minChars config option.  It also clears any filter previously
+     * saved in the current store (defaults to false)
+     */
+    doQuery : function(q, forceAll){
+        
+        if(q === undefined || q === null){
+            q = '';
+        }
+        var qe = {
+            query: q,
+            forceAll: forceAll,
+            combo: this,
+            cancel:false
+        };
+        if(this.fireEvent('beforequery', qe)===false || qe.cancel){
+            return false;
+        }
+        q = qe.query;
+        
+        forceAll = qe.forceAll;
+        if(forceAll === true || (q.length >= this.minChars)){
+            
+            this.hasQuery = true;
+            
+            if(this.lastQuery != q || this.alwaysQuery){
+                this.lastQuery = q;
+                if(this.mode == 'local'){
+                    this.selectedIndex = -1;
+                    if(forceAll){
+                        this.store.clearFilter();
+                    }else{
+                        this.store.filter(this.displayField, q);
+                    }
+                    this.onLoad();
+                }else{
+                    this.store.baseParams[this.queryParam] = q;
+                    
+                    var options = {params : this.getParams(q)};
+                    
+                    if(this.loadNext){
+                        options.add = true;
+                        options.params.start = this.page * this.pageSize;
+                    }
+                    
+                    this.store.load(options);
+                    /*
+                     *  this code will make the page width larger, at the beginning, the list not align correctly, 
+                     *  we should expand the list on onLoad
+                     *  so command out it
+                     */
+//                    this.expand();
+                }
+            }else{
+                this.selectedIndex = -1;
+                this.onLoad();   
+            }
+        }
+        
+        this.loadNext = false;
+    },
+
+    // private
+    getParams : function(q){
+        var p = {};
+        //p[this.queryParam] = q;
+        
+        if(this.pageSize){
+            p.start = 0;
+            p.limit = this.pageSize;
+        }
+        return p;
+    },
+
+    /**
+     * Hides the dropdown list if it is currently expanded. Fires the 'collapse' event on completion.
+     */
+    collapse : function(){
+        if(!this.isExpanded()){
+            return;
+        }
+        
+        this.list.hide();
+        
+        if(this.tickable){
+            this.hasFocus = false;
+            this.okBtn.hide();
+            this.cancelBtn.hide();
+            this.trigger.show();
+        }
+        
+        Roo.get(document).un('mousedown', this.collapseIf, this);
+        Roo.get(document).un('mousewheel', this.collapseIf, this);
+        if (!this.editable) {
+            Roo.get(document).un('keydown', this.listKeyPress, this);
+        }
+        this.fireEvent('collapse', this);
+    },
+
+    // private
+    collapseIf : function(e){
+        var in_combo  = e.within(this.el);
+        var in_list =  e.within(this.list);
+        var is_list = (Roo.get(e.getTarget()).id == this.list.id) ? true : false;
+        
+        if (in_combo || in_list || is_list) {
+            //e.stopPropagation();
+            return;
+        }
+        
+        if(this.tickable){
+            this.onTickableFooterButtonClick(e, false, false);
+        }
+
+        this.collapse();
+        
+    },
+
+    /**
+     * Expands the dropdown list if it is currently hidden. Fires the 'expand' event on completion.
+     */
+    expand : function(){
+       
+        if(this.isExpanded() || !this.hasFocus){
+            return;
+        }
+        
+        var lw = this.listWidth || Math.max(this.inputEl().getWidth(), this.minListWidth);
+        this.list.setWidth(lw);
+        
+        
+         Roo.log('expand');
+        
+        this.list.show();
+        
+        this.restrictHeight();
+        
+        if(this.tickable){
+            
+            this.tickItems = Roo.apply([], this.item);
+            
+            this.okBtn.show();
+            this.cancelBtn.show();
+            this.trigger.hide();
+            
+        }
+        
+        Roo.get(document).on('mousedown', this.collapseIf, this);
+        Roo.get(document).on('mousewheel', this.collapseIf, this);
+        if (!this.editable) {
+            Roo.get(document).on('keydown', this.listKeyPress, this);
+        }
+        
+        this.fireEvent('expand', this);
+    },
+
+    // private
+    // Implements the default empty TriggerField.onTriggerClick function
+    onTriggerClick : function(e)
+    {
+        Roo.log('trigger click');
+        
+        if(this.disabled || !this.triggerList){
+            return;
+        }
+        
+        this.page = 0;
+        this.loadNext = false;
+        
+        if(this.isExpanded()){
+            this.collapse();
+            if (!this.blockFocus) {
+                this.inputEl().focus();
+            }
+            
+        }else {
+            this.hasFocus = true;
+            if(this.triggerAction == 'all') {
+                this.doQuery(this.allQuery, true);
+            } else {
+                this.doQuery(this.getRawValue());
+            }
+            if (!this.blockFocus) {
+                this.inputEl().focus();
+            }
+        }
+    },
+    
+    onTickableTriggerClick : function(e)
+    {
+        if(this.disabled){
+            return;
+        }
+        
+        this.page = 0;
+        this.loadNext = false;
+        this.hasFocus = true;
+        
+        if(this.triggerAction == 'all') {
+            this.doQuery(this.allQuery, true);
+        } else {
+            this.doQuery(this.getRawValue());
+        }
+    },
+    
+    onSearchFieldClick : function(e)
+    {
+        if(this.hasFocus && !this.disabled && e.getTarget().nodeName.toLowerCase() != 'button'){
+            this.onTickableFooterButtonClick(e, false, false);
+            return;
+        }
+        
+        if(this.hasFocus || this.disabled || e.getTarget().nodeName.toLowerCase() == 'button'){
+            return;
+        }
+        
+        this.page = 0;
+        this.loadNext = false;
+        this.hasFocus = true;
+        
+        if(this.triggerAction == 'all') {
+            this.doQuery(this.allQuery, true);
+        } else {
+            this.doQuery(this.getRawValue());
+        }
+    },
+    
+    listKeyPress : function(e)
+    {
+        //Roo.log('listkeypress');
+        // scroll to first matching element based on key pres..
+        if (e.isSpecialKey()) {
+            return false;
+        }
+        var k = String.fromCharCode(e.getKey()).toUpperCase();
+        //Roo.log(k);
+        var match  = false;
+        var csel = this.view.getSelectedNodes();
+        var cselitem = false;
+        if (csel.length) {
+            var ix = this.view.indexOf(csel[0]);
+            cselitem  = this.store.getAt(ix);
+            if (!cselitem.get(this.displayField) || cselitem.get(this.displayField).substring(0,1).toUpperCase() != k) {
+                cselitem = false;
+            }
+            
+        }
+        
+        this.store.each(function(v) { 
+            if (cselitem) {
+                // start at existing selection.
+                if (cselitem.id == v.id) {
+                    cselitem = false;
+                }
+                return true;
+            }
+                
+            if (v.get(this.displayField) && v.get(this.displayField).substring(0,1).toUpperCase() == k) {
+                match = this.store.indexOf(v);
+                return false;
+            }
+            return true;
+        }, this);
+        
+        if (match === false) {
+            return true; // no more action?
+        }
+        // scroll to?
+        this.view.select(match);
+        var sn = Roo.get(this.view.getSelectedNodes()[0])
+        sn.scrollIntoView(sn.dom.parentNode, false);
+    },
+    
+    onViewScroll : function(e, t){
+        
+        if(this.view.el.getScroll().top == 0 ||this.view.el.getScroll().top < this.view.el.dom.scrollHeight - this.view.el.dom.clientHeight || !this.hasFocus || !this.append || this.hasQuery){
+            return;
+        }
+        
+        this.hasQuery = true;
+        
+        this.loading = this.list.select('.loading', true).first();
+        
+        if(this.loading === null){
+            this.list.createChild({
+                tag: 'div',
+                cls: 'loading select2-more-results select2-active',
+                html: 'Loading more results...'
+            })
+            
+            this.loading = this.list.select('.loading', true).first();
+            
+            this.loading.setVisibilityMode(Roo.Element.DISPLAY);
+            
+            this.loading.hide();
+        }
+        
+        this.loading.show();
+        
+        var _combo = this;
+        
+        this.page++;
+        this.loadNext = true;
+        
+        (function() { _combo.doQuery(_combo.allQuery, true); }).defer(500);
+        
+        return;
+    },
+    
+    addItem : function(o)
+    {   
+        var dv = ''; // display value
+        
+        if (this.displayField) {
+            dv = !o || typeof(o[this.displayField]) == 'undefined' ? '' : o[this.displayField];
+        } else {
+            // this is an error condition!!!
+            Roo.log('no  displayField value set for '+ (this.name ? this.name : this.id));
+        }
+        
+        if(!dv.length){
+            return;
+        }
+        
+        var choice = this.choices.createChild({
+            tag: 'li',
+            cls: 'select2-search-choice',
+            cn: [
+                {
+                    tag: 'div',
+                    html: dv
+                },
+                {
+                    tag: 'a',
+                    href: '#',
+                    cls: 'select2-search-choice-close',
+                    tabindex: '-1'
+                }
+            ]
+            
+        }, this.searchField);
+        
+        var close = choice.select('a.select2-search-choice-close', true).first()
+        
+        close.on('click', this.onRemoveItem, this, { item : choice, data : o} );
+        
+        this.item.push(o);
+        
+        this.lastData = o;
+        
+        this.syncValue();
+        
+        this.inputEl().dom.value = '';
+        
+    },
+    
+    onRemoveItem : function(e, _self, o)
+    {
+        e.preventDefault();
+        var index = this.item.indexOf(o.data) * 1;
+        
+        if( index < 0){
+            Roo.log('not this item?!');
+            return;
+        }
+        
+        this.item.splice(index, 1);
+        o.item.remove();
+        
+        this.syncValue();
+        
+        this.fireEvent('remove', this, e);
+        
+    },
+    
+    syncValue : function()
+    {
+        if(!this.item.length){
+            this.clearValue();
+            return;
+        }
+            
+        var value = [];
+        var _this = this;
+        Roo.each(this.item, function(i){
+            if(_this.valueField){
+                value.push(i[_this.valueField]);
+                return;
+            }
+
+            value.push(i);
+        });
+
+        this.value = value.join(',');
+
+        if(this.hiddenField){
+            this.hiddenField.dom.value = this.value;
+        }
+    },
+    
+    clearItem : function()
+    {
+        if(!this.multiple){
+            return;
+        }
+        
+        this.item = [];
+        
+        Roo.each(this.choices.select('>li.select2-search-choice', true).elements, function(c){
+           c.remove();
+        });
+        
+        this.syncValue();
+    },
+    
+    inputEl: function ()
+    {
+        if(this.tickable){
+            return this.searchField;
+        }
+        return this.el.select('input.form-control',true).first();
+    },
+    
+    
+    onTickableFooterButtonClick : function(e, btn, el)
+    {
+        e.preventDefault();
+        
+        if(btn && btn.name == 'cancel'){
+            this.tickItems = Roo.apply([], this.item);
+            this.collapse();
+            return;
+        }
+        
+        this.clearItem();
+        
+        var _this = this;
+        
+        Roo.each(this.tickItems, function(o){
+            _this.addItem(o);
+        });
+        
+        this.collapse();
+        
+    },
+    
+    validate : function()
+    {
+        var v = this.getRawValue();
+        
+        if(this.multiple){
+            v = this.getValue();
+        }
+        
+        if(this.disabled || this.validateValue(v)){
+            this.clearInvalid();
+            return true;
+        }
+        return false;
+    }
+    
+    
+
+    /** 
+    * @cfg {Boolean} grow 
+    * @hide 
+    */
+    /** 
+    * @cfg {Number} growMin 
+    * @hide 
+    */
+    /** 
+    * @cfg {Number} growMax 
+    * @hide 
+    */
+    /**
+     * @hide
+     * @method autoSize
+     */
+});
+/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.View
+ * @extends Roo.util.Observable
+ * Create a "View" for an element based on a data model or UpdateManager and the supplied DomHelper template. 
+ * This class also supports single and multi selection modes. <br>
+ * Create a data model bound view:
+ <pre><code>
+ var store = new Roo.data.Store(...);
+
+ var view = new Roo.View({
+    el : "my-element",
+    tpl : '&lt;div id="{0}"&gt;{2} - {1}&lt;/div&gt;', // auto create template
+    singleSelect: true,
+    selectedClass: "ydataview-selected",
+    store: store
+ });
+
+ // listen for node click?
+ view.on("click", function(vw, index, node, e){
+ alert('Node "' + node.id + '" at index: ' + index + " was clicked.");
+ });
+
+ // load XML data
+ dataModel.load("foobar.xml");
+ </code></pre>
+ For an example of creating a JSON/UpdateManager view, see {@link Roo.JsonView}.
+ * <br><br>
+ * <b>Note: The root of your template must be a single node. Table/row implementations may work but are not supported due to
+ * IE"s limited insertion support with tables and Opera"s faulty event bubbling.</b>
+ * 
+ * Note: old style constructor is still suported (container, template, config)
+ * 
+ * @constructor
+ * Create a new View
+ * @param {Object} config The config object
+ * 
+ */
+Roo.View = function(config, depreciated_tpl, depreciated_config){
+    
+    this.parent = false;
+    
+    if (typeof(depreciated_tpl) == 'undefined') {
+        // new way.. - universal constructor.
+        Roo.apply(this, config);
+        this.el  = Roo.get(this.el);
+    } else {
+        // old format..
+        this.el  = Roo.get(config);
+        this.tpl = depreciated_tpl;
+        Roo.apply(this, depreciated_config);
+    }
+    this.wrapEl  = this.el.wrap().wrap();
+    ///this.el = this.wrapEla.appendChild(document.createElement("div"));
+    
+    
+    if(typeof(this.tpl) == "string"){
+        this.tpl = new Roo.Template(this.tpl);
+    } else {
+        // support xtype ctors..
+        this.tpl = new Roo.factory(this.tpl, Roo);
+    }
+    
+    
+    this.tpl.compile();
+    
+    /** @private */
+    this.addEvents({
+        /**
+         * @event beforeclick
+         * Fires before a click is processed. Returns false to cancel the default action.
+         * @param {Roo.View} this
+         * @param {Number} index The index of the target node
+         * @param {HTMLElement} node The target node
+         * @param {Roo.EventObject} e The raw event object
+         */
+            "beforeclick" : true,
+        /**
+         * @event click
+         * Fires when a template node is clicked.
+         * @param {Roo.View} this
+         * @param {Number} index The index of the target node
+         * @param {HTMLElement} node The target node
+         * @param {Roo.EventObject} e The raw event object
+         */
+            "click" : true,
+        /**
+         * @event dblclick
+         * Fires when a template node is double clicked.
+         * @param {Roo.View} this
+         * @param {Number} index The index of the target node
+         * @param {HTMLElement} node The target node
+         * @param {Roo.EventObject} e The raw event object
+         */
+            "dblclick" : true,
+        /**
+         * @event contextmenu
+         * Fires when a template node is right clicked.
+         * @param {Roo.View} this
+         * @param {Number} index The index of the target node
+         * @param {HTMLElement} node The target node
+         * @param {Roo.EventObject} e The raw event object
+         */
+            "contextmenu" : true,
+        /**
+         * @event selectionchange
+         * Fires when the selected nodes change.
+         * @param {Roo.View} this
+         * @param {Array} selections Array of the selected nodes
+         */
+            "selectionchange" : true,
+    
+        /**
+         * @event beforeselect
+         * Fires before a selection is made. If any handlers return false, the selection is cancelled.
+         * @param {Roo.View} this
+         * @param {HTMLElement} node The node to be selected
+         * @param {Array} selections Array of currently selected nodes
+         */
+            "beforeselect" : true,
+        /**
+         * @event preparedata
+         * Fires on every row to render, to allow you to change the data.
+         * @param {Roo.View} this
+         * @param {Object} data to be rendered (change this)
+         */
+          "preparedata" : true
+          
+          
+        });
+
+
+
+    this.el.on({
+        "click": this.onClick,
+        "dblclick": this.onDblClick,
+        "contextmenu": this.onContextMenu,
+        scope:this
+    });
+
+    this.selections = [];
+    this.nodes = [];
+    this.cmp = new Roo.CompositeElementLite([]);
+    if(this.store){
+        this.store = Roo.factory(this.store, Roo.data);
+        this.setStore(this.store, true);
+    }
+    
+    if ( this.footer && this.footer.xtype) {
+           
+         var fctr = this.wrapEl.appendChild(document.createElement("div"));
+        
+        this.footer.dataSource = this.store
+        this.footer.container = fctr;
+        this.footer = Roo.factory(this.footer, Roo);
+        fctr.insertFirst(this.el);
+        
+        // this is a bit insane - as the paging toolbar seems to detach the el..
+//        dom.parentNode.parentNode.parentNode
+         // they get detached?
+    }
+    
+    
+    Roo.View.superclass.constructor.call(this);
+    
+    
+};
+
+Roo.extend(Roo.View, Roo.util.Observable, {
+    
+     /**
+     * @cfg {Roo.data.Store} store Data store to load data from.
+     */
+    store : false,
+    
+    /**
+     * @cfg {String|Roo.Element} el The container element.
+     */
+    el : '',
+    
+    /**
+     * @cfg {String|Roo.Template} tpl The template used by this View 
+     */
+    tpl : false,
+    /**
+     * @cfg {String} dataName the named area of the template to use as the data area
+     *                          Works with domtemplates roo-name="name"
+     */
+    dataName: false,
+    /**
+     * @cfg {String} selectedClass The css class to add to selected nodes
+     */
+    selectedClass : "x-view-selected",
+     /**
+     * @cfg {String} emptyText The empty text to show when nothing is loaded.
+     */
+    emptyText : "",
+    
+    /**
+     * @cfg {String} text to display on mask (default Loading)
+     */
+    mask : false,
+    /**
+     * @cfg {Boolean} multiSelect Allow multiple selection
+     */
+    multiSelect : false,
+    /**
+     * @cfg {Boolean} singleSelect Allow single selection
+     */
+    singleSelect:  false,
+    
+    /**
+     * @cfg {Boolean} toggleSelect - selecting 
+     */
+    toggleSelect : false,
+    
+    /**
+     * @cfg {Boolean} tickable - selecting 
+     */
+    tickable : false,
+    
+    /**
+     * Returns the element this view is bound to.
+     * @return {Roo.Element}
+     */
+    getEl : function(){
+        return this.wrapEl;
+    },
+    
+    
+
+    /**
+     * Refreshes the view. - called by datachanged on the store. - do not call directly.
+     */
+    refresh : function(){
+        //Roo.log('refresh');
+        var t = this.tpl;
+        
+        // if we are using something like 'domtemplate', then
+        // the what gets used is:
+        // t.applySubtemplate(NAME, data, wrapping data..)
+        // the outer template then get' applied with
+        //     the store 'extra data'
+        // and the body get's added to the
+        //      roo-name="data" node?
+        //      <span class='roo-tpl-{name}'></span> ?????
+        
+        
+        
+        this.clearSelections();
+        this.el.update("");
+        var html = [];
+        var records = this.store.getRange();
+        if(records.length < 1) {
+            
+            // is this valid??  = should it render a template??
+            
+            this.el.update(this.emptyText);
+            return;
+        }
+        var el = this.el;
+        if (this.dataName) {
+            this.el.update(t.apply(this.store.meta)); //????
+            el = this.el.child('.roo-tpl-' + this.dataName);
+        }
+        
+        for(var i = 0, len = records.length; i < len; i++){
+            var data = this.prepareData(records[i].data, i, records[i]);
+            this.fireEvent("preparedata", this, data, i, records[i]);
+            
+            var d = Roo.apply({}, data);
+            
+            if(this.tickable){
+                Roo.apply(d, {'roo-id' : Roo.id()});
+                
+                var _this = this;
+            
+                Roo.each(this.parent.item, function(item){
+                    if(item[_this.parent.valueField] != data[_this.parent.valueField]){
+                        return;
+                    }
+                    Roo.apply(d, {'roo-data-checked' : 'checked'});
+                });
+            }
+            
+            html[html.length] = Roo.util.Format.trim(
+                this.dataName ?
+                    t.applySubtemplate(this.dataName, d, this.store.meta) :
+                    t.apply(d)
+            );
+        }
+        
+        
+        
+        el.update(html.join(""));
+        this.nodes = el.dom.childNodes;
+        this.updateIndexes(0);
+    },
+    
+
+    /**
+     * Function to override to reformat the data that is sent to
+     * the template for each node.
+     * DEPRICATED - use the preparedata event handler.
+     * @param {Array/Object} data The raw data (array of colData for a data model bound view or
+     * a JSON object for an UpdateManager bound view).
+     */
+    prepareData : function(data, index, record)
+    {
+        this.fireEvent("preparedata", this, data, index, record);
+        return data;
+    },
+
+    onUpdate : function(ds, record){
+        // Roo.log('on update');   
+        this.clearSelections();
+        var index = this.store.indexOf(record);
+        var n = this.nodes[index];
+        this.tpl.insertBefore(n, this.prepareData(record.data, index, record));
+        n.parentNode.removeChild(n);
+        this.updateIndexes(index, index);
+    },
+
+    
+    
+// --------- FIXME     
+    onAdd : function(ds, records, index)
+    {
+        //Roo.log(['on Add', ds, records, index] );        
+        this.clearSelections();
+        if(this.nodes.length == 0){
+            this.refresh();
+            return;
+        }
+        var n = this.nodes[index];
+        for(var i = 0, len = records.length; i < len; i++){
+            var d = this.prepareData(records[i].data, i, records[i]);
+            if(n){
+                this.tpl.insertBefore(n, d);
+            }else{
+                
+                this.tpl.append(this.el, d);
+            }
+        }
+        this.updateIndexes(index);
+    },
+
+    onRemove : function(ds, record, index){
+       // Roo.log('onRemove');
+        this.clearSelections();
+        var el = this.dataName  ?
+            this.el.child('.roo-tpl-' + this.dataName) :
+            this.el; 
+        
+        el.dom.removeChild(this.nodes[index]);
+        this.updateIndexes(index);
+    },
+
+    /**
+     * Refresh an individual node.
+     * @param {Number} index
+     */
+    refreshNode : function(index){
+        this.onUpdate(this.store, this.store.getAt(index));
+    },
+
+    updateIndexes : function(startIndex, endIndex){
+        var ns = this.nodes;
+        startIndex = startIndex || 0;
+        endIndex = endIndex || ns.length - 1;
+        for(var i = startIndex; i <= endIndex; i++){
+            ns[i].nodeIndex = i;
+        }
+    },
+
+    /**
+     * Changes the data store this view uses and refresh the view.
+     * @param {Store} store
+     */
+    setStore : function(store, initial){
+        if(!initial && this.store){
+            this.store.un("datachanged", this.refresh);
+            this.store.un("add", this.onAdd);
+            this.store.un("remove", this.onRemove);
+            this.store.un("update", this.onUpdate);
+            this.store.un("clear", this.refresh);
+            this.store.un("beforeload", this.onBeforeLoad);
+            this.store.un("load", this.onLoad);
+            this.store.un("loadexception", this.onLoad);
+        }
+        if(store){
+          
+            store.on("datachanged", this.refresh, this);
+            store.on("add", this.onAdd, this);
+            store.on("remove", this.onRemove, this);
+            store.on("update", this.onUpdate, this);
+            store.on("clear", this.refresh, this);
+            store.on("beforeload", this.onBeforeLoad, this);
+            store.on("load", this.onLoad, this);
+            store.on("loadexception", this.onLoad, this);
+        }
+        
+        if(store){
+            this.refresh();
+        }
+    },
+    /**
+     * onbeforeLoad - masks the loading area.
+     *
+     */
+    onBeforeLoad : function(store,opts)
+    {
+         //Roo.log('onBeforeLoad');   
+        if (!opts.add) {
+            this.el.update("");
+        }
+        this.el.mask(this.mask ? this.mask : "Loading" ); 
+    },
+    onLoad : function ()
+    {
+        this.el.unmask();
+    },
+    
+
+    /**
+     * Returns the template node the passed child belongs to or null if it doesn't belong to one.
+     * @param {HTMLElement} node
+     * @return {HTMLElement} The template node
+     */
+    findItemFromChild : function(node){
+        var el = this.dataName  ?
+            this.el.child('.roo-tpl-' + this.dataName,true) :
+            this.el.dom; 
+        
+        if(!node || node.parentNode == el){
+                   return node;
+           }
+           var p = node.parentNode;
+           while(p && p != el){
+            if(p.parentNode == el){
+               return p;
+            }
+            p = p.parentNode;
+        }
+           return null;
+    },
+
+    /** @ignore */
+    onClick : function(e){
+        var item = this.findItemFromChild(e.getTarget());
+        if(item){
+            var index = this.indexOf(item);
+            if(this.onItemClick(item, index, e) !== false){
+                this.fireEvent("click", this, index, item, e);
+            }
+        }else{
+            this.clearSelections();
+        }
+    },
+
+    /** @ignore */
+    onContextMenu : function(e){
+        var item = this.findItemFromChild(e.getTarget());
+        if(item){
+            this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
+        }
+    },
+
+    /** @ignore */
+    onDblClick : function(e){
+        var item = this.findItemFromChild(e.getTarget());
+        if(item){
+            this.fireEvent("dblclick", this, this.indexOf(item), item, e);
+        }
+    },
+
+    onItemClick : function(item, index, e)
+    {
+        if(this.fireEvent("beforeclick", this, index, item, e) === false){
+            return false;
+        }
+        if (this.toggleSelect) {
+            var m = this.isSelected(item) ? 'unselect' : 'select';
+            //Roo.log(m);
+            var _t = this;
+            _t[m](item, true, false);
+            return true;
+        }
+        if(this.multiSelect || this.singleSelect){
+            if(this.multiSelect && e.shiftKey && this.lastSelection){
+                this.select(this.getNodes(this.indexOf(this.lastSelection), index), false);
+            }else{
+                this.select(item, this.multiSelect && e.ctrlKey);
+                this.lastSelection = item;
+            }
+            
+            if(!this.tickable){
+                e.preventDefault();
+            }
+            
+        }
+        return true;
+    },
+
+    /**
+     * Get the number of selected nodes.
+     * @return {Number}
+     */
+    getSelectionCount : function(){
+        return this.selections.length;
+    },
+
+    /**
+     * Get the currently selected nodes.
+     * @return {Array} An array of HTMLElements
+     */
+    getSelectedNodes : function(){
+        return this.selections;
+    },
+
+    /**
+     * Get the indexes of the selected nodes.
+     * @return {Array}
+     */
+    getSelectedIndexes : function(){
+        var indexes = [], s = this.selections;
+        for(var i = 0, len = s.length; i < len; i++){
+            indexes.push(s[i].nodeIndex);
+        }
+        return indexes;
+    },
+
+    /**
+     * Clear all selections
+     * @param {Boolean} suppressEvent (optional) true to skip firing of the selectionchange event
+     */
+    clearSelections : function(suppressEvent){
+        if(this.nodes && (this.multiSelect || this.singleSelect) && this.selections.length > 0){
+            this.cmp.elements = this.selections;
+            this.cmp.removeClass(this.selectedClass);
+            this.selections = [];
+            if(!suppressEvent){
+                this.fireEvent("selectionchange", this, this.selections);
+            }
+        }
+    },
+
+    /**
+     * Returns true if the passed node is selected
+     * @param {HTMLElement/Number} node The node or node index
+     * @return {Boolean}
+     */
+    isSelected : function(node){
+        var s = this.selections;
+        if(s.length < 1){
+            return false;
+        }
+        node = this.getNode(node);
+        return s.indexOf(node) !== -1;
+    },
+
+    /**
+     * Selects nodes.
+     * @param {Array/HTMLElement/String/Number} nodeInfo An HTMLElement template node, index of a template node, id of a template node or an array of any of those to select
+     * @param {Boolean} keepExisting (optional) true to keep existing selections
+     * @param {Boolean} suppressEvent (optional) true to skip firing of the selectionchange vent
+     */
+    select : function(nodeInfo, keepExisting, suppressEvent){
+        if(nodeInfo instanceof Array){
+            if(!keepExisting){
+                this.clearSelections(true);
+            }
+            for(var i = 0, len = nodeInfo.length; i < len; i++){
+                this.select(nodeInfo[i], true, true);
+            }
+            return;
+        } 
+        var node = this.getNode(nodeInfo);
+        if(!node || this.isSelected(node)){
+            return; // already selected.
+        }
+        if(!keepExisting){
+            this.clearSelections(true);
+        }
+        
+        if(this.fireEvent("beforeselect", this, node, this.selections) !== false){
+            Roo.fly(node).addClass(this.selectedClass);
+            this.selections.push(node);
+            if(!suppressEvent){
+                this.fireEvent("selectionchange", this, this.selections);
+            }
+        }
+        
+        
+    },
+      /**
+     * Unselects nodes.
+     * @param {Array/HTMLElement/String/Number} nodeInfo An HTMLElement template node, index of a template node, id of a template node or an array of any of those to select
+     * @param {Boolean} keepExisting (optional) true IGNORED (for campatibility with select)
+     * @param {Boolean} suppressEvent (optional) true to skip firing of the selectionchange vent
+     */
+    unselect : function(nodeInfo, keepExisting, suppressEvent)
+    {
+        if(nodeInfo instanceof Array){
+            Roo.each(this.selections, function(s) {
+                this.unselect(s, nodeInfo);
+            }, this);
+            return;
+        }
+        var node = this.getNode(nodeInfo);
+        if(!node || !this.isSelected(node)){
+            //Roo.log("not selected");
+            return; // not selected.
+        }
+        // fireevent???
+        var ns = [];
+        Roo.each(this.selections, function(s) {
+            if (s == node ) {
+                Roo.fly(node).removeClass(this.selectedClass);
+
+                return;
+            }
+            ns.push(s);
+        },this);
+        
+        this.selections= ns;
+        this.fireEvent("selectionchange", this, this.selections);
+    },
+
+    /**
+     * Gets a template node.
+     * @param {HTMLElement/String/Number} nodeInfo An HTMLElement template node, index of a template node or the id of a template node
+     * @return {HTMLElement} The node or null if it wasn't found
+     */
+    getNode : function(nodeInfo){
+        if(typeof nodeInfo == "string"){
+            return document.getElementById(nodeInfo);
+        }else if(typeof nodeInfo == "number"){
+            return this.nodes[nodeInfo];
+        }
+        return nodeInfo;
+    },
+
+    /**
+     * Gets a range template nodes.
+     * @param {Number} startIndex
+     * @param {Number} endIndex
+     * @return {Array} An array of nodes
+     */
+    getNodes : function(start, end){
+        var ns = this.nodes;
+        start = start || 0;
+        end = typeof end == "undefined" ? ns.length - 1 : end;
+        var nodes = [];
+        if(start <= end){
+            for(var i = start; i <= end; i++){
+                nodes.push(ns[i]);
+            }
+        } else{
+            for(var i = start; i >= end; i--){
+                nodes.push(ns[i]);
+            }
+        }
+        return nodes;
+    },
+
+    /**
+     * Finds the index of the passed node
+     * @param {HTMLElement/String/Number} nodeInfo An HTMLElement template node, index of a template node or the id of a template node
+     * @return {Number} The index of the node or -1
+     */
+    indexOf : function(node){
+        node = this.getNode(node);
+        if(typeof node.nodeIndex == "number"){
+            return node.nodeIndex;
+        }
+        var ns = this.nodes;
+        for(var i = 0, len = ns.length; i < len; i++){
+            if(ns[i] == node){
+                return i;
+            }
+        }
+        return -1;
+    }
+});
+/*
+ * - LGPL
+ *
+ * based on jquery fullcalendar
+ * 
+ */
+
+Roo.bootstrap = Roo.bootstrap || {};
+/**
+ * @class Roo.bootstrap.Calendar
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Calendar class
+ * @cfg {Boolean} loadMask (true|false) default false
+ * @cfg {Object} header generate the user specific header of the calendar, default false
+
+ * @constructor
+ * Create a new Container
+ * @param {Object} config The config object
+ */
+
+
+
+Roo.bootstrap.Calendar = function(config){
+    Roo.bootstrap.Calendar.superclass.constructor.call(this, config);
+     this.addEvents({
+        /**
+            * @event select
+            * Fires when a date is selected
+            * @param {DatePicker} this
+            * @param {Date} date The selected date
+            */
+        'select': true,
+        /**
+            * @event monthchange
+            * Fires when the displayed month changes 
+            * @param {DatePicker} this
+            * @param {Date} date The selected month
+            */
+        'monthchange': true,
+        /**
+            * @event evententer
+            * Fires when mouse over an event
+            * @param {Calendar} this
+            * @param {event} Event
+            */
+        'evententer': true,
+        /**
+            * @event eventleave
+            * Fires when the mouse leaves an
+            * @param {Calendar} this
+            * @param {event}
+            */
+        'eventleave': true,
+        /**
+            * @event eventclick
+            * Fires when the mouse click an
+            * @param {Calendar} this
+            * @param {event}
+            */
+        'eventclick': true
+        
+    });
+
+};
+
+Roo.extend(Roo.bootstrap.Calendar, Roo.bootstrap.Component,  {
+    
+     /**
+     * @cfg {Number} startDay
+     * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
+     */
+    startDay : 0,
+    
+    loadMask : false,
+    
+    header : false,
+      
+    getAutoCreate : function(){
+        
+        
+        var fc_button = function(name, corner, style, content ) {
+            return Roo.apply({},{
+                tag : 'span',
+                cls : 'fc-button fc-button-'+name+' fc-state-default ' + 
+                         (corner.length ?
+                            'fc-corner-' + corner.split(' ').join(' fc-corner-') :
+                            ''
+                        ),
+                html : '<SPAN class="fc-text-'+style+ '">'+content +'</SPAN>',
+                unselectable: 'on'
+            });
+        };
+        
+        var header = {};
+        
+        if(!this.header){
+            header = {
+                tag : 'table',
+                cls : 'fc-header',
+                style : 'width:100%',
+                cn : [
+                    {
+                        tag: 'tr',
+                        cn : [
+                            {
+                                tag : 'td',
+                                cls : 'fc-header-left',
+                                cn : [
+                                    fc_button('prev', 'left', 'arrow', '&#8249;' ),
+                                    fc_button('next', 'right', 'arrow', '&#8250;' ),
+                                    { tag: 'span', cls: 'fc-header-space' },
+                                    fc_button('today', 'left right', '', 'today' )  // neds state disabled..
+
+
+                                ]
+                            },
+
+                            {
+                                tag : 'td',
+                                cls : 'fc-header-center',
+                                cn : [
+                                    {
+                                        tag: 'span',
+                                        cls: 'fc-header-title',
+                                        cn : {
+                                            tag: 'H2',
+                                            html : 'month / year'
+                                        }
+                                    }
+
+                                ]
+                            },
+                            {
+                                tag : 'td',
+                                cls : 'fc-header-right',
+                                cn : [
+                              /*      fc_button('month', 'left', '', 'month' ),
+                                    fc_button('week', '', '', 'week' ),
+                                    fc_button('day', 'right', '', 'day' )
+                                */    
+
+                                ]
+                            }
+
+                        ]
+                    }
+                ]
+            };
+        }
+        
+        header = this.header;
+        
+       
+        var cal_heads = function() {
+            var ret = [];
+            // fixme - handle this.
+            
+            for (var i =0; i < Date.dayNames.length; i++) {
+                var d = Date.dayNames[i];
+                ret.push({
+                    tag: 'th',
+                    cls : 'fc-day-header fc-' + d.substring(0,3).toLowerCase() + ' fc-widget-header',
+                    html : d.substring(0,3)
+                });
+                
+            }
+            ret[0].cls += ' fc-first';
+            ret[6].cls += ' fc-last';
+            return ret;
+        };
+        var cal_cell = function(n) {
+            return  {
+                tag: 'td',
+                cls : 'fc-day fc-'+n + ' fc-widget-content', ///fc-other-month fc-past
+                cn : [
+                    {
+                        cn : [
+                            {
+                                cls: 'fc-day-number',
+                                html: 'D'
+                            },
+                            {
+                                cls: 'fc-day-content',
+                             
+                                cn : [
+                                     {
+                                        style: 'position: relative;' // height: 17px;
+                                    }
+                                ]
+                            }
+                            
+                            
+                        ]
+                    }
+                ]
+                
+            }
+        };
+        var cal_rows = function() {
+            
+            var ret = [];
+            for (var r = 0; r < 6; r++) {
+                var row= {
+                    tag : 'tr',
+                    cls : 'fc-week',
+                    cn : []
+                };
+                
+                for (var i =0; i < Date.dayNames.length; i++) {
+                    var d = Date.dayNames[i];
+                    row.cn.push(cal_cell(d.substring(0,3).toLowerCase()));
+
+                }
+                row.cn[0].cls+=' fc-first';
+                row.cn[0].cn[0].style = 'min-height:90px';
+                row.cn[6].cls+=' fc-last';
+                ret.push(row);
+                
+            }
+            ret[0].cls += ' fc-first';
+            ret[4].cls += ' fc-prev-last';
+            ret[5].cls += ' fc-last';
+            return ret;
+            
+        };
+        
+        var cal_table = {
+            tag: 'table',
+            cls: 'fc-border-separate',
+            style : 'width:100%',
+            cellspacing  : 0,
+            cn : [
+                { 
+                    tag: 'thead',
+                    cn : [
+                        { 
+                            tag: 'tr',
+                            cls : 'fc-first fc-last',
+                            cn : cal_heads()
+                        }
+                    ]
+                },
+                { 
+                    tag: 'tbody',
+                    cn : cal_rows()
+                }
+                  
+            ]
+        };
+         
+         var cfg = {
+            cls : 'fc fc-ltr',
+            cn : [
+                header,
+                {
+                    cls : 'fc-content',
+                    style : "position: relative;",
+                    cn : [
+                        {
+                            cls : 'fc-view fc-view-month fc-grid',
+                            style : 'position: relative',
+                            unselectable : 'on',
+                            cn : [
+                                {
+                                    cls : 'fc-event-container',
+                                    style : 'position:absolute;z-index:8;top:0;left:0;'
+                                },
+                                cal_table
+                            ]
+                        }
+                    ]
+    
+                }
+           ] 
+            
+        };
+        
+         
+        
+        return cfg;
+    },
+    
+    
+    initEvents : function()
+    {
+        if(!this.store){
+            throw "can not find store for calendar";
+        }
+        
+        var mark = {
+            tag: "div",
+            cls:"x-dlg-mask",
+            style: "text-align:center",
+            cn: [
+                {
+                    tag: "div",
+                    style: "background-color:white;width:50%;margin:250 auto",
+                    cn: [
+                        {
+                            tag: "img",
+                            src: Roo.rootURL + '/images/ux/lightbox/loading.gif' 
+                        },
+                        {
+                            tag: "span",
+                            html: "Loading"
+                        }
+                        
+                    ]
+                }
+            ]
+        }
+        this.maskEl = Roo.DomHelper.append(this.el.select('.fc-content', true).first(), mark, true);
+        
+        var size = this.el.select('.fc-content', true).first().getSize();
+        this.maskEl.setSize(size.width, size.height);
+        this.maskEl.enableDisplayMode("block");
+        if(!this.loadMask){
+            this.maskEl.hide();
+        }
+        
+        this.store = Roo.factory(this.store, Roo.data);
+        this.store.on('load', this.onLoad, this);
+        this.store.on('beforeload', this.onBeforeLoad, this);
+        
+        this.resize();
+        
+        this.cells = this.el.select('.fc-day',true);
+        //Roo.log(this.cells);
+        this.textNodes = this.el.query('.fc-day-number');
+        this.cells.addClassOnOver('fc-state-hover');
+        
+        this.el.select('.fc-button-prev',true).on('click', this.showPrevMonth, this);
+        this.el.select('.fc-button-next',true).on('click', this.showNextMonth, this);
+        this.el.select('.fc-button-today',true).on('click', this.showToday, this);
+        this.el.select('.fc-button',true).addClassOnOver('fc-state-hover');
+        
+        this.on('monthchange', this.onMonthChange, this);
+        
+        this.update(new Date().clearTime());
+    },
+    
+    resize : function() {
+        var sz  = this.el.getSize();
+        
+        this.el.select('.fc-day-header',true).setWidth(sz.width / 7);
+        this.el.select('.fc-day-content div',true).setHeight(34);
+    },
+    
+    
+    // private
+    showPrevMonth : function(e){
+        this.update(this.activeDate.add("mo", -1));
+    },
+    showToday : function(e){
+        this.update(new Date().clearTime());
+    },
+    // private
+    showNextMonth : function(e){
+        this.update(this.activeDate.add("mo", 1));
+    },
+
+    // private
+    showPrevYear : function(){
+        this.update(this.activeDate.add("y", -1));
+    },
+
+    // private
+    showNextYear : function(){
+        this.update(this.activeDate.add("y", 1));
+    },
+
+    
+   // private
+    update : function(date)
+    {
+        var vd = this.activeDate;
+        this.activeDate = date;
+//        if(vd && this.el){
+//            var t = date.getTime();
+//            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
+//                Roo.log('using add remove');
+//                
+//                this.fireEvent('monthchange', this, date);
+//                
+//                this.cells.removeClass("fc-state-highlight");
+//                this.cells.each(function(c){
+//                   if(c.dateValue == t){
+//                       c.addClass("fc-state-highlight");
+//                       setTimeout(function(){
+//                            try{c.dom.firstChild.focus();}catch(e){}
+//                       }, 50);
+//                       return false;
+//                   }
+//                   return true;
+//                });
+//                return;
+//            }
+//        }
+        
+        var days = date.getDaysInMonth();
+        
+        var firstOfMonth = date.getFirstDateOfMonth();
+        var startingPos = firstOfMonth.getDay()-this.startDay;
+        
+        if(startingPos < this.startDay){
+            startingPos += 7;
+        }
+        
+        var pm = date.add(Date.MONTH, -1);
+        var prevStart = pm.getDaysInMonth()-startingPos;
+//        
+        this.cells = this.el.select('.fc-day',true);
+        this.textNodes = this.el.query('.fc-day-number');
+        this.cells.addClassOnOver('fc-state-hover');
+        
+        var cells = this.cells.elements;
+        var textEls = this.textNodes;
+        
+        Roo.each(cells, function(cell){
+            cell.removeClass([ 'fc-past', 'fc-other-month', 'fc-future', 'fc-state-highlight', 'fc-state-disabled']);
+        });
+        
+        days += startingPos;
+
+        // convert everything to numbers so it's fast
+        var day = 86400000;
+        var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
+        //Roo.log(d);
+        //Roo.log(pm);
+        //Roo.log(prevStart);
+        
+        var today = new Date().clearTime().getTime();
+        var sel = date.clearTime().getTime();
+        var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
+        var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
+        var ddMatch = this.disabledDatesRE;
+        var ddText = this.disabledDatesText;
+        var ddays = this.disabledDays ? this.disabledDays.join("") : false;
+        var ddaysText = this.disabledDaysText;
+        var format = this.format;
+        
+        var setCellClass = function(cal, cell){
+            cell.row = 0;
+            cell.events = [];
+            cell.more = [];
+            //Roo.log('set Cell Class');
+            cell.title = "";
+            var t = d.getTime();
+            
+            //Roo.log(d);
+            
+            cell.dateValue = t;
+            if(t == today){
+                cell.className += " fc-today";
+                cell.className += " fc-state-highlight";
+                cell.title = cal.todayText;
+            }
+            if(t == sel){
+                // disable highlight in other month..
+                //cell.className += " fc-state-highlight";
+                
+            }
+            // disabling
+            if(t < min) {
+                cell.className = " fc-state-disabled";
+                cell.title = cal.minText;
+                return;
+            }
+            if(t > max) {
+                cell.className = " fc-state-disabled";
+                cell.title = cal.maxText;
+                return;
+            }
+            if(ddays){
+                if(ddays.indexOf(d.getDay()) != -1){
+                    cell.title = ddaysText;
+                    cell.className = " fc-state-disabled";
+                }
+            }
+            if(ddMatch && format){
+                var fvalue = d.dateFormat(format);
+                if(ddMatch.test(fvalue)){
+                    cell.title = ddText.replace("%0", fvalue);
+                    cell.className = " fc-state-disabled";
+                }
+            }
+            
+            if (!cell.initialClassName) {
+                cell.initialClassName = cell.dom.className;
+            }
+            
+            cell.dom.className = cell.initialClassName  + ' ' +  cell.className;
+        };
+
+        var i = 0;
+        
+        for(; i < startingPos; i++) {
+            textEls[i].innerHTML = (++prevStart);
+            d.setDate(d.getDate()+1);
+            
+            cells[i].className = "fc-past fc-other-month";
+            setCellClass(this, cells[i]);
+        }
+        
+        var intDay = 0;
+        
+        for(; i < days; i++){
+            intDay = i - startingPos + 1;
+            textEls[i].innerHTML = (intDay);
+            d.setDate(d.getDate()+1);
+            
+            cells[i].className = ''; // "x-date-active";
+            setCellClass(this, cells[i]);
+        }
+        var extraDays = 0;
+        
+        for(; i < 42; i++) {
+            textEls[i].innerHTML = (++extraDays);
+            d.setDate(d.getDate()+1);
+            
+            cells[i].className = "fc-future fc-other-month";
+            setCellClass(this, cells[i]);
+        }
+        
+        this.el.select('.fc-header-title h2',true).update(Date.monthNames[date.getMonth()] + " " + date.getFullYear());
+        
+        var totalRows = Math.ceil((date.getDaysInMonth() + date.getFirstDateOfMonth().getDay()) / 7);
+        
+        this.el.select('tr.fc-week.fc-prev-last',true).removeClass('fc-last');
+        this.el.select('tr.fc-week.fc-next-last',true).addClass('fc-last').show();
+        
+        if(totalRows != 6){
+            this.el.select('tr.fc-week.fc-last',true).removeClass('fc-last').addClass('fc-next-last').hide();
+            this.el.select('tr.fc-week.fc-prev-last',true).addClass('fc-last');
+        }
+        
+        this.fireEvent('monthchange', this, date);
+        
+        
+        /*
+        if(!this.internalRender){
+            var main = this.el.dom.firstChild;
+            var w = main.offsetWidth;
+            this.el.setWidth(w + this.el.getBorderWidth("lr"));
+            Roo.fly(main).setWidth(w);
+            this.internalRender = true;
+            // opera does not respect the auto grow header center column
+            // then, after it gets a width opera refuses to recalculate
+            // without a second pass
+            if(Roo.isOpera && !this.secondPass){
+                main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
+                this.secondPass = true;
+                this.update.defer(10, this, [date]);
+            }
+        }
+        */
+        
+    },
+    
+    findCell : function(dt) {
+        dt = dt.clearTime().getTime();
+        var ret = false;
+        this.cells.each(function(c){
+            //Roo.log("check " +c.dateValue + '?=' + dt);
+            if(c.dateValue == dt){
+                ret = c;
+                return false;
+            }
+            return true;
+        });
+        
+        return ret;
+    },
+    
+    findCells : function(ev) {
+        var s = ev.start.clone().clearTime().getTime();
+       // Roo.log(s);
+        var e= ev.end.clone().clearTime().getTime();
+       // Roo.log(e);
+        var ret = [];
+        this.cells.each(function(c){
+             ////Roo.log("check " +c.dateValue + '<' + e + ' > ' + s);
+            
+            if(c.dateValue > e){
+                return ;
+            }
+            if(c.dateValue < s){
+                return ;
+            }
+            ret.push(c);
+        });
+        
+        return ret;    
+    },
+    
+//    findBestRow: function(cells)
+//    {
+//        var ret = 0;
+//        
+//        for (var i =0 ; i < cells.length;i++) {
+//            ret  = Math.max(cells[i].rows || 0,ret);
+//        }
+//        return ret;
+//        
+//    },
+    
+    
+    addItem : function(ev)
+    {
+        // look for vertical location slot in
+        var cells = this.findCells(ev);
+        
+//        ev.row = this.findBestRow(cells);
+        
+        // work out the location.
+        
+        var crow = false;
+        var rows = [];
+        for(var i =0; i < cells.length; i++) {
+            
+            cells[i].row = cells[0].row;
+            
+            if(i == 0){
+                cells[i].row = cells[i].row + 1;
+            }
+            
+            if (!crow) {
+                crow = {
+                    start : cells[i],
+                    end :  cells[i]
+                };
+                continue;
+            }
+            if (crow.start.getY() == cells[i].getY()) {
+                // on same row.
+                crow.end = cells[i];
+                continue;
+            }
+            // different row.
+            rows.push(crow);
+            crow = {
+                start: cells[i],
+                end : cells[i]
+            };
+            
+        }
+        
+        rows.push(crow);
+        ev.els = [];
+        ev.rows = rows;
+        ev.cells = cells;
+        
+        cells[0].events.push(ev);
+        
+        this.calevents.push(ev);
+    },
+    
+    clearEvents: function() {
+        
+        if(!this.calevents){
+            return;
+        }
+        
+        Roo.each(this.cells.elements, function(c){
+            c.row = 0;
+            c.events = [];
+            c.more = [];
+        });
+        
+        Roo.each(this.calevents, function(e) {
+            Roo.each(e.els, function(el) {
+                el.un('mouseenter' ,this.onEventEnter, this);
+                el.un('mouseleave' ,this.onEventLeave, this);
+                el.remove();
+            },this);
+        },this);
+        
+        Roo.each(Roo.select('.fc-more-event', true).elements, function(e){
+            e.remove();
+        });
+        
+    },
+    
+    renderEvents: function()
+    {   
+        var _this = this;
+        
+        this.cells.each(function(c) {
+            
+            if(c.row < 5){
+                return;
+            }
+            
+            var ev = c.events;
+            
+            var r = 4;
+            if(c.row != c.events.length){
+                r = 4 - (4 - (c.row - c.events.length));
+            }
+            
+            c.events = ev.slice(0, r);
+            c.more = ev.slice(r);
+            
+            if(c.more.length && c.more.length == 1){
+                c.events.push(c.more.pop());
+            }
+            
+            c.row = (c.row - ev.length) + c.events.length + ((c.more.length) ? 1 : 0);
+            
+        });
+            
+        this.cells.each(function(c) {
+            
+            c.select('.fc-day-content div',true).first().setHeight(Math.max(34, c.row * 20));
+            
+            
+            for (var e = 0; e < c.events.length; e++){
+                var ev = c.events[e];
+                var rows = ev.rows;
+                
+                for(var i = 0; i < rows.length; i++) {
+                
+                    // how many rows should it span..
+
+                    var  cfg = {
+                        cls : 'roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable',
+                        style : 'position: absolute', // left: 387px; width: 121px; top: 359px;
+
+                        unselectable : "on",
+                        cn : [
+                            {
+                                cls: 'fc-event-inner',
+                                cn : [
+    //                                {
+    //                                  tag:'span',
+    //                                  cls: 'fc-event-time',
+    //                                  html : cells.length > 1 ? '' : ev.time
+    //                                },
+                                    {
+                                      tag:'span',
+                                      cls: 'fc-event-title',
+                                      html : String.format('{0}', ev.title)
+                                    }
+
+
+                                ]
+                            },
+                            {
+                                cls: 'ui-resizable-handle ui-resizable-e',
+                                html : '&nbsp;&nbsp;&nbsp'
+                            }
+
+                        ]
+                    };
+
+                    if (i == 0) {
+                        cfg.cls += ' fc-event-start';
+                    }
+                    if ((i+1) == rows.length) {
+                        cfg.cls += ' fc-event-end';
+                    }
+
+                    var ctr = _this.el.select('.fc-event-container',true).first();
+                    var cg = ctr.createChild(cfg);
+
+                    var sbox = rows[i].start.select('.fc-day-content',true).first().getBox();
+                    var ebox = rows[i].end.select('.fc-day-content',true).first().getBox();
+
+                    var r = (c.more.length) ? 1 : 0;
+                    cg.setXY([sbox.x +2, sbox.y + ((c.row - c.events.length - r + e) * 20)]);    
+                    cg.setWidth(ebox.right - sbox.x -2);
+
+                    cg.on('mouseenter' ,_this.onEventEnter, _this, ev);
+                    cg.on('mouseleave' ,_this.onEventLeave, _this, ev);
+                    cg.on('click', _this.onEventClick, _this, ev);
+
+                    ev.els.push(cg);
+                    
+                }
+                
+            }
+            
+            
+            if(c.more.length){
+                var  cfg = {
+                    cls : 'fc-more-event roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable fc-event-start fc-event-end',
+                    style : 'position: absolute',
+                    unselectable : "on",
+                    cn : [
+                        {
+                            cls: 'fc-event-inner',
+                            cn : [
+                                {
+                                  tag:'span',
+                                  cls: 'fc-event-title',
+                                  html : 'More'
+                                }
+
+
+                            ]
+                        },
+                        {
+                            cls: 'ui-resizable-handle ui-resizable-e',
+                            html : '&nbsp;&nbsp;&nbsp'
+                        }
+
+                    ]
+                };
+
+                var ctr = _this.el.select('.fc-event-container',true).first();
+                var cg = ctr.createChild(cfg);
+
+                var sbox = c.select('.fc-day-content',true).first().getBox();
+                var ebox = c.select('.fc-day-content',true).first().getBox();
+                //Roo.log(cg);
+                cg.setXY([sbox.x +2, sbox.y +((c.row - 1) * 20)]);    
+                cg.setWidth(ebox.right - sbox.x -2);
+
+                cg.on('click', _this.onMoreEventClick, _this, c.more);
+                
+            }
+            
+        });
+        
+        
+        
+    },
+    
+    onEventEnter: function (e, el,event,d) {
+        this.fireEvent('evententer', this, el, event);
+    },
+    
+    onEventLeave: function (e, el,event,d) {
+        this.fireEvent('eventleave', this, el, event);
+    },
+    
+    onEventClick: function (e, el,event,d) {
+        this.fireEvent('eventclick', this, el, event);
+    },
+    
+    onMonthChange: function () {
+        this.store.load();
+    },
+    
+    onMoreEventClick: function(e, el, more)
+    {
+        var _this = this;
+        
+        this.calpopover.placement = 'right';
+        this.calpopover.setTitle('More');
+        
+        this.calpopover.setContent('');
+        
+        var ctr = this.calpopover.el.select('.popover-content', true).first();
+        
+        Roo.each(more, function(m){
+            var cfg = {
+                cls : 'fc-event-hori fc-event-draggable',
+                html : m.title
+            }
+            var cg = ctr.createChild(cfg);
+            
+            cg.on('click', _this.onEventClick, _this, m);
+        });
+        
+        this.calpopover.show(el);
+        
+        
+    },
+    
+    onLoad: function () 
+    {   
+        this.calevents = [];
+        var cal = this;
+        
+        if(this.store.getCount() > 0){
+            this.store.data.each(function(d){
+               cal.addItem({
+                    id : d.data.id,
+                    start: (typeof(d.data.start_dt) === 'string') ? new Date.parseDate(d.data.start_dt, 'Y-m-d H:i:s') : d.data.start_dt,
+                    end : (typeof(d.data.end_dt) === 'string') ? new Date.parseDate(d.data.end_dt, 'Y-m-d H:i:s') : d.data.end_dt,
+                    time : d.data.start_time,
+                    title : d.data.title,
+                    description : d.data.description,
+                    venue : d.data.venue
+                });
+            });
+        }
+        
+        this.renderEvents();
+        
+        if(this.calevents.length && this.loadMask){
+            this.maskEl.hide();
+        }
+    },
+    
+    onBeforeLoad: function()
+    {
+        this.clearEvents();
+        if(this.loadMask){
+            this.maskEl.show();
+        }
+    }
+});
+
+ /*
+ * - LGPL
+ *
+ * element
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Popover
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Popover class
+ * @cfg {String} html contents of the popover   (or false to use children..)
+ * @cfg {String} title of popover (or false to hide)
+ * @cfg {String} placement how it is placed
+ * @cfg {String} trigger click || hover (or false to trigger manually)
+ * @cfg {String} over what (parent or false to trigger manually.)
+ * @cfg {Number} delay - delay before showing
+ * @constructor
+ * Create a new Popover
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Popover = function(config){
+    Roo.bootstrap.Popover.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.Popover, Roo.bootstrap.Component,  {
+    
+    title: 'Fill in a title',
+    html: false,
+    
+    placement : 'right',
+    trigger : 'hover', // hover
+    
+    delay : 0,
+    
+    over: 'parent',
+    
+    can_build_overlaid : false,
+    
+    getChildContainer : function()
+    {
+        return this.el.select('.popover-content',true).first();
+    },
+    
+    getAutoCreate : function(){
+         Roo.log('make popover?');
+        var cfg = {
+           cls : 'popover roo-dynamic',
+           style: 'display:block',
+           cn : [
+                {
+                    cls : 'arrow'
+                },
+                {
+                    cls : 'popover-inner',
+                    cn : [
+                        {
+                            tag: 'h3',
+                            cls: 'popover-title',
+                            html : this.title
+                        },
+                        {
+                            cls : 'popover-content',
+                            html : this.html
+                        }
+                    ]
+                    
+                }
+           ]
+        };
+        
+        return cfg;
+    },
+    setTitle: function(str)
+    {
+        this.el.select('.popover-title',true).first().dom.innerHTML = str;
+    },
+    setContent: function(str)
+    {
+        this.el.select('.popover-content',true).first().dom.innerHTML = str;
+    },
+    // as it get's added to the bottom of the page.
+    onRender : function(ct, position)
+    {
+        Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
+        if(!this.el){
+            var cfg = Roo.apply({},  this.getAutoCreate());
+            cfg.id = Roo.id();
+            
+            if (this.cls) {
+                cfg.cls += ' ' + this.cls;
+            }
+            if (this.style) {
+                cfg.style = this.style;
+            }
+            Roo.log("adding to ")
+            this.el = Roo.get(document.body).createChild(cfg, position);
+            Roo.log(this.el);
+        }
+        this.initEvents();
+    },
+    
+    initEvents : function()
+    {
+        this.el.select('.popover-title',true).setVisibilityMode(Roo.Element.DISPLAY);
+        this.el.enableDisplayMode('block');
+        this.el.hide();
+        if (this.over === false) {
+            return; 
+        }
+        if (this.triggers === false) {
+            return;
+        }
+        var on_el = (this.over == 'parent') ? this.parent().el : Roo.get(this.over);
+        var triggers = this.trigger ? this.trigger.split(' ') : [];
+        Roo.each(triggers, function(trigger) {
+        
+            if (trigger == 'click') {
+                on_el.on('click', this.toggle, this);
+            } else if (trigger != 'manual') {
+                var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin';
+                var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout';
+      
+                on_el.on(eventIn  ,this.enter, this);
+                on_el.on(eventOut, this.leave, this);
+            }
+        }, this);
+        
+    },
+    
+    
+    // private
+    timeout : null,
+    hoverState : null,
+    
+    toggle : function () {
+        this.hoverState == 'in' ? this.leave() : this.enter();
+    },
+    
+    enter : function () {
+       
+    
+        clearTimeout(this.timeout);
+    
+        this.hoverState = 'in';
+    
+        if (!this.delay || !this.delay.show) {
+            this.show();
+            return;
+        }
+        var _t = this;
+        this.timeout = setTimeout(function () {
+            if (_t.hoverState == 'in') {
+                _t.show();
+            }
+        }, this.delay.show)
+    },
+    leave : function() {
+        clearTimeout(this.timeout);
+    
+        this.hoverState = 'out';
+    
+        if (!this.delay || !this.delay.hide) {
+            this.hide();
+            return;
+        }
+        var _t = this;
+        this.timeout = setTimeout(function () {
+            if (_t.hoverState == 'out') {
+                _t.hide();
+            }
+        }, this.delay.hide)
+    },
+    
+    show : function (on_el)
+    {
+        if (!on_el) {
+            on_el= (this.over == 'parent') ? this.parent().el : Roo.get(this.over);
+        }
+        // set content.
+        this.el.select('.popover-title',true).first().dom.innerHtml = this.title;
+        if (this.html !== false) {
+            this.el.select('.popover-content',true).first().dom.innerHtml = this.title;
+        }
+        this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
+        if (!this.title.length) {
+            this.el.select('.popover-title',true).hide();
+        }
+        
+        var placement = typeof this.placement == 'function' ?
+            this.placement.call(this, this.el, on_el) :
+            this.placement;
+            
+        var autoToken = /\s?auto?\s?/i;
+        var autoPlace = autoToken.test(placement);
+        if (autoPlace) {
+            placement = placement.replace(autoToken, '') || 'top';
+        }
+        
+        //this.el.detach()
+        //this.el.setXY([0,0]);
+        this.el.show();
+        this.el.dom.style.display='block';
+        this.el.addClass(placement);
+        
+        //this.el.appendTo(on_el);
+        
+        var p = this.getPosition();
+        var box = this.el.getBox();
+        
+        if (autoPlace) {
+            // fixme..
+        }
+        var align = Roo.bootstrap.Popover.alignment[placement];
+        this.el.alignTo(on_el, align[0],align[1]);
+        //var arrow = this.el.select('.arrow',true).first();
+        //arrow.set(align[2], 
+        
+        this.el.addClass('in');
+        this.hoverState = null;
+        
+        if (this.el.hasClass('fade')) {
+            // fade it?
+        }
+        
+    },
+    hide : function()
+    {
+        this.el.setXY([0,0]);
+        this.el.removeClass('in');
+        this.el.hide();
+        
+    }
+    
+});
+
+Roo.bootstrap.Popover.alignment = {
+    'left' : ['r-l', [-10,0], 'right'],
+    'right' : ['l-r', [10,0], 'left'],
+    'bottom' : ['t-b', [0,10], 'top'],
+    'top' : [ 'b-t', [0,-10], 'bottom']
+};
+
+ /*
+ * - LGPL
+ *
+ * Progress
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Progress
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Progress class
+ * @cfg {Boolean} striped striped of the progress bar
+ * @cfg {Boolean} active animated of the progress bar
+ * 
+ * 
+ * @constructor
+ * Create a new Progress
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Progress = function(config){
+    Roo.bootstrap.Progress.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.Progress, Roo.bootstrap.Component,  {
+    
+    striped : false,
+    active: false,
+    
+    getAutoCreate : function(){
+        var cfg = {
+            tag: 'div',
+            cls: 'progress'
+        };
+        
+        
+        if(this.striped){
+            cfg.cls += ' progress-striped';
+        }
+      
+        if(this.active){
+            cfg.cls += ' active';
+        }
+        
+        
+        return cfg;
+    }
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * ProgressBar
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.ProgressBar
+ * @extends Roo.bootstrap.Component
+ * Bootstrap ProgressBar class
+ * @cfg {Number} aria_valuenow aria-value now
+ * @cfg {Number} aria_valuemin aria-value min
+ * @cfg {Number} aria_valuemax aria-value max
+ * @cfg {String} label label for the progress bar
+ * @cfg {String} panel (success | info | warning | danger )
+ * @cfg {String} role role of the progress bar
+ * @cfg {String} sr_only text
+ * 
+ * 
+ * @constructor
+ * Create a new ProgressBar
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.ProgressBar = function(config){
+    Roo.bootstrap.ProgressBar.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.ProgressBar, Roo.bootstrap.Component,  {
+    
+    aria_valuenow : 0,
+    aria_valuemin : 0,
+    aria_valuemax : 100,
+    label : false,
+    panel : false,
+    role : false,
+    sr_only: false,
+    
+    getAutoCreate : function()
+    {
+        
+        var cfg = {
+            tag: 'div',
+            cls: 'progress-bar',
+            style: 'width:' + Math.ceil((this.aria_valuenow / this.aria_valuemax) * 100) + '%'
+        };
+        
+        if(this.sr_only){
+            cfg.cn = {
+                tag: 'span',
+                cls: 'sr-only',
+                html: this.sr_only
+            }
+        }
+        
+        if(this.role){
+            cfg.role = this.role;
+        }
+        
+        if(this.aria_valuenow){
+            cfg['aria-valuenow'] = this.aria_valuenow;
+        }
+        
+        if(this.aria_valuemin){
+            cfg['aria-valuemin'] = this.aria_valuemin;
+        }
+        
+        if(this.aria_valuemax){
+            cfg['aria-valuemax'] = this.aria_valuemax;
+        }
+        
+        if(this.label && !this.sr_only){
+            cfg.html = this.label;
+        }
+        
+        if(this.panel){
+            cfg.cls += ' progress-bar-' + this.panel;
+        }
+        
+        return cfg;
+    },
+    
+    update : function(aria_valuenow)
+    {
+        this.aria_valuenow = aria_valuenow;
+        
+        this.el.setStyle('width', Math.ceil((this.aria_valuenow / this.aria_valuemax) * 100) + '%');
+    }
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * column
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TabGroup
+ * @extends Roo.bootstrap.Column
+ * Bootstrap Column class
+ * @cfg {String} navId the navigation id (for use with navbars) - will be auto generated if it does not exist..
+ * @cfg {Boolean} carousel true to make the group behave like a carousel
+ * 
+ * @constructor
+ * Create a new TabGroup
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TabGroup = function(config){
+    Roo.bootstrap.TabGroup.superclass.constructor.call(this, config);
+    if (!this.navId) {
+        this.navId = Roo.id();
+    }
+    this.tabs = [];
+    Roo.bootstrap.TabGroup.register(this);
+    
+};
+
+Roo.extend(Roo.bootstrap.TabGroup, Roo.bootstrap.Column,  {
+    
+    carousel : false,
+    transition : false,
+     
+    getAutoCreate : function()
+    {
+        var cfg = Roo.apply({}, Roo.bootstrap.TabGroup.superclass.getAutoCreate.call(this));
+        
+        cfg.cls += ' tab-content';
+        
+        if (this.carousel) {
+            cfg.cls += ' carousel slide';
+            cfg.cn = [{
+               cls : 'carousel-inner'
+            }]
+        }
+        
+        
+        return cfg;
+    },
+    getChildContainer : function()
+    {
+        return this.carousel ? this.el.select('.carousel-inner', true).first() : this.el;
+    },
+    
+    /**
+    * register a Navigation item
+    * @param {Roo.bootstrap.NavItem} the navitem to add
+    */
+    register : function(item)
+    {
+        this.tabs.push( item);
+        item.navId = this.navId; // not really needed..
+    
+    },
+    
+    getActivePanel : function()
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t) {
+            if (t.active) {
+                r = t;
+                return false;
+            }
+            return null;
+        });
+        return r;
+        
+    },
+    getPanelByName : function(n)
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t) {
+            if (t.tabId == n) {
+                r = t;
+                return false;
+            }
+            return null;
+        });
+        return r;
+    },
+    indexOfPanel : function(p)
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t,i) {
+            if (t.tabId == p.tabId) {
+                r = i;
+                return false;
+            }
+            return null;
+        });
+        return r;
+    },
+    /**
+     * show a specific panel
+     * @param {Roo.bootstrap.TabPanel|number|string} panel to change to (use the tabId to specify a specific one)
+     * @return {boolean} false if panel was not shown (invalid entry or beforedeactivate fails.)
+     */
+    showPanel : function (pan)
+    {
+        
+        if (typeof(pan) == 'number') {
+            pan = this.tabs[pan];
+        }
+        if (typeof(pan) == 'string') {
+            pan = this.getPanelByName(pan);
+        }
+        if (pan.tabId == this.getActivePanel().tabId) {
+            return true;
+        }
+        var cur = this.getActivePanel();
+        
+        if (false === cur.fireEvent('beforedeactivate')) {
+            return false;
+        }
+        
+        if (this.carousel && typeof(Roo.get(document.body).dom.style.transition) != 'undefined') {
+            
+            this.transition = true;
+            var dir = this.indexOfPanel(pan) > this.indexOfPanel(cur)  ? 'next' : 'prev';
+            var lr = dir == 'next' ? 'left' : 'right';
+            pan.el.addClass(dir); // or prev
+            pan.el.dom.offsetWidth; // find the offset with - causing a reflow?
+            cur.el.addClass(lr); // or right
+            pan.el.addClass(lr);
+            
+            var _this = this;
+            cur.el.on('transitionend', function() {
+                Roo.log("trans end?");
+                
+                pan.el.removeClass([lr,dir]);
+                pan.setActive(true);
+                
+                cur.el.removeClass([lr]);
+                cur.setActive(false);
+                
+                _this.transition = false;
+                
+            }, this, { single:  true } );
+            return true;
+        }
+        
+        cur.setActive(false);
+        pan.setActive(true);
+        return true;
+        
+    },
+    showPanelNext : function()
+    {
+        var i = this.indexOfPanel(this.getActivePanel());
+        if (i > this.tabs.length) {
+            return;
+        }
+        this.showPanel(this.tabs[i+1]);
+    },
+    showPanelPrev : function()
+    {
+        var i = this.indexOfPanel(this.getActivePanel());
+        if (i  < 1) {
+            return;
+        }
+        this.showPanel(this.tabs[i-1]);
+    }
+    
+    
+  
+});
+
+
+Roo.apply(Roo.bootstrap.TabGroup, {
+    
+    groups: {},
+     /**
+    * register a Navigation Group
+    * @param {Roo.bootstrap.NavGroup} the navgroup to add
+    */
+    register : function(navgrp)
+    {
+        this.groups[navgrp.navId] = navgrp;
+       
+    },
+    /**
+    * fetch a Navigation Group based on the navigation ID
+    * if one does not exist , it will get created.
+    * @param {string} the navgroup to add
+    * @returns {Roo.bootstrap.NavGroup} the navgroup 
+    */
+    get: function(navId) {
+        if (typeof(this.groups[navId]) == 'undefined') {
+            this.register(new Roo.bootstrap.TabGroup({ navId : navId }));
+        }
+        return this.groups[navId] ;
+    }
+    
+    
+    
+});
+
+ /*
+ * - LGPL
+ *
+ * TabPanel
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TabPanel
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TabPanel class
+ * @cfg {Boolean} active panel active
+ * @cfg {String} html panel content
+ * @cfg {String} tabId  unique tab ID (will be autogenerated if not set. - used to match TabItem to Panel)
+ * @cfg {String} navId The Roo.bootstrap.NavGroup which triggers show hide ()
+ * 
+ * 
+ * @constructor
+ * Create a new TabPanel
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TabPanel = function(config){
+    Roo.bootstrap.TabPanel.superclass.constructor.call(this, config);
+    this.addEvents({
+        /**
+            * @event changed
+            * Fires when the active status changes
+            * @param {Roo.bootstrap.TabPanel} this
+            * @param {Boolean} state the new state
+           
+         */
+        'changed': true,
+        /**
+            * @event beforedeactivate
+            * Fires before a tab is de-activated - can be used to do validation on a form.
+            * @param {Roo.bootstrap.TabPanel} this
+            * @return {Boolean} false if there is an error
+           
+         */
+        'beforedeactivate': true
+     });
+    
+    this.tabId = this.tabId || Roo.id();
+  
+};
+
+Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
+    
+    active: false,
+    html: false,
+    tabId: false,
+    navId : false,
+    
+    getAutoCreate : function(){
+        var cfg = {
+            tag: 'div',
+            // item is needed for carousel - not sure if it has any effect otherwise
+            cls: 'tab-pane item',
+            html: this.html || ''
+        };
+        
+        if(this.active){
+            cfg.cls += ' active';
+        }
+        
+        if(this.tabId){
+            cfg.tabId = this.tabId;
+        }
+        
+        
+        return cfg;
+    },
+    
+    initEvents:  function()
+    {
+        Roo.log('-------- init events on tab panel ---------');
+        
+        var p = this.parent();
+        this.navId = this.navId || p.navId;
+        
+        if (typeof(this.navId) != 'undefined') {
+            // not really needed.. but just in case.. parent should be a NavGroup.
+            var tg = Roo.bootstrap.TabGroup.get(this.navId);
+            Roo.log(['register', tg, this]);
+            tg.register(this);
+        }
+    },
+    
+    
+    onRender : function(ct, position)
+    {
+       // Roo.log("Call onRender: " + this.xtype);
+        
+        Roo.bootstrap.TabPanel.superclass.onRender.call(this, ct, position);
+        
+        
+        
+        
+        
+    },
+    
+    setActive: function(state)
+    {
+        Roo.log("panel - set active " + this.tabId + "=" + state);
+        
+        this.active = state;
+        if (!state) {
+            this.el.removeClass('active');
+            
+        } else  if (!this.el.hasClass('active')) {
+            this.el.addClass('active');
+        }
+        this.fireEvent('changed', this, state);
+    }
+    
+    
+});
+
+
+ /*
+ * - LGPL
+ *
+ * DateField
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.DateField
+ * @extends Roo.bootstrap.Input
+ * Bootstrap DateField class
+ * @cfg {Number} weekStart default 0
+ * @cfg {String} viewMode default empty, (months|years)
+ * @cfg {String} minViewMode default empty, (months|years)
+ * @cfg {Number} startDate default -Infinity
+ * @cfg {Number} endDate default Infinity
+ * @cfg {Boolean} todayHighlight default false
+ * @cfg {Boolean} todayBtn default false
+ * @cfg {Boolean} calendarWeeks default false
+ * @cfg {Object} daysOfWeekDisabled default empty
+ * @cfg {Boolean} singleMode default false (true | false)
+ * 
+ * @cfg {Boolean} keyboardNavigation default true
+ * @cfg {String} language default en
+ * 
+ * @constructor
+ * Create a new DateField
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.DateField = function(config){
+    Roo.bootstrap.DateField.superclass.constructor.call(this, config);
+     this.addEvents({
+            /**
+             * @event show
+             * Fires when this field show.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            show : true,
+            /**
+             * @event show
+             * Fires when this field hide.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            hide : true,
+            /**
+             * @event select
+             * Fires when select a date.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            select : true
+        });
+};
+
+Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
+    
+    /**
+     * @cfg {String} format
+     * The default date format string which can be overriden for localization support.  The format must be
+     * valid according to {@link Date#parseDate} (defaults to 'm/d/y').
+     */
+    format : "m/d/y",
+    /**
+     * @cfg {String} altFormats
+     * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
+     * format (defaults to 'm/d/Y|m-d-y|m-d-Y|m/d|m-d|d').
+     */
+    altFormats : "m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d",
+    
+    weekStart : 0,
+    
+    viewMode : '',
+    
+    minViewMode : '',
+    
+    todayHighlight : false,
+    
+    todayBtn: false,
+    
+    language: 'en',
+    
+    keyboardNavigation: true,
+    
+    calendarWeeks: false,
+    
+    startDate: -Infinity,
+    
+    endDate: Infinity,
+    
+    daysOfWeekDisabled: [],
+    
+    _events: [],
+    
+    singleMode : false,
+    
+    UTCDate: function()
+    {
+        return new Date(Date.UTC.apply(Date, arguments));
+    },
+    
+    UTCToday: function()
+    {
+        var today = new Date();
+        return this.UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate());
+    },
+    
+    getDate: function() {
+            var d = this.getUTCDate();
+            return new Date(d.getTime() + (d.getTimezoneOffset()*60000));
+    },
+    
+    getUTCDate: function() {
+            return this.date;
+    },
+    
+    setDate: function(d) {
+            this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset()*60000)));
+    },
+    
+    setUTCDate: function(d) {
+            this.date = d;
+            this.setValue(this.formatDate(this.date));
+    },
+        
+    onRender: function(ct, position)
+    {
+        
+        Roo.bootstrap.DateField.superclass.onRender.call(this, ct, position);
+        
+        this.language = this.language || 'en';
+        this.language = this.language in Roo.bootstrap.DateField.dates ? this.language : this.language.split('-')[0];
+        this.language = this.language in Roo.bootstrap.DateField.dates ? this.language : "en";
+        
+        this.isRTL = Roo.bootstrap.DateField.dates[this.language].rtl || false;
+        this.format = this.format || 'm/d/y';
+        this.isInline = false;
+        this.isInput = true;
+        this.component = this.el.select('.add-on', true).first() || false;
+        this.component = (this.component && this.component.length === 0) ? false : this.component;
+        this.hasInput = this.component && this.inputEL().length;
+        
+        if (typeof(this.minViewMode === 'string')) {
+            switch (this.minViewMode) {
+                case 'months':
+                    this.minViewMode = 1;
+                    break;
+                case 'years':
+                    this.minViewMode = 2;
+                    break;
+                default:
+                    this.minViewMode = 0;
+                    break;
+            }
+        }
+        
+        if (typeof(this.viewMode === 'string')) {
+            switch (this.viewMode) {
+                case 'months':
+                    this.viewMode = 1;
+                    break;
+                case 'years':
+                    this.viewMode = 2;
+                    break;
+                default:
+                    this.viewMode = 0;
+                    break;
+            }
+        }
+                
+        this.pickerEl = Roo.get(document.body).createChild(Roo.bootstrap.DateField.template);
+        
+//        this.el.select('>.input-group', true).first().createChild(Roo.bootstrap.DateField.template);
+        
+        this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.picker().on('mousedown', this.onMousedown, this);
+        this.picker().on('click', this.onClick, this);
+        
+        this.picker().addClass('datepicker-dropdown');
+        
+        this.startViewMode = this.viewMode;
+        
+        if(this.singleMode){
+            Roo.each(this.picker().select('thead > tr > th', true).elements, function(v){
+                v.setVisibilityMode(Roo.Element.DISPLAY)
+                v.hide();
+            });
+            
+            Roo.each(this.picker().select('tbody > tr > td', true).elements, function(v){
+                v.setStyle('width', '189px');
+            });
+        }
+        
+        Roo.each(this.picker().select('tfoot th.today', true).elements, function(v){
+            if(!this.calendarWeeks){
+                v.remove();
+                return;
+            }
+            
+            v.dom.innerHTML = Roo.bootstrap.DateField.dates[this.language].today;
+            v.attr('colspan', function(i, val){
+                return parseInt(val) + 1;
+            });
+        })
+                       
+        
+        this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
+        
+        this.setStartDate(this.startDate);
+        this.setEndDate(this.endDate);
+        
+        this.setDaysOfWeekDisabled(this.daysOfWeekDisabled);
+        
+        this.fillDow();
+        this.fillMonths();
+        this.update();
+        this.showMode();
+        
+        if(this.isInline) {
+            this.show();
+        }
+    },
+    
+    picker : function()
+    {
+        return this.pickerEl;
+//        return this.el.select('.datepicker', true).first();
+    },
+    
+    fillDow: function()
+    {
+        var dowCnt = this.weekStart;
+        
+        var dow = {
+            tag: 'tr',
+            cn: [
+                
+            ]
+        };
+        
+        if(this.calendarWeeks){
+            dow.cn.push({
+                tag: 'th',
+                cls: 'cw',
+                html: '&nbsp;'
+            })
+        }
+        
+        while (dowCnt < this.weekStart + 7) {
+            dow.cn.push({
+                tag: 'th',
+                cls: 'dow',
+                html: Roo.bootstrap.DateField.dates[this.language].daysMin[(dowCnt++)%7]
+            });
+        }
+        
+        this.picker().select('>.datepicker-days thead', true).first().createChild(dow);
+    },
+    
+    fillMonths: function()
+    {    
+        var i = 0;
+        var months = this.picker().select('>.datepicker-months td', true).first();
+        
+        months.dom.innerHTML = '';
+        
+        while (i < 12) {
+            var month = {
+                tag: 'span',
+                cls: 'month',
+                html: Roo.bootstrap.DateField.dates[this.language].monthsShort[i++]
+            }
+            
+            months.createChild(month);
+        }
+        
+    },
+    
+    update: function()
+    {
+        this.date = (typeof(this.date) === 'undefined' || ((typeof(this.date) === 'string') && !this.date.length)) ? this.UTCToday() : (typeof(this.date) === 'string') ? this.parseDate(this.date) : this.date;
+        
+        if (this.date < this.startDate) {
+            this.viewDate = new Date(this.startDate);
+        } else if (this.date > this.endDate) {
+            this.viewDate = new Date(this.endDate);
+        } else {
+            this.viewDate = new Date(this.date);
+        }
+        
+        this.fill();
+    },
+    
+    fill: function() 
+    {
+        var d = new Date(this.viewDate),
+                year = d.getUTCFullYear(),
+                month = d.getUTCMonth(),
+                startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,
+                startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
+                endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
+                endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
+                currentDate = this.date && this.date.valueOf(),
+                today = this.UTCToday();
+        
+        this.picker().select('>.datepicker-days thead th.switch', true).first().dom.innerHTML = Roo.bootstrap.DateField.dates[this.language].months[month]+' '+year;
+        
+//        this.picker().select('>tfoot th.today', true).first().dom.innerHTML = Roo.bootstrap.DateField.dates[this.language].today;
+        
+//        this.picker.select('>tfoot th.today').
+//                                             .text(dates[this.language].today)
+//                                             .toggle(this.todayBtn !== false);
+    
+        this.updateNavArrows();
+        this.fillMonths();
+                                                
+        var prevMonth = this.UTCDate(year, month-1, 28,0,0,0,0),
+        
+        day = prevMonth.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
+         
+        prevMonth.setUTCDate(day);
+        
+        prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7)%7);
+        
+        var nextMonth = new Date(prevMonth);
+        
+        nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
+        
+        nextMonth = nextMonth.valueOf();
+        
+        var fillMonths = false;
+        
+        this.picker().select('>.datepicker-days tbody',true).first().dom.innerHTML = '';
+        
+        while(prevMonth.valueOf() < nextMonth) {
+            var clsName = '';
+            
+            if (prevMonth.getUTCDay() === this.weekStart) {
+                if(fillMonths){
+                    this.picker().select('>.datepicker-days tbody',true).first().createChild(fillMonths);
+                }
+                    
+                fillMonths = {
+                    tag: 'tr',
+                    cn: []
+                };
+                
+                if(this.calendarWeeks){
+                    // ISO 8601: First week contains first thursday.
+                    // ISO also states week starts on Monday, but we can be more abstract here.
+                    var
+                    // Start of current week: based on weekstart/current date
+                    ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
+                    // Thursday of this week
+                    th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
+                    // First Thursday of year, year from thursday
+                    yth = new Date(+(yth = this.UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
+                    // Calendar week: ms between thursdays, div ms per day, div 7 days
+                    calWeek =  (th - yth) / 864e5 / 7 + 1;
+                    
+                    fillMonths.cn.push({
+                        tag: 'td',
+                        cls: 'cw',
+                        html: calWeek
+                    });
+                }
+            }
+            
+            if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
+                clsName += ' old';
+            } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) {
+                clsName += ' new';
+            }
+            if (this.todayHighlight &&
+                prevMonth.getUTCFullYear() == today.getFullYear() &&
+                prevMonth.getUTCMonth() == today.getMonth() &&
+                prevMonth.getUTCDate() == today.getDate()) {
+                clsName += ' today';
+            }
+            
+            if (currentDate && prevMonth.valueOf() === currentDate) {
+                clsName += ' active';
+            }
+            
+            if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate ||
+                    this.daysOfWeekDisabled.indexOf(prevMonth.getUTCDay()) !== -1) {
+                    clsName += ' disabled';
+            }
+            
+            fillMonths.cn.push({
+                tag: 'td',
+                cls: 'day ' + clsName,
+                html: prevMonth.getDate()
+            })
+            
+            prevMonth.setDate(prevMonth.getDate()+1);
+        }
+          
+        var currentYear = this.date && this.date.getUTCFullYear();
+        var currentMonth = this.date && this.date.getUTCMonth();
+        
+        this.picker().select('>.datepicker-months th.switch',true).first().dom.innerHTML = year;
+        
+        Roo.each(this.picker().select('>.datepicker-months tbody span',true).elements, function(v,k){
+            v.removeClass('active');
+            
+            if(currentYear === year && k === currentMonth){
+                v.addClass('active');
+            }
+            
+            if (year < startYear || year > endYear || (year == startYear && k < startMonth) || (year == endYear && k > endMonth)) {
+                v.addClass('disabled');
+            }
+            
+        });
+        
+        
+        year = parseInt(year/10, 10) * 10;
+        
+        this.picker().select('>.datepicker-years th.switch', true).first().dom.innerHTML = year + '-' + (year + 9);
+        
+        this.picker().select('>.datepicker-years tbody td',true).first().dom.innerHTML = '';
+        
+        year -= 1;
+        for (var i = -1; i < 11; i++) {
+            this.picker().select('>.datepicker-years tbody td',true).first().createChild({
+                tag: 'span',
+                cls: 'year' + (i === -1 || i === 10 ? ' old' : '') + (currentYear === year ? ' active' : '') + (year < startYear || year > endYear ? ' disabled' : ''),
+                html: year
+            })
+            
+            year += 1;
+        }
+    },
+    
+    showMode: function(dir) 
+    {
+        if (dir) {
+            this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
+        }
+        
+        Roo.each(this.picker().select('>div',true).elements, function(v){
+            v.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+            v.hide();
+        });
+        this.picker().select('>.datepicker-'+Roo.bootstrap.DateField.modes[this.viewMode].clsName, true).first().show();
+    },
+    
+    place: function()
+    {
+        if(this.isInline) return;
+        
+        this.picker().removeClass(['bottom', 'top']);
+        
+        if((Roo.lib.Dom.getViewHeight() + Roo.get(document.body).getScroll().top) - (this.inputEl().getBottom() + this.picker().getHeight()) < 0){
+            /*
+             * place to the top of element!
+             *
+             */
+            
+            this.picker().addClass('top');
+            this.picker().setTop(this.inputEl().getTop() - this.picker().getHeight()).setLeft(this.inputEl().getLeft());
+            
+            return;
+        }
+        
+        this.picker().addClass('bottom');
+        
+        this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());
+    },
+    
+    parseDate : function(value)
+    {
+        if(!value || value instanceof Date){
+            return value;
+        }
+        var v = Date.parseDate(value, this.format);
+        if (!v && (this.useIso || value.match(/^(\d{4})-0?(\d+)-0?(\d+)/))) {
+            v = Date.parseDate(value, 'Y-m-d');
+        }
+        if(!v && this.altFormats){
+            if(!this.altFormatsArray){
+                this.altFormatsArray = this.altFormats.split("|");
+            }
+            for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
+                v = Date.parseDate(value, this.altFormatsArray[i]);
+            }
+        }
+        return v;
+    },
+    
+    formatDate : function(date, fmt)
+    {   
+        return (!date || !(date instanceof Date)) ?
+        date : date.dateFormat(fmt || this.format);
+    },
+    
+    onFocus : function()
+    {
+        Roo.bootstrap.DateField.superclass.onFocus.call(this);
+        this.show();
+    },
+    
+    onBlur : function()
+    {
+        Roo.bootstrap.DateField.superclass.onBlur.call(this);
+        
+        var d = this.inputEl().getValue();
+        
+        this.setValue(d);
+                
+        this.hide();
+    },
+    
+    show : function()
+    {
+        this.picker().show();
+        this.update();
+        this.place();
+        
+        this.fireEvent('show', this, this.date);
+    },
+    
+    hide : function()
+    {
+        if(this.isInline) return;
+        this.picker().hide();
+        this.viewMode = this.startViewMode;
+        this.showMode();
+        
+        this.fireEvent('hide', this, this.date);
+        
+    },
+    
+    onMousedown: function(e)
+    {
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    keyup: function(e)
+    {
+        Roo.bootstrap.DateField.superclass.keyup.call(this);
+        this.update();
+    },
+
+    setValue: function(v)
+    {
+        
+        // v can be a string or a date..
+        
+        
+        var d = new Date(this.parseDate(v) ).clearTime();
+        
+        if(isNaN(d.getTime())){
+            this.date = this.viewDate = '';
+            Roo.bootstrap.DateField.superclass.setValue.call(this, '');
+            return;
+        }
+        
+        v = this.formatDate(d);
+        
+        Roo.bootstrap.DateField.superclass.setValue.call(this, v);
+        
+        this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
+     
+        this.update();
+
+        this.fireEvent('select', this, this.date);
+        
+    },
+    
+    getValue: function()
+    {
+        return this.formatDate(this.date);
+    },
+    
+    fireKey: function(e)
+    {
+        if (!this.picker().isVisible()){
+            if (e.keyCode == 27) // allow escape to hide and re-show picker
+                this.show();
+            return;
+        }
+        
+        var dateChanged = false,
+        dir, day, month,
+        newDate, newViewDate;
+        
+        switch(e.keyCode){
+            case 27: // escape
+                this.hide();
+                e.preventDefault();
+                break;
+            case 37: // left
+            case 39: // right
+                if (!this.keyboardNavigation) break;
+                dir = e.keyCode == 37 ? -1 : 1;
+                
+                if (e.ctrlKey){
+                    newDate = this.moveYear(this.date, dir);
+                    newViewDate = this.moveYear(this.viewDate, dir);
+                } else if (e.shiftKey){
+                    newDate = this.moveMonth(this.date, dir);
+                    newViewDate = this.moveMonth(this.viewDate, dir);
+                } else {
+                    newDate = new Date(this.date);
+                    newDate.setUTCDate(this.date.getUTCDate() + dir);
+                    newViewDate = new Date(this.viewDate);
+                    newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir);
+                }
+                if (this.dateWithinRange(newDate)){
+                    this.date = newDate;
+                    this.viewDate = newViewDate;
+                    this.setValue(this.formatDate(this.date));
+//                    this.update();
+                    e.preventDefault();
+                    dateChanged = true;
+                }
+                break;
+            case 38: // up
+            case 40: // down
+                if (!this.keyboardNavigation) break;
+                dir = e.keyCode == 38 ? -1 : 1;
+                if (e.ctrlKey){
+                    newDate = this.moveYear(this.date, dir);
+                    newViewDate = this.moveYear(this.viewDate, dir);
+                } else if (e.shiftKey){
+                    newDate = this.moveMonth(this.date, dir);
+                    newViewDate = this.moveMonth(this.viewDate, dir);
+                } else {
+                    newDate = new Date(this.date);
+                    newDate.setUTCDate(this.date.getUTCDate() + dir * 7);
+                    newViewDate = new Date(this.viewDate);
+                    newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7);
+                }
+                if (this.dateWithinRange(newDate)){
+                    this.date = newDate;
+                    this.viewDate = newViewDate;
+                    this.setValue(this.formatDate(this.date));
+//                    this.update();
+                    e.preventDefault();
+                    dateChanged = true;
+                }
+                break;
+            case 13: // enter
+                this.setValue(this.formatDate(this.date));
+                this.hide();
+                e.preventDefault();
+                break;
+            case 9: // tab
+                this.setValue(this.formatDate(this.date));
+                this.hide();
+                break;
+            case 16: // shift
+            case 17: // ctrl
+            case 18: // alt
+                break;
+            default :
+                this.hide();
+                
+        }
+    },
+    
+    
+    onClick: function(e) 
+    {
+        e.stopPropagation();
+        e.preventDefault();
+        
+        var target = e.getTarget();
+        
+        if(target.nodeName.toLowerCase() === 'i'){
+            target = Roo.get(target).dom.parentNode;
+        }
+        
+        var nodeName = target.nodeName;
+        var className = target.className;
+        var html = target.innerHTML;
+        //Roo.log(nodeName);
+        
+        switch(nodeName.toLowerCase()) {
+            case 'th':
+                switch(className) {
+                    case 'switch':
+                        this.showMode(1);
+                        break;
+                    case 'prev':
+                    case 'next':
+                        var dir = Roo.bootstrap.DateField.modes[this.viewMode].navStep * (className == 'prev' ? -1 : 1);
+                        switch(this.viewMode){
+                                case 0:
+                                        this.viewDate = this.moveMonth(this.viewDate, dir);
+                                        break;
+                                case 1:
+                                case 2:
+                                        this.viewDate = this.moveYear(this.viewDate, dir);
+                                        break;
+                        }
+                        this.fill();
+                        break;
+                    case 'today':
+                        var date = new Date();
+                        this.date = this.UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
+//                        this.fill()
+                        this.setValue(this.formatDate(this.date));
+                        
+                        this.hide();
+                        break;
+                }
+                break;
+            case 'span':
+                if (className.indexOf('disabled') < 0) {
+                    this.viewDate.setUTCDate(1);
+                    if (className.indexOf('month') > -1) {
+                        this.viewDate.setUTCMonth(Roo.bootstrap.DateField.dates[this.language].monthsShort.indexOf(html));
+                    } else {
+                        var year = parseInt(html, 10) || 0;
+                        this.viewDate.setUTCFullYear(year);
+                        
+                    }
+                    
+                    if(this.singleMode){
+                        this.setValue(this.formatDate(this.viewDate));
+                        this.hide();
+                        return;
+                    }
+                    
+                    this.showMode(-1);
+                    this.fill();
+                }
+                break;
+                
+            case 'td':
+                //Roo.log(className);
+                if (className.indexOf('day') > -1 && className.indexOf('disabled') < 0 ){
+                    var day = parseInt(html, 10) || 1;
+                    var year = this.viewDate.getUTCFullYear(),
+                        month = this.viewDate.getUTCMonth();
+
+                    if (className.indexOf('old') > -1) {
+                        if(month === 0 ){
+                            month = 11;
+                            year -= 1;
+                        }else{
+                            month -= 1;
+                        }
+                    } else if (className.indexOf('new') > -1) {
+                        if (month == 11) {
+                            month = 0;
+                            year += 1;
+                        } else {
+                            month += 1;
+                        }
+                    }
+                    //Roo.log([year,month,day]);
+                    this.date = this.UTCDate(year, month, day,0,0,0,0);
+                    this.viewDate = this.UTCDate(year, month, Math.min(28, day),0,0,0,0);
+//                    this.fill();
+                    //Roo.log(this.formatDate(this.date));
+                    this.setValue(this.formatDate(this.date));
+                    this.hide();
+                }
+                break;
+        }
+    },
+    
+    setStartDate: function(startDate)
+    {
+        this.startDate = startDate || -Infinity;
+        if (this.startDate !== -Infinity) {
+            this.startDate = this.parseDate(this.startDate);
+        }
+        this.update();
+        this.updateNavArrows();
+    },
+
+    setEndDate: function(endDate)
+    {
+        this.endDate = endDate || Infinity;
+        if (this.endDate !== Infinity) {
+            this.endDate = this.parseDate(this.endDate);
+        }
+        this.update();
+        this.updateNavArrows();
+    },
+    
+    setDaysOfWeekDisabled: function(daysOfWeekDisabled)
+    {
+        this.daysOfWeekDisabled = daysOfWeekDisabled || [];
+        if (typeof(this.daysOfWeekDisabled) !== 'object') {
+            this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
+        }
+        this.daysOfWeekDisabled = this.daysOfWeekDisabled.map(function (d) {
+            return parseInt(d, 10);
+        });
+        this.update();
+        this.updateNavArrows();
+    },
+    
+    updateNavArrows: function() 
+    {
+        if(this.singleMode){
+            return;
+        }
+        
+        var d = new Date(this.viewDate),
+        year = d.getUTCFullYear(),
+        month = d.getUTCMonth();
+        
+        Roo.each(this.picker().select('.prev', true).elements, function(v){
+            v.show();
+            switch (this.viewMode) {
+                case 0:
+
+                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth()) {
+                        v.hide();
+                    }
+                    break;
+                case 1:
+                case 2:
+                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {
+                        v.hide();
+                    }
+                    break;
+            }
+        });
+        
+        Roo.each(this.picker().select('.next', true).elements, function(v){
+            v.show();
+            switch (this.viewMode) {
+                case 0:
+
+                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth()) {
+                        v.hide();
+                    }
+                    break;
+                case 1:
+                case 2:
+                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {
+                        v.hide();
+                    }
+                    break;
+            }
+        })
+    },
+    
+    moveMonth: function(date, dir)
+    {
+        if (!dir) return date;
+        var new_date = new Date(date.valueOf()),
+        day = new_date.getUTCDate(),
+        month = new_date.getUTCMonth(),
+        mag = Math.abs(dir),
+        new_month, test;
+        dir = dir > 0 ? 1 : -1;
+        if (mag == 1){
+            test = dir == -1
+            // If going back one month, make sure month is not current month
+            // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
+            ? function(){
+                return new_date.getUTCMonth() == month;
+            }
+            // If going forward one month, make sure month is as expected
+            // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
+            : function(){
+                return new_date.getUTCMonth() != new_month;
+            };
+            new_month = month + dir;
+            new_date.setUTCMonth(new_month);
+            // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
+            if (new_month < 0 || new_month > 11)
+                new_month = (new_month + 12) % 12;
+        } else {
+            // For magnitudes >1, move one month at a time...
+            for (var i=0; i<mag; i++)
+                // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
+                new_date = this.moveMonth(new_date, dir);
+            // ...then reset the day, keeping it in the new month
+            new_month = new_date.getUTCMonth();
+            new_date.setUTCDate(day);
+            test = function(){
+                return new_month != new_date.getUTCMonth();
+            };
+        }
+        // Common date-resetting loop -- if date is beyond end of month, make it
+        // end of month
+        while (test()){
+            new_date.setUTCDate(--day);
+            new_date.setUTCMonth(new_month);
+        }
+        return new_date;
+    },
+
+    moveYear: function(date, dir)
+    {
+        return this.moveMonth(date, dir*12);
+    },
+
+    dateWithinRange: function(date)
+    {
+        return date >= this.startDate && date <= this.endDate;
+    },
+
+    
+    remove: function() 
+    {
+        this.picker().remove();
+    }
+   
+});
+
+Roo.apply(Roo.bootstrap.DateField,  {
+    
+    head : {
+        tag: 'thead',
+        cn: [
+        {
+            tag: 'tr',
+            cn: [
+            {
+                tag: 'th',
+                cls: 'prev',
+                html: '<i class="fa fa-arrow-left"/>'
+            },
+            {
+                tag: 'th',
+                cls: 'switch',
+                colspan: '5'
+            },
+            {
+                tag: 'th',
+                cls: 'next',
+                html: '<i class="fa fa-arrow-right"/>'
+            }
+
+            ]
+        }
+        ]
+    },
+    
+    content : {
+        tag: 'tbody',
+        cn: [
+        {
+            tag: 'tr',
+            cn: [
+            {
+                tag: 'td',
+                colspan: '7'
+            }
+            ]
+        }
+        ]
+    },
+    
+    footer : {
+        tag: 'tfoot',
+        cn: [
+        {
+            tag: 'tr',
+            cn: [
+            {
+                tag: 'th',
+                colspan: '7',
+                cls: 'today'
+            }
+                    
+            ]
+        }
+        ]
+    },
+    
+    dates:{
+        en: {
+            days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
+            daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+            daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
+            months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+            monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+            today: "Today"
+        }
+    },
+    
+    modes: [
+    {
+        clsName: 'days',
+        navFnc: 'Month',
+        navStep: 1
+    },
+    {
+        clsName: 'months',
+        navFnc: 'FullYear',
+        navStep: 1
+    },
+    {
+        clsName: 'years',
+        navFnc: 'FullYear',
+        navStep: 10
+    }]
+});
+
+Roo.apply(Roo.bootstrap.DateField,  {
+  
+    template : {
+        tag: 'div',
+        cls: 'datepicker dropdown-menu roo-dynamic',
+        cn: [
+        {
+            tag: 'div',
+            cls: 'datepicker-days',
+            cn: [
+            {
+                tag: 'table',
+                cls: 'table-condensed',
+                cn:[
+                Roo.bootstrap.DateField.head,
+                {
+                    tag: 'tbody'
+                },
+                Roo.bootstrap.DateField.footer
+                ]
+            }
+            ]
+        },
+        {
+            tag: 'div',
+            cls: 'datepicker-months',
+            cn: [
+            {
+                tag: 'table',
+                cls: 'table-condensed',
+                cn:[
+                Roo.bootstrap.DateField.head,
+                Roo.bootstrap.DateField.content,
+                Roo.bootstrap.DateField.footer
+                ]
+            }
+            ]
+        },
+        {
+            tag: 'div',
+            cls: 'datepicker-years',
+            cn: [
+            {
+                tag: 'table',
+                cls: 'table-condensed',
+                cn:[
+                Roo.bootstrap.DateField.head,
+                Roo.bootstrap.DateField.content,
+                Roo.bootstrap.DateField.footer
+                ]
+            }
+            ]
+        }
+        ]
+    }
+});
+
+
+ /*
+ * - LGPL
+ *
+ * TimeField
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TimeField
+ * @extends Roo.bootstrap.Input
+ * Bootstrap DateField class
+ * 
+ * 
+ * @constructor
+ * Create a new TimeField
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TimeField = function(config){
+    Roo.bootstrap.TimeField.superclass.constructor.call(this, config);
+    this.addEvents({
+            /**
+             * @event show
+             * Fires when this field show.
+             * @param {Roo.bootstrap.DateField} thisthis
+             * @param {Mixed} date The date value
+             */
+            show : true,
+            /**
+             * @event show
+             * Fires when this field hide.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            hide : true,
+            /**
+             * @event select
+             * Fires when select a date.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            select : true
+        });
+};
+
+Roo.extend(Roo.bootstrap.TimeField, Roo.bootstrap.Input,  {
+    
+    /**
+     * @cfg {String} format
+     * The default time format string which can be overriden for localization support.  The format must be
+     * valid according to {@link Date#parseDate} (defaults to 'H:i').
+     */
+    format : "H:i",
+       
+    onRender: function(ct, position)
+    {
+        
+        Roo.bootstrap.TimeField.superclass.onRender.call(this, ct, position);
+                
+        this.el.select('>.input-group', true).first().createChild(Roo.bootstrap.TimeField.template);
+        
+        this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.pop = this.picker().select('>.datepicker-time',true).first();
+        this.pop.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.picker().on('mousedown', this.onMousedown, this);
+        this.picker().on('click', this.onClick, this);
+        
+        this.picker().addClass('datepicker-dropdown');
+    
+        this.fillTime();
+        this.update();
+            
+        this.pop.select('span.hours-up', true).first().on('click', this.onIncrementHours, this);
+        this.pop.select('span.hours-down', true).first().on('click', this.onDecrementHours, this);
+        this.pop.select('span.minutes-up', true).first().on('click', this.onIncrementMinutes, this);
+        this.pop.select('span.minutes-down', true).first().on('click', this.onDecrementMinutes, this);
+        this.pop.select('button.period', true).first().on('click', this.onTogglePeriod, this);
+        this.pop.select('button.ok', true).first().on('click', this.setTime, this);
+
+    },
+    
+    fireKey: function(e){
+        if (!this.picker().isVisible()){
+            if (e.keyCode == 27) { // allow escape to hide and re-show picker
+                this.show();
+            }
+            return;
+        }
+
+        e.preventDefault();
+        
+        switch(e.keyCode){
+            case 27: // escape
+                this.hide();
+                break;
+            case 37: // left
+            case 39: // right
+                this.onTogglePeriod();
+                break;
+            case 38: // up
+                this.onIncrementMinutes();
+                break;
+            case 40: // down
+                this.onDecrementMinutes();
+                break;
+            case 13: // enter
+            case 9: // tab
+                this.setTime();
+                break;
+        }
+    },
+    
+    onClick: function(e) {
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    picker : function()
+    {
+        return this.el.select('.datepicker', true).first();
+    },
+    
+    fillTime: function()
+    {    
+        var time = this.pop.select('tbody', true).first();
+        
+        time.dom.innerHTML = '';
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'hours-up glyphicon glyphicon-chevron-up'
+                                }
+                            ]
+                        } 
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'minutes-up glyphicon glyphicon-chevron-up'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                }
+            ]
+        });
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'span',
+                            cls: 'timepicker-hour',
+                            html: '00'
+                        }  
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator',
+                    html: ':'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'span',
+                            cls: 'timepicker-minute',
+                            html: '00'
+                        }  
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'button',
+                            type: 'button',
+                            cls: 'btn btn-primary period',
+                            html: 'AM'
+                            
+                        }
+                    ]
+                }
+            ]
+        });
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'hours-down glyphicon glyphicon-chevron-down'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'minutes-down glyphicon glyphicon-chevron-down'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                }
+            ]
+        });
+        
+    },
+    
+    update: function()
+    {
+        
+        this.time = (typeof(this.time) === 'undefined') ? new Date() : this.time;
+        
+        this.fill();
+    },
+    
+    fill: function() 
+    {
+        var hours = this.time.getHours();
+        var minutes = this.time.getMinutes();
+        var period = 'AM';
+        
+        if(hours > 11){
+            period = 'PM';
+        }
+        
+        if(hours == 0){
+            hours = 12;
+        }
+        
+        
+        if(hours > 12){
+            hours = hours - 12;
+        }
+        
+        if(hours < 10){
+            hours = '0' + hours;
+        }
+        
+        if(minutes < 10){
+            minutes = '0' + minutes;
+        }
+        
+        this.pop.select('.timepicker-hour', true).first().dom.innerHTML = hours;
+        this.pop.select('.timepicker-minute', true).first().dom.innerHTML = minutes;
+        this.pop.select('button', true).first().dom.innerHTML = period;
+        
+    },
+    
+    place: function()
+    {   
+        this.picker().removeClass(['bottom-left', 'bottom-right', 'top-left', 'top-right']);
+        
+        var cls = ['bottom'];
+        
+        if((Roo.lib.Dom.getViewHeight() + Roo.get(document.body).getScroll().top) - (this.inputEl().getBottom() + this.picker().getHeight()) < 0){ // top
+            cls.pop();
+            cls.push('top');
+        }
+        
+        cls.push('right');
+        
+        if((Roo.lib.Dom.getViewWidth() + Roo.get(document.body).getScroll().left) - (this.inputEl().getLeft() + this.picker().getWidth()) < 0){ // left
+            cls.pop();
+            cls.push('left');
+        }
+        
+        this.picker().addClass(cls.join('-'));
+        
+        var _this = this;
+        
+        Roo.each(cls, function(c){
+            if(c == 'bottom'){
+                _this.picker().setTop(_this.inputEl().getHeight());
+                return;
+            }
+            if(c == 'top'){
+                _this.picker().setTop(0 - _this.picker().getHeight());
+                return;
+            }
+            
+            if(c == 'left'){
+                _this.picker().setLeft(_this.inputEl().getLeft() + _this.inputEl().getWidth() - _this.el.getLeft() - _this.picker().getWidth());
+                return;
+            }
+            if(c == 'right'){
+                _this.picker().setLeft(_this.inputEl().getLeft() - _this.el.getLeft());
+                return;
+            }
+        });
+        
+    },
+  
+    onFocus : function()
+    {
+        Roo.bootstrap.TimeField.superclass.onFocus.call(this);
+        this.show();
+    },
+    
+    onBlur : function()
+    {
+        Roo.bootstrap.TimeField.superclass.onBlur.call(this);
+        this.hide();
+    },
+    
+    show : function()
+    {
+        this.picker().show();
+        this.pop.show();
+        this.update();
+        this.place();
+        
+        this.fireEvent('show', this, this.date);
+    },
+    
+    hide : function()
+    {
+        this.picker().hide();
+        this.pop.hide();
+        
+        this.fireEvent('hide', this, this.date);
+    },
+    
+    setTime : function()
+    {
+        this.hide();
+        this.setValue(this.time.format(this.format));
+        
+        this.fireEvent('select', this, this.date);
+        
+        
+    },
+    
+    onMousedown: function(e){
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    onIncrementHours: function()
+    {
+        Roo.log('onIncrementHours');
+        this.time = this.time.add(Date.HOUR, 1);
+        this.update();
+        
+    },
+    
+    onDecrementHours: function()
+    {
+        Roo.log('onDecrementHours');
+        this.time = this.time.add(Date.HOUR, -1);
+        this.update();
+    },
+    
+    onIncrementMinutes: function()
+    {
+        Roo.log('onIncrementMinutes');
+        this.time = this.time.add(Date.MINUTE, 1);
+        this.update();
+    },
+    
+    onDecrementMinutes: function()
+    {
+        Roo.log('onDecrementMinutes');
+        this.time = this.time.add(Date.MINUTE, -1);
+        this.update();
+    },
+    
+    onTogglePeriod: function()
+    {
+        Roo.log('onTogglePeriod');
+        this.time = this.time.add(Date.HOUR, 12);
+        this.update();
+    }
+    
+   
+});
+
+Roo.apply(Roo.bootstrap.TimeField,  {
+    
+    content : {
+        tag: 'tbody',
+        cn: [
+            {
+                tag: 'tr',
+                cn: [
+                {
+                    tag: 'td',
+                    colspan: '7'
+                }
+                ]
+            }
+        ]
+    },
+    
+    footer : {
+        tag: 'tfoot',
+        cn: [
+            {
+                tag: 'tr',
+                cn: [
+                {
+                    tag: 'th',
+                    colspan: '7',
+                    cls: '',
+                    cn: [
+                        {
+                            tag: 'button',
+                            cls: 'btn btn-info ok',
+                            html: 'OK'
+                        }
+                    ]
+                }
+
+                ]
+            }
+        ]
+    }
+});
+
+Roo.apply(Roo.bootstrap.TimeField,  {
+  
+    template : {
+        tag: 'div',
+        cls: 'datepicker dropdown-menu',
+        cn: [
+            {
+                tag: 'div',
+                cls: 'datepicker-time',
+                cn: [
+                {
+                    tag: 'table',
+                    cls: 'table-condensed',
+                    cn:[
+                    Roo.bootstrap.TimeField.content,
+                    Roo.bootstrap.TimeField.footer
+                    ]
+                }
+                ]
+            }
+        ]
+    }
+});
+
+
+ /*
+ * - LGPL
+ *
+ * MonthField
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.MonthField
+ * @extends Roo.bootstrap.Input
+ * Bootstrap MonthField class
+ * 
+ * @cfg {String} language default en
+ * 
+ * @constructor
+ * Create a new MonthField
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.MonthField = function(config){
+    Roo.bootstrap.MonthField.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event show
+         * Fires when this field show.
+         * @param {Roo.bootstrap.MonthField} this
+         * @param {Mixed} date The date value
+         */
+        show : true,
+        /**
+         * @event show
+         * Fires when this field hide.
+         * @param {Roo.bootstrap.MonthField} this
+         * @param {Mixed} date The date value
+         */
+        hide : true,
+        /**
+         * @event select
+         * Fires when select a date.
+         * @param {Roo.bootstrap.MonthField} this
+         * @param {Mixed} date The date value
+         */
+        select : true
+    });
+};
+
+Roo.extend(Roo.bootstrap.MonthField, Roo.bootstrap.Input,  {
+    
+    onRender: function(ct, position)
+    {
+        
+        Roo.bootstrap.MonthField.superclass.onRender.call(this, ct, position);
+        
+        this.language = this.language || 'en';
+        this.language = this.language in Roo.bootstrap.MonthField.dates ? this.language : this.language.split('-')[0];
+        this.language = this.language in Roo.bootstrap.MonthField.dates ? this.language : "en";
+        
+        this.isRTL = Roo.bootstrap.MonthField.dates[this.language].rtl || false;
+        this.isInline = false;
+        this.isInput = true;
+        this.component = this.el.select('.add-on', true).first() || false;
+        this.component = (this.component && this.component.length === 0) ? false : this.component;
+        this.hasInput = this.component && this.inputEL().length;
+        
+        this.pickerEl = Roo.get(document.body).createChild(Roo.bootstrap.MonthField.template);
+        
+        this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.picker().on('mousedown', this.onMousedown, this);
+        this.picker().on('click', this.onClick, this);
+        
+        this.picker().addClass('datepicker-dropdown');
+        
+        Roo.each(this.picker().select('tbody > tr > td', true).elements, function(v){
+            v.setStyle('width', '189px');
+        });
+        
+        this.fillMonths();
+        
+        this.update();
+        
+        if(this.isInline) {
+            this.show();
+        }
+        
+    },
+    
+    setValue: function(v)
+    {   
+        Roo.bootstrap.MonthField.superclass.setValue.call(this, v);
+        
+        this.update();
+
+        this.fireEvent('select', this, this.date);
+        
+    },
+    
+    getValue: function()
+    {
+        return this.value;
+    },
+    
+    onClick: function(e) 
+    {
+        e.stopPropagation();
+        e.preventDefault();
+        
+        var target = e.getTarget();
+        
+        if(target.nodeName.toLowerCase() === 'i'){
+            target = Roo.get(target).dom.parentNode;
+        }
+        
+        var nodeName = target.nodeName;
+        var className = target.className;
+        var html = target.innerHTML;
+        
+        if(nodeName.toLowerCase() != 'span' || className.indexOf('disabled') > -1 || className.indexOf('month') == -1){
+            return;
+        }
+        
+        this.vIndex = Roo.bootstrap.MonthField.dates[this.language].monthsShort.indexOf(html);
+        
+        this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);
+        
+        this.hide();
+                        
+    },
+    
+    picker : function()
+    {
+        return this.pickerEl;
+    },
+    
+    fillMonths: function()
+    {    
+        var i = 0;
+        var months = this.picker().select('>.datepicker-months td', true).first();
+        
+        months.dom.innerHTML = '';
+        
+        while (i < 12) {
+            var month = {
+                tag: 'span',
+                cls: 'month',
+                html: Roo.bootstrap.MonthField.dates[this.language].monthsShort[i++]
+            }
+            
+            months.createChild(month);
+        }
+        
+    },
+    
+    update: function()
+    {
+        var _this = this;
+        
+        if(typeof(this.vIndex) == 'undefined' && this.value.length){
+            this.vIndex = Roo.bootstrap.MonthField.dates[this.language].months.indexOf(this.value);
+        }
+        
+        Roo.each(this.pickerEl.select('> .datepicker-months tbody > tr > td > span', true).elements, function(e, k){
+            e.removeClass('active');
+            
+            if(typeof(_this.vIndex) != 'undefined' && k == _this.vIndex){
+                e.addClass('active');
+            }
+        })
+    },
+    
+    place: function()
+    {
+        if(this.isInline) return;
+        
+        this.picker().removeClass(['bottom', 'top']);
+        
+        if((Roo.lib.Dom.getViewHeight() + Roo.get(document.body).getScroll().top) - (this.inputEl().getBottom() + this.picker().getHeight()) < 0){
+            /*
+             * place to the top of element!
+             *
+             */
+            
+            this.picker().addClass('top');
+            this.picker().setTop(this.inputEl().getTop() - this.picker().getHeight()).setLeft(this.inputEl().getLeft());
+            
+            return;
+        }
+        
+        this.picker().addClass('bottom');
+        
+        this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());
+    },
+    
+    onFocus : function()
+    {
+        Roo.bootstrap.MonthField.superclass.onFocus.call(this);
+        this.show();
+    },
+    
+    onBlur : function()
+    {
+        Roo.bootstrap.MonthField.superclass.onBlur.call(this);
+        
+        var d = this.inputEl().getValue();
+        
+        this.setValue(d);
+                
+        this.hide();
+    },
+    
+    show : function()
+    {
+        this.picker().show();
+        this.picker().select('>.datepicker-months', true).first().show();
+        this.update();
+        this.place();
+        
+        this.fireEvent('show', this, this.date);
+    },
+    
+    hide : function()
+    {
+        if(this.isInline) return;
+        this.picker().hide();
+        this.fireEvent('hide', this, this.date);
+        
+    },
+    
+    onMousedown: function(e)
+    {
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    keyup: function(e)
+    {
+        Roo.bootstrap.MonthField.superclass.keyup.call(this);
+        this.update();
+    },
+
+    fireKey: function(e)
+    {
+        if (!this.picker().isVisible()){
+            if (e.keyCode == 27) // allow escape to hide and re-show picker
+                this.show();
+            return;
+        }
+        
+        var dir;
+        
+        switch(e.keyCode){
+            case 27: // escape
+                this.hide();
+                e.preventDefault();
+                break;
+            case 37: // left
+            case 39: // right
+                dir = e.keyCode == 37 ? -1 : 1;
+                
+                this.vIndex = this.vIndex + dir;
+                
+                if(this.vIndex < 0){
+                    this.vIndex = 0;
+                }
+                
+                if(this.vIndex > 11){
+                    this.vIndex = 11;
+                }
+                
+                if(isNaN(this.vIndex)){
+                    this.vIndex = 0;
+                }
+                
+                this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);
+                
+                break;
+            case 38: // up
+            case 40: // down
+                
+                dir = e.keyCode == 38 ? -1 : 1;
+                
+                this.vIndex = this.vIndex + dir * 4;
+                
+                if(this.vIndex < 0){
+                    this.vIndex = 0;
+                }
+                
+                if(this.vIndex > 11){
+                    this.vIndex = 11;
+                }
+                
+                if(isNaN(this.vIndex)){
+                    this.vIndex = 0;
+                }
+                
+                this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);
+                break;
+                
+            case 13: // enter
+                
+                if(typeof(this.vIndex) != 'undefined' && !isNaN(this.vIndex)){
+                    this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);
+                }
+                
+                this.hide();
+                e.preventDefault();
+                break;
+            case 9: // tab
+                if(typeof(this.vIndex) != 'undefined' && !isNaN(this.vIndex)){
+                    this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);
+                }
+                this.hide();
+                break;
+            case 16: // shift
+            case 17: // ctrl
+            case 18: // alt
+                break;
+            default :
+                this.hide();
+                
+        }
+    },
+    
+    remove: function() 
+    {
+        this.picker().remove();
+    }
+   
+});
+
+Roo.apply(Roo.bootstrap.MonthField,  {
+    
+    content : {
+        tag: 'tbody',
+        cn: [
+        {
+            tag: 'tr',
+            cn: [
+            {
+                tag: 'td',
+                colspan: '7'
+            }
+            ]
+        }
+        ]
+    },
+    
+    dates:{
+        en: {
+            months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+            monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+        }
+    }
+});
+
+Roo.apply(Roo.bootstrap.MonthField,  {
+  
+    template : {
+        tag: 'div',
+        cls: 'datepicker dropdown-menu roo-dynamic',
+        cn: [
+            {
+                tag: 'div',
+                cls: 'datepicker-months',
+                cn: [
+                {
+                    tag: 'table',
+                    cls: 'table-condensed',
+                    cn:[
+                        Roo.bootstrap.DateField.content
+                    ]
+                }
+                ]
+            }
+        ]
+    }
+});
+
+
+ /*
+ * - LGPL
+ *
+ * CheckBox
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.CheckBox
+ * @extends Roo.bootstrap.Input
+ * Bootstrap CheckBox class
+ * 
+ * @cfg {String} valueOff The value that should go into the generated input element's value when unchecked.
+ * @cfg {String} inputValue The value that should go into the generated input element's value when checked.
+ * @cfg {String} boxLabel The text that appears beside the checkbox
+ * @cfg {String} weight (primary|warning|info|danger|success) The text that appears beside the checkbox
+ * @cfg {Boolean} checked initnal the element
+ * @cfg {Boolean} inline inline the element (default false)
+ * 
+ * @constructor
+ * Create a new CheckBox
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.CheckBox = function(config){
+    Roo.bootstrap.CheckBox.superclass.constructor.call(this, config);
+   
+    this.addEvents({
+        /**
+        * @event check
+        * Fires when the element is checked or unchecked.
+        * @param {Roo.bootstrap.CheckBox} this This input
+        * @param {Boolean} checked The new checked value
+        * @param {String} oldValue The old value
+        */
+       check : true
+    });
+};
+
+Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
+    
+    inputType: 'checkbox',
+    inputValue: 1,
+    valueOff: 0,
+    boxLabel: false,
+    checked: false,
+    weight : false,
+    inline: false,
+    
+    getAutoCreate : function()
+    {
+        var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
+        
+        var id = Roo.id();
+        
+        var cfg = {};
+        
+        cfg.cls = 'form-group ' + this.inputType; //input-group
+        
+        if(this.inline){
+            cfg.cls += ' ' + this.inputType + '-inline';
+        }
+        
+        var input =  {
+            tag: 'input',
+            id : id,
+            type : this.inputType,
+            value : this.inputType == 'radio' ? this.inputValue : ((!this.checked) ? this.valueOff : this.inputValue),
+            cls : 'roo-' + this.inputType, //'form-box',
+            placeholder : this.placeholder || ''
+            
+        };
+        
+        if (this.weight) { // Validity check?
+            cfg.cls += " " + this.inputType + "-" + this.weight;
+        }
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        if(this.checked){
+            input.checked = this.checked;
+        }
+        
+        if (this.name) {
+            input.name = this.name;
+        }
+        
+        if (this.size) {
+            input.cls += ' input-' + this.size;
+        }
+        
+        var settings=this;
+        
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+       
+        
+        var inputblock = input;
+        
+        
+        
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            
+            inputblock.cn.push(input);
+            
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        }
+        
+        if (align ==='left' && this.fieldLabel.length) {
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label col-md-' + this.labelWidth,
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-md-" + (12 - this.labelWidth), 
+                        cn: [
+                            inputblock
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                cfg.cn = [
+                   
+                    {
+                        tag: this.boxLabel ? 'span' : 'label',
+                        'for': id,
+                        cls: 'control-label box-input-label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    inputblock
+                    
+                ];
+
+        } else {
+            
+                Roo.log(" no label && no align");
+                cfg.cn = [  inputblock ] ;
+                
+                
+        }
+        if(this.boxLabel){
+             var boxLabelCfg = {
+                tag: 'label',
+                //'for': id, // box label is handled by onclick - so no for...
+                cls: 'box-label',
+                html: this.boxLabel
+            }
+            
+            if(this.tooltip){
+                boxLabelCfg.tooltip = this.tooltip;
+            }
+             
+            cfg.cn.push(boxLabelCfg);
+        }
+        
+        
+       
+        return cfg;
+        
+    },
+    
+    /**
+     * return the real input element.
+     */
+    inputEl: function ()
+    {
+        return this.el.select('input.roo-' + this.inputType,true).first();
+    },
+    
+    labelEl: function()
+    {
+        return this.el.select('label.control-label',true).first();
+    },
+    /* depricated... */
+    
+    label: function()
+    {
+        return this.labelEl();
+    },
+    
+    initEvents : function()
+    {
+//        Roo.bootstrap.CheckBox.superclass.initEvents.call(this);
+        
+        this.inputEl().on('click', this.onClick,  this);
+        if (this.boxLabel) { 
+            this.el.select('label.box-label',true).first().on('click', this.onClick,  this);
+        }
+        
+    },
+    
+    onClick : function()
+    {   
+        this.setChecked(!this.checked);
+    },
+    
+    setChecked : function(state,suppressEvent)
+    {
+        var old = this.inputEl().dom.checked;
+        
+        if(this.inputType == 'radio'){
+            
+            Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
+                e.dom.checked = false;
+            });
+            
+            this.inputEl().dom.checked = true;
+            
+            this.inputEl().dom.value = this.inputValue;
+            
+            if(suppressEvent !== true){
+                this.fireEvent('check', this, true, old);
+            }
+            
+            return;
+        }
+        
+        this.checked = state;
+        
+        this.inputEl().dom.checked = state;
+        
+        this.inputEl().dom.value = state ? this.inputValue : this.valueOff;
+        
+        if(suppressEvent !== true){
+            this.fireEvent('check', this, state, old);
+        }
+    },
+    
+    getValue : function()
+    {
+        if(this.inputType == 'radio'){
+            return this.getGroupValue();
+        }
+        
+        return this.inputEl().getValue();
+        
+    },
+    
+    getGroupValue : function()
+    {
+        if(typeof(this.el.up('form').child('input[name='+this.name+']:checked', true)) == 'undefined'){
+            return '';
+        }
+        
+        return this.el.up('form').child('input[name='+this.name+']:checked', true).value;
+    },
+    
+    setValue : function(v,suppressEvent)
+    {
+        if(this.inputType == 'radio'){
+            this.setGroupValue(v, suppressEvent);
+            return;
+        }
+        
+        this.setChecked(((typeof(v) == 'undefined') ? this.checked : (String(v) === String(this.inputValue))), suppressEvent);
+    },
+    
+    setGroupValue : function(v, suppressEvent)
+    {
+        var old = this.inputEl().dom.checked;
+        
+        Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
+            e.dom.checked = false;
+            
+            if(e.dom.value == v){
+                e.dom.checked = true;
+            }
+        });
+        
+        if(suppressEvent !== true){
+            this.fireEvent('check', this, true, old);
+        }
+
+        return;
+    }
+    
+});
+
+/*
+ * - LGPL
+ *
+ * Radio
+ *
+ *
+ * not inline
+ *<div class="radio">
+  <label>
+    <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
+    Option one is this and that&mdash;be sure to include why it's great
+  </label>
+</div>
+ *
+ *
+ *inline
+ *<span>
+ *<label class="radio-inline">fieldLabel</label>
+ *<label class="radio-inline">
+  <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
+</label>
+<span>
+ * 
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Radio
+ * @extends Roo.bootstrap.CheckBox
+ * Bootstrap Radio class
+
+ * @constructor
+ * Create a new Radio
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Radio = function(config){
+    Roo.bootstrap.Radio.superclass.constructor.call(this, config);
+   
+};
+
+Roo.extend(Roo.bootstrap.Radio, Roo.bootstrap.CheckBox,  {
+    
+    inputType: 'radio',
+    inputValue: '',
+    valueOff: '',
+    
+    getAutoCreate : function()
+    {
+        var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
+        align = align || 'left'; // default...
+        
+        
+        
+        var id = Roo.id();
+        
+        var cfg = {
+                tag : this.inline ? 'span' : 'div',
+                cls : '',
+                cn : []
+        };
+        
+        var inline = this.inline ? ' radio-inline' : '';
+        
+        var lbl = {
+                tag: 'label' ,
+                // does not need for, as we wrap the input with it..
+                'for' : id,
+                cls : 'control-label box-label' + inline,
+                cn : []
+        };
+        var labelWidth = this.labelWidth ? this.labelWidth *1 : 100;
+        
+        var fieldLabel = {
+            tag: 'label' ,
+            //cls : 'control-label' + inline,
+            html : this.fieldLabel,
+            style : 'width:' +  labelWidth  + 'px;line-height:1;vertical-align:bottom;cursor:default;' // should be css really.
+        };
+        
+        
+        
+        var input =  {
+            tag: 'input',
+            id : id,
+            type : this.inputType,
+            //value : (!this.checked) ? this.valueOff : this.inputValue,
+            value : this.inputValue,
+            cls : 'roo-radio',
+            placeholder : this.placeholder || '' // ?? needed????
+            
+        };
+        if (this.weight) { // Validity check?
+            input.cls += " radio-" + this.weight;
+        }
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        if(this.checked){
+            input.checked = this.checked;
+        }
+        
+        if (this.name) {
+            input.name = this.name;
+        }
+        
+        if (this.size) {
+            input.cls += ' input-' + this.size;
+        }
+        
+        //?? can span's inline have a width??
+        
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        var inputblock = input;
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                tag : 'span',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            inputblock.cn.push(input);
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        };
+        
+        
+        if (this.fieldLabel && this.fieldLabel.length) {
+            cfg.cn.push(fieldLabel);
+        }
+       
+        // normal bootstrap puts the input inside the label.
+        // however with our styled version - it has to go after the input.
+       
+        //lbl.cn.push(inputblock);
+        
+        var lblwrap =  {
+            tag: 'span',
+            cls: 'radio' + inline,
+            cn: [
+                inputblock,
+                lbl
+            ]
+        };
+        
+        cfg.cn.push( lblwrap);
+        
+        if(this.boxLabel){
+            lbl.cn.push({
+                tag: 'span',
+                html: this.boxLabel
+            })
+        }
+         
+        
+        return cfg;
+        
+    },
+    
+    initEvents : function()
+    {
+//        Roo.bootstrap.CheckBox.superclass.initEvents.call(this);
+        
+        this.inputEl().on('click', this.onClick,  this);
+        if (this.boxLabel) {
+            Roo.log('find label')
+            this.el.select('span.radio label span',true).first().on('click', this.onClick,  this);
+        }
+        
+    },
+    
+    inputEl: function ()
+    {
+        return this.el.select('input.roo-radio',true).first();
+    },
+    onClick : function()
+    {   
+        Roo.log("click");
+        this.setChecked(true);
+    },
+    
+    setChecked : function(state,suppressEvent)
+    {
+        if(state){
+            Roo.each(this.inputEl().up('form').select('input[name='+this.inputEl().dom.name+']', true).elements, function(v){
+                v.dom.checked = false;
+            });
+        }
+        Roo.log(this.inputEl().dom);
+        this.checked = state;
+        this.inputEl().dom.checked = state;
+        
+        if(suppressEvent !== true){
+            this.fireEvent('check', this, state);
+        }
+        
+        //this.inputEl().dom.value = state ? this.inputValue : this.valueOff;
+        
+    },
+    
+    getGroupValue : function()
+    {
+        var value = '';
+        Roo.each(this.inputEl().up('form').select('input[name='+this.inputEl().dom.name+']', true).elements, function(v){
+            if(v.dom.checked == true){
+                value = v.dom.value;
+            }
+        });
+        
+        return value;
+    },
+    
+    /**
+     * Returns the normalized data value (undefined or emptyText will be returned as '').  To return the raw value see {@link #getRawValue}.
+     * @return {Mixed} value The field value
+     */
+    getValue : function(){
+        return this.getGroupValue();
+    }
+    
+});
+
+//<script type="text/javascript">
+
+/*
+ * Based  Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * LGPL
+ *
+ */
+/**
+ * @class Roo.HtmlEditorCore
+ * @extends Roo.Component
+ * Provides a the editing component for the HTML editors in Roo. (bootstrap and Roo.form)
+ *
+ * any element that has display set to 'none' can cause problems in Safari and Firefox.<br/><br/>
+ */
+
+Roo.HtmlEditorCore = function(config){
+    
+    
+    Roo.HtmlEditorCore.superclass.constructor.call(this, config);
+    
+    
+    this.addEvents({
+        /**
+         * @event initialize
+         * Fires when the editor is fully initialized (including the iframe)
+         * @param {Roo.HtmlEditorCore} this
+         */
+        initialize: true,
+        /**
+         * @event activate
+         * Fires when the editor is first receives the focus. Any insertion must wait
+         * until after this event.
+         * @param {Roo.HtmlEditorCore} this
+         */
+        activate: true,
+         /**
+         * @event beforesync
+         * Fires before the textarea is updated with content from the editor iframe. Return false
+         * to cancel the sync.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        beforesync: true,
+         /**
+         * @event beforepush
+         * Fires before the iframe editor is updated with content from the textarea. Return false
+         * to cancel the push.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        beforepush: true,
+         /**
+         * @event sync
+         * Fires when the textarea is updated with content from the editor iframe.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        sync: true,
+         /**
+         * @event push
+         * Fires when the iframe editor is updated with content from the textarea.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        push: true,
+        
+        /**
+         * @event editorevent
+         * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
+         * @param {Roo.HtmlEditorCore} this
+         */
+        editorevent: true
+        
+    });
+    
+    // at this point this.owner is set, so we can start working out the whitelisted / blacklisted elements
+    
+    // defaults : white / black...
+    this.applyBlacklists();
+    
+    
+    
+};
+
+
+Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
+
+
+     /**
+     * @cfg {Roo.form.HtmlEditor|Roo.bootstrap.HtmlEditor} the owner field 
+     */
+    
+    owner : false,
+    
+     /**
+     * @cfg {String} resizable  's' or 'se' or 'e' - wrapps the element in a
+     *                        Roo.resizable.
+     */
+    resizable : false,
+     /**
+     * @cfg {Number} height (in pixels)
+     */   
+    height: 300,
+   /**
+     * @cfg {Number} width (in pixels)
+     */   
+    width: 500,
+    
+    /**
+     * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+     * 
+     */
+    stylesheets: false,
+    
+    // id of frame..
+    frameId: false,
+    
+    // private properties
+    validationEvent : false,
+    deferHeight: true,
+    initialized : false,
+    activated : false,
+    sourceEditMode : false,
+    onFocus : Roo.emptyFn,
+    iframePad:3,
+    hideMode:'offsets',
+    
+    clearUp: true,
+    
+    // blacklist + whitelisted elements..
+    black: false,
+    white: false,
+     
+    
+
+    /**
+     * Protected method that will not generally be called directly. It
+     * is called when the editor initializes the iframe with HTML contents. Override this method if you
+     * want to change the initialization markup of the iframe (e.g. to add stylesheets).
+     */
+    getDocMarkup : function(){
+        // body styles..
+        var st = '';
+        
+        // inherit styels from page...?? 
+        if (this.stylesheets === false) {
+            
+            Roo.get(document.head).select('style').each(function(node) {
+                st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+            });
+            
+            Roo.get(document.head).select('link').each(function(node) { 
+                st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+            });
+            
+        } else if (!this.stylesheets.length) {
+                // simple..
+                st = '<style type="text/css">' +
+                    'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+                   '</style>';
+        } else { 
+            
+        }
+        
+        st +=  '<style type="text/css">' +
+            'IMG { cursor: pointer } ' +
+        '</style>';
+
+        
+        return '<html><head>' + st  +
+            //<style type="text/css">' +
+            //'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+            //'</style>' +
+            ' </head><body class="roo-htmleditor-body"></body></html>';
+    },
+
+    // private
+    onRender : function(ct, position)
+    {
+        var _t = this;
+        //Roo.HtmlEditorCore.superclass.onRender.call(this, ct, position);
+        this.el = this.owner.inputEl ? this.owner.inputEl() : this.owner.el;
+        
+        
+        this.el.dom.style.border = '0 none';
+        this.el.dom.setAttribute('tabIndex', -1);
+        this.el.addClass('x-hidden hide');
+        
+        
+        
+        if(Roo.isIE){ // fix IE 1px bogus margin
+            this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
+        }
+       
+        
+        this.frameId = Roo.id();
+        
+         
+        
+        var iframe = this.owner.wrap.createChild({
+            tag: 'iframe',
+            cls: 'form-control', // bootstrap..
+            id: this.frameId,
+            name: this.frameId,
+            frameBorder : 'no',
+            'src' : Roo.SSL_SECURE_URL ? Roo.SSL_SECURE_URL  :  "javascript:false"
+        }, this.el
+        );
+        
+        
+        this.iframe = iframe.dom;
+
+         this.assignDocWin();
+        
+        this.doc.designMode = 'on';
+       
+        this.doc.open();
+        this.doc.write(this.getDocMarkup());
+        this.doc.close();
+
+        
+        var task = { // must defer to wait for browser to be ready
+            run : function(){
+                //console.log("run task?" + this.doc.readyState);
+                this.assignDocWin();
+                if(this.doc.body || this.doc.readyState == 'complete'){
+                    try {
+                        this.doc.designMode="on";
+                    } catch (e) {
+                        return;
+                    }
+                    Roo.TaskMgr.stop(task);
+                    this.initEditor.defer(10, this);
+                }
+            },
+            interval : 10,
+            duration: 10000,
+            scope: this
+        };
+        Roo.TaskMgr.start(task);
+
+    },
+
+    // private
+    onResize : function(w, h)
+    {
+         Roo.log('resize: ' +w + ',' + h );
+        //Roo.HtmlEditorCore.superclass.onResize.apply(this, arguments);
+        if(!this.iframe){
+            return;
+        }
+        if(typeof w == 'number'){
+            
+            this.iframe.style.width = w + 'px';
+        }
+        if(typeof h == 'number'){
+            
+            this.iframe.style.height = h + 'px';
+            if(this.doc){
+                (this.doc.body || this.doc.documentElement).style.height = (h - (this.iframePad*2)) + 'px';
+            }
+        }
+        
+    },
+
+    /**
+     * Toggles the editor between standard and source edit mode.
+     * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
+     */
+    toggleSourceEdit : function(sourceEditMode){
+        
+        this.sourceEditMode = sourceEditMode === true;
+        
+        if(this.sourceEditMode){
+            Roo.get(this.iframe).addClass(['x-hidden','hide']);     //FIXME - what's the BS styles for these
+            
+        }else{
+            Roo.get(this.iframe).removeClass(['x-hidden','hide']);
+            //this.iframe.className = '';
+            this.deferFocus();
+        }
+        //this.setSize(this.owner.wrap.getSize());
+        //this.fireEvent('editmodechange', this, this.sourceEditMode);
+    },
+
+    
+  
+
+    /**
+     * Protected method that will not generally be called directly. If you need/want
+     * custom HTML cleanup, this is the method you should override.
+     * @param {String} html The HTML to be cleaned
+     * return {String} The cleaned HTML
+     */
+    cleanHtml : function(html){
+        html = String(html);
+        if(html.length > 5){
+            if(Roo.isSafari){ // strip safari nonsense
+                html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
+            }
+        }
+        if(html == '&nbsp;'){
+            html = '';
+        }
+        return html;
+    },
+
+    /**
+     * HTML Editor -> Textarea
+     * Protected method that will not generally be called directly. Syncs the contents
+     * of the editor iframe with the textarea.
+     */
+    syncValue : function(){
+        if(this.initialized){
+            var bd = (this.doc.body || this.doc.documentElement);
+            //this.cleanUpPaste(); -- this is done else where and causes havoc..
+            var html = bd.innerHTML;
+            if(Roo.isSafari){
+                var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
+                var m = bs ? bs.match(/text-align:(.*?);/i) : false;
+                if(m && m[1]){
+                    html = '<div style="'+m[0]+'">' + html + '</div>';
+                }
+            }
+            html = this.cleanHtml(html);
+            // fix up the special chars.. normaly like back quotes in word...
+            // however we do not want to do this with chinese..
+            html = html.replace(/([\x80-\uffff])/g, function (a, b) {
+                var cc = b.charCodeAt();
+                if (
+                    (cc >= 0x4E00 && cc < 0xA000 ) ||
+                    (cc >= 0x3400 && cc < 0x4E00 ) ||
+                    (cc >= 0xf900 && cc < 0xfb00 )
+                ) {
+                        return b;
+                }
+                return "&#"+cc+";" 
+            });
+            if(this.owner.fireEvent('beforesync', this, html) !== false){
+                this.el.dom.value = html;
+                this.owner.fireEvent('sync', this, html);
+            }
+        }
+    },
+
+    /**
+     * Protected method that will not generally be called directly. Pushes the value of the textarea
+     * into the iframe editor.
+     */
+    pushValue : function(){
+        if(this.initialized){
+            var v = this.el.dom.value.trim();
+            
+//            if(v.length < 1){
+//                v = '&#160;';
+//            }
+            
+            if(this.owner.fireEvent('beforepush', this, v) !== false){
+                var d = (this.doc.body || this.doc.documentElement);
+                d.innerHTML = v;
+                this.cleanUpPaste();
+                this.el.dom.value = d.innerHTML;
+                this.owner.fireEvent('push', this, v);
+            }
+        }
+    },
+
+    // private
+    deferFocus : function(){
+        this.focus.defer(10, this);
+    },
+
+    // doc'ed in Field
+    focus : function(){
+        if(this.win && !this.sourceEditMode){
+            this.win.focus();
+        }else{
+            this.el.focus();
+        }
+    },
+    
+    assignDocWin: function()
+    {
+        var iframe = this.iframe;
+        
+         if(Roo.isIE){
+            this.doc = iframe.contentWindow.document;
+            this.win = iframe.contentWindow;
+        } else {
+//            if (!Roo.get(this.frameId)) {
+//                return;
+//            }
+//            this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
+//            this.win = Roo.get(this.frameId).dom.contentWindow;
+            
+            if (!Roo.get(this.frameId) && !iframe.contentDocument) {
+                return;
+            }
+            
+            this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
+            this.win = (iframe.contentWindow || Roo.get(this.frameId).dom.contentWindow);
+        }
+    },
+    
+    // private
+    initEditor : function(){
+        //console.log("INIT EDITOR");
+        this.assignDocWin();
+        
+        
+        
+        this.doc.designMode="on";
+        this.doc.open();
+        this.doc.write(this.getDocMarkup());
+        this.doc.close();
+        
+        var dbody = (this.doc.body || this.doc.documentElement);
+        //var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
+        // this copies styles from the containing element into thsi one..
+        // not sure why we need all of this..
+        //var ss = this.el.getStyles('font-size', 'background-image', 'background-repeat');
+        
+        //var ss = this.el.getStyles( 'background-image', 'background-repeat');
+        //ss['background-attachment'] = 'fixed'; // w3c
+        dbody.bgProperties = 'fixed'; // ie
+        //Roo.DomHelper.applyStyles(dbody, ss);
+        Roo.EventManager.on(this.doc, {
+            //'mousedown': this.onEditorEvent,
+            'mouseup': this.onEditorEvent,
+            'dblclick': this.onEditorEvent,
+            'click': this.onEditorEvent,
+            'keyup': this.onEditorEvent,
+            buffer:100,
+            scope: this
+        });
+        if(Roo.isGecko){
+            Roo.EventManager.on(this.doc, 'keypress', this.mozKeyPress, this);
+        }
+        if(Roo.isIE || Roo.isSafari || Roo.isOpera){
+            Roo.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
+        }
+        this.initialized = true;
+
+        this.owner.fireEvent('initialize', this);
+        this.pushValue();
+    },
+
+    // private
+    onDestroy : function(){
+        
+        
+        
+        if(this.rendered){
+            
+            //for (var i =0; i < this.toolbars.length;i++) {
+            //    // fixme - ask toolbars for heights?
+            //    this.toolbars[i].onDestroy();
+           // }
+            
+            //this.wrap.dom.innerHTML = '';
+            //this.wrap.remove();
+        }
+    },
+
+    // private
+    onFirstFocus : function(){
+        
+        this.assignDocWin();
+        
+        
+        this.activated = true;
+         
+    
+        if(Roo.isGecko){ // prevent silly gecko errors
+            this.win.focus();
+            var s = this.win.getSelection();
+            if(!s.focusNode || s.focusNode.nodeType != 3){
+                var r = s.getRangeAt(0);
+                r.selectNodeContents((this.doc.body || this.doc.documentElement));
+                r.collapse(true);
+                this.deferFocus();
+            }
+            try{
+                this.execCmd('useCSS', true);
+                this.execCmd('styleWithCSS', false);
+            }catch(e){}
+        }
+        this.owner.fireEvent('activate', this);
+    },
+
+    // private
+    adjustFont: function(btn){
+        var adjust = btn.cmd == 'increasefontsize' ? 1 : -1;
+        //if(Roo.isSafari){ // safari
+        //    adjust *= 2;
+       // }
+        var v = parseInt(this.doc.queryCommandValue('FontSize')|| 3, 10);
+        if(Roo.isSafari){ // safari
+            var sm = { 10 : 1, 13: 2, 16:3, 18:4, 24: 5, 32:6, 48: 7 };
+            v =  (v < 10) ? 10 : v;
+            v =  (v > 48) ? 48 : v;
+            v = typeof(sm[v]) == 'undefined' ? 1 : sm[v];
+            
+        }
+        
+        
+        v = Math.max(1, v+adjust);
+        
+        this.execCmd('FontSize', v  );
+    },
+
+    onEditorEvent : function(e){
+        this.owner.fireEvent('editorevent', this, e);
+      //  this.updateToolbar();
+        this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
+    },
+
+    insertTag : function(tg)
+    {
+        // could be a bit smarter... -> wrap the current selected tRoo..
+        if (tg.toLowerCase() == 'span' || tg.toLowerCase() == 'code') {
+            
+            range = this.createRange(this.getSelection());
+            var wrappingNode = this.doc.createElement(tg.toLowerCase());
+            wrappingNode.appendChild(range.extractContents());
+            range.insertNode(wrappingNode);
+
+            return;
+            
+            
+            
+        }
+        this.execCmd("formatblock",   tg);
+        
+    },
+    
+    insertText : function(txt)
+    {
+        
+        
+        var range = this.createRange();
+        range.deleteContents();
+               //alert(Sender.getAttribute('label'));
+               
+        range.insertNode(this.doc.createTextNode(txt));
+    } ,
+    
+     
+
+    /**
+     * Executes a Midas editor command on the editor document and performs necessary focus and
+     * toolbar updates. <b>This should only be called after the editor is initialized.</b>
+     * @param {String} cmd The Midas command
+     * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
+     */
+    relayCmd : function(cmd, value){
+        this.win.focus();
+        this.execCmd(cmd, value);
+        this.owner.fireEvent('editorevent', this);
+        //this.updateToolbar();
+        this.owner.deferFocus();
+    },
+
+    /**
+     * Executes a Midas editor command directly on the editor document.
+     * For visual commands, you should use {@link #relayCmd} instead.
+     * <b>This should only be called after the editor is initialized.</b>
+     * @param {String} cmd The Midas command
+     * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
+     */
+    execCmd : function(cmd, value){
+        this.doc.execCommand(cmd, false, value === undefined ? null : value);
+        this.syncValue();
+    },
+   
+    /**
+     * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
+     * to insert tRoo.
+     * @param {String} text | dom node.. 
+     */
+    insertAtCursor : function(text)
+    {
+        
+        
+        
+        if(!this.activated){
+            return;
+        }
+        /*
+        if(Roo.isIE){
+            this.win.focus();
+            var r = this.doc.selection.createRange();
+            if(r){
+                r.collapse(true);
+                r.pasteHTML(text);
+                this.syncValue();
+                this.deferFocus();
+            
+            }
+            return;
+        }
+        */
+        if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
+            this.win.focus();
+            
+            
+            // from jquery ui (MIT licenced)
+            var range, node;
+            var win = this.win;
+            
+            if (win.getSelection && win.getSelection().getRangeAt) {
+                range = win.getSelection().getRangeAt(0);
+                node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
+                range.insertNode(node);
+            } else if (win.document.selection && win.document.selection.createRange) {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                win.document.selection.createRange().pasteHTML(txt);
+            } else {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                this.execCmd('InsertHTML', txt);
+            } 
+            
+            this.syncValue();
+            
+            this.deferFocus();
+        }
+    },
+ // private
+    mozKeyPress : function(e){
+        if(e.ctrlKey){
+            var c = e.getCharCode(), cmd;
+          
+            if(c > 0){
+                c = String.fromCharCode(c).toLowerCase();
+                switch(c){
+                    case 'b':
+                        cmd = 'bold';
+                        break;
+                    case 'i':
+                        cmd = 'italic';
+                        break;
+                    
+                    case 'u':
+                        cmd = 'underline';
+                        break;
+                    
+                    case 'v':
+                        this.cleanUpPaste.defer(100, this);
+                        return;
+                        
+                }
+                if(cmd){
+                    this.win.focus();
+                    this.execCmd(cmd);
+                    this.deferFocus();
+                    e.preventDefault();
+                }
+                
+            }
+        }
+    },
+
+    // private
+    fixKeys : function(){ // load time branching for fastest keydown performance
+        if(Roo.isIE){
+            return function(e){
+                var k = e.getKey(), r;
+                if(k == e.TAB){
+                    e.stopEvent();
+                    r = this.doc.selection.createRange();
+                    if(r){
+                        r.collapse(true);
+                        r.pasteHTML('&#160;&#160;&#160;&#160;');
+                        this.deferFocus();
+                    }
+                    return;
+                }
+                
+                if(k == e.ENTER){
+                    r = this.doc.selection.createRange();
+                    if(r){
+                        var target = r.parentElement();
+                        if(!target || target.tagName.toLowerCase() != 'li'){
+                            e.stopEvent();
+                            r.pasteHTML('<br />');
+                            r.collapse(false);
+                            r.select();
+                        }
+                    }
+                }
+                if (String.fromCharCode(k).toLowerCase() == 'v') { // paste
+                    this.cleanUpPaste.defer(100, this);
+                    return;
+                }
+                
+                
+            };
+        }else if(Roo.isOpera){
+            return function(e){
+                var k = e.getKey();
+                if(k == e.TAB){
+                    e.stopEvent();
+                    this.win.focus();
+                    this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');
+                    this.deferFocus();
+                }
+                if (String.fromCharCode(k).toLowerCase() == 'v') { // paste
+                    this.cleanUpPaste.defer(100, this);
+                    return;
+                }
+                
+            };
+        }else if(Roo.isSafari){
+            return function(e){
+                var k = e.getKey();
+                
+                if(k == e.TAB){
+                    e.stopEvent();
+                    this.execCmd('InsertText','\t');
+                    this.deferFocus();
+                    return;
+                }
+               if (String.fromCharCode(k).toLowerCase() == 'v') { // paste
+                    this.cleanUpPaste.defer(100, this);
+                    return;
+                }
+                
+             };
+        }
+    }(),
+    
+    getAllAncestors: function()
+    {
+        var p = this.getSelectedNode();
+        var a = [];
+        if (!p) {
+            a.push(p); // push blank onto stack..
+            p = this.getParentElement();
+        }
+        
+        
+        while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
+            a.push(p);
+            p = p.parentNode;
+        }
+        a.push(this.doc.body);
+        return a;
+    },
+    lastSel : false,
+    lastSelNode : false,
+    
+    
+    getSelection : function() 
+    {
+        this.assignDocWin();
+        return Roo.isIE ? this.doc.selection : this.win.getSelection();
+    },
+    
+    getSelectedNode: function() 
+    {
+        // this may only work on Gecko!!!
+        
+        // should we cache this!!!!
+        
+        
+        
+         
+        var range = this.createRange(this.getSelection()).cloneRange();
+        
+        if (Roo.isIE) {
+            var parent = range.parentElement();
+            while (true) {
+                var testRange = range.duplicate();
+                testRange.moveToElementText(parent);
+                if (testRange.inRange(range)) {
+                    break;
+                }
+                if ((parent.nodeType != 1) || (parent.tagName.toLowerCase() == 'body')) {
+                    break;
+                }
+                parent = parent.parentElement;
+            }
+            return parent;
+        }
+        
+        // is ancestor a text element.
+        var ac =  range.commonAncestorContainer;
+        if (ac.nodeType == 3) {
+            ac = ac.parentNode;
+        }
+        
+        var ar = ac.childNodes;
+         
+        var nodes = [];
+        var other_nodes = [];
+        var has_other_nodes = false;
+        for (var i=0;i<ar.length;i++) {
+            if ((ar[i].nodeType == 3) && (!ar[i].data.length)) { // empty text ? 
+                continue;
+            }
+            // fullly contained node.
+            
+            if (this.rangeIntersectsNode(range,ar[i]) && this.rangeCompareNode(range,ar[i]) == 3) {
+                nodes.push(ar[i]);
+                continue;
+            }
+            
+            // probably selected..
+            if ((ar[i].nodeType == 1) && this.rangeIntersectsNode(range,ar[i]) && (this.rangeCompareNode(range,ar[i]) > 0)) {
+                other_nodes.push(ar[i]);
+                continue;
+            }
+            // outer..
+            if (!this.rangeIntersectsNode(range,ar[i])|| (this.rangeCompareNode(range,ar[i]) == 0))  {
+                continue;
+            }
+            
+            
+            has_other_nodes = true;
+        }
+        if (!nodes.length && other_nodes.length) {
+            nodes= other_nodes;
+        }
+        if (has_other_nodes || !nodes.length || (nodes.length > 1)) {
+            return false;
+        }
+        
+        return nodes[0];
+    },
+    createRange: function(sel)
+    {
+        // this has strange effects when using with 
+        // top toolbar - not sure if it's a great idea.
+        //this.editor.contentWindow.focus();
+        if (typeof sel != "undefined") {
+            try {
+                return sel.getRangeAt ? sel.getRangeAt(0) : sel.createRange();
+            } catch(e) {
+                return this.doc.createRange();
+            }
+        } else {
+            return this.doc.createRange();
+        }
+    },
+    getParentElement: function()
+    {
+        
+        this.assignDocWin();
+        var sel = Roo.isIE ? this.doc.selection : this.win.getSelection();
+        
+        var range = this.createRange(sel);
+         
+        try {
+            var p = range.commonAncestorContainer;
+            while (p.nodeType == 3) { // text node
+                p = p.parentNode;
+            }
+            return p;
+        } catch (e) {
+            return null;
+        }
+    
+    },
+    /***
+     *
+     * Range intersection.. the hard stuff...
+     *  '-1' = before
+     *  '0' = hits..
+     *  '1' = after.
+     *         [ -- selected range --- ]
+     *   [fail]                        [fail]
+     *
+     *    basically..
+     *      if end is before start or  hits it. fail.
+     *      if start is after end or hits it fail.
+     *
+     *   if either hits (but other is outside. - then it's not 
+     *   
+     *    
+     **/
+    
+    
+    // @see http://www.thismuchiknow.co.uk/?p=64.
+    rangeIntersectsNode : function(range, node)
+    {
+        var nodeRange = node.ownerDocument.createRange();
+        try {
+            nodeRange.selectNode(node);
+        } catch (e) {
+            nodeRange.selectNodeContents(node);
+        }
+    
+        var rangeStartRange = range.cloneRange();
+        rangeStartRange.collapse(true);
+    
+        var rangeEndRange = range.cloneRange();
+        rangeEndRange.collapse(false);
+    
+        var nodeStartRange = nodeRange.cloneRange();
+        nodeStartRange.collapse(true);
+    
+        var nodeEndRange = nodeRange.cloneRange();
+        nodeEndRange.collapse(false);
+    
+        return rangeStartRange.compareBoundaryPoints(
+                 Range.START_TO_START, nodeEndRange) == -1 &&
+               rangeEndRange.compareBoundaryPoints(
+                 Range.START_TO_START, nodeStartRange) == 1;
+        
+         
+    },
+    rangeCompareNode : function(range, node)
+    {
+        var nodeRange = node.ownerDocument.createRange();
+        try {
+            nodeRange.selectNode(node);
+        } catch (e) {
+            nodeRange.selectNodeContents(node);
+        }
+        
+        
+        range.collapse(true);
+    
+        nodeRange.collapse(true);
+     
+        var ss = range.compareBoundaryPoints( Range.START_TO_START, nodeRange);
+        var ee = range.compareBoundaryPoints(  Range.END_TO_END, nodeRange);
+         
+        //Roo.log(node.tagName + ': ss='+ss +', ee='+ee)
+        
+        var nodeIsBefore   =  ss == 1;
+        var nodeIsAfter    = ee == -1;
+        
+        if (nodeIsBefore && nodeIsAfter)
+            return 0; // outer
+        if (!nodeIsBefore && nodeIsAfter)
+            return 1; //right trailed.
+        
+        if (nodeIsBefore && !nodeIsAfter)
+            return 2;  // left trailed.
+        // fully contined.
+        return 3;
+    },
+
+    // private? - in a new class?
+    cleanUpPaste :  function()
+    {
+        // cleans up the whole document..
+        Roo.log('cleanuppaste');
+        
+        this.cleanUpChildren(this.doc.body);
+        var clean = this.cleanWordChars(this.doc.body.innerHTML);
+        if (clean != this.doc.body.innerHTML) {
+            this.doc.body.innerHTML = clean;
+        }
+        
+    },
+    
+    cleanWordChars : function(input) {// change the chars to hex code
+        var he = Roo.HtmlEditorCore;
+        
+        var output = input;
+        Roo.each(he.swapCodes, function(sw) { 
+            var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
+            
+            output = output.replace(swapper, sw[1]);
+        });
+        
+        return output;
+    },
+    
+    
+    cleanUpChildren : function (n)
+    {
+        if (!n.childNodes.length) {
+            return;
+        }
+        for (var i = n.childNodes.length-1; i > -1 ; i--) {
+           this.cleanUpChild(n.childNodes[i]);
+        }
+    },
+    
+    
+        
+    
+    cleanUpChild : function (node)
+    {
+        var ed = this;
+        //console.log(node);
+        if (node.nodeName == "#text") {
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        if (node.nodeName == "#comment") {
+            node.parentNode.removeChild(node);
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        var lcname = node.tagName.toLowerCase();
+        // we ignore whitelists... ?? = not really the way to go, but we probably have not got a full
+        // whitelist of tags..
+        
+        if (this.black.indexOf(lcname) > -1 && this.clearUp ) {
+            // remove node.
+            node.parentNode.removeChild(node);
+            return;
+            
+        }
+        
+        var remove_keep_children= Roo.HtmlEditorCore.remove.indexOf(node.tagName.toLowerCase()) > -1;
+        
+        // remove <a name=....> as rendering on yahoo mailer is borked with this.
+        // this will have to be flaged elsewhere - perhaps ablack=name... on the mailer..
+        
+        //if (node.tagName.toLowerCase() == 'a' && !node.hasAttribute('href')) {
+        //    remove_keep_children = true;
+        //}
+        
+        if (remove_keep_children) {
+            this.cleanUpChildren(node);
+            // inserts everything just before this node...
+            while (node.childNodes.length) {
+                var cn = node.childNodes[0];
+                node.removeChild(cn);
+                node.parentNode.insertBefore(cn, node);
+            }
+            node.parentNode.removeChild(node);
+            return;
+        }
+        
+        if (!node.attributes || !node.attributes.length) {
+            this.cleanUpChildren(node);
+            return;
+        }
+        
+        function cleanAttr(n,v)
+        {
+            
+            if (v.match(/^\./) || v.match(/^\//)) {
+                return;
+            }
+            if (v.match(/^(http|https):\/\//) || v.match(/^mailto:/)) {
+                return;
+            }
+            if (v.match(/^#/)) {
+                return;
+            }
+//            Roo.log("(REMOVE TAG)"+ node.tagName +'.' + n + '=' + v);
+            node.removeAttribute(n);
+            
+        }
+        
+        var cwhite = this.cwhite;
+        var cblack = this.cblack;
+            
+        function cleanStyle(n,v)
+        {
+            if (v.match(/expression/)) { //XSS?? should we even bother..
+                node.removeAttribute(n);
+                return;
+            }
+            
+            var parts = v.split(/;/);
+            var clean = [];
+            
+            Roo.each(parts, function(p) {
+                p = p.replace(/^\s+/g,'').replace(/\s+$/g,'');
+                if (!p.length) {
+                    return true;
+                }
+                var l = p.split(':').shift().replace(/\s+/g,'');
+                l = l.replace(/^\s+/g,'').replace(/\s+$/g,'');
+                
+                if ( cwhite.length && cblack.indexOf(l) > -1) {
+//                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
+                    //node.removeAttribute(n);
+                    return true;
+                }
+                //Roo.log()
+                // only allow 'c whitelisted system attributes'
+                if ( cwhite.length &&  cwhite.indexOf(l) < 0) {
+//                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
+                    //node.removeAttribute(n);
+                    return true;
+                }
+                
+                
+                 
+                
+                clean.push(p);
+                return true;
+            });
+            if (clean.length) { 
+                node.setAttribute(n, clean.join(';'));
+            } else {
+                node.removeAttribute(n);
+            }
+            
+        }
+        
+        
+        for (var i = node.attributes.length-1; i > -1 ; i--) {
+            var a = node.attributes[i];
+            //console.log(a);
+            
+            if (a.name.toLowerCase().substr(0,2)=='on')  {
+                node.removeAttribute(a.name);
+                continue;
+            }
+            if (Roo.HtmlEditorCore.ablack.indexOf(a.name.toLowerCase()) > -1) {
+                node.removeAttribute(a.name);
+                continue;
+            }
+            if (Roo.HtmlEditorCore.aclean.indexOf(a.name.toLowerCase()) > -1) {
+                cleanAttr(a.name,a.value); // fixme..
+                continue;
+            }
+            if (a.name == 'style') {
+                cleanStyle(a.name,a.value);
+                continue;
+            }
+            /// clean up MS crap..
+            // tecnically this should be a list of valid class'es..
+            
+            
+            if (a.name == 'class') {
+                if (a.value.match(/^Mso/)) {
+                    node.className = '';
+                }
+                
+                if (a.value.match(/body/)) {
+                    node.className = '';
+                }
+                continue;
+            }
+            
+            // style cleanup!?
+            // class cleanup?
+            
+        }
+        
+        
+        this.cleanUpChildren(node);
+        
+        
+    },
+    /**
+     * Clean up MS wordisms...
+     */
+    cleanWord : function(node)
+    {
+        var _t = this;
+        var cleanWordChildren = function()
+        {
+            if (!node.childNodes.length) {
+                return;
+            }
+            for (var i = node.childNodes.length-1; i > -1 ; i--) {
+               _t.cleanWord(node.childNodes[i]);
+            }
+        }
+        
+        
+        if (!node) {
+            this.cleanWord(this.doc.body);
+            return;
+        }
+        if (node.nodeName == "#text") {
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        if (node.nodeName == "#comment") {
+            node.parentNode.removeChild(node);
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        
+        if (node.tagName.toLowerCase().match(/^(style|script|applet|embed|noframes|noscript)$/)) {
+            node.parentNode.removeChild(node);
+            return;
+        }
+        
+        // remove - but keep children..
+        if (node.tagName.toLowerCase().match(/^(meta|link|\\?xml:|st1:|o:|font)/)) {
+            while (node.childNodes.length) {
+                var cn = node.childNodes[0];
+                node.removeChild(cn);
+                node.parentNode.insertBefore(cn, node);
+            }
+            node.parentNode.removeChild(node);
+            cleanWordChildren();
+            return;
+        }
+        // clean styles
+        if (node.className.length) {
+            
+            var cn = node.className.split(/\W+/);
+            var cna = [];
+            Roo.each(cn, function(cls) {
+                if (cls.match(/Mso[a-zA-Z]+/)) {
+                    return;
+                }
+                cna.push(cls);
+            });
+            node.className = cna.length ? cna.join(' ') : '';
+            if (!cna.length) {
+                node.removeAttribute("class");
+            }
+        }
+        
+        if (node.hasAttribute("lang")) {
+            node.removeAttribute("lang");
+        }
+        
+        if (node.hasAttribute("style")) {
+            
+            var styles = node.getAttribute("style").split(";");
+            var nstyle = [];
+            Roo.each(styles, function(s) {
+                if (!s.match(/:/)) {
+                    return;
+                }
+                var kv = s.split(":");
+                if (kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)) {
+                    return;
+                }
+                // what ever is left... we allow.
+                nstyle.push(s);
+            });
+            node.setAttribute("style", nstyle.length ? nstyle.join(';') : '');
+            if (!nstyle.length) {
+                node.removeAttribute('style');
+            }
+        }
+        
+        cleanWordChildren();
+        
+        
+    },
+    domToHTML : function(currentElement, depth, nopadtext) {
+        
+        depth = depth || 0;
+        nopadtext = nopadtext || false;
+    
+        if (!currentElement) {
+            return this.domToHTML(this.doc.body);
+        }
+        
+        //Roo.log(currentElement);
+        var j;
+        var allText = false;
+        var nodeName = currentElement.nodeName;
+        var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
+        
+        if  (nodeName == '#text') {
+            
+            return nopadtext ? currentElement.nodeValue : currentElement.nodeValue.trim();
+        }
+        
+        
+        var ret = '';
+        if (nodeName != 'BODY') {
+             
+            var i = 0;
+            // Prints the node tagName, such as <A>, <IMG>, etc
+            if (tagName) {
+                var attr = [];
+                for(i = 0; i < currentElement.attributes.length;i++) {
+                    // quoting?
+                    var aname = currentElement.attributes.item(i).name;
+                    if (!currentElement.attributes.item(i).value.length) {
+                        continue;
+                    }
+                    attr.push(aname + '="' + Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"' );
+                }
+                
+                ret = "<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">";
+            } 
+            else {
+                
+                // eack
+            }
+        } else {
+            tagName = false;
+        }
+        if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
+            return ret;
+        }
+        if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { // or code?
+            nopadtext = true;
+        }
+        
+        
+        // Traverse the tree
+        i = 0;
+        var currentElementChild = currentElement.childNodes.item(i);
+        var allText = true;
+        var innerHTML  = '';
+        lastnode = '';
+        while (currentElementChild) {
+            // Formatting code (indent the tree so it looks nice on the screen)
+            var nopad = nopadtext;
+            if (lastnode == 'SPAN') {
+                nopad  = true;
+            }
+            // text
+            if  (currentElementChild.nodeName == '#text') {
+                var toadd = Roo.util.Format.htmlEncode(currentElementChild.nodeValue);
+                toadd = nopadtext ? toadd : toadd.trim();
+                if (!nopad && toadd.length > 80) {
+                    innerHTML  += "\n" + (new Array( depth + 1 )).join( "  "  );
+                }
+                innerHTML  += toadd;
+                
+                i++;
+                currentElementChild = currentElement.childNodes.item(i);
+                lastNode = '';
+                continue;
+            }
+            allText = false;
+            
+            innerHTML  += nopad ? '' : "\n" + (new Array( depth + 1 )).join( "  "  );
+                
+            // Recursively traverse the tree structure of the child node
+            innerHTML   += this.domToHTML(currentElementChild, depth+1, nopadtext);
+            lastnode = currentElementChild.nodeName;
+            i++;
+            currentElementChild=currentElement.childNodes.item(i);
+        }
+        
+        ret += innerHTML;
+        
+        if (!allText) {
+                // The remaining code is mostly for formatting the tree
+            ret+= nopadtext ? '' : "\n" + (new Array( depth  )).join( "  "  );
+        }
+        
+        
+        if (tagName) {
+            ret+= "</"+tagName+">";
+        }
+        return ret;
+        
+    },
+        
+    applyBlacklists : function()
+    {
+        var w = typeof(this.owner.white) != 'undefined' && this.owner.white ? this.owner.white  : [];
+        var b = typeof(this.owner.black) != 'undefined' && this.owner.black ? this.owner.black :  [];
+        
+        this.white = [];
+        this.black = [];
+        Roo.each(Roo.HtmlEditorCore.white, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            this.white.push(tag);
+            
+        }, this);
+        
+        Roo.each(w, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.white.indexOf(tag) > -1) {
+                return;
+            }
+            this.white.push(tag);
+            
+        }, this);
+        
+        
+        Roo.each(Roo.HtmlEditorCore.black, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            this.black.push(tag);
+            
+        }, this);
+        
+        Roo.each(b, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.black.indexOf(tag) > -1) {
+                return;
+            }
+            this.black.push(tag);
+            
+        }, this);
+        
+        
+        w = typeof(this.owner.cwhite) != 'undefined' && this.owner.cwhite ? this.owner.cwhite  : [];
+        b = typeof(this.owner.cblack) != 'undefined' && this.owner.cblack ? this.owner.cblack :  [];
+        
+        this.cwhite = [];
+        this.cblack = [];
+        Roo.each(Roo.HtmlEditorCore.cwhite, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            this.cwhite.push(tag);
+            
+        }, this);
+        
+        Roo.each(w, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.cwhite.indexOf(tag) > -1) {
+                return;
+            }
+            this.cwhite.push(tag);
+            
+        }, this);
+        
+        
+        Roo.each(Roo.HtmlEditorCore.cblack, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            this.cblack.push(tag);
+            
+        }, this);
+        
+        Roo.each(b, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.cblack.indexOf(tag) > -1) {
+                return;
+            }
+            this.cblack.push(tag);
+            
+        }, this);
+    },
+    
+    setStylesheets : function(stylesheets)
+    {
+        if(typeof(stylesheets) == 'string'){
+            Roo.get(this.iframe.contentDocument.head).createChild({
+                tag : 'link',
+                rel : 'stylesheet',
+                type : 'text/css',
+                href : stylesheets
+            });
+            
+            return;
+        }
+        var _this = this;
+     
+        Roo.each(stylesheets, function(s) {
+            if(!s.length){
+                return;
+            }
+            
+            Roo.get(_this.iframe.contentDocument.head).createChild({
+                tag : 'link',
+                rel : 'stylesheet',
+                type : 'text/css',
+                href : s
+            });
+        });
+
+        
+    },
+    
+    removeStylesheets : function()
+    {
+        var _this = this;
+        
+        Roo.each(Roo.get(_this.iframe.contentDocument.head).select('link[rel=stylesheet]', true).elements, function(s){
+            s.remove();
+        });
+    }
+    
+    // hide stuff that is not compatible
+    /**
+     * @event blur
+     * @hide
+     */
+    /**
+     * @event change
+     * @hide
+     */
+    /**
+     * @event focus
+     * @hide
+     */
+    /**
+     * @event specialkey
+     * @hide
+     */
+    /**
+     * @cfg {String} fieldClass @hide
+     */
+    /**
+     * @cfg {String} focusClass @hide
+     */
+    /**
+     * @cfg {String} autoCreate @hide
+     */
+    /**
+     * @cfg {String} inputType @hide
+     */
+    /**
+     * @cfg {String} invalidClass @hide
+     */
+    /**
+     * @cfg {String} invalidText @hide
+     */
+    /**
+     * @cfg {String} msgFx @hide
+     */
+    /**
+     * @cfg {String} validateOnBlur @hide
+     */
+});
+
+Roo.HtmlEditorCore.white = [
+        'area', 'br', 'img', 'input', 'hr', 'wbr',
+        
+       'address', 'blockquote', 'center', 'dd',      'dir',       'div', 
+       'dl',      'dt',         'h1',     'h2',      'h3',        'h4', 
+       'h5',      'h6',         'hr',     'isindex', 'listing',   'marquee', 
+       'menu',    'multicol',   'ol',     'p',       'plaintext', 'pre', 
+       'table',   'ul',         'xmp', 
+       
+       'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', 
+      'thead',   'tr', 
+     
+      'dir', 'menu', 'ol', 'ul', 'dl',
+       
+      'embed',  'object'
+];
+
+
+Roo.HtmlEditorCore.black = [
+    //    'embed',  'object', // enable - backend responsiblity to clean thiese
+        'applet', // 
+        'base',   'basefont', 'bgsound', 'blink',  'body', 
+        'frame',  'frameset', 'head',    'html',   'ilayer', 
+        'iframe', 'layer',  'link',     'meta',    'object',   
+        'script', 'style' ,'title',  'xml' // clean later..
+];
+Roo.HtmlEditorCore.clean = [
+    'script', 'style', 'title', 'xml'
+];
+Roo.HtmlEditorCore.remove = [
+    'font'
+];
+// attributes..
+
+Roo.HtmlEditorCore.ablack = [
+    'on'
+];
+    
+Roo.HtmlEditorCore.aclean = [ 
+    'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc' 
+];
+
+// protocols..
+Roo.HtmlEditorCore.pwhite= [
+        'http',  'https',  'mailto'
+];
+
+// white listed style attributes.
+Roo.HtmlEditorCore.cwhite= [
+      //  'text-align', /// default is to allow most things..
+      
+         
+//        'font-size'//??
+];
+
+// black listed style attributes.
+Roo.HtmlEditorCore.cblack= [
+      //  'font-size' -- this can be set by the project 
+];
+
+
+Roo.HtmlEditorCore.swapCodes   =[ 
+    [    8211, "--" ], 
+    [    8212, "--" ], 
+    [    8216,  "'" ],  
+    [    8217, "'" ],  
+    [    8220, '"' ],  
+    [    8221, '"' ],  
+    [    8226, "*" ],  
+    [    8230, "..." ]
+]; 
+
+    /*
+ * - LGPL
+ *
+ * HtmlEditor
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.HtmlEditor
+ * @extends Roo.bootstrap.TextArea
+ * Bootstrap HtmlEditor class
+
+ * @constructor
+ * Create a new HtmlEditor
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.HtmlEditor = function(config){
+    Roo.bootstrap.HtmlEditor.superclass.constructor.call(this, config);
+    if (!this.toolbars) {
+        this.toolbars = [];
+    }
+    this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config));
+    this.addEvents({
+            /**
+             * @event initialize
+             * Fires when the editor is fully initialized (including the iframe)
+             * @param {HtmlEditor} this
+             */
+            initialize: true,
+            /**
+             * @event activate
+             * Fires when the editor is first receives the focus. Any insertion must wait
+             * until after this event.
+             * @param {HtmlEditor} this
+             */
+            activate: true,
+             /**
+             * @event beforesync
+             * Fires before the textarea is updated with content from the editor iframe. Return false
+             * to cancel the sync.
+             * @param {HtmlEditor} this
+             * @param {String} html
+             */
+            beforesync: true,
+             /**
+             * @event beforepush
+             * Fires before the iframe editor is updated with content from the textarea. Return false
+             * to cancel the push.
+             * @param {HtmlEditor} this
+             * @param {String} html
+             */
+            beforepush: true,
+             /**
+             * @event sync
+             * Fires when the textarea is updated with content from the editor iframe.
+             * @param {HtmlEditor} this
+             * @param {String} html
+             */
+            sync: true,
+             /**
+             * @event push
+             * Fires when the iframe editor is updated with content from the textarea.
+             * @param {HtmlEditor} this
+             * @param {String} html
+             */
+            push: true,
+             /**
+             * @event editmodechange
+             * Fires when the editor switches edit modes
+             * @param {HtmlEditor} this
+             * @param {Boolean} sourceEdit True if source edit, false if standard editing.
+             */
+            editmodechange: true,
+            /**
+             * @event editorevent
+             * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
+             * @param {HtmlEditor} this
+             */
+            editorevent: true,
+            /**
+             * @event firstfocus
+             * Fires when on first focus - needed by toolbars..
+             * @param {HtmlEditor} this
+             */
+            firstfocus: true,
+            /**
+             * @event autosave
+             * Auto save the htmlEditor value as a file into Events
+             * @param {HtmlEditor} this
+             */
+            autosave: true,
+            /**
+             * @event savedpreview
+             * preview the saved version of htmlEditor
+             * @param {HtmlEditor} this
+             */
+            savedpreview: true
+        });
+};
+
+
+Roo.extend(Roo.bootstrap.HtmlEditor, Roo.bootstrap.TextArea,  {
+    
+    
+      /**
+     * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
+     */
+    toolbars : false,
+   
+     /**
+     * @cfg {String} resizable  's' or 'se' or 'e' - wrapps the element in a
+     *                        Roo.resizable.
+     */
+    resizable : false,
+     /**
+     * @cfg {Number} height (in pixels)
+     */   
+    height: 300,
+   /**
+     * @cfg {Number} width (in pixels)
+     */   
+    width: false,
+    
+    /**
+     * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+     * 
+     */
+    stylesheets: false,
+    
+    // id of frame..
+    frameId: false,
+    
+    // private properties
+    validationEvent : false,
+    deferHeight: true,
+    initialized : false,
+    activated : false,
+    
+    onFocus : Roo.emptyFn,
+    iframePad:3,
+    hideMode:'offsets',
+    
+    
+    tbContainer : false,
+    
+    toolbarContainer :function() {
+        return this.wrap.select('.x-html-editor-tb',true).first();
+    },
+
+    /**
+     * Protected method that will not generally be called directly. It
+     * is called when the editor creates its toolbar. Override this method if you need to
+     * add custom toolbar buttons.
+     * @param {HtmlEditor} editor
+     */
+    createToolbar : function(){
+        
+        Roo.log("create toolbars");
+        
+        this.toolbars = [ new Roo.bootstrap.htmleditor.ToolbarStandard({editor: this} ) ];
+        this.toolbars[0].render(this.toolbarContainer());
+        
+        return;
+        
+//        if (!editor.toolbars || !editor.toolbars.length) {
+//            editor.toolbars = [ new Roo.bootstrap.HtmlEditor.ToolbarStandard() ]; // can be empty?
+//        }
+//        
+//        for (var i =0 ; i < editor.toolbars.length;i++) {
+//            editor.toolbars[i] = Roo.factory(
+//                    typeof(editor.toolbars[i]) == 'string' ?
+//                        { xtype: editor.toolbars[i]} : editor.toolbars[i],
+//                Roo.bootstrap.HtmlEditor);
+//            editor.toolbars[i].init(editor);
+//        }
+    },
+
+     
+    // private
+    onRender : function(ct, position)
+    {
+       // Roo.log("Call onRender: " + this.xtype);
+        var _t = this;
+        Roo.bootstrap.HtmlEditor.superclass.onRender.call(this, ct, position);
+      
+        this.wrap = this.inputEl().wrap({
+            cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
+        });
+        
+        this.editorcore.onRender(ct, position);
+         
+        if (this.resizable) {
+            this.resizeEl = new Roo.Resizable(this.wrap, {
+                pinned : true,
+                wrap: true,
+                dynamic : true,
+                minHeight : this.height,
+                height: this.height,
+                handles : this.resizable,
+                width: this.width,
+                listeners : {
+                    resize : function(r, w, h) {
+                        _t.onResize(w,h); // -something
+                    }
+                }
+            });
+            
+        }
+        this.createToolbar(this);
+       
+        
+        if(!this.width && this.resizable){
+            this.setSize(this.wrap.getSize());
+        }
+        if (this.resizeEl) {
+            this.resizeEl.resizeTo.defer(100, this.resizeEl,[ this.width,this.height ] );
+            // should trigger onReize..
+        }
+        
+    },
+
+    // private
+    onResize : function(w, h)
+    {
+        Roo.log('resize: ' +w + ',' + h );
+        Roo.bootstrap.HtmlEditor.superclass.onResize.apply(this, arguments);
+        var ew = false;
+        var eh = false;
+        
+        if(this.inputEl() ){
+            if(typeof w == 'number'){
+                var aw = w - this.wrap.getFrameWidth('lr');
+                this.inputEl().setWidth(this.adjustWidth('textarea', aw));
+                ew = aw;
+            }
+            if(typeof h == 'number'){
+                 var tbh = -11;  // fixme it needs to tool bar size!
+                for (var i =0; i < this.toolbars.length;i++) {
+                    // fixme - ask toolbars for heights?
+                    tbh += this.toolbars[i].el.getHeight();
+                    //if (this.toolbars[i].footer) {
+                    //    tbh += this.toolbars[i].footer.el.getHeight();
+                    //}
+                }
+              
+                
+                
+                
+                
+                var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
+                ah -= 5; // knock a few pixes off for look..
+                this.inputEl().setHeight(this.adjustWidth('textarea', ah));
+                var eh = ah;
+            }
+        }
+        Roo.log('onResize:' + [w,h,ew,eh].join(',') );
+        this.editorcore.onResize(ew,eh);
+        
+    },
+
+    /**
+     * Toggles the editor between standard and source edit mode.
+     * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
+     */
+    toggleSourceEdit : function(sourceEditMode)
+    {
+        this.editorcore.toggleSourceEdit(sourceEditMode);
+        
+        if(this.editorcore.sourceEditMode){
+            Roo.log('editor - showing textarea');
+            
+//            Roo.log('in');
+//            Roo.log(this.syncValue());
+            this.syncValue();
+            this.inputEl().removeClass(['hide', 'x-hidden']);
+            this.inputEl().dom.removeAttribute('tabIndex');
+            this.inputEl().focus();
+        }else{
+            Roo.log('editor - hiding textarea');
+//            Roo.log('out')
+//            Roo.log(this.pushValue()); 
+            this.pushValue();
+            
+            this.inputEl().addClass(['hide', 'x-hidden']);
+            this.inputEl().dom.setAttribute('tabIndex', -1);
+            //this.deferFocus();
+        }
+         
+        if(this.resizable){
+            this.setSize(this.wrap.getSize());
+        }
+        
+        this.fireEvent('editmodechange', this, this.editorcore.sourceEditMode);
+    },
+    // private (for BoxComponent)
+    adjustSize : Roo.BoxComponent.prototype.adjustSize,
+
+    // private (for BoxComponent)
+    getResizeEl : function(){
+        return this.wrap;
+    },
+
+    // private (for BoxComponent)
+    getPositionEl : function(){
+        return this.wrap;
+    },
+
+    // private
+    initEvents : function(){
+        this.originalValue = this.getValue();
+    },
+
+//    /**
+//     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+//     * @method
+//     */
+//    markInvalid : Roo.emptyFn,
+//    /**
+//     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+//     * @method
+//     */
+//    clearInvalid : Roo.emptyFn,
+
+    setValue : function(v){
+        Roo.bootstrap.HtmlEditor.superclass.setValue.call(this, v);
+        this.editorcore.pushValue();
+    },
+
+     
+    // private
+    deferFocus : function(){
+        this.focus.defer(10, this);
+    },
+
+    // doc'ed in Field
+    focus : function(){
+        this.editorcore.focus();
+        
+    },
+      
+
+    // private
+    onDestroy : function(){
+        
+        
+        
+        if(this.rendered){
+            
+            for (var i =0; i < this.toolbars.length;i++) {
+                // fixme - ask toolbars for heights?
+                this.toolbars[i].onDestroy();
+            }
+            
+            this.wrap.dom.innerHTML = '';
+            this.wrap.remove();
+        }
+    },
+
+    // private
+    onFirstFocus : function(){
+        //Roo.log("onFirstFocus");
+        this.editorcore.onFirstFocus();
+         for (var i =0; i < this.toolbars.length;i++) {
+            this.toolbars[i].onFirstFocus();
+        }
+        
+    },
+    
+    // private
+    syncValue : function()
+    {   
+        this.editorcore.syncValue();
+    },
+    
+    pushValue : function()
+    {   
+        this.editorcore.pushValue();
+    }
+     
+    
+    // hide stuff that is not compatible
+    /**
+     * @event blur
+     * @hide
+     */
+    /**
+     * @event change
+     * @hide
+     */
+    /**
+     * @event focus
+     * @hide
+     */
+    /**
+     * @event specialkey
+     * @hide
+     */
+    /**
+     * @cfg {String} fieldClass @hide
+     */
+    /**
+     * @cfg {String} focusClass @hide
+     */
+    /**
+     * @cfg {String} autoCreate @hide
+     */
+    /**
+     * @cfg {String} inputType @hide
+     */
+    /**
+     * @cfg {String} invalidClass @hide
+     */
+    /**
+     * @cfg {String} invalidText @hide
+     */
+    /**
+     * @cfg {String} msgFx @hide
+     */
+    /**
+     * @cfg {String} validateOnBlur @hide
+     */
+});
+    
+   
+   
+   
+      
+Roo.namespace('Roo.bootstrap.htmleditor');
+/**
+ * @class Roo.bootstrap.HtmlEditorToolbar1
+ * Basic Toolbar
+ * 
+ * Usage:
+ *
+ new Roo.bootstrap.HtmlEditor({
+    ....
+    toolbars : [
+        new Roo.bootstrap.HtmlEditorToolbar1({
+            disable : { fonts: 1 , format: 1, ..., ... , ...],
+            btns : [ .... ]
+        })
+    }
+     
+ * 
+ * @cfg {Object} disable List of elements to disable..
+ * @cfg {Array} btns List of additional buttons.
+ * 
+ * 
+ * NEEDS Extra CSS? 
+ * .x-html-editor-tb .x-edit-none .x-btn-text { background: none; }
+ */
+Roo.bootstrap.htmleditor.ToolbarStandard = function(config)
+{
+    
+    Roo.apply(this, config);
+    
+    // default disabled, based on 'good practice'..
+    this.disable = this.disable || {};
+    Roo.applyIf(this.disable, {
+        fontSize : true,
+        colors : true,
+        specialElements : true
+    });
+    Roo.bootstrap.htmleditor.ToolbarStandard.superclass.constructor.call(this, config);
+    
+    this.editor = config.editor;
+    this.editorcore = config.editor.editorcore;
+    
+    this.buttons   = new Roo.util.MixedCollection(false, function(o) { return o.cmd; });
+    
+    //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
+    // dont call parent... till later.
+}
+Roo.extend(Roo.bootstrap.htmleditor.ToolbarStandard, Roo.bootstrap.NavSimplebar,  {
+     
+    bar : true,
+    
+    editor : false,
+    editorcore : false,
+    
+    
+    formats : [
+        "p" ,  
+        "h1","h2","h3","h4","h5","h6", 
+        "pre", "code", 
+        "abbr", "acronym", "address", "cite", "samp", "var",
+        'div','span'
+    ],
+    
+    onRender : function(ct, position)
+    {
+       // Roo.log("Call onRender: " + this.xtype);
+        
+       Roo.bootstrap.htmleditor.ToolbarStandard.superclass.onRender.call(this, ct, position);
+       Roo.log(this.el);
+       this.el.dom.style.marginBottom = '0';
+       var _this = this;
+       var editorcore = this.editorcore;
+       var editor= this.editor;
+       
+       var children = [];
+       var btn = function(id,cmd , toggle, handler){
+       
+            var  event = toggle ? 'toggle' : 'click';
+       
+            var a = {
+                size : 'sm',
+                xtype: 'Button',
+                xns: Roo.bootstrap,
+                glyphicon : id,
+                cmd : id || cmd,
+                enableToggle:toggle !== false,
+                //html : 'submit'
+                pressed : toggle ? false : null,
+                listeners : {}
+            }
+            a.listeners[toggle ? 'toggle' : 'click'] = function() {
+                handler ? handler.call(_this,this) :_this.onBtnClick.call(_this, cmd ||  id);
+            }
+            children.push(a);
+            return a;
+       }
+        
+        var style = {
+                xtype: 'Button',
+                size : 'sm',
+                xns: Roo.bootstrap,
+                glyphicon : 'font',
+                //html : 'submit'
+                menu : {
+                    xtype: 'Menu',
+                    xns: Roo.bootstrap,
+                    items:  []
+                }
+        };
+        Roo.each(this.formats, function(f) {
+            style.menu.items.push({
+                xtype :'MenuItem',
+                xns: Roo.bootstrap,
+                html : '<'+ f+' style="margin:2px">'+f +'</'+ f+'>',
+                tagname : f,
+                listeners : {
+                    click : function()
+                    {
+                        editorcore.insertTag(this.tagname);
+                        editor.focus();
+                    }
+                }
+                
+            });
+        });
+         children.push(style);   
+            
+            
+        btn('bold',false,true);
+        btn('italic',false,true);
+        btn('align-left', 'justifyleft',true);
+        btn('align-center', 'justifycenter',true);
+        btn('align-right' , 'justifyright',true);
+        btn('link', false, false, function(btn) {
+            //Roo.log("create link?");
+            var url = prompt(this.createLinkText, this.defaultLinkValue);
+            if(url && url != 'http:/'+'/'){
+                this.editorcore.relayCmd('createlink', url);
+            }
+        }),
+        btn('list','insertunorderedlist',true);
+        btn('pencil', false,true, function(btn){
+                Roo.log(this);
+                
+                this.toggleSourceEdit(btn.pressed);
+        });
+        /*
+        var cog = {
+                xtype: 'Button',
+                size : 'sm',
+                xns: Roo.bootstrap,
+                glyphicon : 'cog',
+                //html : 'submit'
+                menu : {
+                    xtype: 'Menu',
+                    xns: Roo.bootstrap,
+                    items:  []
+                }
+        };
+        
+        cog.menu.items.push({
+            xtype :'MenuItem',
+            xns: Roo.bootstrap,
+            html : Clean styles,
+            tagname : f,
+            listeners : {
+                click : function()
+                {
+                    editorcore.insertTag(this.tagname);
+                    editor.focus();
+                }
+            }
+            
+        });
+       */
+        
+         
+       this.xtype = 'NavSimplebar';
+        
+        for(var i=0;i< children.length;i++) {
+            
+            this.buttons.add(this.addxtypeChild(children[i]));
+            
+        }
+        
+        editor.on('editorevent', this.updateToolbar, this);
+    },
+    onBtnClick : function(id)
+    {
+       this.editorcore.relayCmd(id);
+       this.editorcore.focus();
+    },
+    
+    /**
+     * Protected method that will not generally be called directly. It triggers
+     * a toolbar update by reading the markup state of the current selection in the editor.
+     */
+    updateToolbar: function(){
+
+        if(!this.editorcore.activated){
+            this.editor.onFirstFocus(); // is this neeed?
+            return;
+        }
+
+        var btns = this.buttons; 
+        var doc = this.editorcore.doc;
+        btns.get('bold').setActive(doc.queryCommandState('bold'));
+        btns.get('italic').setActive(doc.queryCommandState('italic'));
+        //btns.get('underline').setActive(doc.queryCommandState('underline'));
+        
+        btns.get('align-left').setActive(doc.queryCommandState('justifyleft'));
+        btns.get('align-center').setActive(doc.queryCommandState('justifycenter'));
+        btns.get('align-right').setActive(doc.queryCommandState('justifyright'));
+        
+        //btns[frameId + '-insertorderedlist').setActive(doc.queryCommandState('insertorderedlist'));
+        btns.get('list').setActive(doc.queryCommandState('insertunorderedlist'));
+         /*
+        
+        var ans = this.editorcore.getAllAncestors();
+        if (this.formatCombo) {
+            
+            
+            var store = this.formatCombo.store;
+            this.formatCombo.setValue("");
+            for (var i =0; i < ans.length;i++) {
+                if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
+                    // select it..
+                    this.formatCombo.setValue(ans[i].tagName.toLowerCase());
+                    break;
+                }
+            }
+        }
+        
+        
+        
+        // hides menus... - so this cant be on a menu...
+        Roo.bootstrap.MenuMgr.hideAll();
+        */
+        Roo.bootstrap.MenuMgr.hideAll();
+        //this.editorsyncValue();
+    },
+    onFirstFocus: function() {
+        this.buttons.each(function(item){
+           item.enable();
+        });
+    },
+    toggleSourceEdit : function(sourceEditMode){
+        
+          
+        if(sourceEditMode){
+            Roo.log("disabling buttons");
+           this.buttons.each( function(item){
+                if(item.cmd != 'pencil'){
+                    item.disable();
+                }
+            });
+          
+        }else{
+            Roo.log("enabling buttons");
+            if(this.editorcore.initialized){
+                this.buttons.each( function(item){
+                    item.enable();
+                });
+            }
+            
+        }
+        Roo.log("calling toggole on editor");
+        // tell the editor that it's been pressed..
+        this.editor.toggleSourceEdit(sourceEditMode);
+       
+    }
+});
+
+
+
+
+
+/**
+ * @class Roo.bootstrap.Table.AbstractSelectionModel
+ * @extends Roo.util.Observable
+ * Abstract base class for grid SelectionModels.  It provides the interface that should be
+ * implemented by descendant classes.  This class should not be directly instantiated.
+ * @constructor
+ */
+Roo.bootstrap.Table.AbstractSelectionModel = function(){
+    this.locked = false;
+    Roo.bootstrap.Table.AbstractSelectionModel.superclass.constructor.call(this);
+};
+
+
+Roo.extend(Roo.bootstrap.Table.AbstractSelectionModel, Roo.util.Observable,  {
+    /** @ignore Called by the grid automatically. Do not call directly. */
+    init : function(grid){
+        this.grid = grid;
+        this.initEvents();
+    },
+
+    /**
+     * Locks the selections.
+     */
+    lock : function(){
+        this.locked = true;
+    },
+
+    /**
+     * Unlocks the selections.
+     */
+    unlock : function(){
+        this.locked = false;
+    },
+
+    /**
+     * Returns true if the selections are locked.
+     * @return {Boolean}
+     */
+    isLocked : function(){
+        return this.locked;
+    }
+});
+/**
+ * @extends Roo.bootstrap.Table.AbstractSelectionModel
+ * @class Roo.bootstrap.Table.RowSelectionModel
+ * The default SelectionModel used by {@link Roo.bootstrap.Table}.
+ * It supports multiple selections and keyboard selection/navigation. 
+ * @constructor
+ * @param {Object} config
+ */
+
+Roo.bootstrap.Table.RowSelectionModel = function(config){
+    Roo.apply(this, config);
+    this.selections = new Roo.util.MixedCollection(false, function(o){
+        return o.id;
+    });
+
+    this.last = false;
+    this.lastActive = false;
+
+    this.addEvents({
+        /**
+            * @event selectionchange
+            * Fires when the selection changes
+            * @param {SelectionModel} this
+            */
+           "selectionchange" : true,
+        /**
+            * @event afterselectionchange
+            * Fires after the selection changes (eg. by key press or clicking)
+            * @param {SelectionModel} this
+            */
+           "afterselectionchange" : true,
+        /**
+            * @event beforerowselect
+            * Fires when a row is selected being selected, return false to cancel.
+            * @param {SelectionModel} this
+            * @param {Number} rowIndex The selected index
+            * @param {Boolean} keepExisting False if other selections will be cleared
+            */
+           "beforerowselect" : true,
+        /**
+            * @event rowselect
+            * Fires when a row is selected.
+            * @param {SelectionModel} this
+            * @param {Number} rowIndex The selected index
+            * @param {Roo.data.Record} r The record
+            */
+           "rowselect" : true,
+        /**
+            * @event rowdeselect
+            * Fires when a row is deselected.
+            * @param {SelectionModel} this
+            * @param {Number} rowIndex The selected index
+            */
+        "rowdeselect" : true
+    });
+    Roo.bootstrap.Table.RowSelectionModel.superclass.constructor.call(this);
+    this.locked = false;
+};
+
+Roo.extend(Roo.bootstrap.Table.RowSelectionModel, Roo.bootstrap.Table.AbstractSelectionModel,  {
+    /**
+     * @cfg {Boolean} singleSelect
+     * True to allow selection of only one row at a time (defaults to false)
+     */
+    singleSelect : false,
+
+    // private
+    initEvents : function(){
+
+        if(!this.grid.enableDragDrop && !this.grid.enableDrag){
+            this.grid.on("mousedown", this.handleMouseDown, this);
+        }else{ // allow click to work like normal
+            this.grid.on("rowclick", this.handleDragableRowClick, this);
+        }
+
+        this.rowNav = new Roo.KeyNav(this.grid.getGridEl(), {
+            "up" : function(e){
+                if(!e.shiftKey){
+                    this.selectPrevious(e.shiftKey);
+                }else if(this.last !== false && this.lastActive !== false){
+                    var last = this.last;
+                    this.selectRange(this.last,  this.lastActive-1);
+                    this.grid.getView().focusRow(this.lastActive);
+                    if(last !== false){
+                        this.last = last;
+                    }
+                }else{
+                    this.selectFirstRow();
+                }
+                this.fireEvent("afterselectionchange", this);
+            },
+            "down" : function(e){
+                if(!e.shiftKey){
+                    this.selectNext(e.shiftKey);
+                }else if(this.last !== false && this.lastActive !== false){
+                    var last = this.last;
+                    this.selectRange(this.last,  this.lastActive+1);
+                    this.grid.getView().focusRow(this.lastActive);
+                    if(last !== false){
+                        this.last = last;
+                    }
+                }else{
+                    this.selectFirstRow();
+                }
+                this.fireEvent("afterselectionchange", this);
+            },
+            scope: this
+        });
+
+        var view = this.grid.view;
+        view.on("refresh", this.onRefresh, this);
+        view.on("rowupdated", this.onRowUpdated, this);
+        view.on("rowremoved", this.onRemove, this);
+    },
+
+    // private
+    onRefresh : function(){
+        var ds = this.grid.dataSource, i, v = this.grid.view;
+        var s = this.selections;
+        s.each(function(r){
+            if((i = ds.indexOfId(r.id)) != -1){
+                v.onRowSelect(i);
+            }else{
+                s.remove(r);
+            }
+        });
+    },
+
+    // private
+    onRemove : function(v, index, r){
+        this.selections.remove(r);
+    },
+
+    // private
+    onRowUpdated : function(v, index, r){
+        if(this.isSelected(r)){
+            v.onRowSelect(index);
+        }
+    },
+
+    /**
+     * Select records.
+     * @param {Array} records The records to select
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectRecords : function(records, keepExisting){
+        if(!keepExisting){
+            this.clearSelections();
+        }
+        var ds = this.grid.dataSource;
+        for(var i = 0, len = records.length; i < len; i++){
+            this.selectRow(ds.indexOf(records[i]), true);
+        }
+    },
+
+    /**
+     * Gets the number of selected rows.
+     * @return {Number}
+     */
+    getCount : function(){
+        return this.selections.length;
+    },
+
+    /**
+     * Selects the first row in the grid.
+     */
+    selectFirstRow : function(){
+        this.selectRow(0);
+    },
+
+    /**
+     * Select the last row.
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectLastRow : function(keepExisting){
+        this.selectRow(this.grid.dataSource.getCount() - 1, keepExisting);
+    },
+
+    /**
+     * Selects the row immediately following the last selected row.
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectNext : function(keepExisting){
+        if(this.last !== false && (this.last+1) < this.grid.dataSource.getCount()){
+            this.selectRow(this.last+1, keepExisting);
+            this.grid.getView().focusRow(this.last);
+        }
+    },
+
+    /**
+     * Selects the row that precedes the last selected row.
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectPrevious : function(keepExisting){
+        if(this.last){
+            this.selectRow(this.last-1, keepExisting);
+            this.grid.getView().focusRow(this.last);
+        }
+    },
+
+    /**
+     * Returns the selected records
+     * @return {Array} Array of selected records
+     */
+    getSelections : function(){
+        return [].concat(this.selections.items);
+    },
+
+    /**
+     * Returns the first selected record.
+     * @return {Record}
+     */
+    getSelected : function(){
+        return this.selections.itemAt(0);
+    },
+
+
+    /**
+     * Clears all selections.
+     */
+    clearSelections : function(fast){
+        if(this.locked) return;
+        if(fast !== true){
+            var ds = this.grid.dataSource;
+            var s = this.selections;
+            s.each(function(r){
+                this.deselectRow(ds.indexOfId(r.id));
+            }, this);
+            s.clear();
+        }else{
+            this.selections.clear();
+        }
+        this.last = false;
+    },
+
+
+    /**
+     * Selects all rows.
+     */
+    selectAll : function(){
+        if(this.locked) return;
+        this.selections.clear();
+        for(var i = 0, len = this.grid.dataSource.getCount(); i < len; i++){
+            this.selectRow(i, true);
+        }
+    },
+
+    /**
+     * Returns True if there is a selection.
+     * @return {Boolean}
+     */
+    hasSelection : function(){
+        return this.selections.length > 0;
+    },
+
+    /**
+     * Returns True if the specified row is selected.
+     * @param {Number/Record} record The record or index of the record to check
+     * @return {Boolean}
+     */
+    isSelected : function(index){
+        var r = typeof index == "number" ? this.grid.dataSource.getAt(index) : index;
+        return (r && this.selections.key(r.id) ? true : false);
+    },
+
+    /**
+     * Returns True if the specified record id is selected.
+     * @param {String} id The id of record to check
+     * @return {Boolean}
+     */
+    isIdSelected : function(id){
+        return (this.selections.key(id) ? true : false);
+    },
+
+    // private
+    handleMouseDown : function(e, t){
+        var view = this.grid.getView(), rowIndex;
+        if(this.isLocked() || (rowIndex = view.findRowIndex(t)) === false){
+            return;
+        };
+        if(e.shiftKey && this.last !== false){
+            var last = this.last;
+            this.selectRange(last, rowIndex, e.ctrlKey);
+            this.last = last; // reset the last
+            view.focusRow(rowIndex);
+        }else{
+            var isSelected = this.isSelected(rowIndex);
+            if(e.button !== 0 && isSelected){
+                view.focusRow(rowIndex);
+            }else if(e.ctrlKey && isSelected){
+                this.deselectRow(rowIndex);
+            }else if(!isSelected){
+                this.selectRow(rowIndex, e.button === 0 && (e.ctrlKey || e.shiftKey));
+                view.focusRow(rowIndex);
+            }
+        }
+        this.fireEvent("afterselectionchange", this);
+    },
+    // private
+    handleDragableRowClick :  function(grid, rowIndex, e) 
+    {
+        if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
+            this.selectRow(rowIndex, false);
+            grid.view.focusRow(rowIndex);
+             this.fireEvent("afterselectionchange", this);
+        }
+    },
+    
+    /**
+     * Selects multiple rows.
+     * @param {Array} rows Array of the indexes of the row to select
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectRows : function(rows, keepExisting){
+        if(!keepExisting){
+            this.clearSelections();
+        }
+        for(var i = 0, len = rows.length; i < len; i++){
+            this.selectRow(rows[i], true);
+        }
+    },
+
+    /**
+     * Selects a range of rows. All rows in between startRow and endRow are also selected.
+     * @param {Number} startRow The index of the first row in the range
+     * @param {Number} endRow The index of the last row in the range
+     * @param {Boolean} keepExisting (optional) True to retain existing selections
+     */
+    selectRange : function(startRow, endRow, keepExisting){
+        if(this.locked) return;
+        if(!keepExisting){
+            this.clearSelections();
+        }
+        if(startRow <= endRow){
+            for(var i = startRow; i <= endRow; i++){
+                this.selectRow(i, true);
+            }
+        }else{
+            for(var i = startRow; i >= endRow; i--){
+                this.selectRow(i, true);
+            }
+        }
+    },
+
+    /**
+     * Deselects a range of rows. All rows in between startRow and endRow are also deselected.
+     * @param {Number} startRow The index of the first row in the range
+     * @param {Number} endRow The index of the last row in the range
+     */
+    deselectRange : function(startRow, endRow, preventViewNotify){
+        if(this.locked) return;
+        for(var i = startRow; i <= endRow; i++){
+            this.deselectRow(i, preventViewNotify);
+        }
+    },
+
+    /**
+     * Selects a row.
+     * @param {Number} row The index of the row to select
+     * @param {Boolean} keepExisting (optional) True to keep existing selections
+     */
+    selectRow : function(index, keepExisting, preventViewNotify){
+        if(this.locked || (index < 0 || index >= this.grid.dataSource.getCount())) return;
+        if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
+            if(!keepExisting || this.singleSelect){
+                this.clearSelections();
+            }
+            var r = this.grid.dataSource.getAt(index);
+            this.selections.add(r);
+            this.last = this.lastActive = index;
+            if(!preventViewNotify){
+                this.grid.getView().onRowSelect(index);
+            }
+            this.fireEvent("rowselect", this, index, r);
+            this.fireEvent("selectionchange", this);
+        }
+    },
+
+    /**
+     * Deselects a row.
+     * @param {Number} row The index of the row to deselect
+     */
+    deselectRow : function(index, preventViewNotify){
+        if(this.locked) return;
+        if(this.last == index){
+            this.last = false;
+        }
+        if(this.lastActive == index){
+            this.lastActive = false;
+        }
+        var r = this.grid.dataSource.getAt(index);
+        this.selections.remove(r);
+        if(!preventViewNotify){
+            this.grid.getView().onRowDeselect(index);
+        }
+        this.fireEvent("rowdeselect", this, index);
+        this.fireEvent("selectionchange", this);
+    },
+
+    // private
+    restoreLast : function(){
+        if(this._last){
+            this.last = this._last;
+        }
+    },
+
+    // private
+    acceptsNav : function(row, col, cm){
+        return !cm.isHidden(col) && cm.isCellEditable(col, row);
+    },
+
+    // private
+    onEditorKey : function(field, e){
+        var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
+        if(k == e.TAB){
+            e.stopEvent();
+            ed.completeEdit();
+            if(e.shiftKey){
+                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
+            }else{
+                newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
+            }
+        }else if(k == e.ENTER && !e.ctrlKey){
+            e.stopEvent();
+            ed.completeEdit();
+            if(e.shiftKey){
+                newCell = g.walkCells(ed.row-1, ed.col, -1, this.acceptsNav, this);
+            }else{
+                newCell = g.walkCells(ed.row+1, ed.col, 1, this.acceptsNav, this);
+            }
+        }else if(k == e.ESC){
+            ed.cancelEdit();
+        }
+        if(newCell){
+            g.startEditing(newCell[0], newCell[1]);
+        }
+    }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.bootstrap.PagingToolbar
+ * @extends Roo.Row
+ * A specialized toolbar that is bound to a {@link Roo.data.Store} and provides automatic paging controls.
+ * @constructor
+ * Create a new PagingToolbar
+ * @param {Object} config The config object
+ */
+Roo.bootstrap.PagingToolbar = function(config)
+{
+    // old args format still supported... - xtype is prefered..
+        // created from xtype...
+    var ds = config.dataSource;
+    this.toolbarItems = [];
+    if (config.items) {
+        this.toolbarItems = config.items;
+//        config.items = [];
+    }
+    
+    Roo.bootstrap.PagingToolbar.superclass.constructor.call(this, config);
+    this.ds = ds;
+    this.cursor = 0;
+    if (ds) { 
+        this.bind(ds);
+    }
+    
+    this.navgroup = new Roo.bootstrap.NavGroup({ cls: 'pagination' });
+    
+};
+
+Roo.extend(Roo.bootstrap.PagingToolbar, Roo.bootstrap.NavSimplebar, {
+    /**
+     * @cfg {Roo.data.Store} dataSource
+     * The underlying data store providing the paged data
+     */
+    /**
+     * @cfg {String/HTMLElement/Element} container
+     * container The id or element that will contain the toolbar
+     */
+    /**
+     * @cfg {Boolean} displayInfo
+     * True to display the displayMsg (defaults to false)
+     */
+    /**
+     * @cfg {Number} pageSize
+     * The number of records to display per page (defaults to 20)
+     */
+    pageSize: 20,
+    /**
+     * @cfg {String} displayMsg
+     * The paging status message to display (defaults to "Displaying {start} - {end} of {total}")
+     */
+    displayMsg : 'Displaying {0} - {1} of {2}',
+    /**
+     * @cfg {String} emptyMsg
+     * The message to display when no records are found (defaults to "No data to display")
+     */
+    emptyMsg : 'No data to display',
+    /**
+     * Customizable piece of the default paging text (defaults to "Page")
+     * @type String
+     */
+    beforePageText : "Page",
+    /**
+     * Customizable piece of the default paging text (defaults to "of %0")
+     * @type String
+     */
+    afterPageText : "of {0}",
+    /**
+     * Customizable piece of the default paging text (defaults to "First Page")
+     * @type String
+     */
+    firstText : "First Page",
+    /**
+     * Customizable piece of the default paging text (defaults to "Previous Page")
+     * @type String
+     */
+    prevText : "Previous Page",
+    /**
+     * Customizable piece of the default paging text (defaults to "Next Page")
+     * @type String
+     */
+    nextText : "Next Page",
+    /**
+     * Customizable piece of the default paging text (defaults to "Last Page")
+     * @type String
+     */
+    lastText : "Last Page",
+    /**
+     * Customizable piece of the default paging text (defaults to "Refresh")
+     * @type String
+     */
+    refreshText : "Refresh",
+
+    buttons : false,
+    // private
+    onRender : function(ct, position) 
+    {
+        Roo.bootstrap.PagingToolbar.superclass.onRender.call(this, ct, position);
+        this.navgroup.parentId = this.id;
+        this.navgroup.onRender(this.el, null);
+        // add the buttons to the navgroup
+        
+        if(this.displayInfo){
+            Roo.log(this.el.select('ul.navbar-nav',true).first());
+            this.el.select('ul.navbar-nav',true).first().createChild({cls:'x-paging-info'});
+            this.displayEl = this.el.select('.x-paging-info', true).first();
+//            var navel = this.navgroup.addItem( { tagtype : 'span', html : '', cls : 'x-paging-info', preventDefault : true } );
+//            this.displayEl = navel.el.select('span',true).first();
+        }
+        
+        var _this = this;
+        
+        if(this.buttons){
+            Roo.each(_this.buttons, function(e){
+               Roo.factory(e).onRender(_this.el, null);
+            });
+        }
+            
+        Roo.each(_this.toolbarItems, function(e) {
+            _this.navgroup.addItem(e);
+        });
+        
+        
+        this.first = this.navgroup.addItem({
+            tooltip: this.firstText,
+            cls: "prev",
+            icon : 'fa fa-backward',
+            disabled: true,
+            preventDefault: true,
+            listeners : { click : this.onClick.createDelegate(this, ["first"]) }
+        });
+        
+        this.prev =  this.navgroup.addItem({
+            tooltip: this.prevText,
+            cls: "prev",
+            icon : 'fa fa-step-backward',
+            disabled: true,
+            preventDefault: true,
+            listeners : { click :  this.onClick.createDelegate(this, ["prev"]) }
+        });
+    //this.addSeparator();
+        
+        
+        var field = this.navgroup.addItem( {
+            tagtype : 'span',
+            cls : 'x-paging-position',
+            
+            html : this.beforePageText  +
+                '<input type="text" size="3" value="1" class="x-grid-page-number">' +
+                '<span class="x-paging-after">' +  String.format(this.afterPageText, 1) + '</span>'
+         } ); //?? escaped?
+        
+        this.field = field.el.select('input', true).first();
+        this.field.on("keydown", this.onPagingKeydown, this);
+        this.field.on("focus", function(){this.dom.select();});
+    
+    
+        this.afterTextEl =  field.el.select('.x-paging-after',true).first();
+        //this.field.setHeight(18);
+        //this.addSeparator();
+        this.next = this.navgroup.addItem({
+            tooltip: this.nextText,
+            cls: "next",
+            html : ' <i class="fa fa-step-forward">',
+            disabled: true,
+            preventDefault: true,
+            listeners : { click :  this.onClick.createDelegate(this, ["next"]) }
+        });
+        this.last = this.navgroup.addItem({
+            tooltip: this.lastText,
+            icon : 'fa fa-forward',
+            cls: "next",
+            disabled: true,
+            preventDefault: true,
+            listeners : { click :  this.onClick.createDelegate(this, ["last"]) }
+        });
+    //this.addSeparator();
+        this.loading = this.navgroup.addItem({
+            tooltip: this.refreshText,
+            icon: 'fa fa-refresh',
+            preventDefault: true,
+            listeners : { click : this.onClick.createDelegate(this, ["refresh"]) }
+        });
+
+    },
+
+    // private
+    updateInfo : function(){
+        if(this.displayEl){
+            var count = (typeof(this.getCount) == 'undefined') ? this.ds.getCount() : this.getCount();
+            var msg = count == 0 ?
+                this.emptyMsg :
+                String.format(
+                    this.displayMsg,
+                    this.cursor+1, this.cursor+count, this.ds.getTotalCount()    
+                );
+            this.displayEl.update(msg);
+        }
+    },
+
+    // private
+    onLoad : function(ds, r, o){
+       this.cursor = o.params ? o.params.start : 0;
+       var d = this.getPageData(),
+            ap = d.activePage,
+            ps = d.pages;
+        
+       this.afterTextEl.dom.innerHTML = String.format(this.afterPageText, d.pages);
+       this.field.dom.value = ap;
+       this.first.setDisabled(ap == 1);
+       this.prev.setDisabled(ap == 1);
+       this.next.setDisabled(ap == ps);
+       this.last.setDisabled(ap == ps);
+       this.loading.enable();
+       this.updateInfo();
+    },
+
+    // private
+    getPageData : function(){
+        var total = this.ds.getTotalCount();
+        return {
+            total : total,
+            activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
+            pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
+        };
+    },
+
+    // private
+    onLoadError : function(){
+        this.loading.enable();
+    },
+
+    // private
+    onPagingKeydown : function(e){
+        var k = e.getKey();
+        var d = this.getPageData();
+        if(k == e.RETURN){
+            var v = this.field.dom.value, pageNum;
+            if(!v || isNaN(pageNum = parseInt(v, 10))){
+                this.field.dom.value = d.activePage;
+                return;
+            }
+            pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
+            this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
+            e.stopEvent();
+        }
+        else if(k == e.HOME || (k == e.UP && e.ctrlKey) || (k == e.PAGEUP && e.ctrlKey) || (k == e.RIGHT && e.ctrlKey) || k == e.END || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey))
+        {
+          var pageNum = (k == e.HOME || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey)) ? 1 : d.pages;
+          this.field.dom.value = pageNum;
+          this.ds.load({params:{start: (pageNum - 1) * this.pageSize, limit: this.pageSize}});
+          e.stopEvent();
+        }
+        else if(k == e.UP || k == e.RIGHT || k == e.PAGEUP || k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
+        {
+          var v = this.field.dom.value, pageNum; 
+          var increment = (e.shiftKey) ? 10 : 1;
+          if(k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
+            increment *= -1;
+          if(!v || isNaN(pageNum = parseInt(v, 10))) {
+            this.field.dom.value = d.activePage;
+            return;
+          }
+          else if(parseInt(v, 10) + increment >= 1 & parseInt(v, 10) + increment <= d.pages)
+          {
+            this.field.dom.value = parseInt(v, 10) + increment;
+            pageNum = Math.min(Math.max(1, pageNum + increment), d.pages) - 1;
+            this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
+          }
+          e.stopEvent();
+        }
+    },
+
+    // private
+    beforeLoad : function(){
+        if(this.loading){
+            this.loading.disable();
+        }
+    },
+
+    // private
+    onClick : function(which){
+        
+        var ds = this.ds;
+        if (!ds) {
+            return;
+        }
+        
+        switch(which){
+            case "first":
+                ds.load({params:{start: 0, limit: this.pageSize}});
+            break;
+            case "prev":
+                ds.load({params:{start: Math.max(0, this.cursor-this.pageSize), limit: this.pageSize}});
+            break;
+            case "next":
+                ds.load({params:{start: this.cursor+this.pageSize, limit: this.pageSize}});
+            break;
+            case "last":
+                var total = ds.getTotalCount();
+                var extra = total % this.pageSize;
+                var lastStart = extra ? (total - extra) : total-this.pageSize;
+                ds.load({params:{start: lastStart, limit: this.pageSize}});
+            break;
+            case "refresh":
+                ds.load({params:{start: this.cursor, limit: this.pageSize}});
+            break;
+        }
+    },
+
+    /**
+     * Unbinds the paging toolbar from the specified {@link Roo.data.Store}
+     * @param {Roo.data.Store} store The data store to unbind
+     */
+    unbind : function(ds){
+        ds.un("beforeload", this.beforeLoad, this);
+        ds.un("load", this.onLoad, this);
+        ds.un("loadexception", this.onLoadError, this);
+        ds.un("remove", this.updateInfo, this);
+        ds.un("add", this.updateInfo, this);
+        this.ds = undefined;
+    },
+
+    /**
+     * Binds the paging toolbar to the specified {@link Roo.data.Store}
+     * @param {Roo.data.Store} store The data store to bind
+     */
+    bind : function(ds){
+        ds.on("beforeload", this.beforeLoad, this);
+        ds.on("load", this.onLoad, this);
+        ds.on("loadexception", this.onLoadError, this);
+        ds.on("remove", this.updateInfo, this);
+        ds.on("add", this.updateInfo, this);
+        this.ds = ds;
+    }
+});/*
+ * - LGPL
+ *
+ * element
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.MessageBar
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MessageBar class
+ * @cfg {String} html contents of the MessageBar
+ * @cfg {String} weight (info | success | warning | danger) default info
+ * @cfg {String} beforeClass insert the bar before the given class
+ * @cfg {Boolean} closable (true | false) default false
+ * @cfg {Boolean} fixed (true | false) default false, fix the bar at the top
+ * 
+ * @constructor
+ * Create a new Element
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.MessageBar = function(config){
+    Roo.bootstrap.MessageBar.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.MessageBar, Roo.bootstrap.Component,  {
+    
+    html: '',
+    weight: 'info',
+    closable: false,
+    fixed: false,
+    beforeClass: 'bootstrap-sticky-wrap',
+    
+    getAutoCreate : function(){
+        
+        var cfg = {
+            tag: 'div',
+            cls: 'alert alert-dismissable alert-' + this.weight,
+            cn: [
+                {
+                    tag: 'span',
+                    cls: 'message',
+                    html: this.html || ''
+                }
+            ]
+        }
+        
+        if(this.fixed){
+            cfg.cls += ' alert-messages-fixed';
+        }
+        
+        if(this.closable){
+            cfg.cn.push({
+                tag: 'button',
+                cls: 'close',
+                html: 'x'
+            });
+        }
+        
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
+        
+        if(!this.el){
+            var cfg = Roo.apply({},  this.getAutoCreate());
+            cfg.id = Roo.id();
+            
+            if (this.cls) {
+                cfg.cls += ' ' + this.cls;
+            }
+            if (this.style) {
+                cfg.style = this.style;
+            }
+            this.el = Roo.get(document.body).createChild(cfg, Roo.select('.'+this.beforeClass, true).first());
+            
+            this.el.setVisibilityMode(Roo.Element.DISPLAY);
+        }
+        
+        this.el.select('>button.close').on('click', this.hide, this);
+        
+    },
+    
+    show : function()
+    {
+        if (!this.rendered) {
+            this.render();
+        }
+        
+        this.el.show();
+        
+        this.fireEvent('show', this);
+        
+    },
+    
+    hide : function()
+    {
+        if (!this.rendered) {
+            this.render();
+        }
+        
+        this.el.hide();
+        
+        this.fireEvent('hide', this);
+    },
+    
+    update : function()
+    {
+//        var e = this.el.dom.firstChild;
+//        
+//        if(this.closable){
+//            e = e.nextSibling;
+//        }
+//        
+//        e.data = this.html || '';
+
+        this.el.select('>.message', true).first().dom.innerHTML = this.html || '';
+    }
+   
+});
+
+
+     /*
+ * - LGPL
+ *
+ * Graph
+ * 
+ */
+
+
+/**
+ * @class Roo.bootstrap.Graph
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Graph class
+> Prameters
+ -sm {number} sm 4
+ -md {number} md 5
+ @cfg {String} graphtype  bar | vbar | pie
+ @cfg {number} g_x coodinator | centre x (pie)
+ @cfg {number} g_y coodinator | centre y (pie)
+ @cfg {number} g_r radius (pie)
+ @cfg {number} g_height height of the chart (respected by all elements in the set)
+ @cfg {number} g_width width of the chart (respected by all elements in the set)
+ @cfg {Object} title The title of the chart
+    
+ -{Array}  values
+ -opts (object) options for the chart 
+     o {
+     o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
+     o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
+     o vgutter (number)
+     o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
+     o stacked (boolean) whether or not to tread values as in a stacked bar chart
+     o to
+     o stretch (boolean)
+     o }
+ -opts (object) options for the pie
+     o{
+     o cut
+     o startAngle (number)
+     o endAngle (number)
+     } 
+ *
+ * @constructor
+ * Create a new Input
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Graph = function(config){
+    Roo.bootstrap.Graph.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        // img events
+        /**
+         * @event click
+         * The img click event for the img.
+         * @param {Roo.EventObject} e
+         */
+        "click" : true
+    });
+};
+
+Roo.extend(Roo.bootstrap.Graph, Roo.bootstrap.Component,  {
+    
+    sm: 4,
+    md: 5,
+    graphtype: 'bar',
+    g_height: 250,
+    g_width: 400,
+    g_x: 50,
+    g_y: 50,
+    g_r: 30,
+    opts:{
+        //g_colors: this.colors,
+        g_type: 'soft',
+        g_gutter: '20%'
+
+    },
+    title : false,
+
+    getAutoCreate : function(){
+        
+        var cfg = {
+            tag: 'div',
+            html : null
+        }
+        
+        
+        return  cfg;
+    },
+
+    onRender : function(ct,position){
+        Roo.bootstrap.Graph.superclass.onRender.call(this,ct,position);
+        this.raphael = Raphael(this.el.dom);
+        
+                    // data1 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    // data2 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    // data3 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    // txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
+                /*
+                r.text(160, 10, "Single Series Chart").attr(txtattr);
+                r.text(480, 10, "Multiline Series Chart").attr(txtattr);
+                r.text(160, 250, "Multiple Series Stacked Chart").attr(txtattr);
+                r.text(480, 250, 'Multiline Series Stacked Vertical Chart. Type "round"').attr(txtattr);
+                
+                r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]], 0, {type: "sharp"});
+                r.barchart(330, 10, 300, 220, data1);
+                r.barchart(10, 250, 300, 220, data2, {stacked: true});
+                r.barchart(330, 250, 300, 220, data3, {stacked: true, type: "round"});
+                */
+                
+                // var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
+                // r.barchart(30, 30, 560, 250,  xdata, {
+                //    labels : [55, 20, 13, 32, 5, 1, 2, 10,5 , 10],
+                //     axis : "0 0 1 1",
+                //     axisxlabels :  xdata
+                //     //yvalues : cols,
+                   
+                // });
+//        var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
+//        
+//        this.load(null,xdata,{
+//                axis : "0 0 1 1",
+//                axisxlabels :  xdata
+//                });
+
+    },
+
+    load : function(graphtype,xdata,opts){
+        this.raphael.clear();
+        if(!graphtype) {
+            graphtype = this.graphtype;
+        }
+        if(!opts){
+            opts = this.opts;
+        }
+        var r = this.raphael,
+            fin = function () {
+                this.flag = r.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
+            },
+            fout = function () {
+                this.flag.animate({opacity: 0}, 300, function () {this.remove();});
+            },
+            pfin = function() {
+                this.sector.stop();
+                this.sector.scale(1.1, 1.1, this.cx, this.cy);
+
+                if (this.label) {
+                    this.label[0].stop();
+                    this.label[0].attr({ r: 7.5 });
+                    this.label[1].attr({ "font-weight": 800 });
+                }
+            },
+            pfout = function() {
+                this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
+
+                if (this.label) {
+                    this.label[0].animate({ r: 5 }, 500, "bounce");
+                    this.label[1].attr({ "font-weight": 400 });
+                }
+            };
+
+        switch(graphtype){
+            case 'bar':
+                this.raphael.barchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
+                break;
+            case 'hbar':
+                this.raphael.hbarchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
+                break;
+            case 'pie':
+//                opts = { legend: ["%% - Enterprise Users", "% - ddd","Chrome Users"], legendpos: "west", 
+//                href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]};
+//            
+                this.raphael.piechart(this.g_x,this.g_y,this.g_r,xdata,opts).hover(pfin, pfout);
+                
+                break;
+
+        }
+        
+        if(this.title){
+            this.raphael.text(this.title.x, this.title.y, this.title.text).attr(this.title.attr);
+        }
+        
+    },
+    
+    setTitle: function(o)
+    {
+        this.title = o;
+    },
+    
+    initEvents: function() {
+        
+        if(!this.href){
+            this.el.on('click', this.onClick, this);
+        }
+    },
+    
+    onClick : function(e)
+    {
+        Roo.log('img onclick');
+        this.fireEvent('click', this, e);
+    }
+   
+});
+
+/*
+ * - LGPL
+ *
+ * numberBox
+ * 
+ */
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+
+/**
+ * @class Roo.bootstrap.dash.NumberBox
+ * @extends Roo.bootstrap.Component
+ * Bootstrap NumberBox class
+ * @cfg {String} headline Box headline
+ * @cfg {String} content Box content
+ * @cfg {String} icon Box icon
+ * @cfg {String} footer Footer text
+ * @cfg {String} fhref Footer href
+ * 
+ * @constructor
+ * Create a new NumberBox
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.dash.NumberBox = function(config){
+    Roo.bootstrap.dash.NumberBox.superclass.constructor.call(this, config);
+    
+};
+
+Roo.extend(Roo.bootstrap.dash.NumberBox, Roo.bootstrap.Component,  {
+    
+    headline : '',
+    content : '',
+    icon : '',
+    footer : '',
+    fhref : '',
+    ficon : '',
+    
+    getAutoCreate : function(){
+        
+        var cfg = {
+            tag : 'div',
+            cls : 'small-box ',
+            cn : [
+                {
+                    tag : 'div',
+                    cls : 'inner',
+                    cn :[
+                        {
+                            tag : 'h3',
+                            cls : 'roo-headline',
+                            html : this.headline
+                        },
+                        {
+                            tag : 'p',
+                            cls : 'roo-content',
+                            html : this.content
+                        }
+                    ]
+                }
+            ]
+        }
+        
+        if(this.icon){
+            cfg.cn.push({
+                tag : 'div',
+                cls : 'icon',
+                cn :[
+                    {
+                        tag : 'i',
+                        cls : 'ion ' + this.icon
+                    }
+                ]
+            });
+        }
+        
+        if(this.footer){
+            var footer = {
+                tag : 'a',
+                cls : 'small-box-footer',
+                href : this.fhref || '#',
+                html : this.footer
+            };
+            
+            cfg.cn.push(footer);
+            
+        }
+        
+        return  cfg;
+    },
+
+    onRender : function(ct,position){
+        Roo.bootstrap.dash.NumberBox.superclass.onRender.call(this,ct,position);
+
+
+       
+                
+    },
+
+    setHeadline: function (value)
+    {
+        this.el.select('.roo-headline',true).first().dom.innerHTML = value;
+    },
+    
+    setFooter: function (value, href)
+    {
+        this.el.select('a.small-box-footer',true).first().dom.innerHTML = value;
+        
+        if(href){
+            this.el.select('a.small-box-footer',true).first().attr('href', href);
+        }
+        
+    },
+
+    setContent: function (value)
+    {
+        this.el.select('.roo-content',true).first().dom.innerHTML = value;
+    },
+
+    initEvents: function() 
+    {   
+        
+    }
+    
+});
+
+/*
+ * - LGPL
+ *
+ * TabBox
+ * 
+ */
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+
+/**
+ * @class Roo.bootstrap.dash.TabBox
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TabBox class
+ * @cfg {String} title Title of the TabBox
+ * @cfg {String} icon Icon of the TabBox
+ * @cfg {Boolean} showtabs (true|false) show the tabs default true
+ * @cfg {Boolean} tabScrollable (true|false) tab scrollable when mobile view default false
+ * 
+ * @constructor
+ * Create a new TabBox
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.dash.TabBox = function(config){
+    Roo.bootstrap.dash.TabBox.superclass.constructor.call(this, config);
+    this.addEvents({
+        // raw events
+        /**
+         * @event addpane
+         * When a pane is added
+         * @param {Roo.bootstrap.dash.TabPane} pane
+         */
+        "addpane" : true,
+        /**
+         * @event activatepane
+         * When a pane is activated
+         * @param {Roo.bootstrap.dash.TabPane} pane
+         */
+        "activatepane" : true
+        
+         
+    });
+    
+    this.panes = [];
+};
+
+Roo.extend(Roo.bootstrap.dash.TabBox, Roo.bootstrap.Component,  {
+
+    title : '',
+    icon : false,
+    showtabs : true,
+    tabScrollable : false,
+    
+    getChildContainer : function()
+    {
+        return this.el.select('.tab-content', true).first();
+    },
+    
+    getAutoCreate : function(){
+        
+        var header = {
+            tag: 'li',
+            cls: 'pull-left header',
+            html: this.title,
+            cn : []
+        };
+        
+        if(this.icon){
+            header.cn.push({
+                tag: 'i',
+                cls: 'fa ' + this.icon
+            });
+        }
+        
+        var h = {
+            tag: 'ul',
+            cls: 'nav nav-tabs pull-right',
+            cn: [
+                header
+            ]
+        };
+        
+        if(this.tabScrollable){
+            h = {
+                tag: 'div',
+                cls: 'tab-header',
+                cn: [
+                    {
+                        tag: 'ul',
+                        cls: 'nav nav-tabs pull-right',
+                        cn: [
+                            header
+                        ]
+                    }
+                ]
+            }
+        }
+        
+        var cfg = {
+            tag: 'div',
+            cls: 'nav-tabs-custom',
+            cn: [
+                h,
+                {
+                    tag: 'div',
+                    cls: 'tab-content no-padding',
+                    cn: []
+                }
+            ]
+        }
+
+        return  cfg;
+    },
+    initEvents : function()
+    {
+        //Roo.log('add add pane handler');
+        this.on('addpane', this.onAddPane, this);
+    },
+     /**
+     * Updates the box title
+     * @param {String} html to set the title to.
+     */
+    setTitle : function(value)
+    {
+        this.el.select('.nav-tabs .header', true).first().dom.innerHTML = value;
+    },
+    onAddPane : function(pane)
+    {
+        this.panes.push(pane);
+        //Roo.log('addpane');
+        //Roo.log(pane);
+        // tabs are rendere left to right..
+        if(!this.showtabs){
+            return;
+        }
+        
+        var ctr = this.el.select('.nav-tabs', true).first();
+         
+         
+        var existing = ctr.select('.nav-tab',true);
+        var qty = existing.getCount();;
+        
+        
+        var tab = ctr.createChild({
+            tag : 'li',
+            cls : 'nav-tab' + (qty ? '' : ' active'),
+            cn : [
+                {
+                    tag : 'a',
+                    href:'#',
+                    html : pane.title
+                }
+            ]
+        }, qty ? existing.first().dom : ctr.select('.header', true).first().dom );
+        pane.tab = tab;
+        
+        tab.on('click', this.onTabClick.createDelegate(this, [pane], true));
+        if (!qty) {
+            pane.el.addClass('active');
+        }
+        
+                
+    },
+    onTabClick : function(ev,un,ob,pane)
+    {
+        //Roo.log('tab - prev default');
+        ev.preventDefault();
+        
+        
+        this.el.select('.nav-tabs li.nav-tab', true).removeClass('active');
+        pane.tab.addClass('active');
+        //Roo.log(pane.title);
+        this.getChildContainer().select('.tab-pane',true).removeClass('active');
+        // technically we should have a deactivate event.. but maybe add later.
+        // and it should not de-activate the selected tab...
+        this.fireEvent('activatepane', pane);
+        pane.el.addClass('active');
+        pane.fireEvent('activate');
+        
+        
+    },
+    
+    getActivePane : function()
+    {
+        var r = false;
+        Roo.each(this.panes, function(p) {
+            if(p.el.hasClass('active')){
+                r = p;
+                return false;
+            }
+            
+            return;
+        });
+        
+        return r;
+    }
+    
+    
+});
+
+/*
+ * - LGPL
+ *
+ * Tab pane
+ * 
+ */
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+/**
+ * @class Roo.bootstrap.TabPane
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TabPane class
+ * @cfg {Boolean} active (false | true) Default false
+ * @cfg {String} title title of panel
+
+ * 
+ * @constructor
+ * Create a new TabPane
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.dash.TabPane = function(config){
+    Roo.bootstrap.dash.TabPane.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        // raw events
+        /**
+         * @event activate
+         * When a pane is activated
+         * @param {Roo.bootstrap.dash.TabPane} pane
+         */
+        "activate" : true
+         
+    });
+};
+
+Roo.extend(Roo.bootstrap.dash.TabPane, Roo.bootstrap.Component,  {
+    
+    active : false,
+    title : '',
+    
+    // the tabBox that this is attached to.
+    tab : false,
+     
+    getAutoCreate : function() 
+    {
+        var cfg = {
+            tag: 'div',
+            cls: 'tab-pane'
+        }
+        
+        if(this.active){
+            cfg.cls += ' active';
+        }
+        
+        return cfg;
+    },
+    initEvents  : function()
+    {
+        //Roo.log('trigger add pane handler');
+        this.parent().fireEvent('addpane', this)
+    },
+    
+     /**
+     * Updates the tab title 
+     * @param {String} html to set the title to.
+     */
+    setTitle: function(str)
+    {
+        if (!this.tab) {
+            return;
+        }
+        this.title = str;
+        this.tab.select('a', true).first().dom.innerHTML = str;
+        
+    }
+    
+    
+    
+});
+
+
+
+ /*
+ * - LGPL
+ *
+ * menu
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Menu
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Menu class - container for Menu
+ * @cfg {String} html Text of the menu
+ * @cfg {String} weight (default | primary | success | info | warning | danger | inverse)
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Menu align to (top | bottom) default bottom
+ * 
+ * 
+ * @constructor
+ * Create a new Menu
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Menu = function(config){
+    Roo.bootstrap.menu.Menu.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event beforeshow
+         * Fires before this menu is displayed
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        beforeshow : true,
+        /**
+         * @event beforehide
+         * Fires before this menu is hidden
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        beforehide : true,
+        /**
+         * @event show
+         * Fires after this menu is displayed
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        show : true,
+        /**
+         * @event hide
+         * Fires after this menu is hidden
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        hide : true,
+        /**
+         * @event click
+         * Fires when this menu is clicked (or when the enter key is pressed while it is active)
+         * @param {Roo.bootstrap.menu.Menu} this
+         * @param {Roo.EventObject} e
+         */
+        click : true
+    });
+    
+};
+
+Roo.extend(Roo.bootstrap.menu.Menu, Roo.bootstrap.Component,  {
+    
+    submenu : false,
+    html : '',
+    weight : 'default',
+    icon : false,
+    pos : 'bottom',
+    
+    
+    getChildContainer : function() {
+        if(this.isSubMenu){
+            return this.el;
+        }
+        
+        return this.el.select('ul.dropdown-menu', true).first();  
+    },
+    
+    getAutoCreate : function()
+    {
+        var text = [
+            {
+                tag : 'span',
+                cls : 'roo-menu-text',
+                html : this.html
+            }
+        ];
+        
+        if(this.icon){
+            text.unshift({
+                tag : 'i',
+                cls : 'fa ' + this.icon
+            })
+        }
+        
+        
+        var cfg = {
+            tag : 'div',
+            cls : 'btn-group',
+            cn : [
+                {
+                    tag : 'button',
+                    cls : 'dropdown-button btn btn-' + this.weight,
+                    cn : text
+                },
+                {
+                    tag : 'button',
+                    cls : 'dropdown-toggle btn btn-' + this.weight,
+                    cn : [
+                        {
+                            tag : 'span',
+                            cls : 'caret'
+                        }
+                    ]
+                },
+                {
+                    tag : 'ul',
+                    cls : 'dropdown-menu'
+                }
+            ]
+            
+        };
+        
+        if(this.pos == 'top'){
+            cfg.cls += ' dropup';
+        }
+        
+        if(this.isSubMenu){
+            cfg = {
+                tag : 'ul',
+                cls : 'dropdown-menu'
+            }
+        }
+       
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        this.isSubMenu = ct.hasClass('dropdown-submenu');
+        
+        Roo.bootstrap.menu.Menu.superclass.onRender.call(this, ct, position);
+    },
+    
+    initEvents : function() 
+    {
+        if(this.isSubMenu){
+            return;
+        }
+        
+        this.hidden = true;
+        
+        this.triggerEl = this.el.select('button.dropdown-toggle', true).first();
+        this.triggerEl.on('click', this.onTriggerPress, this);
+        
+        this.buttonEl = this.el.select('button.dropdown-button', true).first();
+        this.buttonEl.on('click', this.onClick, this);
+        
+    },
+    
+    list : function()
+    {
+        if(this.isSubMenu){
+            return this.el;
+        }
+        
+        return this.el.select('ul.dropdown-menu', true).first();
+    },
+    
+    onClick : function(e)
+    {
+        this.fireEvent("click", this, e);
+    },
+    
+    onTriggerPress  : function(e)
+    {   
+        if (this.isVisible()) {
+            this.hide();
+        } else {
+            this.show();
+        }
+    },
+    
+    isVisible : function(){
+        return !this.hidden;
+    },
+    
+    show : function()
+    {
+        this.fireEvent("beforeshow", this);
+        
+        this.hidden = false;
+        this.el.addClass('open');
+        
+        Roo.get(document).on("mouseup", this.onMouseUp, this);
+        
+        this.fireEvent("show", this);
+        
+        
+    },
+    
+    hide : function()
+    {
+        this.fireEvent("beforehide", this);
+        
+        this.hidden = true;
+        this.el.removeClass('open');
+        
+        Roo.get(document).un("mouseup", this.onMouseUp);
+        
+        this.fireEvent("hide", this);
+    },
+    
+    onMouseUp : function()
+    {
+        this.hide();
+    }
+    
+});
+
+ /*
+ * - LGPL
+ *
+ * menu item
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Item
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MenuItem class
+ * @cfg {Boolean} submenu (true | false) default false
+ * @cfg {String} html text of the item
+ * @cfg {String} href the link
+ * @cfg {Boolean} disable (true | false) default false
+ * @cfg {Boolean} preventDefault (true | false) default true
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Submenu align to (left | right) default right 
+ * 
+ * 
+ * @constructor
+ * Create a new Item
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Item = function(config){
+    Roo.bootstrap.menu.Item.superclass.constructor.call(this, config);
+    this.addEvents({
+        /**
+         * @event mouseover
+         * Fires when the mouse is hovering over this menu
+         * @param {Roo.bootstrap.menu.Item} this
+         * @param {Roo.EventObject} e
+         */
+        mouseover : true,
+        /**
+         * @event mouseout
+         * Fires when the mouse exits this menu
+         * @param {Roo.bootstrap.menu.Item} this
+         * @param {Roo.EventObject} e
+         */
+        mouseout : true,
+        // raw events
+        /**
+         * @event click
+         * The raw click event for the entire grid.
+         * @param {Roo.EventObject} e
+         */
+        click : true
+    });
+};
+
+Roo.extend(Roo.bootstrap.menu.Item, Roo.bootstrap.Component,  {
+    
+    submenu : false,
+    href : '',
+    html : '',
+    preventDefault: true,
+    disable : false,
+    icon : false,
+    pos : 'right',
+    
+    getAutoCreate : function()
+    {
+        var text = [
+            {
+                tag : 'span',
+                cls : 'roo-menu-item-text',
+                html : this.html
+            }
+        ];
+        
+        if(this.icon){
+            text.unshift({
+                tag : 'i',
+                cls : 'fa ' + this.icon
+            })
+        }
+        
+        var cfg = {
+            tag : 'li',
+            cn : [
+                {
+                    tag : 'a',
+                    href : this.href || '#',
+                    cn : text
+                }
+            ]
+        };
+        
+        if(this.disable){
+            cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'disabled' : (cfg.cls + ' disabled');
+        }
+        
+        if(this.submenu){
+            cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'dropdown-submenu' : (cfg.cls + ' dropdown-submenu');
+            
+            if(this.pos == 'left'){
+                cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'pull-left' : (cfg.cls + ' pull-left');
+            }
+        }
+        
+        return cfg;
+    },
+    
+    initEvents : function() 
+    {
+        this.el.on('mouseover', this.onMouseOver, this);
+        this.el.on('mouseout', this.onMouseOut, this);
+        
+        this.el.select('a', true).first().on('click', this.onClick, this);
+        
+    },
+    
+    onClick : function(e)
+    {
+        if(this.preventDefault){
+            e.preventDefault();
+        }
+        
+        this.fireEvent("click", this, e);
+    },
+    
+    onMouseOver : function(e)
+    {
+        if(this.submenu && this.pos == 'left'){
+            this.el.select('ul.dropdown-menu', true).first().setLeft(this.el.select('ul.dropdown-menu', true).first().getWidth() * -1);
+        }
+        
+        this.fireEvent("mouseover", this, e);
+    },
+    
+    onMouseOut : function(e)
+    {
+        this.fireEvent("mouseout", this, e);
+    }
+});
+
+
+ /*
+ * - LGPL
+ *
+ * menu separator
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Separator
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Separator class
+ * 
+ * @constructor
+ * Create a new Separator
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Separator = function(config){
+    Roo.bootstrap.menu.Separator.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.menu.Separator, Roo.bootstrap.Component,  {
+    
+    getAutoCreate : function(){
+        var cfg = {
+            tag : 'li',
+            cls: 'divider'
+        };
+        
+        return cfg;
+    }
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * Tooltip
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Tooltip
+ * Bootstrap Tooltip class
+ * This is basic at present - all componets support it by default, however they should add tooltipEl() method
+ * to determine which dom element triggers the tooltip.
+ * 
+ * It needs to add support for additional attributes like tooltip-position
+ * 
+ * @constructor
+ * Create a new Toolti
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Tooltip = function(config){
+    Roo.bootstrap.Tooltip.superclass.constructor.call(this, config);
+};
+
+Roo.apply(Roo.bootstrap.Tooltip, {
+    /**
+     * @function init initialize tooltip monitoring.
+     * @static
+     */
+    currentEl : false,
+    currentTip : false,
+    currentRegion : false,
+    
+    //  init : delay?
+    
+    init : function()
+    {
+        Roo.get(document).on('mouseover', this.enter ,this);
+        Roo.get(document).on('mouseout', this.leave, this);
+         
+        
+        this.currentTip = new Roo.bootstrap.Tooltip();
+    },
+    
+    enter : function(ev)
+    {
+        var dom = ev.getTarget();
+        //Roo.log(['enter',dom]);
+        var el = Roo.fly(dom);
+        if (this.currentEl) {
+            //Roo.log(dom);
+            //Roo.log(this.currentEl);
+            //Roo.log(this.currentEl.contains(dom));
+            if (this.currentEl == el) {
+                return;
+            }
+            if (dom != this.currentEl.dom && this.currentEl.contains(dom)) {
+                return;
+            }
+
+        }
+        
+        
+        
+        if (this.currentTip.el) {
+            this.currentTip.el.hide(); // force hiding...
+        }    
+        //Roo.log(el);
+        if (!el.attr('tooltip')) { // parents who have tip?
+            return;
+        }
+        this.currentEl = el;
+        this.currentTip.bind(el);
+        this.currentRegion = Roo.lib.Region.getRegion(dom);
+        this.currentTip.enter();
+        
+    },
+    leave : function(ev)
+    {
+        var dom = ev.getTarget();
+        //Roo.log(['leave',dom]);
+        if (!this.currentEl) {
+            return;
+        }
+        
+        
+        if (dom != this.currentEl.dom) {
+            return;
+        }
+        var xy = ev.getXY();
+        if (this.currentRegion.contains( new Roo.lib.Region( xy[1], xy[0] ,xy[1], xy[0]  ))) {
+            return;
+        }
+        // only activate leave if mouse cursor is outside... bounding box..
+        
+        
+        
+        
+        if (this.currentTip) {
+            this.currentTip.leave();
+        }
+        //Roo.log('clear currentEl');
+        this.currentEl = false;
+        
+        
+    },
+    alignment : {
+        'left' : ['r-l', [-2,0], 'right'],
+        'right' : ['l-r', [2,0], 'left'],
+        'bottom' : ['t-b', [0,2], 'top'],
+        'top' : [ 'b-t', [0,-2], 'bottom']
+    }
+    
+});
+
+
+Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component,  {
+    
+    
+    bindEl : false,
+    
+    delay : null, // can be { show : 300 , hide: 500}
+    
+    timeout : null,
+    
+    hoverState : null, //???
+    
+    placement : 'bottom', 
+    
+    getAutoCreate : function(){
+    
+        var cfg = {
+           cls : 'tooltip',
+           role : 'tooltip',
+           cn : [
+                {
+                    cls : 'tooltip-arrow'
+                },
+                {
+                    cls : 'tooltip-inner'
+                }
+           ]
+        };
+        
+        return cfg;
+    },
+    bind : function(el)
+    {
+        this.bindEl = el;
+    },
+      
+    
+    enter : function () {
+       
+        if (this.timeout != null) {
+            clearTimeout(this.timeout);
+        }
+        
+        this.hoverState = 'in';
+         //Roo.log("enter - show");
+        if (!this.delay || !this.delay.show) {
+            this.show();
+            return;
+        }
+        var _t = this;
+        this.timeout = setTimeout(function () {
+            if (_t.hoverState == 'in') {
+                _t.show();
+            }
+        }, this.delay.show);
+    },
+    leave : function()
+    {
+        clearTimeout(this.timeout);
+    
+        this.hoverState = 'out';
+         if (!this.delay || !this.delay.hide) {
+            this.hide();
+            return 
+        }
+       
+        var _t = this;
+        this.timeout = setTimeout(function () {
+            //Roo.log("leave - timeout");
+            
+            if (_t.hoverState == 'out') {
+                _t.hide();
+                Roo.bootstrap.Tooltip.currentEl = false;
+            }
+        }, delay)
+    },
+    
+    show : function ()
+    {
+        if (!this.el) {
+            this.render(document.body);
+        }
+        // set content.
+        //Roo.log([this.bindEl, this.bindEl.attr('tooltip')]);
+        this.el.select('.tooltip-inner',true).first().dom.innerHTML = this.bindEl.attr('tooltip');
+        
+        this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
+        
+        var placement = typeof this.placement == 'function' ?
+            this.placement.call(this, this.el, on_el) :
+            this.placement;
+            
+        var autoToken = /\s?auto?\s?/i;
+        var autoPlace = autoToken.test(placement);
+        if (autoPlace) {
+            placement = placement.replace(autoToken, '') || 'top';
+        }
+        
+        //this.el.detach()
+        //this.el.setXY([0,0]);
+        this.el.show();
+        //this.el.dom.style.display='block';
+        this.el.addClass(placement);
+        
+        //this.el.appendTo(on_el);
+        
+        var p = this.getPosition();
+        var box = this.el.getBox();
+        
+        if (autoPlace) {
+            // fixme..
+        }
+        var align = Roo.bootstrap.Tooltip.alignment[placement];
+        this.el.alignTo(this.bindEl, align[0],align[1]);
+        //var arrow = this.el.select('.arrow',true).first();
+        //arrow.set(align[2], 
+        
+        this.el.addClass('in fade');
+        this.hoverState = null;
+        
+        if (this.el.hasClass('fade')) {
+            // fade it?
+        }
+        
+    },
+    hide : function()
+    {
+         
+        if (!this.el) {
+            return;
+        }
+        //this.el.setXY([0,0]);
+        this.el.removeClass('in');
+        //this.el.hide();
+        
+    }
+    
+});
+
+ /*
+ * - LGPL
+ *
+ * Location Picker
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.LocationPicker
+ * @extends Roo.bootstrap.Component
+ * Bootstrap LocationPicker class
+ * @cfg {Number} latitude Position when init default 0
+ * @cfg {Number} longitude Position when init default 0
+ * @cfg {Number} zoom default 15
+ * @cfg {String} mapTypeId default google.maps.MapTypeId.ROADMAP
+ * @cfg {Boolean} mapTypeControl default false
+ * @cfg {Boolean} disableDoubleClickZoom default false
+ * @cfg {Boolean} scrollwheel default true
+ * @cfg {Boolean} streetViewControl default false
+ * @cfg {Number} radius default 0
+ * @cfg {String} locationName
+ * @cfg {Boolean} draggable default true
+ * @cfg {Boolean} enableAutocomplete default false
+ * @cfg {Boolean} enableReverseGeocode default true
+ * @cfg {String} markerTitle
+ * 
+ * @constructor
+ * Create a new LocationPicker
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.LocationPicker = function(config){
+    
+    Roo.bootstrap.LocationPicker.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event initial
+         * Fires when the picker initialized.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Google Location} location
+         */
+        initial : true,
+        /**
+         * @event positionchanged
+         * Fires when the picker position changed.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Google Location} location
+         */
+        positionchanged : true,
+        /**
+         * @event resize
+         * Fires when the map resize.
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        resize : true,
+        /**
+         * @event show
+         * Fires when the map show.
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        show : true,
+        /**
+         * @event hide
+         * Fires when the map hide.
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        hide : true,
+        /**
+         * @event mapClick
+         * Fires when click the map.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Map event} e
+         */
+        mapClick : true,
+        /**
+         * @event mapRightClick
+         * Fires when right click the map.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Map event} e
+         */
+        mapRightClick : true,
+        /**
+         * @event markerClick
+         * Fires when click the marker.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Map event} e
+         */
+        markerClick : true,
+        /**
+         * @event markerRightClick
+         * Fires when right click the marker.
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Map event} e
+         */
+        markerRightClick : true,
+        /**
+         * @event OverlayViewDraw
+         * Fires when OverlayView Draw
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        OverlayViewDraw : true,
+        /**
+         * @event OverlayViewOnAdd
+         * Fires when OverlayView Draw
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        OverlayViewOnAdd : true,
+        /**
+         * @event OverlayViewOnRemove
+         * Fires when OverlayView Draw
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        OverlayViewOnRemove : true,
+        /**
+         * @event OverlayViewShow
+         * Fires when OverlayView Draw
+         * @param {Roo.bootstrap.LocationPicker} this
+         * @param {Pixel} cpx
+         */
+        OverlayViewShow : true,
+        /**
+         * @event OverlayViewHide
+         * Fires when OverlayView Draw
+         * @param {Roo.bootstrap.LocationPicker} this
+         */
+        OverlayViewHide : true
+    });
+        
+};
+
+Roo.extend(Roo.bootstrap.LocationPicker, Roo.bootstrap.Component,  {
+    
+    gMapContext: false,
+    
+    latitude: 0,
+    longitude: 0,
+    zoom: 15,
+    mapTypeId: false,
+    mapTypeControl: false,
+    disableDoubleClickZoom: false,
+    scrollwheel: true,
+    streetViewControl: false,
+    radius: 0,
+    locationName: '',
+    draggable: true,
+    enableAutocomplete: false,
+    enableReverseGeocode: true,
+    markerTitle: '',
+    
+    getAutoCreate: function()
+    {
+
+        var cfg = {
+            tag: 'div',
+            cls: 'roo-location-picker'
+        };
+        
+        return cfg
+    },
+    
+    initEvents: function(ct, position)
+    {       
+        if(!this.el.getWidth() || this.isApplied()){
+            return;
+        }
+        
+        this.el.setVisibilityMode(Roo.Element.DISPLAY);
+        
+        this.initial();
+    },
+    
+    initial: function()
+    {
+        if(!this.mapTypeId){
+            this.mapTypeId = google.maps.MapTypeId.ROADMAP;
+        }
+        
+        this.gMapContext = this.GMapContext();
+        
+        this.initOverlayView();
+        
+        this.OverlayView = new Roo.bootstrap.LocationPicker.OverlayView(this.gMapContext.map);
+        
+        var _this = this;
+                
+        google.maps.event.addListener(this.gMapContext.marker, "dragend", function(event) {
+            _this.setPosition(_this.gMapContext.marker.position);
+        });
+        
+        google.maps.event.addListener(this.gMapContext.map, 'click', function(event){
+            _this.fireEvent('mapClick', this, event);
+            
+        });
+
+        google.maps.event.addListener(this.gMapContext.map, 'rightclick', function(event){
+            _this.fireEvent('mapRightClick', this, event);
+            
+        });
+        
+        google.maps.event.addListener(this.gMapContext.marker, 'click', function(event){
+            _this.fireEvent('markerClick', this, event);
+            
+        });
+
+        google.maps.event.addListener(this.gMapContext.marker, 'rightclick', function(event){
+            _this.fireEvent('markerRightClick', this, event);
+            
+        });
+        
+        this.setPosition(this.gMapContext.location);
+        
+        this.fireEvent('initial', this, this.gMapContext.location);
+    },
+    
+    initOverlayView: function()
+    {
+        var _this = this;
+        
+        Roo.bootstrap.LocationPicker.OverlayView.prototype = Roo.apply(new google.maps.OverlayView(), {
+            
+            draw: function()
+            {
+                _this.fireEvent('OverlayViewDraw', _this);
+            },
+            
+            onAdd: function()
+            {
+                _this.fireEvent('OverlayViewOnAdd', _this);
+            },
+            
+            onRemove: function()
+            {
+                _this.fireEvent('OverlayViewOnRemove', _this);
+            },
+            
+            show: function(cpx)
+            {
+                _this.fireEvent('OverlayViewShow', _this, cpx);
+            },
+            
+            hide: function()
+            {
+                _this.fireEvent('OverlayViewHide', _this);
+            }
+            
+        });
+    },
+    
+    fromLatLngToContainerPixel: function(event)
+    {
+        return this.OverlayView.getProjection().fromLatLngToContainerPixel(event.latLng);
+    },
+    
+    isApplied: function() 
+    {
+        return this.getGmapContext() == false ? false : true;
+    },
+    
+    getGmapContext: function() 
+    {
+        return this.gMapContext
+    },
+    
+    GMapContext: function() 
+    {
+        var _map = new google.maps.Map(this.el.dom, this);
+        var _marker = new google.maps.Marker({
+            position: new google.maps.LatLng(this.latitude, this.longitude),
+            map: _map,
+            title: this.markerTitle,
+            draggable: this.draggable
+        });
+        
+        return {
+            map: _map,
+            marker: _marker,
+            circle: null,
+            location: _marker.position,
+            radius: this.radius,
+            locationName: this.locationName,
+            addressComponents: {
+                formatted_address: null,
+                addressLine1: null,
+                addressLine2: null,
+                streetName: null,
+                streetNumber: null,
+                city: null,
+                district: null,
+                state: null,
+                stateOrProvince: null
+            },
+            settings: this,
+            domContainer: this.el.dom,
+            geodecoder: new google.maps.Geocoder()
+        };
+    },
+    
+    drawCircle: function(center, radius, options) 
+    {
+        if (this.gMapContext.circle != null) {
+            this.gMapContext.circle.setMap(null);
+        }
+        if (radius > 0) {
+            radius *= 1;
+            options = Roo.apply({}, options, {
+                strokeColor: "#0000FF",
+                strokeOpacity: .35,
+                strokeWeight: 2,
+                fillColor: "#0000FF",
+                fillOpacity: .2
+            });
+            
+            options.map = this.gMapContext.map;
+            options.radius = radius;
+            options.center = center;
+            this.gMapContext.circle = new google.maps.Circle(options);
+            return this.gMapContext.circle;
+        }
+        
+        return null;
+    },
+    
+    setPosition: function(location) 
+    {
+        this.gMapContext.location = location;
+        this.gMapContext.marker.setPosition(location);
+        this.gMapContext.map.panTo(location);
+        this.drawCircle(location, this.gMapContext.radius, {});
+        
+        var _this = this;
+        
+        if (this.gMapContext.settings.enableReverseGeocode) {
+            this.gMapContext.geodecoder.geocode({
+                latLng: this.gMapContext.location
+            }, function(results, status) {
+                
+                if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
+                    _this.gMapContext.locationName = results[0].formatted_address;
+                    _this.gMapContext.addressComponents = _this.address_component_from_google_geocode(results[0].address_components);
+                    
+                    _this.fireEvent('positionchanged', this, location);
+                }
+            });
+            
+            return;
+        }
+        
+        this.fireEvent('positionchanged', this, location);
+    },
+    
+    resize: function()
+    {
+        google.maps.event.trigger(this.gMapContext.map, "resize");
+        
+        this.gMapContext.map.setCenter(this.gMapContext.marker.position);
+        
+        this.fireEvent('resize', this);
+    },
+    
+    setPositionByLatLng: function(latitude, longitude)
+    {
+        this.setPosition(new google.maps.LatLng(latitude, longitude));
+    },
+    
+    getCurrentPosition: function() 
+    {
+        return {
+            latitude: this.gMapContext.location.lat(),
+            longitude: this.gMapContext.location.lng()
+        };
+    },
+    
+    getAddressName: function() 
+    {
+        return this.gMapContext.locationName;
+    },
+    
+    getAddressComponents: function() 
+    {
+        return this.gMapContext.addressComponents;
+    },
+    
+    address_component_from_google_geocode: function(address_components) 
+    {
+        var result = {};
+        
+        for (var i = 0; i < address_components.length; i++) {
+            var component = address_components[i];
+            if (component.types.indexOf("postal_code") >= 0) {
+                result.postalCode = component.short_name;
+            } else if (component.types.indexOf("street_number") >= 0) {
+                result.streetNumber = component.short_name;
+            } else if (component.types.indexOf("route") >= 0) {
+                result.streetName = component.short_name;
+            } else if (component.types.indexOf("neighborhood") >= 0) {
+                result.city = component.short_name;
+            } else if (component.types.indexOf("locality") >= 0) {
+                result.city = component.short_name;
+            } else if (component.types.indexOf("sublocality") >= 0) {
+                result.district = component.short_name;
+            } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
+                result.stateOrProvince = component.short_name;
+            } else if (component.types.indexOf("country") >= 0) {
+                result.country = component.short_name;
+            }
+        }
+        
+        result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
+        result.addressLine2 = "";
+        return result;
+    },
+    
+    setZoomLevel: function(zoom)
+    {
+        this.gMapContext.map.setZoom(zoom);
+    },
+    
+    show: function()
+    {
+        if(!this.el){
+            return;
+        }
+        
+        this.el.show();
+        
+        this.resize();
+        
+        this.fireEvent('show', this);
+    },
+    
+    hide: function()
+    {
+        if(!this.el){
+            return;
+        }
+        
+        this.el.hide();
+        
+        this.fireEvent('hide', this);
+    }
+    
+});
+
+Roo.apply(Roo.bootstrap.LocationPicker, {
+    
+    OverlayView : function(map, options)
+    {
+        options = options || {};
+        
+        this.setMap(map);
+    }
+    
+    
+});/*
+ * - LGPL
+ *
+ * Alert
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Alert
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Alert class
+ * @cfg {String} title The title of alert
+ * @cfg {String} html The content of alert
+ * @cfg {String} weight (  success | info | warning | danger )
+ * @cfg {String} faicon font-awesomeicon
+ * 
+ * @constructor
+ * Create a new alert
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.Alert = function(config){
+    Roo.bootstrap.Alert.superclass.constructor.call(this, config);
+    
+};
+
+Roo.extend(Roo.bootstrap.Alert, Roo.bootstrap.Component,  {
+    
+    title: '',
+    html: '',
+    weight: false,
+    faicon: false,
+    
+    getAutoCreate : function()
+    {
+        
+        var cfg = {
+            tag : 'div',
+            cls : 'alert',
+            cn : [
+                {
+                    tag : 'i',
+                    cls : 'roo-alert-icon'
+                    
+                },
+                {
+                    tag : 'b',
+                    cls : 'roo-alert-title',
+                    html : this.title
+                },
+                {
+                    tag : 'span',
+                    cls : 'roo-alert-text',
+                    html : this.html
+                }
+            ]
+        };
+        
+        if(this.faicon){
+            cfg.cn[0].cls += ' fa ' + this.faicon;
+        }
+        
+        if(this.weight){
+            cfg.cls += ' alert-' + this.weight;
+        }
+        
+        return cfg;
+    },
+    
+    initEvents: function() 
+    {
+        this.el.setVisibilityMode(Roo.Element.DISPLAY);
+    },
+    
+    setTitle : function(str)
+    {
+        this.el.select('.roo-alert-title',true).first().dom.innerHTML = str;
+    },
+    
+    setText : function(str)
+    {
+        this.el.select('.roo-alert-text',true).first().dom.innerHTML = str;
+    },
+    
+    setWeight : function(weight)
+    {
+        if(this.weight){
+            this.el.select('.alert',true).first().removeClass('alert-' + this.weight);
+        }
+        
+        this.weight = weight;
+        
+        this.el.select('.alert',true).first().addClass('alert-' + this.weight);
+    },
+    
+    setIcon : function(icon)
+    {
+        if(this.faicon){
+            this.el.select('.roo-alert-icon',true).first().removeClass(['fa', 'fa-' + this.faicon]);
+        }
+        
+        this.faicon = icon
+        
+        this.el.select('.roo-alert-icon',true).first().addClass(['fa', 'fa-' + this.faicon]);
+    },
+    
+    hide: function() 
+    {
+        this.el.hide();   
+    },
+    
+    show: function() 
+    {  
+        this.el.show();   
+    }
+    
+});
+
\ No newline at end of file
index e69de29..c8b230d 100644 (file)
@@ -0,0 +1,492 @@
+//Roo/bootstrap/Component.js
+Roo.bootstrap=Roo.bootstrap||{};Roo.bootstrap.Component=function(A){Roo.bootstrap.Component.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Component,Roo.BoxComponent,{allowDomMove:false,cls:false,style:false,autoCreate:false,tooltip:null,initEvents:function(){},xattr:false,parentId:false,can_build_overlaid:true,container_method:false,dataId:false,name:false,parent:function(){return Roo.ComponentMgr.get(this.parentId)},onRender:function(ct,A){Roo.bootstrap.Component.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));this.el.dom.removeAttribute('xtype');this.initEvents();}return;}var B=Roo.apply({},this.getAutoCreate());B.id=Roo.id();if(this.xattr&&typeof(this.xattr)=='object'){for(var i in this.xattr){B[i]=this.xattr[i];}}if(this.dataId){B.dataId=this.dataId;}if(this.cls){B.cls=(typeof(B.cls)=='undefined')?this.cls:B.cls+' '+this.cls;}if(this.style){B.style=this.style;}if(this.name){B.name=this.name;}
+this.el=ct.createChild(B,A);if(this.tooltip){this.tooltipEl().attr('tooltip',this.tooltip);}if(this.tabIndex!==undefined){this.el.dom.setAttribute('tabIndex',this.tabIndex);}
+this.initEvents();},getChildContainer:function(){return this.el;},tooltipEl:function(){return this.el;},addxtype:function(A,B){var cn=this;cn=Roo.factory(A);cn.parentType=this.xtype;cn.parentId=this.id;B=(typeof(B)=='undefined')?'getChildContainer':B;if(typeof(cn.container_method)=='string'){B=cn.container_method;}var C=(typeof(A['flexy:foreach'])!='undefined');var D=(typeof(A['flexy:if'])!='undefined');var E=Roo.XComponent.build_from_html;var F=(A.xtype=='Body');var G=(Roo.get(document.body).attr('xtype')=='Roo.bootstrap.Body');var H=Roo.get(this[B](false));if((C||D||this.can_build_overlaid==false)&&E){return false;}if(!C||!E||F||!G){if(!D||typeof(A.name)=='undefined'||!E||F||!G){return this.addxtypeChild(A,B);}var I=H?H.child('>*[name='+A.name+']'):false;if(I){return this.addxtypeChild(Roo.apply({},A),B);}
+Roo.log('skipping render');return cn;}var J=false;while(true){var I=H?H.child('>*[xtype]'):false;if(!I){break;}if(I&&I.attr('xtype').split('.').pop()!=cn.xtype){break;}
+J=this.addxtypeChild(Roo.apply({},A),B);}return J;},addxtypeChild:function(A,B){Roo.debug&&Roo.log('addxtypeChild:'+B);var cn=this;B=(typeof(B)=='undefined')?'getChildContainer':B;var C=(typeof(A['flexy:if'])!='undefined')||(typeof(A['flexy:foreach'])!='undefined');skip_children=false;if(A.xtype!='Body'){cn=Roo.factory(A);cn.parentType=this.xtype;cn.parentId=this.id;var D=Roo.XComponent.build_from_html;if(Roo.get(document.body).attr('xtype')=='Roo.bootstrap.Body'){var E=Roo.get(this[B](false));var F=E?E.child('>*[xtype]'):false;if(F&&F.attr('xtype').split('.').pop()==cn.xtype){cn.el=F;}else {Roo.debug&&Roo.log("MISSING "+cn.xtype+" on child of "+(this.el?this.el.attr('xbuilderid'):'no parent'));Roo.debug&&Roo.log(E);Roo.debug&&Roo.log(F);Roo.debug&&Roo.log(cn);}}if(D&&C&&!cn.el&&cn.can_build_overlaid){Roo.debug&&Roo.log('skipping render');Roo.debug&&Roo.log(A);if(!cn.el){Roo.debug&&Roo.log('skipping all children');skip_children=true;}}else {cn.render(this[B](true));}}var G=[];if(!A.items||!A.items.length){cn.items=G;return cn;}var H=A.items;delete A.items;if(!skip_children){for(var i=0;i<H.length;i++){G.push(cn.addxtype(Roo.apply({},H[i])));}}
+cn.items=G;return cn;}});
+//Roo/bootstrap/Body.js
+Roo.bootstrap.Body=function(A){Roo.bootstrap.Body.superclass.constructor.call(this,A);this.el=Roo.get(document.body);if(this.cls&&this.cls.length){Roo.get(document.body).addClass(this.cls);}};Roo.extend(Roo.bootstrap.Body,Roo.bootstrap.Component,{autoCreate:{cls:'container'},onRender:function(ct,A){}});
+//Roo/bootstrap/ButtonGroup.js
+Roo.bootstrap.ButtonGroup=function(A){Roo.bootstrap.ButtonGroup.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.ButtonGroup,Roo.bootstrap.Component,{size:'',align:'',direction:'',toolbar:false,btn:true,getAutoCreate:function(){var A={cls:'btn-group',html:null}
+A.html=this.html||A.html;if(this.toolbar){A={cls:'btn-toolbar',html:null};return A;}if(['vertical','justified'].indexOf(this.align)!==-1){A.cls='btn-group-'+this.align;if(this.align=='justified'){console.log(this.items);}}if(['lg','sm','xs'].indexOf(this.size)!==-1){A.cls+=' btn-group-'+this.size;}if(this.direction=='up'){A.cls+=' dropup';}return A;}});
+//Roo/bootstrap/Button.js
+Roo.bootstrap.Button=function(A){Roo.bootstrap.Button.superclass.constructor.call(this,A);this.addEvents({"click":true,"toggle":true});};Roo.extend(Roo.bootstrap.Button,Roo.bootstrap.Component,{html:false,active:false,weight:'',size:'',tag:'button',href:'',disabled:false,isClose:false,glyphicon:'',badge:'',theme:'default',inverse:false,toggle:false,ontext:'ON',offtext:'OFF',defaulton:true,preventDefault:true,removeClass:false,name:false,target:false,pressed:null,getAutoCreate:function(){var A={tag:'button',cls:'roo-button',html:''};if(['a','button','input','submit'].indexOf(this.tag)<0){throw "Invalid value for tag: "+this.tag+". must be a, button, input or submit.";this.tag='button';}else {A.tag=this.tag;}
+A.html='<span class="roo-button-text">'+(this.html||A.html)+'</span>';if(this.toggle==true){A={tag:'div',cls:'slider-frame roo-button',cn:[{tag:'span','data-on-text':'ON','data-off-text':'OFF',cls:'slider-button',html:this.offtext}]};if(['default','primary','success','info','warning','danger','link'].indexOf(this.weight)>-1){A.cls+=' '+this.weight;}return A;}if(this.isClose){A.cls+=' close';A["aria-hidden"]=true;A.html="&times;";return A;}if(this.theme==='default'){A.cls='btn roo-button';this.weight=this.weight.length?this.weight:'default';if(['default','primary','success','info','warning','danger','link'].indexOf(this.weight)>-1){A.cls+=' btn-'+this.weight;}}else if(this.theme==='glow'){A.tag='a';A.cls='btn-glow roo-button';if(['default','primary','success','info','warning','danger','link'].indexOf(this.weight)>-1){A.cls+=' '+this.weight;}}if(this.inverse){this.cls+=' inverse';}if(this.active){A.cls+=' active';}if(this.disabled){A.disabled='disabled';}if(this.items){Roo.log('changing to ul');A.tag='ul';this.glyphicon='caret';}
+A.cls+=this.size.length?(' btn-'+this.size):'';if(this.parentType==='Navbar'&&!this.parent().bar){Roo.log('changing to li?');A.tag='li';A.cls='';A.cn=[{tag:'a',cls:'roo-button',html:this.html,href:this.href||'#'}];if(this.menu){A.cn[0].html=this.html+' <span class="caret"></span>';A.cls+=' dropdown';}delete A.html;}
+A.cls+=this.parentType==='Navbar'?' navbar-btn':'';if(this.glyphicon){A.html=' '+A.html;A.cn=[{tag:'span',cls:'glyphicon glyphicon-'+this.glyphicon}];}if(this.badge){A.html+=' ';A.tag='a';A.href=this.href;var B=A.html;if(this.glyphicon){B={tag:'span',cls:'glyphicon glyphicon-'+this.glyphicon,html:this.html};}
+A.cn=[B,{tag:'span',cls:'badge',html:this.badge}];A.html='';}if(this.menu){A.cls+=' dropdown';A.html=typeof(A.html)!='undefined'?A.html+' <span class="caret"></span>':'<span class="caret"></span>';}if(A.tag!=='a'&&this.href!==''){throw "Tag must be a to set href.";}else if(this.href.length>0){A.href=this.href;}if(this.removeClass){A.cls='';}if(this.target){A.target=this.target;}return A;},initEvents:function(){if(typeof(this.menu)!='undefined'){this.menu.parentType=this.xtype;this.menu.triggerEl=this.el;this.addxtype(Roo.apply({},this.menu));}if(this.el.hasClass('roo-button')){this.el.on('click',this.onClick,this);}else {this.el.select('.roo-button').on('click',this.onClick,this);}if(this.removeClass){this.el.on('click',this.onClick,this);}
+this.el.enableDisplayMode();},onClick:function(e){if(this.disabled){return;}
+Roo.log('button on click ');if(this.preventDefault){e.preventDefault();}if(this.pressed===true||this.pressed===false){this.pressed=!this.pressed;this.el[this.pressed?'addClass':'removeClass']('active');this.fireEvent('toggle',this,e,this.pressed);}
+this.fireEvent('click',this,e);},enable:function(){this.disabled=false;this.el.removeClass('disabled');},disable:function(){this.disabled=true;this.el.addClass('disabled');},setActive:function(v){this.el[v?'addClass':'removeClass']('active');},toggleActive:function(){var A=this.el.hasClass('active');this.setActive(!A);},setText:function(A){this.el.select('.roo-button-text',true).first().dom.innerHTML=A;},getText:function(){return this.el.select('.roo-button-text',true).first().dom.innerHTML;},hide:function(){this.el.hide();},show:function(){this.el.show();}});
+//Roo/bootstrap/Column.js
+Roo.bootstrap.Column=function(A){Roo.bootstrap.Column.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Column,Roo.bootstrap.Component,{xs:false,sm:false,md:false,lg:false,xsoff:false,smoff:false,mdoff:false,lgoff:false,html:'',offset:0,alert:false,fa:false,icon:false,hidden:false,fasize:1,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.Column.superclass.getAutoCreate.call(this));A={tag:'div',cls:'column'};var B=this;['xs','sm','md','lg'].map(function(D){if(B[D+'off']!==false){A.cls+=' col-'+D+'-offset-'+B[D+'off'];}if(B[D]===false){return;}
+Roo.log(B[D]);if(!B[D]){A.cls+=' hidden-'+D;return;}
+A.cls+=' col-'+D+'-'+B[D];});if(this.hidden){A.cls+=' hidden';}if(this.alert&&["success","info","warning","danger"].indexOf(this.alert)>-1){A.cls+=' alert alert-'+this.alert;}if(this.html.length){A.html=this.html;}if(this.fa){var C='';if(this.fasize>1){C=' fa-'+this.fasize+'x';}
+A.html='<i class="fa fa-'+this.fa+C+'"></i>'+(A.html||'');}if(this.icon){A.html='<i class="glyphicon glyphicon-'+this.icon+'"></i>'+(A.html||'');}return A;}});
+//Roo/bootstrap/Container.js
+Roo.bootstrap.Container=function(A){Roo.bootstrap.Container.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Container,Roo.bootstrap.Component,{jumbotron:false,well:'',panel:'',header:'',footer:'',sticky:'',tag:false,alert:false,fa:false,icon:false,getChildContainer:function(){if(!this.el){return false;}if(this.panel.length){return this.el.select('.panel-body',true).first();}return this.el;},getAutoCreate:function(){var A={tag:this.tag||'div',html:'',cls:''};if(this.jumbotron){A.cls='jumbotron';}if(this.sticky.length){var bd=Roo.get(document.body);if(!bd.hasClass('bootstrap-sticky')){bd.addClass('bootstrap-sticky');Roo.select('html',true).setStyle('height','100%');}
+A.cls+='bootstrap-sticky-'+this.sticky;}if(this.well.length){switch(this.well){case 'lg':case 'sm':A.cls+=' well well-'+this.well;break;default:A.cls+=' well';break;}}if(this.hidden){A.cls+=' hidden';}if(this.alert&&["success","info","warning","danger"].indexOf(this.alert)>-1){A.cls+=' alert alert-'+this.alert;}var B=A;if(this.panel.length){A.cls+=' panel panel-'+this.panel;A.cn=[];if(this.header.length){A.cn.push({cls:'panel-heading',cn:[{tag:'h3',cls:'panel-title',html:this.header}]});}
+B=false;A.cn.push({cls:'panel-body',html:this.html});if(this.footer.length){A.cn.push({cls:'panel-footer',html:this.footer});}}if(B){B.html=this.html||A.html;if(this.fa){B.html='<i class="fa fa-'+this.fa+'"></i>'+B.html;}if(this.icon){B.html='<i class="glyphicon glyphicon-'+this.icon+'"></i>'+B.html;}}if((!this.cls||!this.cls.length)&&(!A.cls||!A.cls.length)){A.cls='container';}return A;},titleEl:function(){if(!this.el||!this.panel.length||!this.header.length){return;}return this.el.select('.panel-title',true).first();},setTitle:function(v){var A=this.titleEl();if(!A){return;}
+A.dom.innerHTML=v;},getTitle:function(){var A=this.titleEl();if(!A){return '';}return A.dom.innerHTML;},show:function(){this.el.removeClass('hidden');},hide:function(){if(!this.el.hasClass('hidden')){this.el.addClass('hidden');}}});
+//Roo/bootstrap/Img.js
+Roo.bootstrap.Img=function(A){Roo.bootstrap.Img.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.Img,Roo.bootstrap.Component,{imgResponsive:true,border:'',src:'',href:false,target:false,getAutoCreate:function(){var A={tag:'img',cls:(this.imgResponsive)?'img-responsive':'',html:null}
+A.html=this.html||A.html;A.src=this.src||A.src;if(['rounded','circle','thumbnail'].indexOf(this.border)>-1){A.cls+=' img-'+this.border;}if(this.alt){A.alt=this.alt;}if(this.href){var a={tag:'a',href:this.href,cn:[A]};if(this.target){a.target=this.target;}}return (this.href)?a:A;},initEvents:function(){if(!this.href){this.el.on('click',this.onClick,this);}},onClick:function(e){Roo.log('img onclick');this.fireEvent('click',this,e);}});
+//Roo/bootstrap/Link.js
+Roo.bootstrap.Link=function(A){Roo.bootstrap.Link.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.Link,Roo.bootstrap.Component,{href:false,target:false,preventDefault:false,anchor:false,alt:false,getAutoCreate:function(){var A={tag:'a'};if(this.anchor===false){A.html=this.html||'html-missing';A.href=this.href||'#';}else {A.name=this.anchor;if(this.html!==false){A.html=this.html;}if(this.href!==false){A.href=this.href;}}if(this.alt!==false){A.alt=this.alt;}if(this.target!==false){A.target=this.target;}return A;},initEvents:function(){if(!this.href||this.preventDefault){this.el.on('click',this.onClick,this);}},onClick:function(e){if(this.preventDefault){e.preventDefault();}
+this.fireEvent('click',this,e);}});
+//Roo/bootstrap/Header.js
+Roo.bootstrap.Header=function(A){Roo.bootstrap.Header.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Header,Roo.bootstrap.Component,{html:false,level:1,getAutoCreate:function(){var A={tag:'h'+(1*this.level),html:this.html||'fill in html'};return A;}});
+//Roo/bootstrap/MenuMgr.js
+Roo.bootstrap.MenuMgr=function(){var A,B,C={},D=false,E=new Date();function init(){A={};B=new Roo.util.MixedCollection();Roo.get(document).addKeyListener(27,function(){if(B.length>0){hideAll();}});}function hideAll(){if(B&&B.length>0){var c=B.clone();c.each(function(m){m.hide();});}}function onHide(m){B.remove(m);if(B.length<1){Roo.get(document).un("mouseup",onMouseDown);D=false;}}function onShow(m){var F=B.last();E=new Date();B.add(m);if(!D){Roo.get(document).on("mouseup",onMouseDown);D=true;}if(m.parentMenu){m.parentMenu.activeChild=m;}else if(F&&F.isVisible()){}}function onBeforeHide(m){if(m.activeChild){m.activeChild.hide();}if(m.autoHideTimer){clearTimeout(m.autoHideTimer);delete m.autoHideTimer;}}function onBeforeShow(m){var pm=m.parentMenu;if(!pm&&!m.allowOtherMenus){hideAll();}else if(pm&&pm.activeChild&&B!=m){pm.activeChild.hide();}}function onMouseDown(e){Roo.log("on MouseDown");if(E.getElapsed()>50&&B.length>0&&!e.getTarget(".x-menu")&&!e.getTarget('.user-menu')){hideAll();}}function onBeforeCheck(mi,F){if(F){var g=C[mi.group];for(var i=0,l=g.length;i<l;i++){if(g[i]!=mi){g[i].setChecked(false);}}}}return {hideAll:function(){hideAll();},register:function(F){if(!A){init();}
+A[F.id]=F;F.on("beforehide",onBeforeHide);F.on("hide",onHide);F.on("beforeshow",onBeforeShow);F.on("show",onShow);var g=F.group;if(g&&F.events["checkchange"]){if(!C[g]){C[g]=[];}
+C[g].push(F);F.on("checkchange",onCheck);}},get:function(F){if(typeof F=="string"){return A[F];}else if(F.events){return F;}return false;},unregister:function(F){delete A[F.id];F.un("beforehide",onBeforeHide);F.un("hide",onHide);F.un("beforeshow",onBeforeShow);F.un("show",onShow);var g=F.group;if(g&&F.events["checkchange"]){C[g].remove(F);F.un("checkchange",onCheck);}},registerCheckable:function(F){var g=F.group;if(g){if(!C[g]){C[g]=[];}
+C[g].push(F);F.on("beforecheckchange",onBeforeCheck);}},unregisterCheckable:function(F){var g=F.group;if(g){C[g].remove(F);F.un("beforecheckchange",onBeforeCheck);}}};}();
+//Roo/bootstrap/Menu.js
+Roo.bootstrap.Menu=function(A){Roo.bootstrap.Menu.superclass.constructor.call(this,A);if(this.registerMenu){Roo.bootstrap.MenuMgr.register(this);}
+this.addEvents({beforeshow:true,beforehide:true,show:true,hide:true,click:true,mouseover:true,mouseout:true,itemclick:true});this.menuitems=new Roo.util.MixedCollection(false,function(o){return o.el.id;});};Roo.extend(Roo.bootstrap.Menu,Roo.bootstrap.Component,{triggerEl:false,type:false,registerMenu:true,menuItems:false,hidden:true,parentMenu:false,getChildContainer:function(){return this.el;},getAutoCreate:function(){var A={tag:'ul',cls:'dropdown-menu',style:'z-index:1000'};if(this.type==='submenu'){A.cls='submenu active';}if(this.type==='treeview'){A.cls='treeview-menu';}return A;},initEvents:function(){this.triggerEl.on('click',this.onTriggerPress,this);this.triggerEl.addClass('dropdown-toggle');this.el.on(Roo.isTouch?'touchstart':'click',this.onClick,this);this.el.on("mouseover",this.onMouseOver,this);this.el.on("mouseout",this.onMouseOut,this);},findTargetItem:function(e){var t=e.getTarget(".dropdown-menu-item",this.el,true);if(!t){return false;}if(t&&t.id){return this.menuitems.get(t.id);}return false;},onClick:function(e){Roo.log("menu.onClick");var t=this.findTargetItem(e);if(!t||t.isContainer){return;}
+Roo.log(e);Roo.log('pass click event');t.onClick(e);this.fireEvent("click",this,t,e);this.hide();},onMouseOver:function(e){var t=this.findTargetItem(e);this.fireEvent("mouseover",this,e,t);},isVisible:function(){return !this.hidden;},onMouseOut:function(e){var t=this.findTargetItem(e);this.fireEvent("mouseout",this,e,t);},show:function(el,A,B){this.parentMenu=B;if(!this.el){this.render();}
+this.fireEvent("beforeshow",this);this.showAt(this.el.getAlignToXY(el,A||this.defaultAlign),B,false);},showAt:function(xy,A,_e){this.parentMenu=A;if(!this.el){this.render();}if(_e!==false){this.fireEvent("beforeshow",this);}
+this.hideMenuItems();this.hidden=false;this.triggerEl.addClass('open');this.focus();this.fireEvent("show",this);},focus:function(){return;if(!this.hidden){this.doFocus.defer(50,this);}},doFocus:function(){if(!this.hidden){this.focusEl.focus();}},hide:function(A){this.hideMenuItems();if(this.el&&this.isVisible()){this.fireEvent("beforehide",this);if(this.activeItem){this.activeItem.deactivate();this.activeItem=null;}
+this.triggerEl.removeClass('open');;this.hidden=true;this.fireEvent("hide",this);}if(A===true&&this.parentMenu){this.parentMenu.hide(true);}},onTriggerPress:function(e){Roo.log('trigger press');if(Roo.get(e.getTarget()).findParent('.dropdown-menu')){return;}if(this.isVisible()){Roo.log('hide');this.hide();}else {this.show(this.triggerEl,false,false);}},hideMenuItems:function(){Roo.select('.open',true).each(function(aa){aa.removeClass('open');})},addxtypeChild:function(A,B){var C=Roo.bootstrap.Menu.superclass.addxtypeChild.call(this,A,B);this.menuitems.add(C);return C;},getEl:function(){Roo.log(this.el);return this.el;}});
+//Roo/bootstrap/MenuItem.js
+Roo.bootstrap.MenuItem=function(A){Roo.bootstrap.MenuItem.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.MenuItem,Roo.bootstrap.Component,{href:false,html:false,preventDefault:true,isContainer:false,getAutoCreate:function(){if(this.isContainer){return {tag:'li',cls:'dropdown-menu-item'};}var A={tag:'li',cls:'dropdown-menu-item',cn:[{tag:'a',href:'#',html:'Link'}]};if(this.parent().type=='treeview'){A.cls='treeview-menu';}
+A.cn[0].href=this.href||A.cn[0].href;A.cn[0].html=this.html||A.cn[0].html;return A;},initEvents:function(){},onClick:function(e){Roo.log('item on click ');this.fireEvent('click',this,e);},getEl:function(){return this.el;}});
+//Roo/bootstrap/MenuSeparator.js
+Roo.bootstrap.MenuSeparator=function(A){Roo.bootstrap.MenuSeparator.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.MenuSeparator,Roo.bootstrap.Component,{getAutoCreate:function(){var A={cls:'divider',tag:'li'};return A;}});
+//Roo/bootstrap/Modal.js
+Roo.bootstrap.Modal=function(A){Roo.bootstrap.Modal.superclass.constructor.call(this,A);this.addEvents({"btnclick":true});this.buttons=this.buttons||[];};Roo.extend(Roo.bootstrap.Modal,Roo.bootstrap.Component,{title:'test dialog',buttons:false,body:false,specificTitle:false,buttonPosition:'right',allow_close:true,animate:true,onRender:function(ct,A){Roo.bootstrap.Component.superclass.onRender.call(this,ct,A);if(!this.el){var B=Roo.apply({},this.getAutoCreate());B.id=Roo.id();if(this.cls){B.cls+=' '+this.cls;}if(this.style){B.style=this.style;}
+this.el=Roo.get(document.body).createChild(B,A);}if(this.tabIndex!==undefined){this.el.dom.setAttribute('tabIndex',this.tabIndex);}
+this.maskEl=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-dlg-mask"},true);this.maskEl.enableDisplayMode("block");this.maskEl.hide();if(this.buttons.length){Roo.each(this.buttons,function(bb){b=Roo.apply({},bb);b.xns=b.xns||Roo.bootstrap;b.xtype=b.xtype||'Button';if(typeof(b.listeners)=='undefined'){b.listeners={click:this.onButtonClick.createDelegate(this)};}var E=Roo.factory(b);E.onRender(this.el.select('.modal-footer div').first());},this);}var C=[];if(typeof(this.items)!='undefined'){var D=this.items;delete this.items;for(var i=0;i<D.length;i++){C.push(this.addxtype(Roo.apply({},D[i])));}}
+this.items=C;this.body=this.el.select('.modal-body',true).first();this.close=this.el.select('.modal-header .close',true).first();this.footer=this.el.select('.modal-footer',true).first();this.initEvents();},getAutoCreate:function(){var A={cls:'modal-body',html:this.html||''};var B={tag:'h4',cls:'modal-title',html:this.title};if(this.specificTitle){B=this.title;};var C=[];if(this.allow_close){C.push({tag:'button',cls:'close',html:'&times'});}
+C.push(B);var D={cls:"modal",style:'display: none',cn:[{cls:"modal-dialog",cn:[{cls:"modal-content",cn:[{cls:'modal-header',cn:C},A,{cls:'modal-footer',cn:[{tag:'div',cls:'btn-'+this.buttonPosition}]}]}]}]};if(this.animate){D.cls+=' fade';}return D;},getChildContainer:function(){return this.el.select('.modal-body',true).first();},getButtonContainer:function(){return this.el.select('.modal-footer div',true).first();},initEvents:function(){this.el.select('.modal-header .close').on('click',this.hide,this);},show:function(){if(!this.rendered){this.render();}
+this.el.setStyle('display','block');if(this.animate){var A=this;(function(){A.el.addClass('in');}).defer(50);}else {this.el.addClass('in');}
+Roo.get(document.body).addClass("x-body-masked");this.maskEl.setSize(Roo.lib.Dom.getViewWidth(true),Roo.lib.Dom.getViewHeight(true));this.maskEl.show();this.el.setStyle('zIndex','10001');this.fireEvent('show',this);},hide:function(){this.maskEl.hide();Roo.get(document.body).removeClass("x-body-masked");this.el.removeClass('in');if(this.animate){var A=this;(function(){A.el.setStyle('display','none');}).defer(150);}else {this.el.setStyle('display','none');}
+this.fireEvent('hide',this);},addButton:function(A,cb){var b=Roo.apply({},{html:A});b.xns=b.xns||Roo.bootstrap;b.xtype=b.xtype||'Button';if(typeof(b.listeners)=='undefined'){b.listeners={click:cb.createDelegate(this)};}var B=Roo.factory(b);B.onRender(this.el.select('.modal-footer div').first());return B;},setDefaultButton:function(A){},resizeTo:function(w,h){},setContentSize:function(w,h){},onButtonClick:function(A,e){this.fireEvent('btnclick',A.name,e);},setTitle:function(A){this.el.select('.modal-title',true).first().dom.innerHTML=A;}});Roo.apply(Roo.bootstrap.Modal,{OK:[{name:'ok',weight:'primary',html:'OK'}],YESNO:[{name:'no',html:'No'},{name:'yes',weight:'primary',html:'Yes'}],OKCANCEL:[{name:'cancel',html:'Cancel'},{name:'ok',weight:'primary',html:'OK'}],YESNOCANCEL:[{name:'yes',weight:'primary',html:'Yes'},{name:'no',html:'No'},{name:'cancel',html:'Cancel'}]});
+//Roo/bootstrap/MessageBox.js
+Roo.bootstrap.MessageBox=function(){var A,B,C,D;var E,F,G,H,I,pp;var J,K,L;var M=function(Q){A.hide();Roo.callback(B.fn,B.scope||window,[Q,K.dom.value],1);};var N=function(){if(B&&B.cls){A.el.removeClass(B.cls);}};var O=function(b){var Q=0;if(!b){J["ok"].hide();J["cancel"].hide();J["yes"].hide();J["no"].hide();return Q;}
+A.footer.dom.style.display='';for(var k in J){if(typeof J[k]!="function"){if(b[k]){J[k].show();J[k].setText(typeof b[k]=="string"?b[k]:Roo.bootstrap.MessageBox.buttonText[k]);Q+=J[k].el.getWidth()+15;}else {J[k].hide();}}}return Q;};var P=function(d,k,e){if(B&&B.closable!==false){A.hide();}if(e){e.stopEvent();}};return {getDialog:function(){if(!A){A=new Roo.bootstrap.Modal({closeClick:function(){if(B&&B.buttons&&B.buttons.no&&!B.buttons.cancel){M("no");}else {M("cancel");}}});A.render();A.on("hide",N);C=A.mask;J={};this.buttons=J;var bt=this.buttonText;J["ok"]=A.addButton(bt["ok"],M.createCallback("ok"));J["yes"]=A.addButton(bt["yes"],M.createCallback("yes"));J["no"]=A.addButton(bt["no"],M.createCallback("no"));J["cancel"]=A.addButton(bt["cancel"],M.createCallback("cancel"));Roo.log(J)
+E=A.body.createChild({html:'<span class="roo-mb-text"></span><br /><input type="text" class="roo-mb-input" />'+'<textarea class="roo-mb-textarea"></textarea>'+'<div class="roo-mb-progress-wrap"><div class="roo-mb-progress"><div class="roo-mb-progress-bar">&#160;</div></div></div>'});F=E.dom.firstChild;G=Roo.get(E.dom.childNodes[2]);G.enableDisplayMode();G.addKeyListener([10,13],function(){if(A.isVisible()&&B&&B.buttons){if(B.buttons.ok){M("ok");}else if(B.buttons.yes){M("yes");}}});H=Roo.get(E.dom.childNodes[3]);H.enableDisplayMode();I=Roo.get(E.dom.childNodes[4]);I.enableDisplayMode();var pf=I.dom.firstChild;if(pf){pp=Roo.get(pf.firstChild);pp.setHeight(pf.offsetHeight);}}return A;},updateText:function(Q){if(!A.isVisible()&&!B.width){A.resizeTo(this.maxWidth,100);}
+F.innerHTML=Q||'&#160;';var cw=Math.max(F.offsetWidth,F.parentNode.scrollWidth);var w=Math.max(Math.min(B.width||cw,this.maxWidth),Math.max(B.minWidth||this.minWidth,L));if(B.prompt){K.setWidth(w);}if(A.isVisible()){A.fixedcenter=false;}if(E.getHeight()>(Roo.lib.Dom.getViewHeight()-100)){E.setHeight(Roo.lib.Dom.getViewHeight()-100);E.dom.style.overflowY='auto'+(Roo.isIE?'':' !important');}else {E.dom.style.height='';E.dom.style.overflowY='';}if(cw>w){E.dom.style.get='auto'+(Roo.isIE?'':' !important');}else {E.dom.style.overflowX='';}
+A.setContentSize(w,E.getHeight());if(A.isVisible()){A.fixedcenter=true;}return this;},updateProgress:function(Q,R){if(R){this.updateText(R);}if(pp){pp.setWidth(Math.floor(Q*I.dom.firstChild.offsetWidth));}return this;},isVisible:function(){return A&&A.isVisible();},hide:function(){if(this.isVisible()){A.hide();}},show:function(Q){if(this.isVisible()){this.hide();Roo.log("[Roo.Messagebox] Show called while message displayed:");Roo.log("Old Dialog Message:"+F.innerHTML);Roo.log("New Dialog Message:"+Q.msg)}var d=this.getDialog();B=Q;d.setTitle(B.title||"&#160;");d.close.setDisplayed(B.closable!==false);K=G;B.prompt=B.prompt||(B.multiline?true:false);if(B.prompt){if(B.multiline){G.hide();H.show();H.setHeight(typeof B.multiline=="number"?B.multiline:this.defaultTextHeight);K=H;}else {G.show();H.hide();}}else {G.hide();H.hide();}
+I.setDisplayed(B.progress===true);this.updateProgress(0);K.dom.value=B.value||"";if(B.prompt){A.setDefaultButton(K);}else {var bs=B.buttons;var db=null;if(bs&&bs.ok){db=J["ok"];}else if(bs&&bs.yes){db=J["yes"];}
+A.setDefaultButton(db);}
+L=O(B.buttons);this.updateText(B.msg);if(B.cls){d.el.addClass(B.cls);}
+d.proxyDrag=B.proxyDrag===true;d.modal=B.modal!==false;d.mask=B.modal!==false?C:false;if(!d.isVisible()){document.body.appendChild(A.el.dom);d.animateTarget=null;d.show(Q.animEl);}return this;},progress:function(Q,R){this.show({title:Q,msg:R,buttons:false,progress:true,closable:false,minWidth:this.minProgressWidth,modal:true});return this;},alert:function(Q,R,fn,S){this.show({title:Q,msg:R,buttons:this.OK,fn:fn,scope:S,modal:true});return this;},wait:function(Q,R){this.show({title:R,msg:Q,buttons:false,closable:false,progress:true,modal:true,width:300,wait:true});D=Roo.TaskMgr.start({run:function(i){Roo.MessageBox.updateProgress(((((i+20)%20)+1)*5)*.01);},interval:1000});return this;},confirm:function(Q,R,fn,S){this.show({title:Q,msg:R,buttons:this.YESNO,fn:fn,scope:S,modal:true});return this;},prompt:function(Q,R,fn,S,T){this.show({title:Q,msg:R,buttons:this.OKCANCEL,fn:fn,minWidth:250,scope:S,prompt:true,multiline:T,modal:true});return this;},OK:{ok:true},YESNO:{yes:true,no:true},OKCANCEL:{ok:true,cancel:true},YESNOCANCEL:{yes:true,no:true,cancel:true},defaultTextHeight:75,maxWidth:600,minWidth:100,minProgressWidth:250,buttonText:{ok:"OK",cancel:"Cancel",yes:"Yes",no:"No"}};}();Roo.MessageBox=Roo.MessageBox||Roo.bootstrap.MessageBox;Roo.Msg=Roo.Msg||Roo.MessageBox;
+//Roo/bootstrap/Navbar.js
+Roo.bootstrap.Navbar=function(A){Roo.bootstrap.Navbar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Navbar,Roo.bootstrap.Component,{navItems:false,loadMask:false,getAutoCreate:function(){throw {message:"nav bar is now a abstract base class - use NavSimplebar / NavHeaderbar / NavSidebar etc..."};},initEvents:function(){this.el.select('.navbar-toggle',true).on('click',function(){this.el.select('.navbar-collapse',true).toggleClass('in');},this);var A={tag:"div",cls:"x-dlg-mask"}
+this.maskEl=Roo.DomHelper.append(this.el,A,true);var B=this.el.getSize();this.maskEl.setSize(B.width,B.height);this.maskEl.enableDisplayMode("block");this.maskEl.hide();if(this.loadMask){this.maskEl.show();}},getChildContainer:function(){if(this.el.select('.collapse').getCount()){return this.el.select('.collapse',true).first();}return this.el;},mask:function(){this.maskEl.show();},unmask:function(){this.maskEl.hide();}});
+//Roo/bootstrap/NavSimplebar.js
+Roo.bootstrap.NavSimplebar=function(A){Roo.bootstrap.NavSimplebar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.NavSimplebar,Roo.bootstrap.Navbar,{inverse:false,type:false,arrangement:'',align:false,main:false,tag:false,getAutoCreate:function(){var A={tag:this.tag||'div',cls:'navbar'};A.cn=[{cls:'nav',tag:'ul'}];this.type=this.type||'nav';if(['tabs','pills'].indexOf(this.type)!==-1){A.cn[0].cls+=' nav-'+this.type}else {if(this.type!=='nav'){Roo.log('nav type must be nav/tabs/pills')}
+A.cn[0].cls+=' navbar-nav'}if(['stacked','justified'].indexOf(this.arrangement)!==-1){A.cn[0].cls+=' nav-'+this.arrangement;}if(this.align==='right'){A.cn[0].cls+=' navbar-right';}if(this.inverse){A.cls+=' navbar-inverse';}return A;}});
+//Roo/bootstrap/NavHeaderbar.js
+Roo.bootstrap.NavHeaderbar=function(A){Roo.bootstrap.NavHeaderbar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.NavHeaderbar,Roo.bootstrap.NavSimplebar,{position:'',brand:'',brand_href:false,srButton:true,autohide:false,desktopCenter:false,getAutoCreate:function(){var A={tag:this.nav||'nav',cls:'navbar',role:'navigation',cn:[]};var cn=A.cn;if(this.desktopCenter){cn.push({cls:'container',cn:[]});cn=cn[0].cn;}if(this.srButton){cn.push({tag:'div',cls:'navbar-header',cn:[{tag:'button',type:'button',cls:'navbar-toggle','data-toggle':'collapse',cn:[{tag:'span',cls:'sr-only',html:'Toggle navigation'},{tag:'span',cls:'icon-bar'},{tag:'span',cls:'icon-bar'},{tag:'span',cls:'icon-bar'}]}]});}
+cn.push({tag:'div',cls:'collapse navbar-collapse',cn:[]});A.cls+=this.inverse?' navbar-inverse':' navbar-default';if(['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1){A.cls+=' navbar-'+this.position;A.tag=this.tag||(this.position=='fixed-bottom'?'footer':'header');}if(this.brand!==''){cn[0].cn.push({tag:'a',href:this.brand_href?this.brand_href:'#',cls:'navbar-brand',cn:[this.brand]});}if(this.main){A.cls+=' main-nav';}return A;},getHeaderChildContainer:function(){if(this.el.select('.navbar-header').getCount()){return this.el.select('.navbar-header',true).first();}return this.getChildContainer();},initEvents:function(){Roo.bootstrap.NavHeaderbar.superclass.initEvents.call(this);if(this.autohide){var A=0;var ft=this.el;Roo.get(document).on('scroll',function(e){var ns=Roo.get(document).getScroll().top;var os=A;A=ns;if(ns>os){ft.removeClass('slideDown');ft.addClass('slideUp');return;}
+ft.removeClass('slideUp');ft.addClass('slideDown');},this);}}});
+//Roo/bootstrap/NavSidebar.js
+Roo.bootstrap.NavSidebar=function(A){Roo.bootstrap.NavSidebar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.NavSidebar,Roo.bootstrap.Navbar,{sidebar:true,getAutoCreate:function(){return {tag:'div',cls:'sidebar sidebar-nav'};}});
+//Roo/bootstrap/NavGroup.js
+Roo.bootstrap.NavGroup=function(A){Roo.bootstrap.NavGroup.superclass.constructor.call(this,A);this.navItems=[];Roo.bootstrap.NavGroup.register(this);this.addEvents({'changed':true});};Roo.extend(Roo.bootstrap.NavGroup,Roo.bootstrap.Component,{align:'',inverse:false,form:false,type:'nav',navId:'',navItems:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));A={tag:'ul',cls:'nav'};if(['tabs','pills'].indexOf(this.type)!==-1){A.cls+=' nav-'+this.type}else {if(this.type!=='nav'){Roo.log('nav type must be nav/tabs/pills')}
+A.cls+=' navbar-nav'}if(this.parent().sidebar){A={tag:'ul',cls:'dashboard-menu sidebar-menu'};return A;}if(this.form===true){A={tag:'form',cls:'navbar-form'};if(this.align==='right'){A.cls+=' navbar-right';}else {A.cls+=' navbar-left';}}if(this.align==='right'){A.cls+=' navbar-right';}if(this.inverse){A.cls+=' navbar-inverse';}return A;},setActiveItem:function(A){var B=false;Roo.each(this.navItems,function(v){if(v==A){return;}if(v.isActive()){v.setActive(false,true);B=v;}});A.setActive(true,true);this.fireEvent('changed',this,A,B);},getActive:function(){var A=false;Roo.each(this.navItems,function(v){if(v.isActive()){A=v;}});return A;},indexOfNav:function(){var A=false;Roo.each(this.navItems,function(v,i){if(v.isActive()){A=i;}});return A;},addItem:function(A){var cn=new Roo.bootstrap.NavItem(A);this.register(cn);cn.parentId=this.id;cn.onRender(this.el,null);return cn;},register:function(A){this.navItems.push(A);A.navId=this.navId;},clearAll:function(){this.navItems=[];this.el.dom.innerHTML='';},getNavItem:function(A){var B=false;Roo.each(this.navItems,function(e){if(e.tabId==A){B=e;return false;}return true;});return B;},setActiveNext:function(){var i=this.indexOfNav(this.getActive());if(i>this.navItems.length){return;}
+this.setActiveItem(this.navItems[i+1]);},setActivePrev:function(){var i=this.indexOfNav(this.getActive());if(i<1){return;}
+this.setActiveItem(this.navItems[i-1]);},clearWasActive:function(A){Roo.each(this.navItems,function(e){if(e.tabId!=A.tabId&&e.was_active){e.was_active=false;return false;}return true;});},getWasActive:function(){var r=false;Roo.each(this.navItems,function(e){if(e.was_active){r=e;return false;}return true;});return r;}});Roo.apply(Roo.bootstrap.NavGroup,{groups:{},register:function(A){this.groups[A.navId]=A;},get:function(A){if(typeof(this.groups[A])=='undefined'){return false;}return this.groups[A];}});
+//Roo/bootstrap/NavItem.js
+Roo.bootstrap.NavItem=function(A){Roo.bootstrap.NavItem.superclass.constructor.call(this,A);this.addEvents({"click":true,'changed':true});};Roo.extend(Roo.bootstrap.NavItem,Roo.bootstrap.Component,{href:false,html:'',badge:'',icon:false,glyphicon:false,active:false,preventDefault:false,tabId:false,tagtype:'a',disabled:false,was_active:false,getAutoCreate:function(){var A={tag:'li',cls:'nav-item'};if(this.active){A.cls=typeof(A.cls)=='undefined'?'active':A.cls+' active';}if(this.disabled){A.cls+=' disabled';}if(this.href||this.html||this.glyphicon||this.icon){A.cn=[{tag:this.tagtype,href:this.href||"#",html:this.html||''}];if(this.icon){A.cn[0].html='<i class="'+this.icon+'"></i> <span>'+A.cn[0].html+'</span>'}if(this.glyphicon){A.cn[0].html='<span class="glyphicon glyphicon-'+this.glyphicon+'"></span> '+A.cn[0].html;}if(this.menu){A.cn[0].html+=" <span class='caret'></span>";}if(this.badge!==''){A.cn[0].html+=' <span class="badge">'+this.badge+'</span>';}}return A;},initEvents:function(){if(typeof(this.menu)!='undefined'){this.menu.parentType=this.xtype;this.menu.triggerEl=this.el;this.menu=this.addxtype(Roo.apply({},this.menu));}
+this.el.select('a',true).on('click',this.onClick,this);if(this.tagtype=='span'){this.el.select('span',true).on('click',this.onClick,this);}
+this.parent().register(this);},onClick:function(e){if(this.preventDefault||this.href=='#'){e.preventDefault();}if(this.disabled){return;}var tg=Roo.bootstrap.TabGroup.get(this.navId);if(tg&&tg.transition){Roo.log("waiting for the transitionend");return;}
+Roo.log("fire event clicked");if(this.fireEvent('click',this,e)===false){return;};if(this.tagtype=='span'){return;}var p=this.parent();if(['tabs','pills'].indexOf(p.type)!==-1){if(typeof(p.setActiveItem)!=='undefined'){p.setActiveItem(this);}}if(p.parentType=='NavHeaderbar'&&!this.menu){p.parent().el.select('.navbar-collapse',true).removeClass('in');}},isActive:function(){return this.active},setActive:function(A,B,C){if(this.active&&!A&this.navId){this.was_active=true;var nv=Roo.bootstrap.NavGroup.get(this.navId);if(nv){nv.clearWasActive(this);}}
+this.active=A;if(!A){this.el.removeClass('active');}else if(!this.el.hasClass('active')){this.el.addClass('active');}if(B){this.fireEvent('changed',this,A);}if(!this.navId||!this.tabId||!A||C){return;}var tg=Roo.bootstrap.TabGroup.get(this.navId);if(!tg){return;}var D=tg.getPanelByName(this.tabId);if(!D){return;}if(false==tg.showPanel(D)){var nv=Roo.bootstrap.NavGroup.get(this.navId);if(nv){var E=nv.getWasActive();if(E){E.setActive(true,false,true);}}}},setDisabled:function(A){this.disabled=A;if(!A){this.el.removeClass('disabled');}else if(!this.el.hasClass('disabled')){this.el.addClass('disabled');}},tooltipEl:function(){return this.el.select(''+this.tagtype+'',true).first();}});
+//Roo/bootstrap/NavSidebarItem.js
+Roo.bootstrap.NavSidebarItem=function(A){Roo.bootstrap.NavSidebarItem.superclass.constructor.call(this,A);this.addEvents({"click":true,'changed':true});};Roo.extend(Roo.bootstrap.NavSidebarItem,Roo.bootstrap.NavItem,{getAutoCreate:function(){var a={tag:'a',href:this.href||'#',cls:'',html:'',cn:[]};var A={tag:'li',cls:'',cn:[a]};var span={tag:'span',html:this.html||''};if(this.active){A.cls+=' active';}if(this.glyphicon||this.icon){var c=this.glyphicon?('glyphicon glyphicon-'+this.glyphicon):this.icon;a.cn.push({tag:'i',cls:c});}
+a.cn.push(span);if(this.badge!==''){a.cn.push({tag:'span',cls:'badge pull-right '+(this.badgecls||''),html:this.badge});}if(this.menu){a.cn.push({tag:'i',cls:'glyphicon glyphicon-chevron-down pull-right'});a.cls+='dropdown-toggle treeview';}return A;}});
+//Roo/bootstrap/Row.js
+Roo.bootstrap.Row=function(A){Roo.bootstrap.Row.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Row,Roo.bootstrap.Component,{getAutoCreate:function(){return {cls:'row clearfix'};}});
+//Roo/bootstrap/Element.js
+Roo.bootstrap.Element=function(A){Roo.bootstrap.Element.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Element,Roo.bootstrap.Component,{tag:'div',cls:'',html:'',getAutoCreate:function(){var A={tag:this.tag,cls:this.cls,html:this.html};return A;}});
+//Roo/bootstrap/Pagination.js
+Roo.bootstrap.Pagination=function(A){Roo.bootstrap.Pagination.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Pagination,Roo.bootstrap.Component,{cls:false,size:false,inverse:false,getAutoCreate:function(){var A={tag:'ul',cls:'pagination'};if(this.inverse){A.cls+=' inverse';}if(this.html){A.html=this.html;}if(this.cls){A.cls+=" "+this.cls;}return A;}});
+//Roo/bootstrap/PaginationItem.js
+Roo.bootstrap.PaginationItem=function(A){Roo.bootstrap.PaginationItem.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.PaginationItem,Roo.bootstrap.Component,{href:false,html:false,preventDefault:true,active:false,cls:false,disabled:false,getAutoCreate:function(){var A={tag:'li',cn:[{tag:'a',href:this.href?this.href:'#',html:this.html?this.html:''}]};if(this.cls){A.cls=this.cls;}if(this.disabled){A.cls=typeof(A.cls)!=='undefined'?A.cls+' disabled':'disabled';}if(this.active){A.cls=typeof(A.cls)!=='undefined'?A.cls+' active':'active';}return A;},initEvents:function(){this.el.on('click',this.onClick,this);},onClick:function(e){Roo.log('PaginationItem on click ');if(this.preventDefault){e.preventDefault();}if(this.disabled){return;}
+this.fireEvent('click',this,e);}});
+//Roo/bootstrap/Slider.js
+Roo.bootstrap.Slider=function(A){Roo.bootstrap.Slider.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Slider,Roo.bootstrap.Component,{getAutoCreate:function(){var A={tag:'div',cls:'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',cn:[{tag:'a',cls:'ui-slider-handle ui-state-default ui-corner-all'}]};return A;}});
+//Roo/grid/ColumnModel.js
+Roo.grid.ColumnModel=function(A){this.config=A;this.lookup={};for(var i=0,B=A.length;i<B;i++){var c=A[i];if(typeof c.dataIndex=="undefined"){c.dataIndex=i;}if(typeof c.renderer=="string"){c.renderer=Roo.util.Format[c.renderer];}if(typeof c.id=="undefined"){c.id=Roo.id();}if(c.editor&&c.editor.xtype){c.editor=Roo.factory(c.editor,Roo.grid);}if(c.editor&&c.editor.isFormField){c.editor=new Roo.grid.GridEditor(c.editor);}
+this.lookup[c.id]=c;}
+this.defaultWidth=100;this.defaultSortable=false;this.addEvents({"widthchange":true,"headerchange":true,"hiddenchange":true,"columnmoved":true,"columnlockchange":true});Roo.grid.ColumnModel.superclass.constructor.call(this);};Roo.extend(Roo.grid.ColumnModel,Roo.util.Observable,{getColumnId:function(A){return this.config[A].id;},getColumnById:function(id){return this.lookup[id];},getColumnByDataIndex:function(A){var B=this.findColumnIndex(A);return B>-1?this.config[B]:false;},getIndexById:function(id){for(var i=0,A=this.config.length;i<A;i++){if(this.config[i].id==id){return i;}}return -1;},findColumnIndex:function(A){for(var i=0,B=this.config.length;i<B;i++){if(this.config[i].dataIndex==A){return i;}}return -1;},moveColumn:function(A,B){var c=this.config[A];this.config.splice(A,1);this.config.splice(B,0,c);this.dataMap=null;this.fireEvent("columnmoved",this,A,B);},isLocked:function(A){return this.config[A].locked===true;},setLocked:function(A,B,C){if(this.isLocked(A)==B){return;}
+this.config[A].locked=B;if(!C){this.fireEvent("columnlockchange",this,A,B);}},getTotalLockedWidth:function(){var A=0;for(var i=0;i<this.config.length;i++){if(this.isLocked(i)&&!this.isHidden(i)){this.totalWidth+=this.getColumnWidth(i);}}return A;},getLockedCount:function(){for(var i=0,A=this.config.length;i<A;i++){if(!this.isLocked(i)){return i;}}},getColumnCount:function(A){if(A===true){var c=0;for(var i=0,B=this.config.length;i<B;i++){if(!this.isHidden(i)){c++;}}return c;}return this.config.length;},getColumnsBy:function(fn,A){var r=[];for(var i=0,B=this.config.length;i<B;i++){var c=this.config[i];if(fn.call(A||this,c,i)===true){r[r.length]=c;}}return r;},isSortable:function(A){if(typeof this.config[A].sortable=="undefined"){return this.defaultSortable;}return this.config[A].sortable;},getRenderer:function(A){if(!this.config[A].renderer){return Roo.grid.ColumnModel.defaultRenderer;}return this.config[A].renderer;},setRenderer:function(A,fn){this.config[A].renderer=fn;},getColumnWidth:function(A){return this.config[A].width*1||this.defaultWidth;},setColumnWidth:function(A,B,C){this.config[A].width=B;this.totalWidth=null;if(!C){this.fireEvent("widthchange",this,A,B);}},getTotalWidth:function(A){if(!this.totalWidth){this.totalWidth=0;for(var i=0,B=this.config.length;i<B;i++){if(A||!this.isHidden(i)){this.totalWidth+=this.getColumnWidth(i);}}}return this.totalWidth;},getColumnHeader:function(A){return this.config[A].header;},setColumnHeader:function(A,B){this.config[A].header=B;this.fireEvent("headerchange",this,A,B);},getColumnTooltip:function(A){return this.config[A].tooltip;},setColumnTooltip:function(A,B){this.config[A].tooltip=B;},getDataIndex:function(A){return this.config[A].dataIndex;},setDataIndex:function(A,B){this.config[A].dataIndex=B;},isCellEditable:function(A,B){return (this.config[A].editable||(typeof this.config[A].editable=="undefined"&&this.config[A].editor))?true:false;},getCellEditor:function(A,B){return this.config[A].editor;},setEditable:function(A,B){this.config[A].editable=B;},isHidden:function(A){return this.config[A].hidden;},isFixed:function(A){return this.config[A].fixed;},isResizable:function(A){return A>=0&&this.config[A].resizable!==false&&this.config[A].fixed!==true;},setHidden:function(A,B){this.config[A].hidden=B;this.totalWidth=null;this.fireEvent("hiddenchange",this,A,B);},setEditor:function(A,B){this.config[A].editor=B;}});Roo.grid.ColumnModel.defaultRenderer=function(A){if(typeof A=="string"&&A.length<1){return "&#160;";}return A;};Roo.grid.DefaultColumnModel=Roo.grid.ColumnModel;
+//Roo/LoadMask.js
+Roo.LoadMask=function(el,A){this.el=Roo.get(el);Roo.apply(this,A);if(this.store){this.store.on('beforeload',this.onBeforeLoad,this);this.store.on('load',this.onLoad,this);this.store.on('loadexception',this.onLoadException,this);this.removeMask=false;}else {var um=this.el.getUpdateManager();um.showLoadIndicator=false;um.on('beforeupdate',this.onBeforeLoad,this);um.on('update',this.onLoad,this);um.on('failure',this.onLoad,this);this.removeMask=true;}};Roo.LoadMask.prototype={msg:'Loading...',msgCls:'x-mask-loading',disabled:false,disable:function(){this.disabled=true;},enable:function(){this.disabled=false;},onLoadException:function(){Roo.log(arguments);if(typeof(arguments[3])!='undefined'){Roo.MessageBox.alert("Error loading",arguments[3]);}this.el.unmask(this.removeMask);},onLoad:function(){this.el.unmask(this.removeMask);},onBeforeLoad:function(){if(!this.disabled){this.el.mask(this.msg,this.msgCls);}},destroy:function(){if(this.store){this.store.un('beforeload',this.onBeforeLoad,this);this.store.un('load',this.onLoad,this);this.store.un('loadexception',this.onLoadException,this);}else {var um=this.el.getUpdateManager();um.un('beforeupdate',this.onBeforeLoad,this);um.un('update',this.onLoad,this);um.un('failure',this.onLoad,this);}}};
+//Roo/bootstrap/Table.js
+Roo.bootstrap.Table=function(A){Roo.bootstrap.Table.superclass.constructor.call(this,A);if(this.sm){this.selModel=Roo.factory(this.sm,Roo.bootstrap.Table);this.sm=this.selModel;this.sm.xmodule=this.xmodule||false;}if(this.cm&&typeof(this.cm.config)=='undefined'){this.colModel=new Roo.grid.ColumnModel(this.cm);this.cm=this.colModel;this.cm.xmodule=this.xmodule||false;}if(this.store){this.store=Roo.factory(this.store,Roo.data);this.ds=this.store;this.ds.xmodule=this.xmodule||false;}if(this.footer&&this.store){this.footer.dataSource=this.ds;this.footer=Roo.factory(this.footer);}
+this.addEvents({"cellclick":true,"celldblclick":true,"rowclick":true,"rowdblclick":true,"mouseover":true,"mouseout":true,'rowclass':true,'rowsrendered':true});};Roo.extend(Roo.bootstrap.Table,Roo.bootstrap.Component,{cls:false,align:false,bgcolor:false,border:false,cellpadding:false,cellspacing:false,frame:false,rules:false,sortable:false,summary:false,width:false,striped:false,bordered:false,hover:false,condensed:false,responsive:false,sm:false,cm:false,store:false,loadMask:false,tfoot:true,thead:true,RowSelection:false,CellSelection:false,layout:false,mainBody:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.Table.superclass.getAutoCreate.call(this));A={tag:'table',cls:'table',cn:[]};if(this.striped){A.cls+=' table-striped';}if(this.hover){A.cls+=' table-hover';}if(this.bordered){A.cls+=' table-bordered';}if(this.condensed){A.cls+=' table-condensed';}if(this.responsive){A.cls+=' table-responsive';}if(this.cls){A.cls+=' '+this.cls;}if(this.align){A.align=this.align;}if(this.bgcolor){A.bgcolor=this.bgcolor;}if(this.border){A.border=this.border;}if(this.cellpadding){A.cellpadding=this.cellpadding;}if(this.cellspacing){A.cellspacing=this.cellspacing;}if(this.frame){A.frame=this.frame;}if(this.rules){A.rules=this.rules;}if(this.sortable){A.sortable=this.sortable;}if(this.summary){A.summary=this.summary;}if(this.width){A.width=this.width;}if(this.layout){A.style=(typeof(A.style)=='undefined')?('table-layout:'+this.layout+';'):(A.style+('table-layout:'+this.layout+';'));}if(this.store||this.cm){if(this.thead){A.cn.push(this.renderHeader());}
+A.cn.push(this.renderBody());if(this.tfoot){A.cn.push(this.renderFooter());}
+A.cls+=' TableGrid';}return {cn:[A]};},initEvents:function(){if(!this.store||!this.cm){return;}
+this.mainBody=this.el.select('tbody',true).first();var A=this;Roo.each(this.el.select('thead th.sortable',true).elements,function(e){e.on('click',A.sort,A);});this.el.on("click",this.onClick,this);this.el.on("dblclick",this.onDblClick,this);if(this.footer){this.footer.parentId=this.id;this.footer.onRender(this.el.select('tfoot tr td').first(),null);}
+this.maskEl=new Roo.LoadMask(this.el,{store:this.ds,msgCls:'roo-el-mask-msg'});this.store.on('load',this.onLoad,this);this.store.on('beforeload',this.onBeforeLoad,this);this.store.on('update',this.onUpdate,this);this.store.on('add',this.onAdd,this);},onMouseover:function(e,el){var A=Roo.get(el);if(!A){return;}if(e.getTarget().nodeName.toLowerCase()!='td'){A=A.findParent('td',false,true);}var B=A.findParent('tr',false,true);var C=A.dom.cellIndex;var D=B.dom.rowIndex-1;this.fireEvent('mouseover',this,A,D,C,e);},onMouseout:function(e,el){var A=Roo.get(el);if(!A){return;}if(e.getTarget().nodeName.toLowerCase()!='td'){A=A.findParent('td',false,true);}var B=A.findParent('tr',false,true);var C=A.dom.cellIndex;var D=B.dom.rowIndex-1;this.fireEvent('mouseout',this,A,D,C,e);},onClick:function(e,el){var A=Roo.get(el);if(!A||(!this.CellSelection&&!this.RowSelection)){return;}if(e.getTarget().nodeName.toLowerCase()!='td'){A=A.findParent('td',false,true);}if(!A||typeof(A)=='undefined'){return;}var B=A.findParent('tr',false,true);if(!B||typeof(B)=='undefined'){return;}var C=A.dom.cellIndex;var D=this.getRowIndex(B);if(this.CellSelection){this.fireEvent('cellclick',this,A,D,C,e);}if(this.RowSelection){this.fireEvent('rowclick',this,B,D,e);}},onDblClick:function(e,el){var A=Roo.get(el);if(!A||(!this.CellSelection&&!this.RowSelection)){return;}if(e.getTarget().nodeName.toLowerCase()!='td'){A=A.findParent('td',false,true);}if(!A||typeof(A)=='undefined'){return;}var B=A.findParent('tr',false,true);if(!B||typeof(B)=='undefined'){return;}var C=A.dom.cellIndex;var D=this.getRowIndex(B);if(this.CellSelection){this.fireEvent('celldblclick',this,A,D,C,e);}if(this.RowSelection){this.fireEvent('rowdblclick',this,B,D,e);}},sort:function(e,el){var A=Roo.get(el);if(!A.hasClass('sortable')){return;}var B=A.attr('sort');var C='ASC';if(A.hasClass('glyphicon-arrow-up')){C='DESC';}
+this.store.sortInfo={field:B,direction:C};if(this.footer){Roo.log("calling footer first");this.footer.onClick('first');}else {this.store.load({params:{start:0}});}},renderHeader:function(){var A={tag:'thead',cn:[]};var cm=this.cm;for(var i=0,B=cm.getColumnCount();i<B;i++){var C=cm.config[i];var c={tag:'th',style:'',html:cm.getColumnHeader(i)};if(typeof(C.tooltip)!='undefined'){c.tooltip=C.tooltip;}if(typeof(C.hidden)!='undefined'&&C.hidden){c.style+=' display:none;';}if(typeof(C.dataIndex)!='undefined'){c.sort=C.dataIndex;}if(typeof(C.sortable)!='undefined'&&C.sortable){c.cls='sortable';}if(typeof(C.align)!='undefined'&&C.align.length){c.style+=' text-align:'+C.align+';';}if(typeof(C.width)!='undefined'){c.style+=' width:'+C.width+'px;';}
+A.cn.push(c)}return A;},renderBody:function(){var A={tag:'tbody',cn:[{tag:'tr',cn:[{tag:'td',colspan:this.cm.getColumnCount()}]}]};return A;},renderFooter:function(){var A={tag:'tfoot',cn:[{tag:'tr',cn:[{tag:'td',colspan:this.cm.getColumnCount()}]}]};return A;},onLoad:function(){Roo.log('ds onload');this.clear();var A=this;var cm=this.cm;var ds=this.store;Roo.each(this.el.select('thead th.sortable',true).elements,function(e){e.removeClass(['glyphicon','glyphicon-arrow-up','glyphicon-arrow-down']);if(e.hasClass('sortable')&&e.attr('sort')==A.store.sortInfo.field&&A.store.sortInfo.direction.toUpperCase()=='ASC'){e.addClass(['glyphicon','glyphicon-arrow-up']);}if(e.hasClass('sortable')&&e.attr('sort')==A.store.sortInfo.field&&A.store.sortInfo.direction.toUpperCase()=='DESC'){e.addClass(['glyphicon','glyphicon-arrow-down']);}});var B=this.mainBody;if(ds.getCount()>0){ds.data.each(function(d,C){var D=this.renderRow(cm,ds,C);B.createChild(D);var E=this;if(D.cellObjects.length){Roo.each(D.cellObjects,function(r){E.renderCellObject(r);})}},this);}
+Roo.each(this.el.select('tbody td',true).elements,function(e){e.on('mouseover',A.onMouseover,A);});Roo.each(this.el.select('tbody td',true).elements,function(e){e.on('mouseout',A.onMouseout,A);});this.fireEvent('rowsrendered',this);},onUpdate:function(ds,A){this.refreshRow(A);},onRemove:function(ds,A,B,C){if(C!==true){this.fireEvent("beforerowremoved",this,B,A);}var bt=this.mainBody.dom;var D=this.el.select('tbody > tr',true).elements;if(typeof(D[B])!='undefined'){bt.removeChild(D[B].dom);}if(C!==true){this.fireEvent("rowremoved",this,B,A);}},onAdd:function(ds,A,B){var bt=this.mainBody.dom;for(var i=0;i<A.length;i++){this.insertRow(this.store,B+i,false);return;}},refreshRow:function(A){var ds=this.store,B;if(typeof A=='number'){B=A;A=ds.getAt(B);}else {B=ds.indexOf(A);}
+this.insertRow(ds,B,true);this.onRemove(ds,A,B+1,true);this.fireEvent("rowupdated",this,B,A);},insertRow:function(dm,A,B){if(!B){this.fireEvent("beforerowsinserted",this,A);}var C=this.renderRow(this.cm,this.store,A);var e=this.mainBody.createChild(C,this.getRowDom(A));var D=this;if(C.cellObjects.length){Roo.each(C.cellObjects,function(r){D.renderCellObject(r);})}if(!B){this.fireEvent("rowsinserted",this,A);}},getRowDom:function(A){var B=this.el.select('tbody > tr',true).elements;return (typeof(B[A])=='undefined')?false:B[A];},renderRow:function(cm,ds,A){var d=ds.getAt(A);var B={tag:'tr',cn:[]};var C=[];for(var i=0,D=cm.getColumnCount();i<D;i++){var E=cm.config[i];var F=cm.getRenderer(i);var G='';var id=false;if(typeof(F)!=='undefined'){G=F(d.data[cm.getDataIndex(i)],false,d);}if(typeof(G)==='object'){id=Roo.id();C.push({container:id,cfg:G})}var H={record:d,rowIndex:A,colIndex:i,rowClass:''}
+this.fireEvent('rowclass',this,H);var td={tag:'td',cls:H.rowClass,style:'',html:(typeof(G)==='object')?'':G};if(id){td.id=id;}if(typeof(E.hidden)!='undefined'&&E.hidden){td.style+=' display:none;';}if(typeof(E.align)!='undefined'&&E.align.length){td.style+=' text-align:'+E.align+';';}if(typeof(E.width)!='undefined'){td.style+=' width:'+E.width+'px;';}if(typeof(E.cursor)!='undefined'){td.style+=' cursor:'+E.cursor+';';}
+B.cn.push(td);}
+B.cellObjects=C;return B;},onBeforeLoad:function(){},clear:function(){this.el.select('tbody',true).first().dom.innerHTML='';},setRowVisibility:function(A,B){var bt=this.mainBody.dom;var C=this.el.select('tbody > tr',true).elements;if(typeof(C[A])=='undefined'){return;}
+C[A].dom.style.display=B?'':'none';},getSelectionModel:function(){if(!this.selModel){this.selModel=new Roo.bootstrap.Table.RowSelectionModel();}return this.selModel;},renderCellObject:function(r){var A=this;var t=r.cfg.render(r.container);if(r.cfg.cn){Roo.each(r.cfg.cn,function(c){var B={container:t.getChildContainer(),cfg:c}
+A.renderCellObject(B);})}},getRowIndex:function(A){var B=-1;Roo.each(this.el.select('tbody > tr',true).elements,function(el,C){if(el!=A){return;}
+B=C;});return B;}});
+//Roo/bootstrap/TableCell.js
+Roo.bootstrap.TableCell=function(A){Roo.bootstrap.TableCell.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TableCell,Roo.bootstrap.Component,{html:false,cls:false,tag:false,abbr:false,align:false,axis:false,bgcolor:false,charoff:false,colspan:false,headers:false,height:false,nowrap:false,rowspan:false,scope:false,valign:false,width:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));A={tag:'td'};if(this.tag){A.tag=this.tag;}if(this.html){A.html=this.html}if(this.cls){A.cls=this.cls}if(this.abbr){A.abbr=this.abbr}if(this.align){A.align=this.align}if(this.axis){A.axis=this.axis}if(this.bgcolor){A.bgcolor=this.bgcolor}if(this.charoff){A.charoff=this.charoff}if(this.colspan){A.colspan=this.colspan}if(this.headers){A.headers=this.headers}if(this.height){A.height=this.height}if(this.nowrap){A.nowrap=this.nowrap}if(this.rowspan){A.rowspan=this.rowspan}if(this.scope){A.scope=this.scope}if(this.valign){A.valign=this.valign}if(this.width){A.width=this.width}return A;}});
+//Roo/bootstrap/TableRow.js
+Roo.bootstrap.TableRow=function(A){Roo.bootstrap.TableRow.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TableRow,Roo.bootstrap.Component,{cls:false,align:false,bgcolor:false,charoff:false,valign:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));A={tag:'tr'};if(this.cls){A.cls=this.cls;}if(this.align){A.align=this.align;}if(this.bgcolor){A.bgcolor=this.bgcolor;}if(this.charoff){A.charoff=this.charoff;}if(this.valign){A.valign=this.valign;}return A;}});
+//Roo/bootstrap/TableBody.js
+Roo.bootstrap.TableBody=function(A){Roo.bootstrap.TableBody.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TableBody,Roo.bootstrap.Component,{cls:false,tag:false,align:false,charoff:false,valign:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TableBody.superclass.getAutoCreate.call(this));A={tag:'tbody'};if(this.cls){A.cls=this.cls}if(this.tag){A.tag=this.tag;}if(this.align){A.align=this.align;}if(this.charoff){A.charoff=this.charoff;}if(this.valign){A.valign=this.valign;}return A;}});
+//Roo/form/Action.js
+Roo.namespace('Roo.form');Roo.form.Action=function(A,B){this.form=A;this.options=B||{};};Roo.form.Action.CLIENT_INVALID='client';Roo.form.Action.SERVER_INVALID='server';Roo.form.Action.CONNECT_FAILURE='connect';Roo.form.Action.LOAD_FAILURE='load';Roo.form.Action.prototype={type:'default',failureType:undefined,response:undefined,result:undefined,run:function(A){},success:function(A){},handleResponse:function(A){},failure:function(A){this.response=A;this.failureType=Roo.form.Action.CONNECT_FAILURE;this.form.afterAction(this,false);},processResponse:function(A){this.response=A;if(!A.responseText){return true;}
+this.result=this.handleResponse(A);return this.result;},getUrl:function(A){var B=this.options.url||this.form.url||this.form.el.dom.action;if(A){var p=this.getParams();if(p){B+=(B.indexOf('?')!=-1?'&':'?')+p;}}return B;},getMethod:function(){return (this.options.method||this.form.method||this.form.el.dom.method||'POST').toUpperCase();},getParams:function(){var bp=this.form.baseParams;var p=this.options.params;if(p){if(typeof p=="object"){p=Roo.urlEncode(Roo.applyIf(p,bp));}else if(typeof p=='string'&&bp){p+='&'+Roo.urlEncode(bp);}}else if(bp){p=Roo.urlEncode(bp);}return p;},createCallback:function(){return {success:this.success,failure:this.failure,scope:this,timeout:(this.form.timeout*1000),upload:this.form.fileUpload?this.success:undefined};}};Roo.form.Action.Submit=function(A,B){Roo.form.Action.Submit.superclass.constructor.call(this,A,B);};Roo.extend(Roo.form.Action.Submit,Roo.form.Action,{type:'submit',haveProgress:false,uploadComplete:false,uploadProgress:function(){if(!this.form.progressUrl){return;}if(!this.haveProgress){Roo.MessageBox.progress("Uploading","Uploading");}if(this.uploadComplete){Roo.MessageBox.hide();return;}
+this.haveProgress=true;var A=this.form.findField('UPLOAD_IDENTIFIER').getValue();var c=new Roo.data.Connection();c.request({url:this.form.progressUrl,params:{id:A},method:'GET',success:function(B){var C=false;var D;try{C=Roo.decode(B.responseText)}catch(e){Roo.log("Invalid data from server..");Roo.log(D);return;}if(!C||!C.success){Roo.log(C);Roo.MessageBox.alert(Roo.encode(C));return;}var E=C.data;if(this.uploadComplete){Roo.MessageBox.hide();return;}if(E){Roo.MessageBox.updateProgress(E.bytes_uploaded/E.bytes_total,Math.floor((E.bytes_total-E.bytes_uploaded)/1000)+'k remaining');}
+this.uploadProgress.defer(2000,this);},failure:function(B){Roo.log('progress url failed ');Roo.log(B);},scope:this});},run:function(){this.form.getValues();var o=this.options;var A=this.getMethod();var B=A=='POST';if(o.clientValidation===false||this.form.isValid()){if(this.form.progressUrl){this.form.findField('UPLOAD_IDENTIFIER').setValue((new Date()*1)+''+Math.random());}Roo.Ajax.request(Roo.apply(this.createCallback(),{form:this.form.el.dom,url:this.getUrl(!B),method:A,params:B?this.getParams():null,isUpload:this.form.fileUpload}));this.uploadProgress();}else if(o.clientValidation!==false){this.failureType=Roo.form.Action.CLIENT_INVALID;this.form.afterAction(this,false);}},success:function(A){this.uploadComplete=true;if(this.haveProgress){Roo.MessageBox.hide();}var B=this.processResponse(A);if(B===true||B.success){this.form.afterAction(this,true);return;}if(B.errors){this.form.markInvalid(B.errors);this.failureType=Roo.form.Action.SERVER_INVALID;}
+this.form.afterAction(this,false);},failure:function(A){this.uploadComplete=true;if(this.haveProgress){Roo.MessageBox.hide();}
+this.response=A;this.failureType=Roo.form.Action.CONNECT_FAILURE;this.form.afterAction(this,false);},handleResponse:function(A){if(this.form.errorReader){var rs=this.form.errorReader.read(A);var B=[];if(rs.records){for(var i=0,C=rs.records.length;i<C;i++){var r=rs.records[i];B[i]=r.data;}}if(B.length<1){B=null;}return {success:rs.success,errors:B};}var D=false;try{D=Roo.decode(A.responseText);}catch(e){D={success:false,errorMsg:"Failed to read server message: "+(A?A.responseText:' - no message'),errors:[]};}return D;}});Roo.form.Action.Load=function(A,B){Roo.form.Action.Load.superclass.constructor.call(this,A,B);this.reader=this.form.reader;};Roo.extend(Roo.form.Action.Load,Roo.form.Action,{type:'load',run:function(){Roo.Ajax.request(Roo.apply(this.createCallback(),{method:this.getMethod(),url:this.getUrl(false),params:this.getParams()}));},success:function(A){var B=this.processResponse(A);if(B===true||!B.success||!B.data){this.failureType=Roo.form.Action.LOAD_FAILURE;this.form.afterAction(this,false);return;}
+this.form.clearInvalid();this.form.setValues(B.data);this.form.afterAction(this,true);},handleResponse:function(A){if(this.form.reader){var rs=this.form.reader.read(A);var B=rs.records&&rs.records[0]?rs.records[0].data:null;return {success:rs.success,data:B};}return Roo.decode(A.responseText);}});Roo.form.Action.ACTION_TYPES={'load':Roo.form.Action.Load,'submit':Roo.form.Action.Submit};
+//Roo/bootstrap/Form.js
+Roo.bootstrap.Form=function(A){Roo.bootstrap.Form.superclass.constructor.call(this,A);this.addEvents({clientvalidation:true,beforeaction:true,actionfailed:true,actioncomplete:true});};Roo.extend(Roo.bootstrap.Form,Roo.bootstrap.Component,{method:'POST',timeout:30,align:'left',activeAction:null,waitMsgTarget:false,loadMask:true,getAutoCreate:function(){var A={tag:'form',method:this.method||'POST',id:this.id||Roo.id(),cls:''};if(this.parent().xtype.match(/^Nav/)){A.cls='navbar-form navbar-'+this.align;}if(this.labelAlign=='left'){A.cls+=' form-horizontal';}return A;},initEvents:function(){this.el.on('submit',this.onSubmit,this);this.el.on('keypress',function(e){if(e.getCharCode()!=13){return true;}if(e.getTarget().nodeName.toLowerCase()==='textarea'){return true;}
+Roo.log("keypress blocked");e.preventDefault();return false;});},onSubmit:function(e){e.stopEvent();},isValid:function(){var A=this.getItems();var B=true;A.each(function(f){if(!f.validate()){B=false;}});return B;},isDirty:function(){var A=false;var B=this.getItems();B.each(function(f){if(f.isDirty()){A=true;return false;}return true;});return A;},doAction:function(A,B){if(typeof A=='string'){A=new Roo.form.Action.ACTION_TYPES[A](this,B);}if(this.fireEvent('beforeaction',this,A)!==false){this.beforeAction(A);A.run.defer(100,A);}return this;},beforeAction:function(A){var o=A.options;if(this.loadMask){this.el.mask(o.waitMsg||"Sending",'x-mask-loading');}},afterAction:function(A,B){this.activeAction=null;var o=A.options;this.el.unmask();if(B){if(o.reset){this.reset();}
+Roo.callback(o.success,o.scope,[this,A]);this.fireEvent('actioncomplete',this,A);}else {if((typeof(A.result)!='undefined')&&(typeof(A.result.errors)!='undefined')&&(typeof(A.result.errors.needs_confirm)!='undefined')){var _t=this;Roo.log("not supported yet");return;}
+Roo.callback(o.failure,o.scope,[this,A]);if(!this.hasListener('actionfailed')){Roo.log("need to add dialog support");}
+this.fireEvent('actionfailed',this,A);}},findField:function(id){var A=this.getItems();var B=A.get(id);if(!B){A.each(function(f){if(f.isFormField&&(f.dataIndex==id||f.id==id||f.getName()==id)){B=f;return false;}return true;});}return B||null;},markInvalid:function(A){if(A instanceof Array){for(var i=0,B=A.length;i<B;i++){var C=A[i];var f=this.findField(C.id);if(f){f.markInvalid(C.msg);}}}else {var D,id;for(id in A){if(typeof A[id]!='function'&&(D=this.findField(id))){D.markInvalid(A[id]);}}}return this;},setValues:function(A){if(A instanceof Array){for(var i=0,B=A.length;i<B;i++){var v=A[i];var f=this.findField(v.id);if(f){f.setValue(v.value);if(this.trackResetOnLoad){f.originalValue=f.getValue();}}}}else {var C,id;for(id in A){if(typeof A[id]!='function'&&(C=this.findField(id))){if(C.setFromData&&C.valueField&&C.displayField&&(C.store&&!C.store.isLocal)){var sd={};sd[C.valueField]=typeof(A[C.hiddenName])=='undefined'?'':A[C.hiddenName];sd[C.displayField]=typeof(A[C.name])=='undefined'?'':A[C.name];C.setFromData(sd);}else {C.setValue(A[id]);}if(this.trackResetOnLoad){C.originalValue=C.getValue();}}}}return this;},getValues:function(A){var fs=Roo.lib.Ajax.serializeForm(this.el.dom);if(A===true){return fs;}return Roo.urlDecode(fs);},getFieldValues:function(A){var B=this.getItems();var C={};B.each(function(f){if(!f.getName()){return;}var v=f.getValue();if(f.inputType=='radio'){if(typeof(C[f.getName()])=='undefined'){C[f.getName()]='';}if(!f.el.dom.checked){return;}
+v=f.el.dom.value;}if((typeof(v)=='object')&&f.getRawValue){v=f.getRawValue();}if(f.name!=f.getName()){C[f.name]=f.getRawValue();}
+C[f.getName()]=v;});return C;},clearInvalid:function(){var A=this.getItems();A.each(function(f){f.clearInvalid();});return this;},reset:function(){var A=this.getItems();A.each(function(f){f.reset();});Roo.each(this.childForms||[],function(f){f.reset();});return this;},getItems:function(){var r=new Roo.util.MixedCollection(false,function(o){return o.id||(o.id=Roo.id());});var A=function(el){if(el.inputEl){r.add(el);}if(!el.items){return;}
+Roo.each(el.items,function(e){A(e);});};A(this);return r;}});
+//Roo/form/VTypes.js
+Roo.form.VTypes=function(){var A=/^[a-zA-Z_]+$/;var B=/^[a-zA-Z0-9_]+$/;var C=/^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;var D=/(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;return {'email':function(v){return C.test(v);},'emailText':'This field should be an e-mail address in the format "user@domain.com"','emailMask':/[a-z0-9_\.\-@]/i,'url':function(v){return D.test(v);},'urlText':'This field should be a URL in the format "http:/'+'/www.domain.com"','alpha':function(v){return A.test(v);},'alphaText':'This field should only contain letters and _','alphaMask':/[a-z_]/i,'alphanum':function(v){return B.test(v);},'alphanumText':'This field should only contain letters, numbers and _','alphanumMask':/[a-z0-9_]/i};}();
+//Roo/bootstrap/Input.js
+Roo.bootstrap.Input=function(A){Roo.bootstrap.Input.superclass.constructor.call(this,A);this.addEvents({focus:true,blur:true,specialkey:true,change:true,invalid:true,valid:true,keyup:true});};Roo.extend(Roo.bootstrap.Input,Roo.bootstrap.Component,{validationEvent:"keyup",validateOnBlur:true,validationDelay:250,focusClass:"x-form-focus",invalidClass:"has-error",selectOnFocus:false,maskRe:null,vtype:null,disableKeyFilter:false,disabled:false,allowBlank:true,blankText:"This field is required",minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",validator:null,regex:null,regexText:"",fieldLabel:'',inputType:'text',name:false,placeholder:false,before:false,after:false,size:false,hasFocus:false,preventMark:false,isFormField:true,value:'',labelWidth:2,labelAlign:false,readOnly:false,align:false,formatedValue:false,parentLabelAlign:function(){var A=this;while(A.parent()){A=A.parent();if(typeof(A.labelAlign)!='undefined'){return A.labelAlign;}}return 'left';},getAutoCreate:function(){var A=(!this.labelAlign)?this.parentLabelAlign():this.labelAlign;var id=Roo.id();var B={};if(this.inputType!='hidden'){B.cls='form-group'}var C={tag:'input',id:id,type:this.inputType,value:this.value,cls:'form-control',placeholder:this.placeholder||''};if(this.align){C.style=(typeof(C.style)=='undefined')?('text-align:'+this.align):(C.style+'text-align:'+this.align);}if(this.maxLength&&this.maxLength!=Number.MAX_VALUE){C.maxLength=this.maxLength;}if(this.disabled){C.disabled=true;}if(this.readOnly){C.readonly=true;}if(this.name){C.name=this.name;}if(this.size){C.cls+=' input-'+this.size;}var D=this;['xs','sm','md','lg'].map(function(F){if(D[F]){B.cls+=' col-'+F+'-'+D[F];}});var E=C;if(this.before||this.after){E={cls:'input-group',cn:[]};if(this.before&&typeof(this.before)=='string'){E.cn.push({tag:'span',cls:'roo-input-before input-group-addon',html:this.before});}if(this.before&&typeof(this.before)=='object'){this.before=Roo.factory(this.before);Roo.log(this.before);E.cn.push({tag:'span',cls:'roo-input-before input-group-'+(this.before.xtype=='Button'?'btn':'addon')});}
+E.cn.push(C);if(this.after&&typeof(this.after)=='string'){E.cn.push({tag:'span',cls:'roo-input-after input-group-addon',html:this.after});}if(this.after&&typeof(this.after)=='object'){this.after=Roo.factory(this.after);Roo.log(this.after);E.cn.push({tag:'span',cls:'roo-input-after input-group-'+(this.after.xtype=='Button'?'btn':'addon')});}};if(A==='left'&&this.fieldLabel.length){Roo.log("left and has label");B.cn=[{tag:'label','for':id,cls:'control-label col-sm-'+this.labelWidth,html:this.fieldLabel},{cls:"col-sm-"+(12-this.labelWidth),cn:[E]}];}else if(this.fieldLabel.length){Roo.log(" label");B.cn=[{tag:'label',html:this.fieldLabel},E];}else {Roo.log(" no label && no align");B.cn=[E];};Roo.log('input-parentType: '+this.parentType);if(this.parentType==='Navbar'&&this.parent().bar){B.cls+=' navbar-form';Roo.log(B);}return B;},inputEl:function(){return this.el.select('input.form-control',true).first();},tooltipEl:function(){return this.inputEl();},setDisabled:function(v){var i=this.inputEl().dom;if(!v){i.removeAttribute('disabled');return;}
+i.setAttribute('disabled','true');},initEvents:function(){this.inputEl().on("keydown",this.fireKey,this);this.inputEl().on("focus",this.onFocus,this);this.inputEl().on("blur",this.onBlur,this);this.inputEl().relayEvent('keyup',this);this.originalValue=this.getValue();if(this.validationEvent=='keyup'){this.validationTask=new Roo.util.DelayedTask(this.validate,this);this.inputEl().on('keyup',this.filterValidation,this);}else if(this.validationEvent!==false){this.inputEl().on(this.validationEvent,this.validate,this,{buffer:this.validationDelay});}if(this.selectOnFocus){this.on("focus",this.preFocus,this);}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Roo.form.VTypes[this.vtype+'Mask']))){this.inputEl().on("keypress",this.filterKeys,this);}if(this.inputEl().is('input[type=password]')&&Roo.isSafari){this.inputEl().on('keydown',this.SafariOnKeyDown,this);}if(typeof(this.before)=='object'){this.before.render(this.el.select('.roo-input-before',true).first());}if(typeof(this.after)=='object'){this.after.render(this.el.select('.roo-input-after',true).first());}},filterValidation:function(e){if(!e.isNavKeyPress()){this.validationTask.delay(this.validationDelay);}},validate:function(){if(this.disabled||this.validateValue(this.getRawValue())){this.clearInvalid();return true;}return false;},validateValue:function(A){if(A.length<1){if(this.allowBlank){this.clearInvalid();return true;}else {this.markInvalid(this.blankText);return false;}}if(A.length<this.minLength){this.markInvalid(String.format(this.minLengthText,this.minLength));return false;}if(A.length>this.maxLength){this.markInvalid(String.format(this.maxLengthText,this.maxLength));return false;}if(this.vtype){var vt=Roo.form.VTypes;if(!vt[this.vtype](A,this)){this.markInvalid(this.vtypeText||vt[this.vtype+'Text']);return false;}}if(typeof this.validator=="function"){var B=this.validator(A);if(B!==true){this.markInvalid(B);return false;}}if(this.regex&&!this.regex.test(A)){this.markInvalid(this.regexText);return false;}return true;},fireKey:function(e){if(e.isNavKeyPress()){this.fireEvent("specialkey",this,e);}},focus:function(A){if(this.rendered){this.inputEl().focus();if(A===true){this.inputEl().dom.select();}}return this;},onFocus:function(){if(!Roo.isOpera&&this.focusClass){}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this);}},beforeBlur:Roo.emptyFn,onBlur:function(){this.beforeBlur();if(!Roo.isOpera&&this.focusClass){}
+this.hasFocus=false;if(this.validationEvent!==false&&this.validateOnBlur&&this.validationEvent!="blur"){this.validate();}var v=this.getValue();if(String(v)!==String(this.startValue)){this.fireEvent('change',this,v,this.startValue);}
+this.fireEvent("blur",this);},reset:function(){this.setValue(this.originalValue);this.clearInvalid();},getName:function(){return this.name;},getValue:function(){var v=this.inputEl().getValue();return v;},getRawValue:function(){var v=this.inputEl().getValue();return v;},setRawValue:function(v){return this.inputEl().dom.value=(v===null||v===undefined?'':v);},selectText:function(A,B){var v=this.getRawValue();if(v.length>0){A=A===undefined?0:A;B=B===undefined?v.length:B;var d=this.inputEl().dom;if(d.setSelectionRange){d.setSelectionRange(A,B);}else if(d.createTextRange){var C=d.createTextRange();C.moveStart("character",A);C.moveEnd("character",v.length-B);C.select();}}},setValue:function(v){this.value=v;if(this.rendered){this.inputEl().dom.value=(v===null||v===undefined?'':v);this.validate();}},preFocus:function(){if(this.selectOnFocus){this.inputEl().dom.select();}},filterKeys:function(e){var k=e.getKey();if(!Roo.isIE&&(e.isNavKeyPress()||k==e.BACKSPACE||(k==e.DELETE &&e.button==-1))){return;}var c=e.getCharCode(),cc=String.fromCharCode(c);if(Roo.isIE&&(e.isSpecialKey()||!cc)){return;}if(!this.maskRe.test(cc)){e.stopEvent();}},clearInvalid:function(){if(!this.el||this.preventMark){return;}
+this.el.removeClass(this.invalidClass);this.fireEvent('valid',this);},markInvalid:function(A){if(!this.el||this.preventMark){return;}
+this.el.addClass(this.invalidClass);this.fireEvent('invalid',this,A);},SafariOnKeyDown:function(A){var B=false;if(this.inputEl().dom.selectionEnd>0){B=(this.inputEl().dom.selectionEnd-this.inputEl().dom.selectionStart-this.getValue().length==0)?true:false;}if(((A.getKey()==8||A.getKey()==46)&&this.getValue().length==1)){A.preventDefault();this.setValue('');return;}if(B&&A.getCharCode()>31){A.preventDefault();var cc=String.fromCharCode(A.getCharCode());this.setValue(A.shiftKey?cc:cc.toLowerCase());}},adjustWidth:function(A,w){A=A.toLowerCase();if(typeof w=='number'&&Roo.isStrict&&!Roo.isSafari){if(Roo.isIE&&(A=='input'||A=='textarea')){if(A=='input'){return w+2;}if(A=='textarea'){return w-2;}}else if(Roo.isOpera){if(A=='input'){return w+2;}if(A=='textarea'){return w-2;}}}return w;}});
+//Roo/bootstrap/TextArea.js
+Roo.bootstrap.TextArea=function(A){Roo.bootstrap.TextArea.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TextArea,Roo.bootstrap.Input,{cols:false,rows:5,readOnly:false,warp:'soft',resize:false,value:false,html:false,getAutoCreate:function(){var A=(!this.labelAlign)?this.parentLabelAlign():this.labelAlign;var id=Roo.id();var B={};var C={tag:'textarea',id:id,warp:this.warp,rows:this.rows,value:this.value||'',html:this.html||'',cls:'form-control',placeholder:this.placeholder||''};if(this.maxLength&&this.maxLength!=Number.MAX_VALUE){C.maxLength=this.maxLength;}if(this.resize){C.style=(typeof(C.style)=='undefined')?'resize:'+this.resize:C.style+'resize:'+this.resize;}if(this.cols){C.cols=this.cols;}if(this.readOnly){C.readonly=true;}if(this.name){C.name=this.name;}if(this.size){C.cls=(typeof(C.cls)=='undefined')?'input-'+this.size:C.cls+' input-'+this.size;}var D=this;['xs','sm','md','lg'].map(function(F){if(D[F]){B.cls+=' col-'+F+'-'+D[F];}});var E=C;if(this.before||this.after){E={cls:'input-group',cn:[]};if(this.before){E.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
+E.cn.push(C);if(this.after){E.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}}if(A==='left'&&this.fieldLabel.length){Roo.log("left and has label");B.cn=[{tag:'label','for':id,cls:'control-label col-sm-'+this.labelWidth,html:this.fieldLabel},{cls:"col-sm-"+(12-this.labelWidth),cn:[E]}];}else if(this.fieldLabel.length){Roo.log(" label");B.cn=[{tag:'label',html:this.fieldLabel},E];}else {Roo.log(" no label && no align");B.cn=[E];}if(this.disabled){C.disabled=true;}return B;},inputEl:function(){return this.el.select('textarea.form-control',true).first();}});
+//Roo/bootstrap/TriggerField.js
+Roo.bootstrap.TriggerField=function(A){this.mimicing=false;Roo.bootstrap.TriggerField.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TriggerField,Roo.bootstrap.Input,{hideTrigger:false,autoSize:Roo.emptyFn,monitorTab:true,deferHeight:true,actionMode:'wrap',caret:false,getAutoCreate:function(){var A=this.labelAlign||this.parentLabelAlign();var id=Roo.id();var B={cls:'form-group'};var C={tag:'input',id:id,type:this.inputType,cls:'form-control',autocomplete:'false',placeholder:this.placeholder||''};if(this.name){C.name=this.name;}if(this.size){C.cls+=' input-'+this.size;}if(this.disabled){C.disabled=true;}var D=C;if(this.before||this.after){D={cls:'input-group',cn:[]};if(this.before){D.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
+D.cn.push(C);if(this.after){D.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}};var E={tag:'div',cn:[{tag:'input',type:'hidden',cls:'form-hidden-field'},D]};if(this.multiple){Roo.log('multiple');E={tag:'div',cn:[{tag:'input',type:'hidden',cls:'form-hidden-field'},{tag:'ul',cls:'select2-choices',cn:[{tag:'li',cls:'select2-search-field',cn:[D]}]}]}};var F={cls:'select2-container input-group',cn:[E]};if(!this.multiple&&this.showToggleBtn){var G={tag:'span',cls:'caret'};if(this.caret!=false){G={tag:'i',cls:'fa fa-'+this.caret};}
+F.cn.push({tag:'span',cls:'input-group-addon btn dropdown-toggle',cn:[G,{tag:'span',cls:'combobox-clear',cn:[{tag:'i',cls:'icon-remove'}]}]})}if(this.multiple){F.cls+=' select2-container-multi';}if(A==='left'&&this.fieldLabel.length){Roo.log("left and has label");B.cn=[{tag:'label','for':id,cls:'control-label col-sm-'+this.labelWidth,html:this.fieldLabel},{cls:"col-sm-"+(12-this.labelWidth),cn:[F]}];}else if(this.fieldLabel.length){Roo.log(" label");B.cn=[{tag:'label',html:this.fieldLabel},F];}else {Roo.log(" no label && no align");B=F}var H=this;['xs','sm','md','lg'].map(function(I){if(H[I]){B.cls+=' col-'+I+'-'+H[I];}});return B;},onResize:function(w,h){},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.inputEl();},getPositionEl:function(){return this.inputEl();},alignErrorIcon:function(){this.errorIcon.alignTo(this.inputEl(),'tl-tr',[2,0]);},initEvents:function(){this.createList();Roo.bootstrap.TriggerField.superclass.initEvents.call(this);if(!this.multiple&&this.showToggleBtn){this.trigger=this.el.select('span.dropdown-toggle',true).first();if(this.hideTrigger){this.trigger.setDisplayed(false);}
+this.trigger.on("click",this.onTriggerClick,this,{preventDefault:true});}if(this.multiple){this.inputEl().on("click",this.onTriggerClick,this,{preventDefault:true});}},createList:function(){this.list=Roo.get(document.body).createChild({tag:'ul',cls:'typeahead typeahead-long dropdown-menu',style:'display:none'});this.list.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';;},initTrigger:function(){},onDestroy:function(){if(this.trigger){this.trigger.removeAllListeners();}
+Roo.bootstrap.TriggerField.superclass.onDestroy.call(this);},onFocus:function(){Roo.bootstrap.TriggerField.superclass.onFocus.call(this);},checkTab:function(e){if(e.getKey()==e.TAB){this.triggerBlur();}},onBlur:function(){},mimicBlur:function(e,t){},triggerBlur:function(){this.mimicing=false;Roo.get(Roo.isIE?document.body:document).un("mousedown",this.mimicBlur);if(this.monitorTab){this.el.un("keydown",this.checkTab,this);}
+Roo.bootstrap.TriggerField.superclass.onBlur.call(this);},validateBlur:function(e,t){return true;},onDisable:function(){this.inputEl().dom.disabled=true;},onEnable:function(){this.inputEl().dom.disabled=false;},onShow:function(){var ae=this.getActionEl();if(ae){ae.dom.style.display='';ae.dom.style.visibility='visible';}},onHide:function(){var ae=this.getActionEl();ae.dom.style.display='none';},onTriggerClick:Roo.emptyFn});
+//Roo/data/SortTypes.js
+Roo.data.SortTypes={none:function(s){return s;},stripTagsRE:/<\/?[^>]+>/gi,asText:function(s){return String(s).replace(this.stripTagsRE,"");},asUCText:function(s){return String(s).toUpperCase().replace(this.stripTagsRE,"");},asUCString:function(s){return String(s).toUpperCase();},asDate:function(s){if(!s){return 0;}if(s instanceof Date){return s.getTime();}return Date.parse(String(s));},asFloat:function(s){var A=parseFloat(String(s).replace(/,/g,""));if(isNaN(A))A=0;return A;},asInt:function(s){var A=parseInt(String(s).replace(/,/g,""));if(isNaN(A))A=0;return A;}};
+//Roo/data/Record.js
+Roo.data.Record=function(A,id){this.id=(id||id===0)?id:++Roo.data.Record.AUTO_ID;this.data=A;};Roo.data.Record.create=function(o){var f=function(){f.superclass.constructor.apply(this,arguments);};Roo.extend(f,Roo.data.Record);var p=f.prototype;p.fields=new Roo.util.MixedCollection(false,function(B){return B.name;});for(var i=0,A=o.length;i<A;i++){p.fields.add(new Roo.data.Field(o[i]));}
+f.getField=function(B){return p.fields.get(B);};return f;};Roo.data.Record.AUTO_ID=1000;Roo.data.Record.EDIT='edit';Roo.data.Record.REJECT='reject';Roo.data.Record.COMMIT='commit';Roo.data.Record.prototype={dirty:false,editing:false,error:null,modified:null,join:function(A){this.store=A;},set:function(A,B){if(this.data[A]==B){return;}
+this.dirty=true;if(!this.modified){this.modified={};}if(typeof this.modified[A]=='undefined'){this.modified[A]=this.data[A];}
+this.data[A]=B;if(!this.editing&&this.store){this.store.afterEdit(this);}},get:function(A){return this.data[A];},beginEdit:function(){this.editing=true;this.modified={};},cancelEdit:function(){this.editing=false;delete this.modified;},endEdit:function(){this.editing=false;if(this.dirty&&this.store){this.store.afterEdit(this);}},reject:function(){var m=this.modified;for(var n in m){if(typeof m[n]!="function"){this.data[n]=m[n];}}
+this.dirty=false;delete this.modified;this.editing=false;if(this.store){this.store.afterReject(this);}},commit:function(){this.dirty=false;delete this.modified;this.editing=false;if(this.store){this.store.afterCommit(this);}},hasError:function(){return this.error!=null;},clearError:function(){this.error=null;},copy:function(A){return new this.constructor(Roo.apply({},this.data),A||this.id);}};
+//Roo/data/Store.js
+Roo.data.Store=function(A){this.data=new Roo.util.MixedCollection(false);this.data.getKey=function(o){return o.id;};this.baseParams={};this.paramNames={"start":"start","limit":"limit","sort":"sort","dir":"dir","multisort":"_multisort"};if(A&&A.data){this.inlineData=A.data;delete A.data;}
+Roo.apply(this,A);if(this.reader){this.reader=Roo.factory(this.reader,Roo.data);this.reader.xmodule=this.xmodule||false;if(!this.recordType){this.recordType=this.reader.recordType;}if(this.reader.onMetaChange){this.reader.onMetaChange=this.onMetaChange.createDelegate(this);}}if(this.recordType){this.fields=this.recordType.prototype.fields;}
+this.modified=[];this.addEvents({datachanged:true,metachange:true,add:true,remove:true,update:true,clear:true,beforeload:true,beforeloadadd:true,load:true,loadexception:true});if(this.proxy){this.proxy=Roo.factory(this.proxy,Roo.data);this.proxy.xmodule=this.xmodule||false;this.relayEvents(this.proxy,["loadexception"]);}
+this.sortToggle={};this.sortOrder=[];Roo.data.Store.superclass.constructor.call(this);if(this.inlineData){this.loadData(this.inlineData);delete this.inlineData;}};Roo.extend(Roo.data.Store,Roo.util.Observable,{multiSort:false,remoteSort:false,pruneModifiedRecords:false,lastOptions:null,add:function(A){A=[].concat(A);for(var i=0,B=A.length;i<B;i++){A[i].join(this);}var C=this.data.length;this.data.addAll(A);this.fireEvent("add",this,A,C);},remove:function(A){var B=this.data.indexOf(A);this.data.removeAt(B);if(this.pruneModifiedRecords){this.modified.remove(A);}
+this.fireEvent("remove",this,A,B);},removeAll:function(){this.data.clear();if(this.pruneModifiedRecords){this.modified=[];}
+this.fireEvent("clear",this);},insert:function(A,B){B=[].concat(B);for(var i=0,C=B.length;i<C;i++){this.data.insert(A,B[i]);B[i].join(this);}
+this.fireEvent("add",this,B,A);},indexOf:function(A){return this.data.indexOf(A);},indexOfId:function(id){return this.data.indexOfKey(id);},getById:function(id){return this.data.key(id);},getAt:function(A){return this.data.itemAt(A);},getRange:function(A,B){return this.data.getRange(A,B);},storeOptions:function(o){o=Roo.apply({},o);delete o.callback;delete o.scope;this.lastOptions=o;},load:function(A){A=A||{};if(this.fireEvent("beforeload",this,A)!==false){this.storeOptions(A);var p=Roo.apply(A.params||{},this.baseParams);if(!this.reader.metaFromRemote){p._requestMeta=1;}if(this.sortInfo&&this.remoteSort){var pn=this.paramNames;p[pn["sort"]]=this.sortInfo.field;p[pn["dir"]]=this.sortInfo.direction;}if(this.multiSort){var pn=this.paramNames;p[pn["multisort"]]=Roo.encode({sort:this.sortToggle,order:this.sortOrder});}
+this.proxy.load(p,this.reader,this.loadRecords,this,A);}},reload:function(A){this.load(Roo.applyIf(A||{},this.lastOptions));},loadRecords:function(o,A,B){if(!o||B===false){if(B!==false){this.fireEvent("load",this,[],A,o);}if(A.callback){A.callback.call(A.scope||this,[],A,false);}return;}if(o.success===false){if(!this.hasListener('loadexception')&&typeof(o.raw.errorMsg)!='undefined'){Roo.MessageBox.alert("Error loading",o.raw.errorMsg);}
+this.fireEvent("loadexception",this,o,A,o.raw.errorMsg);return;}var r=o.records,t=o.totalRecords||r.length;this.fireEvent("beforeloadadd",this,r,A,o);if(!A||A.add!==true){if(this.pruneModifiedRecords){this.modified=[];}for(var i=0,C=r.length;i<C;i++){r[i].join(this);}if(this.snapshot){this.data=this.snapshot;delete this.snapshot;}
+this.data.clear();this.data.addAll(r);this.totalLength=t;this.applySort();this.fireEvent("datachanged",this);}else {this.totalLength=Math.max(t,this.data.length+r.length);this.add(r);}
+this.fireEvent("load",this,r,A,o);if(A.callback){A.callback.call(A.scope||this,r,A,true);}},loadData:function(o,A){var r=this.reader.readRecords(o);this.loadRecords(r,{add:A},true);},getCount:function(){return this.data.length||0;},getTotalCount:function(){return this.totalLength||0;},getSortState:function(){return this.sortInfo;},applySort:function(){if(this.sortInfo&&!this.remoteSort){var s=this.sortInfo,f=s.field;var st=this.fields.get(f).sortType;var fn=function(r1,r2){var v1=st(r1.data[f]),v2=st(r2.data[f]);return v1>v2?1:(v1<v2?-1:0);};this.data.sort(s.direction,fn);if(this.snapshot&&this.snapshot!=this.data){this.snapshot.sort(s.direction,fn);}}},setDefaultSort:function(A,B){this.sortInfo={field:A,direction:B?B.toUpperCase():"ASC"};},sort:function(A,B){var f=this.fields.get(A);if(!B){this.sortToggle[f.name]=this.sortToggle[f.name]||f.sortDir;if(this.multiSort||(this.sortInfo&&this.sortInfo.field==f.name)){B=(this.sortToggle[f.name]||"ASC").toggle("ASC","DESC");}else {B=f.sortDir;}}
+this.sortToggle[f.name]=B;this.sortInfo={field:f.name,direction:B};if(!this.remoteSort){this.applySort();this.fireEvent("datachanged",this);}else {this.load(this.lastOptions);}},each:function(fn,A){this.data.each(fn,A);},getModifiedRecords:function(){return this.modified;},createFilterFn:function(A,B,C){if(!B.exec){B=String(B);if(B.length==0){return false;}
+B=new RegExp((C===true?'':'^')+Roo.escapeRe(B),"i");}return function(r){return B.test(r.data[A]);};},sum:function(A,B,C){var rs=this.data.items,v=0;B=B||0;C=(C||C===0)?C:rs.length-1;for(var i=B;i<=C;i++){v+=(rs[i].data[A]||0);}return v;},filter:function(A,B,C){var fn=this.createFilterFn(A,B,C);return fn?this.filterBy(fn):this.clearFilter();},filterBy:function(fn,A){this.snapshot=this.snapshot||this.data;this.data=this.queryBy(fn,A||this);this.fireEvent("datachanged",this);},query:function(A,B,C){var fn=this.createFilterFn(A,B,C);return fn?this.queryBy(fn):this.data.clone();},queryBy:function(fn,A){var B=this.snapshot||this.data;return B.filterBy(fn,A||this);},collect:function(A,B,C){var d=(C===true&&this.snapshot)?this.snapshot.items:this.data.items;var v,sv,r=[],l={};for(var i=0,D=d.length;i<D;i++){v=d[i].data[A];sv=String(v);if((B||!Roo.isEmpty(v))&&!l[sv]){l[sv]=true;r[r.length]=v;}}return r;},clearFilter:function(A){if(this.snapshot&&this.snapshot!=this.data){this.data=this.snapshot;delete this.snapshot;if(A!==true){this.fireEvent("datachanged",this);}}},afterEdit:function(A){if(this.modified.indexOf(A)==-1){this.modified.push(A);}
+this.fireEvent("update",this,A,Roo.data.Record.EDIT);},afterReject:function(A){this.modified.remove(A);this.fireEvent("update",this,A,Roo.data.Record.REJECT);},afterCommit:function(A){this.modified.remove(A);this.fireEvent("update",this,A,Roo.data.Record.COMMIT);},commitChanges:function(){var m=this.modified.slice(0);this.modified=[];for(var i=0,A=m.length;i<A;i++){m[i].commit();}},rejectChanges:function(){var m=this.modified.slice(0);this.modified=[];for(var i=0,A=m.length;i<A;i++){m[i].reject();}},onMetaChange:function(A,B,o){this.recordType=B;this.fields=B.prototype.fields;delete this.snapshot;this.sortInfo=A.sortInfo||this.sortInfo;this.modified=[];this.fireEvent('metachange',this,this.reader.meta);},moveIndex:function(A,B){var C=this.indexOf(A);var D=C+B;this.remove(A);this.insert(D,A);}});
+//Roo/data/SimpleStore.js
+Roo.data.SimpleStore=function(A){Roo.data.SimpleStore.superclass.constructor.call(this,{isLocal:true,reader:new Roo.data.ArrayReader({id:A.id},Roo.data.Record.create(A.fields)),proxy:new Roo.data.MemoryProxy(A.data)});this.load();};Roo.extend(Roo.data.SimpleStore,Roo.data.Store);
+//Roo/data/JsonStore.js
+Roo.data.JsonStore=function(c){Roo.data.JsonStore.superclass.constructor.call(this,Roo.apply(c,{proxy:!c.data?new Roo.data.HttpProxy({url:c.url}):undefined,reader:new Roo.data.JsonReader(c,c.fields)}));};Roo.extend(Roo.data.JsonStore,Roo.data.Store);
+//Roo/data/Field.js
+Roo.data.Field=function(A){if(typeof A=="string"){A={name:A};}
+Roo.apply(this,A);if(!this.type){this.type="auto";}var st=Roo.data.SortTypes;if(typeof this.sortType=="string"){this.sortType=st[this.sortType];}if(!this.sortType){switch(this.type){case "string":this.sortType=st.asUCString;break;case "date":this.sortType=st.asDate;break;default:this.sortType=st.none;}}var B=/[\$,%]/g;if(!this.convert){var cv,C=this.dateFormat;switch(this.type){case "":case "auto":case undefined:cv=function(v){return v;};break;case "string":cv=function(v){return (v===undefined||v===null)?'':String(v);};break;case "int":cv=function(v){return v!==undefined&&v!==null&&v!==''?parseInt(String(v).replace(B,""),10):'';};break;case "float":cv=function(v){return v!==undefined&&v!==null&&v!==''?parseFloat(String(v).replace(B,""),10):'';};break;case "bool":case "boolean":cv=function(v){return v===true||v==="true"||v==1;};break;case "date":cv=function(v){if(!v){return '';}if(v instanceof Date){return v;}if(C){if(C=="timestamp"){return new Date(v*1000);}return Date.parseDate(v,C);}var D=Date.parse(v);return D?new Date(D):null;};break;}
+this.convert=cv;}};Roo.data.Field.prototype={dateFormat:null,defaultValue:"",mapping:null,sortType:null,sortDir:"ASC"};
+//Roo/data/DataReader.js
+Roo.data.DataReader=function(A,B){this.meta=A;this.recordType=B instanceof Array?Roo.data.Record.create(B):B;};Roo.data.DataReader.prototype={newRow:function(d){var da={};this.recordType.prototype.fields.each(function(c){switch(c.type){case 'int':da[c.name]=0;break;case 'date':da[c.name]=new Date();break;case 'float':da[c.name]=0.0;break;case 'boolean':da[c.name]=false;break;default:da[c.name]="";break;}});return new this.recordType(Roo.apply(da,d));}};
+//Roo/data/DataProxy.js
+Roo.data.DataProxy=function(){this.addEvents({beforeload:true,load:true,loadexception:true});Roo.data.DataProxy.superclass.constructor.call(this);};Roo.extend(Roo.data.DataProxy,Roo.util.Observable);
+//Roo/data/MemoryProxy.js
+Roo.data.MemoryProxy=function(A){if(A.data){A=A.data;}
+Roo.data.MemoryProxy.superclass.constructor.call(this);this.data=A;};Roo.extend(Roo.data.MemoryProxy,Roo.data.DataProxy,{load:function(A,B,C,D,E){A=A||{};var F;try{F=B.readRecords(this.data);}catch(e){this.fireEvent("loadexception",this,E,null,e);C.call(D,null,E,false);return;}
+C.call(D,F,E,true);},update:function(A,B){}});
+//Roo/data/HttpProxy.js
+Roo.data.HttpProxy=function(A){Roo.data.HttpProxy.superclass.constructor.call(this);this.conn=A;this.useAjax=!A||!A.events;};Roo.extend(Roo.data.HttpProxy,Roo.data.DataProxy,{getConnection:function(){return this.useAjax?Roo.Ajax:this.conn;},load:function(A,B,C,D,E){if(this.fireEvent("beforeload",this,A)!==false){var o={params:A||{},request:{callback:C,scope:D,arg:E},reader:B,callback:this.loadResponse,scope:this};if(this.useAjax){Roo.applyIf(o,this.conn);if(this.activeRequest){Roo.Ajax.abort(this.activeRequest);}
+this.activeRequest=Roo.Ajax.request(o);}else {this.conn.request(o);}}else {C.call(D||this,null,E,false);}},loadResponse:function(o,A,B){delete this.activeRequest;if(!A){this.fireEvent("loadexception",this,o,B);o.request.callback.call(o.request.scope,null,o.request.arg,false);return;}var C;try{C=o.reader.read(B);}catch(e){this.fireEvent("loadexception",this,o,B,e);o.request.callback.call(o.request.scope,null,o.request.arg,false);return;}
+this.fireEvent("load",this,o,o.request.arg);o.request.callback.call(o.request.scope,C,o.request.arg,true);},update:function(A){},updateResponse:function(A){}});
+//Roo/data/ScriptTagProxy.js
+Roo.data.ScriptTagProxy=function(A){Roo.data.ScriptTagProxy.superclass.constructor.call(this);Roo.apply(this,A);this.head=document.getElementsByTagName("head")[0];};Roo.data.ScriptTagProxy.TRANS_ID=1000;Roo.extend(Roo.data.ScriptTagProxy,Roo.data.DataProxy,{timeout:30000,callbackParam:"callback",nocache:true,load:function(A,B,C,D,E){if(this.fireEvent("beforeload",this,A)!==false){var p=Roo.urlEncode(Roo.apply(A,this.extraParams));var F=this.url;F+=(F.indexOf("?")!=-1?"&":"?")+p;if(this.nocache){F+="&_dc="+(new Date().getTime());}var G=++Roo.data.ScriptTagProxy.TRANS_ID;var H={id:G,cb:"stcCallback"+G,scriptId:"stcScript"+G,params:A,arg:E,url:F,callback:C,scope:D,reader:B};var I=this;window[H.cb]=function(o){I.handleResponse(o,H);};F+=String.format("&{0}={1}",this.callbackParam,H.cb);if(this.autoAbort!==false){this.abort();}
+H.timeoutId=this.handleFailure.defer(this.timeout,this,[H]);var J=document.createElement("script");J.setAttribute("src",F);J.setAttribute("type","text/javascript");J.setAttribute("id",H.scriptId);this.head.appendChild(J);this.trans=H;}else {C.call(D||this,null,E,false);}},isLoading:function(){return this.trans?true:false;},abort:function(){if(this.isLoading()){this.destroyTrans(this.trans);}},destroyTrans:function(A,B){this.head.removeChild(document.getElementById(A.scriptId));clearTimeout(A.timeoutId);if(B){window[A.cb]=undefined;try{delete window[A.cb];}catch(e){}}else {window[A.cb]=function(){window[A.cb]=undefined;try{delete window[A.cb];}catch(e){}};}},handleResponse:function(o,A){this.trans=false;this.destroyTrans(A,true);var B;try{B=A.reader.readRecords(o);}catch(e){this.fireEvent("loadexception",this,o,A.arg,e);A.callback.call(A.scope||window,null,A.arg,false);return;}
+this.fireEvent("load",this,o,A.arg);A.callback.call(A.scope||window,B,A.arg,true);},handleFailure:function(A){this.trans=false;this.destroyTrans(A,false);this.fireEvent("loadexception",this,null,A.arg);A.callback.call(A.scope||window,null,A.arg,false);}});
+//Roo/data/JsonReader.js
+Roo.data.JsonReader=function(A,B){A=A||{};Roo.applyIf(A,{totalProperty:'total',successProperty:'success',root:'data',id:'id'});Roo.data.JsonReader.superclass.constructor.call(this,A,B||A.fields);};Roo.extend(Roo.data.JsonReader,Roo.data.DataReader,{metaFromRemote:false,read:function(A){var B=A.responseText;var o=eval("("+B+")");if(!o){throw {message:"JsonReader.read: Json object not found"};}if(o.metaData){delete this.ef;this.metaFromRemote=true;this.meta=o.metaData;this.recordType=Roo.data.Record.create(o.metaData.fields);this.onMetaChange(this.meta,this.recordType,o);}return this.readRecords(o);},onMetaChange:function(A,B,o){},simpleAccess:function(A,B){return A[B];},getJsonAccessor:function(){var re=/[\[\.]/;return function(A){try{return (re.test(A))?new Function("obj","return obj."+A):function(B){return B[A];};}catch(e){}return Roo.emptyFn;};}(),readRecords:function(o){this.o=o;var s=this.meta,A=this.recordType,f=A?A.prototype.fields:null,fi=f?f.items:[],fl=f?f.length:0;if(!this.ef){if(s.totalProperty){this.getTotal=this.getJsonAccessor(s.totalProperty);}if(s.successProperty){this.getSuccess=this.getJsonAccessor(s.successProperty);}
+this.getRoot=s.root?this.getJsonAccessor(s.root):function(p){return p;};if(s.id){var g=this.getJsonAccessor(s.id);this.getId=function(I){var r=g(I);return (r===undefined||r==="")?null:r;};}else {this.getId=function(){return null;};}
+this.ef=[];for(var jj=0;jj<fl;jj++){f=fi[jj];var B=(f.mapping!==undefined&&f.mapping!==null)?f.mapping:f.name;this.ef[jj]=this.getJsonAccessor(B);}}var C=this.getRoot(o),c=C.length,D=c,E=true;if(s.totalProperty){var vt=parseInt(this.getTotal(o),10);if(!isNaN(vt)){D=vt;}}if(s.successProperty){var vs=this.getSuccess(o);if(vs===false||vs==='false'){E=false;}}var F=[];for(var i=0;i<c;i++){var n=C[i];var G={};var id=this.getId(n);for(var j=0;j<fl;j++){f=fi[j];var v=this.ef[j](n);if(!f.convert){Roo.log('missing convert for '+f.name);Roo.log(f);continue;}
+G[f.name]=f.convert((v!==undefined)?v:f.defaultValue);}var H=new A(G,id);H.json=n;F[i]=H;}return {raw:o,success:E,records:F,totalRecords:D};}});
+//Roo/data/ArrayReader.js
+Roo.data.ArrayReader=function(A,B){Roo.data.ArrayReader.superclass.constructor.call(this,A,B);};Roo.extend(Roo.data.ArrayReader,Roo.data.JsonReader,{readRecords:function(o){var A=this.meta?this.meta.id:null;var B=this.recordType,C=B.prototype.fields;var D=[];var E=o;for(var i=0;i<E.length;i++){var n=E[i];var F={};var id=((A||A===0)&&n[A]!==undefined&&n[A]!==""?n[A]:null);for(var j=0,G=C.length;j<G;j++){var f=C.items[j];var k=f.mapping!==undefined&&f.mapping!==null?f.mapping:j;var v=n[k]!==undefined?n[k]:f.defaultValue;v=f.convert(v);F[f.name]=v;}var H=new B(F,id);H.json=n;D[D.length]=H;}return {records:D,totalRecords:D.length};}});
+//Roo/bootstrap/ComboBox.js
+Roo.bootstrap.ComboBox=function(A){Roo.bootstrap.ComboBox.superclass.constructor.call(this,A);this.addEvents({'expand':true,'collapse':true,'beforeselect':true,'select':true,'beforequery':true,'add':true,'edit':true,'remove':true});this.item=[];this.tickItems=[];this.selectedIndex=-1;if(this.mode=='local'){if(A.queryDelay===undefined){this.queryDelay=10;}if(A.minChars===undefined){this.minChars=0;}}};Roo.extend(Roo.bootstrap.ComboBox,Roo.bootstrap.TriggerField,{listWidth:undefined,displayField:undefined,valueField:undefined,hiddenName:undefined,listClass:'',selectedClass:'active',shadow:'sides',listAlign:'tl-bl?',maxHeight:300,triggerAction:'query',minChars:4,typeAhead:false,queryDelay:500,pageSize:0,selectOnFocus:false,queryParam:'query',loadingText:'Loading...',resizable:false,handleHeight:8,editable:true,allQuery:'',mode:'remote',minListWidth:70,forceSelection:false,typeAheadDelay:250,valueNotFoundText:undefined,blockFocus:false,disableClear:false,alwaysQuery:false,multiple:false,addicon:false,editicon:false,page:0,hasQuery:false,append:false,loadNext:false,autoFocus:true,tickable:false,btnPosition:'right',triggerList:true,showToggleBtn:true,getAutoCreate:function(){var A=false;if(!this.tickable){A=Roo.bootstrap.ComboBox.superclass.getAutoCreate.call(this);return A;}var B=this.labelAlign||this.parentLabelAlign();A={cls:'form-group roo-combobox-tickable'};var C={tag:'div',cls:'tickable-buttons',cn:[{tag:'button',type:'button',cls:'btn btn-link btn-edit pull-'+this.btnPosition,html:'Edit'},{tag:'button',type:'button',name:'ok',cls:'btn btn-link btn-ok pull-'+this.btnPosition,html:'Done'},{tag:'button',type:'button',name:'cancel',cls:'btn btn-link btn-cancel pull-'+this.btnPosition,html:'Cancel'}]};var D=this;Roo.each(C.cn,function(c){if(D.size){c.cls+=' btn-'+D.size;}if(D.disabled){c.disabled=true;}});var E={tag:'div',cn:[{tag:'input',type:'hidden',cls:'form-hidden-field'},{tag:'ul',cls:'select2-choices',cn:[{tag:'li',cls:'select2-search-field',cn:[C]}]}]};var combobox={cls:'select2-container input-group select2-container-multi',cn:[E]};if(B==='left'&&this.fieldLabel.length){Roo.log("left and has label");A.cn=[{tag:'label','for':id,cls:'control-label col-sm-'+this.labelWidth,html:this.fieldLabel},{cls:"col-sm-"+(12-this.labelWidth),cn:[combobox]}];}else if(this.fieldLabel.length){Roo.log(" label");A.cn=[{tag:'label',html:this.fieldLabel},combobox];}else {Roo.log(" no label && no align");A=combobox}var F=this;['xs','sm','md','lg'].map(function(G){if(F[G]){A.cls+=' col-'+G+'-'+F[G];}});return A;},initEvents:function(){if(!this.store){throw "can not find store for combo";}
+this.store=Roo.factory(this.store,Roo.data);if(this.tickable){this.initTickableEvents();return;}
+Roo.bootstrap.ComboBox.superclass.initEvents.call(this);if(this.hiddenName){this.hiddenField=this.el.select('input.form-hidden-field',true).first();this.hiddenField.dom.value=this.hiddenValue!==undefined?this.hiddenValue:this.value!==undefined?this.value:'';this.el.dom.removeAttribute('name');this.hiddenField.dom.setAttribute('name',this.hiddenName);}var A='x-combo-list';var B=this;(function(){var lw=B.listWidth||Math.max(B.inputEl().getWidth(),B.minListWidth);B.list.setWidth(lw);}).defer(100);this.list.on('mouseover',this.onViewOver,this);this.list.on('mousemove',this.onViewMove,this);this.list.on('scroll',this.onViewScroll,this);if(!this.tpl){this.tpl='<li><a href="#">{'+this.displayField+'}</a></li>';}
+this.view=new Roo.View(this.list,this.tpl,{singleSelect:true,store:this.store,selectedClass:this.selectedClass});this.view.on('click',this.onViewClick,this);this.store.on('beforeload',this.onBeforeLoad,this);this.store.on('load',this.onLoad,this);this.store.on('loadexception',this.onLoadException,this);if(!this.editable){this.editable=true;this.setEditable(false);}
+this.keyNav=new Roo.KeyNav(this.inputEl(),{"up":function(e){this.inKeyMode=true;this.selectPrev();},"down":function(e){if(!this.isExpanded()){this.onTriggerClick();}else {this.inKeyMode=true;this.selectNext();}},"enter":function(e){this.collapse();if(this.fireEvent("specialkey",this,e)){this.onViewClick(false);}return true;},"esc":function(e){this.collapse();},"tab":function(e){this.collapse();if(this.fireEvent("specialkey",this,e)){this.onViewClick(false);}return true;},scope:this,doRelay:function(C,D,E){if(E=='down'||this.scope.isExpanded()){return Roo.KeyNav.prototype.doRelay.apply(this,arguments);}return true;},forceKeyDown:true});this.queryDelay=Math.max(this.queryDelay||10,this.mode=='local'?10:250);this.dqTask=new Roo.util.DelayedTask(this.initQuery,this);if(this.typeAhead){this.taTask=new Roo.util.DelayedTask(this.onTypeAhead,this);}if(this.editable!==false){this.inputEl().on("keyup",this.onKeyUp,this);}if(this.forceSelection){this.inputEl().on('blur',this.doForce,this);}if(this.multiple){this.choices=this.el.select('ul.select2-choices',true).first();this.searchField=this.el.select('ul li.select2-search-field',true).first();}},initTickableEvents:function(){this.createList();if(this.hiddenName){this.hiddenField=this.el.select('input.form-hidden-field',true).first();this.hiddenField.dom.value=this.hiddenValue!==undefined?this.hiddenValue:this.value!==undefined?this.value:'';this.el.dom.removeAttribute('name');this.hiddenField.dom.setAttribute('name',this.hiddenName);}
+this.choices=this.el.select('ul.select2-choices',true).first();this.searchField=this.el.select('ul li.select2-search-field',true).first();if(this.triggerList){this.searchField.on("click",this.onSearchFieldClick,this,{preventDefault:true});}
+this.trigger=this.el.select('.tickable-buttons > .btn-edit',true).first();this.trigger.on("click",this.onTickableTriggerClick,this,{preventDefault:true});this.okBtn=this.el.select('.tickable-buttons > .btn-ok',true).first();this.cancelBtn=this.el.select('.tickable-buttons > .btn-cancel',true).first();this.okBtn.on('click',this.onTickableFooterButtonClick,this,this.okBtn);this.cancelBtn.on('click',this.onTickableFooterButtonClick,this,this.cancelBtn);this.trigger.setVisibilityMode(Roo.Element.DISPLAY);this.okBtn.setVisibilityMode(Roo.Element.DISPLAY);this.cancelBtn.setVisibilityMode(Roo.Element.DISPLAY);this.okBtn.hide();this.cancelBtn.hide();var A=this;(function(){var lw=A.listWidth||Math.max(A.inputEl().getWidth(),A.minListWidth);A.list.setWidth(lw);}).defer(100);this.list.on('mouseover',this.onViewOver,this);this.list.on('mousemove',this.onViewMove,this);this.list.on('scroll',this.onViewScroll,this);if(!this.tpl){this.tpl='<li class="select2-result"><div class="checkbox"><input id="{roo-id}" type="checkbox" {roo-data-checked}><label for="{roo-id}"><b>{'+this.displayField+'}</b></label></li>';}
+this.view=new Roo.View(this.list,this.tpl,{singleSelect:true,tickable:true,parent:this,store:this.store,selectedClass:this.selectedClass});this.view.on('click',this.onViewClick,this);this.store.on('beforeload',this.onBeforeLoad,this);this.store.on('load',this.onLoad,this);this.store.on('loadexception',this.onLoadException,this);this.queryDelay=Math.max(this.queryDelay||10,this.mode=='local'?10:250);this.dqTask=new Roo.util.DelayedTask(this.initQuery,this);if(this.typeAhead){this.taTask=new Roo.util.DelayedTask(this.onTypeAhead,this);}},onDestroy:function(){if(this.view){this.view.setStore(null);this.view.el.removeAllListeners();this.view.el.remove();this.view.purgeListeners();}if(this.list){this.list.dom.innerHTML='';}if(this.store){this.store.un('beforeload',this.onBeforeLoad,this);this.store.un('load',this.onLoad,this);this.store.un('loadexception',this.onLoadException,this);}
+Roo.bootstrap.ComboBox.superclass.onDestroy.call(this);},fireKey:function(e){if(e.isNavKeyPress()&&!this.list.isVisible()){this.fireEvent("specialkey",this,e);}},onResize:function(w,h){},setEditable:function(A){if(A==this.editable){return;}
+this.editable=A;if(!A){this.inputEl().dom.setAttribute('readOnly',true);this.inputEl().on('mousedown',this.onTriggerClick,this);this.inputEl().addClass('x-combo-noedit');}else {this.inputEl().dom.setAttribute('readOnly',false);this.inputEl().un('mousedown',this.onTriggerClick,this);this.inputEl().removeClass('x-combo-noedit');}},onBeforeLoad:function(A,B){if(!this.hasFocus){return;}if(!B.add){this.list.dom.innerHTML='<li class="loading-indicator">'+(this.loadingText||'loading')+'</li>';}
+this.restrictHeight();this.selectedIndex=-1;},onLoad:function(){this.hasQuery=false;if(!this.hasFocus){return;}if(typeof(this.loading)!=='undefined'&&this.loading!==null){this.loading.hide();}if(this.store.getCount()>0){this.expand();if(this.lastQuery==this.allQuery){if(this.editable&&!this.tickable){this.inputEl().dom.select();}if(!this.selectByValue(this.value,true)&&this.autoFocus&&(typeof(this.store.lastOptions.add)=='undefined'||this.store.lastOptions.add!=true)){this.select(0,true);}}else {if(this.autoFocus){this.selectNext();}if(this.typeAhead&&this.lastKey!=Roo.EventObject.BACKSPACE&&this.lastKey!=Roo.EventObject.DELETE ){this.taTask.delay(this.typeAheadDelay);}}}else {this.onEmptyResults();}},onLoadException:function(){this.hasQuery=false;if(typeof(this.loading)!=='undefined'&&this.loading!==null){this.loading.hide();}
+this.collapse();Roo.log(this.store.reader.jsonData);if(this.store&&typeof(this.store.reader.jsonData.errorMsg)!='undefined'){}},onTypeAhead:function(){if(this.store.getCount()>0){var r=this.store.getAt(0);var A=r.data[this.displayField];var B=A.length;var C=this.getRawValue().length;if(C!=B){this.setRawValue(A);this.selectText(C,A.length);}}},onSelect:function(A,B){if(this.fireEvent('beforeselect',this,A,B)!==false){this.setFromData(B>-1?A.data:false);this.collapse();this.fireEvent('select',this,A,B);}},getValue:function(){if(this.multiple){return (this.hiddenField)?this.hiddenField.dom.value:this.value;}if(this.valueField){return typeof this.value!='undefined'?this.value:'';}else {return Roo.bootstrap.ComboBox.superclass.getValue.call(this);}},clearValue:function(){if(this.hiddenField){this.hiddenField.dom.value='';}
+this.value='';this.setRawValue('');this.lastSelectionText='';},setValue:function(v){if(this.multiple){this.syncValue();return;}var A=v;if(this.valueField){var r=this.findRecord(this.valueField,v);if(r){A=r.data[this.displayField];}else if(this.valueNotFoundText!==undefined){A=this.valueNotFoundText;}}
+this.lastSelectionText=A;if(this.hiddenField){this.hiddenField.dom.value=v;}
+Roo.bootstrap.ComboBox.superclass.setValue.call(this,A);this.value=v;},lastData:false,setFromData:function(o){if(this.multiple){this.addItem(o);return;}var dv='';var vv='';this.lastData=o;if(this.displayField){dv=!o||typeof(o[this.displayField])=='undefined'?'':o[this.displayField];}else {Roo.log('no  displayField value set for '+(this.name?this.name:this.id));}if(this.valueField){vv=!o||typeof(o[this.valueField])=='undefined'?dv:o[this.valueField];}if(this.hiddenField){this.hiddenField.dom.value=vv;this.lastSelectionText=dv;Roo.bootstrap.ComboBox.superclass.setValue.call(this,dv);this.value=vv;return;}
+this.lastSelectionText=dv;Roo.bootstrap.ComboBox.superclass.setValue.call(this,dv);this.value=vv;},reset:function(){this.setValue(this.originalValue);this.clearInvalid();this.lastData=false;if(this.view){this.view.clearSelections();}},findRecord:function(A,B){var C;if(this.store.getCount()>0){this.store.each(function(r){if(r.data[A]==B){C=r;return false;}return true;});}return C;},getName:function(){if(!this.rendered){return ''};return !this.hiddenName&&this.inputEl().dom.name?this.inputEl().dom.name:(this.hiddenName||'');},onViewMove:function(e,t){this.inKeyMode=false;},onViewOver:function(e,t){if(this.inKeyMode){return;}var A=this.view.findItemFromChild(t);if(A){var B=this.view.indexOf(A);this.select(B,false);}},onViewClick:function(A,B,el,e){var C=this.view.getSelectedIndexes()[0];var r=this.store.getAt(C);if(this.tickable){if(e.getTarget().nodeName.toLowerCase()!='input'){return;}var rm=false;var D=this;Roo.each(this.tickItems,function(v,k){if(typeof(v)!='undefined'&&v[D.valueField]==r.data[D.valueField]){D.tickItems.splice(k,1);rm=true;return;}});if(rm){return;}
+this.tickItems.push(r.data);return;}if(r){this.onSelect(r,C);}if(B!==false&&!this.blockFocus){this.inputEl().focus();}},restrictHeight:function(){this.list.alignTo(this.inputEl(),this.listAlign);this.list.alignTo(this.inputEl(),this.listAlign);},onEmptyResults:function(){this.collapse();},isExpanded:function(){return this.list.isVisible();},selectByValue:function(v,A){if(v!==undefined&&v!==null){var r=this.findRecord(this.valueField||this.displayField,v);if(r){this.select(this.store.indexOf(r),A);return true;}}return false;},select:function(A,B){this.selectedIndex=A;this.view.select(A);if(B!==false){var el=this.view.getNode(A);if(el&&!this.multiple&&!this.tickable){this.list.scrollChildIntoView(el,false);}}},selectNext:function(){var ct=this.store.getCount();if(ct>0){if(this.selectedIndex==-1){this.select(0);}else if(this.selectedIndex<ct-1){this.select(this.selectedIndex+1);}}},selectPrev:function(){var ct=this.store.getCount();if(ct>0){if(this.selectedIndex==-1){this.select(0);}else if(this.selectedIndex!=0){this.select(this.selectedIndex-1);}}},onKeyUp:function(e){if(this.editable!==false&&!e.isSpecialKey()){this.lastKey=e.getKey();this.dqTask.delay(this.queryDelay);}},validateBlur:function(){return !this.list||!this.list.isVisible();},initQuery:function(){this.doQuery(this.getRawValue());},doForce:function(){if(this.inputEl().dom.value.length>0){this.inputEl().dom.value=this.lastSelectionText===undefined?'':this.lastSelectionText;}},doQuery:function(q,A){if(q===undefined||q===null){q='';}var qe={query:q,forceAll:A,combo:this,cancel:false};if(this.fireEvent('beforequery',qe)===false||qe.cancel){return false;}
+q=qe.query;A=qe.forceAll;if(A===true||(q.length>=this.minChars)){this.hasQuery=true;if(this.lastQuery!=q||this.alwaysQuery){this.lastQuery=q;if(this.mode=='local'){this.selectedIndex=-1;if(A){this.store.clearFilter();}else {this.store.filter(this.displayField,q);}
+this.onLoad();}else {this.store.baseParams[this.queryParam]=q;var B={params:this.getParams(q)};if(this.loadNext){B.add=true;B.params.start=this.page*this.pageSize;}
+this.store.load(B);}}else {this.selectedIndex=-1;this.onLoad();}}
+this.loadNext=false;},getParams:function(q){var p={};if(this.pageSize){p.start=0;p.limit=this.pageSize;}return p;},collapse:function(){if(!this.isExpanded()){return;}
+this.list.hide();if(this.tickable){this.hasFocus=false;this.okBtn.hide();this.cancelBtn.hide();this.trigger.show();}
+Roo.get(document).un('mousedown',this.collapseIf,this);Roo.get(document).un('mousewheel',this.collapseIf,this);if(!this.editable){Roo.get(document).un('keydown',this.listKeyPress,this);}
+this.fireEvent('collapse',this);},collapseIf:function(e){var A=e.within(this.el);var B=e.within(this.list);var C=(Roo.get(e.getTarget()).id==this.list.id)?true:false;if(A||B||C){return;}if(this.tickable){this.onTickableFooterButtonClick(e,false,false);}
+this.collapse();},expand:function(){if(this.isExpanded()||!this.hasFocus){return;}var lw=this.listWidth||Math.max(this.inputEl().getWidth(),this.minListWidth);this.list.setWidth(lw);Roo.log('expand');this.list.show();this.restrictHeight();if(this.tickable){this.tickItems=Roo.apply([],this.item);this.okBtn.show();this.cancelBtn.show();this.trigger.hide();}
+Roo.get(document).on('mousedown',this.collapseIf,this);Roo.get(document).on('mousewheel',this.collapseIf,this);if(!this.editable){Roo.get(document).on('keydown',this.listKeyPress,this);}
+this.fireEvent('expand',this);},onTriggerClick:function(e){Roo.log('trigger click');if(this.disabled||!this.triggerList){return;}
+this.page=0;this.loadNext=false;if(this.isExpanded()){this.collapse();if(!this.blockFocus){this.inputEl().focus();}}else {this.hasFocus=true;if(this.triggerAction=='all'){this.doQuery(this.allQuery,true);}else {this.doQuery(this.getRawValue());}if(!this.blockFocus){this.inputEl().focus();}}},onTickableTriggerClick:function(e){if(this.disabled){return;}
+this.page=0;this.loadNext=false;this.hasFocus=true;if(this.triggerAction=='all'){this.doQuery(this.allQuery,true);}else {this.doQuery(this.getRawValue());}},onSearchFieldClick:function(e){if(this.hasFocus&&!this.disabled&&e.getTarget().nodeName.toLowerCase()!='button'){this.onTickableFooterButtonClick(e,false,false);return;}if(this.hasFocus||this.disabled||e.getTarget().nodeName.toLowerCase()=='button'){return;}
+this.page=0;this.loadNext=false;this.hasFocus=true;if(this.triggerAction=='all'){this.doQuery(this.allQuery,true);}else {this.doQuery(this.getRawValue());}},listKeyPress:function(e){if(e.isSpecialKey()){return false;}var k=String.fromCharCode(e.getKey()).toUpperCase();var A=false;var B=this.view.getSelectedNodes();var C=false;if(B.length){var ix=this.view.indexOf(B[0]);C=this.store.getAt(ix);if(!C.get(this.displayField)||C.get(this.displayField).substring(0,1).toUpperCase()!=k){C=false;}}
+this.store.each(function(v){if(C){if(C.id==v.id){C=false;}return true;}if(v.get(this.displayField)&&v.get(this.displayField).substring(0,1).toUpperCase()==k){A=this.store.indexOf(v);return false;}return true;},this);if(A===false){return true;}
+this.view.select(A);var sn=Roo.get(this.view.getSelectedNodes()[0])
+sn.scrollIntoView(sn.dom.parentNode,false);},onViewScroll:function(e,t){if(this.view.el.getScroll().top==0||this.view.el.getScroll().top<this.view.el.dom.scrollHeight-this.view.el.dom.clientHeight||!this.hasFocus||!this.append||this.hasQuery){return;}
+this.hasQuery=true;this.loading=this.list.select('.loading',true).first();if(this.loading===null){this.list.createChild({tag:'div',cls:'loading select2-more-results select2-active',html:'Loading more results...'})
+this.loading=this.list.select('.loading',true).first();this.loading.setVisibilityMode(Roo.Element.DISPLAY);this.loading.hide();}
+this.loading.show();var A=this;this.page++;this.loadNext=true;(function(){A.doQuery(A.allQuery,true);}).defer(500);return;},addItem:function(o){var dv='';if(this.displayField){dv=!o||typeof(o[this.displayField])=='undefined'?'':o[this.displayField];}else {Roo.log('no  displayField value set for '+(this.name?this.name:this.id));}if(!dv.length){return;}var A=this.choices.createChild({tag:'li',cls:'select2-search-choice',cn:[{tag:'div',html:dv},{tag:'a',href:'#',cls:'select2-search-choice-close',tabindex:'-1'}]},this.searchField);var B=A.select('a.select2-search-choice-close',true).first()
+B.on('click',this.onRemoveItem,this,{item:A,data:o});this.item.push(o);this.lastData=o;this.syncValue();this.inputEl().dom.value='';},onRemoveItem:function(e,A,o){e.preventDefault();var B=this.item.indexOf(o.data)*1;if(B<0){Roo.log('not this item?!');return;}
+this.item.splice(B,1);o.item.remove();this.syncValue();this.fireEvent('remove',this,e);},syncValue:function(){if(!this.item.length){this.clearValue();return;}var A=[];var B=this;Roo.each(this.item,function(i){if(B.valueField){A.push(i[B.valueField]);return;}
+A.push(i);});this.value=A.join(',');if(this.hiddenField){this.hiddenField.dom.value=this.value;}},clearItem:function(){if(!this.multiple){return;}
+this.item=[];Roo.each(this.choices.select('>li.select2-search-choice',true).elements,function(c){c.remove();});this.syncValue();},inputEl:function(){if(this.tickable){return this.searchField;}return this.el.select('input.form-control',true).first();},onTickableFooterButtonClick:function(e,A,el){e.preventDefault();if(A&&A.name=='cancel'){this.tickItems=Roo.apply([],this.item);this.collapse();return;}
+this.clearItem();var B=this;Roo.each(this.tickItems,function(o){B.addItem(o);});this.collapse();},validate:function(){var v=this.getRawValue();if(this.multiple){v=this.getValue();}if(this.disabled||this.validateValue(v)){this.clearInvalid();return true;}return false;}});
+//Roo/View.js
+Roo.View=function(A,B,C){this.parent=false;if(typeof(B)=='undefined'){Roo.apply(this,A);this.el=Roo.get(this.el);}else {this.el=Roo.get(A);this.tpl=B;Roo.apply(this,C);}
+this.wrapEl=this.el.wrap().wrap();if(typeof(this.tpl)=="string"){this.tpl=new Roo.Template(this.tpl);}else {this.tpl=new Roo.factory(this.tpl,Roo);}
+this.tpl.compile();this.addEvents({"beforeclick":true,"click":true,"dblclick":true,"contextmenu":true,"selectionchange":true,"beforeselect":true,"preparedata":true});this.el.on({"click":this.onClick,"dblclick":this.onDblClick,"contextmenu":this.onContextMenu,scope:this});this.selections=[];this.nodes=[];this.cmp=new Roo.CompositeElementLite([]);if(this.store){this.store=Roo.factory(this.store,Roo.data);this.setStore(this.store,true);}if(this.footer&&this.footer.xtype){var D=this.wrapEl.appendChild(document.createElement("div"));this.footer.dataSource=this.store
+this.footer.container=D;this.footer=Roo.factory(this.footer,Roo);D.insertFirst(this.el);}
+Roo.View.superclass.constructor.call(this);};Roo.extend(Roo.View,Roo.util.Observable,{store:false,el:'',tpl:false,dataName:false,selectedClass:"x-view-selected",emptyText:"",mask:false,multiSelect:false,singleSelect:false,toggleSelect:false,tickable:false,getEl:function(){return this.wrapEl;},refresh:function(){var t=this.tpl;this.clearSelections();this.el.update("");var A=[];var B=this.store.getRange();if(B.length<1){this.el.update(this.emptyText);return;}var el=this.el;if(this.dataName){this.el.update(t.apply(this.store.meta));el=this.el.child('.roo-tpl-'+this.dataName);}for(var i=0,C=B.length;i<C;i++){var D=this.prepareData(B[i].data,i,B[i]);this.fireEvent("preparedata",this,D,i,B[i]);var d=Roo.apply({},D);if(this.tickable){Roo.apply(d,{'roo-id':Roo.id()});var E=this;Roo.each(this.parent.item,function(F){if(F[E.parent.valueField]!=D[E.parent.valueField]){return;}
+Roo.apply(d,{'roo-data-checked':'checked'});});}
+A[A.length]=Roo.util.Format.trim(this.dataName?t.applySubtemplate(this.dataName,d,this.store.meta):t.apply(d));}
+el.update(A.join(""));this.nodes=el.dom.childNodes;this.updateIndexes(0);},prepareData:function(A,B,C){this.fireEvent("preparedata",this,A,B,C);return A;},onUpdate:function(ds,A){this.clearSelections();var B=this.store.indexOf(A);var n=this.nodes[B];this.tpl.insertBefore(n,this.prepareData(A.data,B,A));n.parentNode.removeChild(n);this.updateIndexes(B,B);},onAdd:function(ds,A,B){this.clearSelections();if(this.nodes.length==0){this.refresh();return;}var n=this.nodes[B];for(var i=0,C=A.length;i<C;i++){var d=this.prepareData(A[i].data,i,A[i]);if(n){this.tpl.insertBefore(n,d);}else {this.tpl.append(this.el,d);}}
+this.updateIndexes(B);},onRemove:function(ds,A,B){this.clearSelections();var el=this.dataName?this.el.child('.roo-tpl-'+this.dataName):this.el;el.dom.removeChild(this.nodes[B]);this.updateIndexes(B);},refreshNode:function(A){this.onUpdate(this.store,this.store.getAt(A));},updateIndexes:function(A,B){var ns=this.nodes;A=A||0;B=B||ns.length-1;for(var i=A;i<=B;i++){ns[i].nodeIndex=i;}},setStore:function(A,B){if(!B&&this.store){this.store.un("datachanged",this.refresh);this.store.un("add",this.onAdd);this.store.un("remove",this.onRemove);this.store.un("update",this.onUpdate);this.store.un("clear",this.refresh);this.store.un("beforeload",this.onBeforeLoad);this.store.un("load",this.onLoad);this.store.un("loadexception",this.onLoad);}if(A){A.on("datachanged",this.refresh,this);A.on("add",this.onAdd,this);A.on("remove",this.onRemove,this);A.on("update",this.onUpdate,this);A.on("clear",this.refresh,this);A.on("beforeload",this.onBeforeLoad,this);A.on("load",this.onLoad,this);A.on("loadexception",this.onLoad,this);}if(A){this.refresh();}},onBeforeLoad:function(A,B){if(!B.add){this.el.update("");}
+this.el.mask(this.mask?this.mask:"Loading");},onLoad:function(){this.el.unmask();},findItemFromChild:function(A){var el=this.dataName?this.el.child('.roo-tpl-'+this.dataName,true):this.el.dom;if(!A||A.parentNode==el){return A;}var p=A.parentNode;while(p&&p!=el){if(p.parentNode==el){return p;}
+p=p.parentNode;}return null;},onClick:function(e){var A=this.findItemFromChild(e.getTarget());if(A){var B=this.indexOf(A);if(this.onItemClick(A,B,e)!==false){this.fireEvent("click",this,B,A,e);}}else {this.clearSelections();}},onContextMenu:function(e){var A=this.findItemFromChild(e.getTarget());if(A){this.fireEvent("contextmenu",this,this.indexOf(A),A,e);}},onDblClick:function(e){var A=this.findItemFromChild(e.getTarget());if(A){this.fireEvent("dblclick",this,this.indexOf(A),A,e);}},onItemClick:function(A,B,e){if(this.fireEvent("beforeclick",this,B,A,e)===false){return false;}if(this.toggleSelect){var m=this.isSelected(A)?'unselect':'select';var _t=this;_t[m](A,true,false);return true;}if(this.multiSelect||this.singleSelect){if(this.multiSelect&&e.shiftKey&&this.lastSelection){this.select(this.getNodes(this.indexOf(this.lastSelection),B),false);}else {this.select(A,this.multiSelect&&e.ctrlKey);this.lastSelection=A;}if(!this.tickable){e.preventDefault();}}return true;},getSelectionCount:function(){return this.selections.length;},getSelectedNodes:function(){return this.selections;},getSelectedIndexes:function(){var A=[],s=this.selections;for(var i=0,B=s.length;i<B;i++){A.push(s[i].nodeIndex);}return A;},clearSelections:function(A){if(this.nodes&&(this.multiSelect||this.singleSelect)&&this.selections.length>0){this.cmp.elements=this.selections;this.cmp.removeClass(this.selectedClass);this.selections=[];if(!A){this.fireEvent("selectionchange",this,this.selections);}}},isSelected:function(A){var s=this.selections;if(s.length<1){return false;}
+A=this.getNode(A);return s.indexOf(A)!==-1;},select:function(A,B,C){if(A instanceof Array){if(!B){this.clearSelections(true);}for(var i=0,D=A.length;i<D;i++){this.select(A[i],true,true);}return;}var E=this.getNode(A);if(!E||this.isSelected(E)){return;}if(!B){this.clearSelections(true);}if(this.fireEvent("beforeselect",this,E,this.selections)!==false){Roo.fly(E).addClass(this.selectedClass);this.selections.push(E);if(!C){this.fireEvent("selectionchange",this,this.selections);}}},unselect:function(A,B,C){if(A instanceof Array){Roo.each(this.selections,function(s){this.unselect(s,A);},this);return;}var D=this.getNode(A);if(!D||!this.isSelected(D)){return;}var ns=[];Roo.each(this.selections,function(s){if(s==D){Roo.fly(D).removeClass(this.selectedClass);return;}
+ns.push(s);},this);this.selections=ns;this.fireEvent("selectionchange",this,this.selections);},getNode:function(A){if(typeof A=="string"){return document.getElementById(A);}else if(typeof A=="number"){return this.nodes[A];}return A;},getNodes:function(A,B){var ns=this.nodes;A=A||0;B=typeof B=="undefined"?ns.length-1:B;var C=[];if(A<=B){for(var i=A;i<=B;i++){C.push(ns[i]);}}else {for(var i=A;i>=B;i--){C.push(ns[i]);}}return C;},indexOf:function(A){A=this.getNode(A);if(typeof A.nodeIndex=="number"){return A.nodeIndex;}var ns=this.nodes;for(var i=0,B=ns.length;i<B;i++){if(ns[i]==A){return i;}}return -1;}});
+//Roo/bootstrap/Calendar.js
+Roo.bootstrap=Roo.bootstrap||{};Roo.bootstrap.Calendar=function(A){Roo.bootstrap.Calendar.superclass.constructor.call(this,A);this.addEvents({'select':true,'monthchange':true,'evententer':true,'eventleave':true,'eventclick':true});};Roo.extend(Roo.bootstrap.Calendar,Roo.bootstrap.Component,{startDay:0,loadMask:false,header:false,getAutoCreate:function(){var A=function(H,I,J,K){return Roo.apply({},{tag:'span',cls:'fc-button fc-button-'+H+' fc-state-default '+(I.length?'fc-corner-'+I.split(' ').join(' fc-corner-'):''),html:'<SPAN class="fc-text-'+J+'">'+K+'</SPAN>',unselectable:'on'});};var B={};if(!this.header){B={tag:'table',cls:'fc-header',style:'width:100%',cn:[{tag:'tr',cn:[{tag:'td',cls:'fc-header-left',cn:[A('prev','left','arrow','&#8249;'),A('next','right','arrow','&#8250;'),{tag:'span',cls:'fc-header-space'},A('today','left right','','today')]},{tag:'td',cls:'fc-header-center',cn:[{tag:'span',cls:'fc-header-title',cn:{tag:'H2',html:'month / year'}}]},{tag:'td',cls:'fc-header-right',cn:[]}]}]};}
+B=this.header;var C=function(){var H=[];for(var i=0;i<Date.dayNames.length;i++){var d=Date.dayNames[i];H.push({tag:'th',cls:'fc-day-header fc-'+d.substring(0,3).toLowerCase()+' fc-widget-header',html:d.substring(0,3)});}
+H[0].cls+=' fc-first';H[6].cls+=' fc-last';return H;};var D=function(n){return {tag:'td',cls:'fc-day fc-'+n+' fc-widget-content',cn:[{cn:[{cls:'fc-day-number',html:'D'},{cls:'fc-day-content',cn:[{style:'position: relative;'}]}]}]}};var E=function(){var H=[];for(var r=0;r<6;r++){var I={tag:'tr',cls:'fc-week',cn:[]};for(var i=0;i<Date.dayNames.length;i++){var d=Date.dayNames[i];I.cn.push(D(d.substring(0,3).toLowerCase()));}
+I.cn[0].cls+=' fc-first';I.cn[0].cn[0].style='min-height:90px';I.cn[6].cls+=' fc-last';H.push(I);}
+H[0].cls+=' fc-first';H[4].cls+=' fc-prev-last';H[5].cls+=' fc-last';return H;};var F={tag:'table',cls:'fc-border-separate',style:'width:100%',cellspacing:0,cn:[{tag:'thead',cn:[{tag:'tr',cls:'fc-first fc-last',cn:C()}]},{tag:'tbody',cn:E()}]};var G={cls:'fc fc-ltr',cn:[B,{cls:'fc-content',style:"position: relative;",cn:[{cls:'fc-view fc-view-month fc-grid',style:'position: relative',unselectable:'on',cn:[{cls:'fc-event-container',style:'position:absolute;z-index:8;top:0;left:0;'},F]}]}]};return G;},initEvents:function(){if(!this.store){throw "can not find store for calendar";}var A={tag:"div",cls:"x-dlg-mask",style:"text-align:center",cn:[{tag:"div",style:"background-color:white;width:50%;margin:250 auto",cn:[{tag:"img",src:Roo.rootURL+'/images/ux/lightbox/loading.gif'},{tag:"span",html:"Loading"}]}]}
+this.maskEl=Roo.DomHelper.append(this.el.select('.fc-content',true).first(),A,true);var B=this.el.select('.fc-content',true).first().getSize();this.maskEl.setSize(B.width,B.height);this.maskEl.enableDisplayMode("block");if(!this.loadMask){this.maskEl.hide();}
+this.store=Roo.factory(this.store,Roo.data);this.store.on('load',this.onLoad,this);this.store.on('beforeload',this.onBeforeLoad,this);this.resize();this.cells=this.el.select('.fc-day',true);this.textNodes=this.el.query('.fc-day-number');this.cells.addClassOnOver('fc-state-hover');this.el.select('.fc-button-prev',true).on('click',this.showPrevMonth,this);this.el.select('.fc-button-next',true).on('click',this.showNextMonth,this);this.el.select('.fc-button-today',true).on('click',this.showToday,this);this.el.select('.fc-button',true).addClassOnOver('fc-state-hover');this.on('monthchange',this.onMonthChange,this);this.update(new Date().clearTime());},resize:function(){var sz=this.el.getSize();this.el.select('.fc-day-header',true).setWidth(sz.width/7);this.el.select('.fc-day-content div',true).setHeight(34);},showPrevMonth:function(e){this.update(this.activeDate.add("mo",-1));},showToday:function(e){this.update(new Date().clearTime());},showNextMonth:function(e){this.update(this.activeDate.add("mo",1));},showPrevYear:function(){this.update(this.activeDate.add("y",-1));},showNextYear:function(){this.update(this.activeDate.add("y",1));},update:function(A){var vd=this.activeDate;this.activeDate=A;var B=A.getDaysInMonth();var C=A.getFirstDateOfMonth();var D=C.getDay()-this.startDay;if(D<this.startDay){D+=7;}var pm=A.add(Date.MONTH,-1);var E=pm.getDaysInMonth()-D;this.cells=this.el.select('.fc-day',true);this.textNodes=this.el.query('.fc-day-number');this.cells.addClassOnOver('fc-state-hover');var F=this.cells.elements;var G=this.textNodes;Roo.each(F,function(V){V.removeClass(['fc-past','fc-other-month','fc-future','fc-state-highlight','fc-state-disabled']);});B+=D;var H=86400000;var d=(new Date(pm.getFullYear(),pm.getMonth(),E)).clearTime();var I=new Date().clearTime().getTime();var J=A.clearTime().getTime();var K=this.minDate?this.minDate.clearTime():Number.NEGATIVE_INFINITY;var L=this.maxDate?this.maxDate.clearTime():Number.POSITIVE_INFINITY;var M=this.disabledDatesRE;var N=this.disabledDatesText;var O=this.disabledDays?this.disabledDays.join(""):false;var P=this.disabledDaysText;var Q=this.format;var R=function(V,W){W.row=0;W.events=[];W.more=[];W.title="";var t=d.getTime();W.dateValue=t;if(t==I){W.className+=" fc-today";W.className+=" fc-state-highlight";W.title=V.todayText;}if(t==J){}if(t<K){W.className=" fc-state-disabled";W.title=V.minText;return;}if(t>L){W.className=" fc-state-disabled";W.title=V.maxText;return;}if(O){if(O.indexOf(d.getDay())!=-1){W.title=P;W.className=" fc-state-disabled";}}if(M&&Q){var X=d.dateFormat(Q);if(M.test(X)){W.title=N.replace("%0",X);W.className=" fc-state-disabled";}}if(!W.initialClassName){W.initialClassName=W.dom.className;}
+W.dom.className=W.initialClassName+' '+W.className;};var i=0;for(;i<D;i++){G[i].innerHTML=(++E);d.setDate(d.getDate()+1);F[i].className="fc-past fc-other-month";R(this,F[i]);}var S=0;for(;i<B;i++){S=i-D+1;G[i].innerHTML=(S);d.setDate(d.getDate()+1);F[i].className='';R(this,F[i]);}var T=0;for(;i<42;i++){G[i].innerHTML=(++T);d.setDate(d.getDate()+1);F[i].className="fc-future fc-other-month";R(this,F[i]);}
+this.el.select('.fc-header-title h2',true).update(Date.monthNames[A.getMonth()]+" "+A.getFullYear());var U=Math.ceil((A.getDaysInMonth()+A.getFirstDateOfMonth().getDay())/7);this.el.select('tr.fc-week.fc-prev-last',true).removeClass('fc-last');this.el.select('tr.fc-week.fc-next-last',true).addClass('fc-last').show();if(U!=6){this.el.select('tr.fc-week.fc-last',true).removeClass('fc-last').addClass('fc-next-last').hide();this.el.select('tr.fc-week.fc-prev-last',true).addClass('fc-last');}
+this.fireEvent('monthchange',this,A);},findCell:function(dt){dt=dt.clearTime().getTime();var A=false;this.cells.each(function(c){if(c.dateValue==dt){A=c;return false;}return true;});return A;},findCells:function(ev){var s=ev.start.clone().clearTime().getTime();var e=ev.end.clone().clearTime().getTime();var A=[];this.cells.each(function(c){if(c.dateValue>e){return;}if(c.dateValue<s){return;}
+A.push(c);});return A;},addItem:function(ev){var A=this.findCells(ev);var B=false;var C=[];for(var i=0;i<A.length;i++){A[i].row=A[0].row;if(i==0){A[i].row=A[i].row+1;}if(!B){B={start:A[i],end:A[i]};continue;}if(B.start.getY()==A[i].getY()){B.end=A[i];continue;}
+C.push(B);B={start:A[i],end:A[i]};}
+C.push(B);ev.els=[];ev.rows=C;ev.cells=A;A[0].events.push(ev);this.calevents.push(ev);},clearEvents:function(){if(!this.calevents){return;}
+Roo.each(this.cells.elements,function(c){c.row=0;c.events=[];c.more=[];});Roo.each(this.calevents,function(e){Roo.each(e.els,function(el){el.un('mouseenter',this.onEventEnter,this);el.un('mouseleave',this.onEventLeave,this);el.remove();},this);},this);Roo.each(Roo.select('.fc-more-event',true).elements,function(e){e.remove();});},renderEvents:function(){var A=this;this.cells.each(function(c){if(c.row<5){return;}var ev=c.events;var r=4;if(c.row!=c.events.length){r=4-(4-(c.row-c.events.length));}
+c.events=ev.slice(0,r);c.more=ev.slice(r);if(c.more.length&&c.more.length==1){c.events.push(c.more.pop());}
+c.row=(c.row-ev.length)+c.events.length+((c.more.length)?1:0);});this.cells.each(function(c){c.select('.fc-day-content div',true).first().setHeight(Math.max(34,c.row*20));for(var e=0;e<c.events.length;e++){var ev=c.events[e];var B=ev.rows;for(var i=0;i<B.length;i++){var C={cls:'roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable',style:'position: absolute',unselectable:"on",cn:[{cls:'fc-event-inner',cn:[{tag:'span',cls:'fc-event-title',html:String.format('{0}',ev.title)}]},{cls:'ui-resizable-handle ui-resizable-e',html:'&nbsp;&nbsp;&nbsp'}]};if(i==0){C.cls+=' fc-event-start';}if((i+1)==B.length){C.cls+=' fc-event-end';}var D=A.el.select('.fc-event-container',true).first();var cg=D.createChild(C);var E=B[i].start.select('.fc-day-content',true).first().getBox();var F=B[i].end.select('.fc-day-content',true).first().getBox();var r=(c.more.length)?1:0;cg.setXY([E.x+2,E.y+((c.row-c.events.length-r+e)*20)]);cg.setWidth(F.right-E.x-2);cg.on('mouseenter',A.onEventEnter,A,ev);cg.on('mouseleave',A.onEventLeave,A,ev);cg.on('click',A.onEventClick,A,ev);ev.els.push(cg);}}if(c.more.length){var C={cls:'fc-more-event roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable fc-event-start fc-event-end',style:'position: absolute',unselectable:"on",cn:[{cls:'fc-event-inner',cn:[{tag:'span',cls:'fc-event-title',html:'More'}]},{cls:'ui-resizable-handle ui-resizable-e',html:'&nbsp;&nbsp;&nbsp'}]};var D=A.el.select('.fc-event-container',true).first();var cg=D.createChild(C);var E=c.select('.fc-day-content',true).first().getBox();var F=c.select('.fc-day-content',true).first().getBox();cg.setXY([E.x+2,E.y+((c.row-1)*20)]);cg.setWidth(F.right-E.x-2);cg.on('click',A.onMoreEventClick,A,c.more);}});},onEventEnter:function(e,el,A,d){this.fireEvent('evententer',this,el,A);},onEventLeave:function(e,el,A,d){this.fireEvent('eventleave',this,el,A);},onEventClick:function(e,el,A,d){this.fireEvent('eventclick',this,el,A);},onMonthChange:function(){this.store.load();},onMoreEventClick:function(e,el,A){var B=this;this.calpopover.placement='right';this.calpopover.setTitle('More');this.calpopover.setContent('');var C=this.calpopover.el.select('.popover-content',true).first();Roo.each(A,function(m){var D={cls:'fc-event-hori fc-event-draggable',html:m.title};var cg=C.createChild(D);cg.on('click',B.onEventClick,B,m);});this.calpopover.show(el);},onLoad:function(){this.calevents=[];var A=this;if(this.store.getCount()>0){this.store.data.each(function(d){A.addItem({id:d.data.id,start:(typeof(d.data.start_dt)==='string')?new Date.parseDate(d.data.start_dt,'Y-m-d H:i:s'):d.data.start_dt,end:(typeof(d.data.end_dt)==='string')?new Date.parseDate(d.data.end_dt,'Y-m-d H:i:s'):d.data.end_dt,time:d.data.start_time,title:d.data.title,description:d.data.description,venue:d.data.venue});});}
+this.renderEvents();if(this.calevents.length&&this.loadMask){this.maskEl.hide();}},onBeforeLoad:function(){this.clearEvents();if(this.loadMask){this.maskEl.show();}}});
+//Roo/bootstrap/Popover.js
+Roo.bootstrap.Popover=function(A){Roo.bootstrap.Popover.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Popover,Roo.bootstrap.Component,{title:'Fill in a title',html:false,placement:'right',trigger:'hover',delay:0,over:'parent',can_build_overlaid:false,getChildContainer:function(){return this.el.select('.popover-content',true).first();},getAutoCreate:function(){Roo.log('make popover?');var A={cls:'popover roo-dynamic',style:'display:block',cn:[{cls:'arrow'},{cls:'popover-inner',cn:[{tag:'h3',cls:'popover-title',html:this.title},{cls:'popover-content',html:this.html}]}]};return A;},setTitle:function(A){this.el.select('.popover-title',true).first().dom.innerHTML=A;},setContent:function(A){this.el.select('.popover-content',true).first().dom.innerHTML=A;},onRender:function(ct,A){Roo.bootstrap.Component.superclass.onRender.call(this,ct,A);if(!this.el){var B=Roo.apply({},this.getAutoCreate());B.id=Roo.id();if(this.cls){B.cls+=' '+this.cls;}if(this.style){B.style=this.style;}
+Roo.log("adding to ")
+this.el=Roo.get(document.body).createChild(B,A);Roo.log(this.el);}
+this.initEvents();},initEvents:function(){this.el.select('.popover-title',true).setVisibilityMode(Roo.Element.DISPLAY);this.el.enableDisplayMode('block');this.el.hide();if(this.over===false){return;}if(this.triggers===false){return;}var A=(this.over=='parent')?this.parent().el:Roo.get(this.over);var B=this.trigger?this.trigger.split(' '):[];Roo.each(B,function(C){if(C=='click'){A.on('click',this.toggle,this);}else if(C!='manual'){var D=C=='hover'?'mouseenter':'focusin';var E=C=='hover'?'mouseleave':'focusout';A.on(D,this.enter,this);A.on(E,this.leave,this);}},this);},timeout:null,hoverState:null,toggle:function(){this.hoverState=='in'?this.leave():this.enter();},enter:function(){clearTimeout(this.timeout);this.hoverState='in';if(!this.delay||!this.delay.show){this.show();return;}var _t=this;this.timeout=setTimeout(function(){if(_t.hoverState=='in'){_t.show();}},this.delay.show)},leave:function(){clearTimeout(this.timeout);this.hoverState='out';if(!this.delay||!this.delay.hide){this.hide();return;}var _t=this;this.timeout=setTimeout(function(){if(_t.hoverState=='out'){_t.hide();}},this.delay.hide)},show:function(A){if(!A){A=(this.over=='parent')?this.parent().el:Roo.get(this.over);}
+this.el.select('.popover-title',true).first().dom.innerHtml=this.title;if(this.html!==false){this.el.select('.popover-content',true).first().dom.innerHtml=this.title;}
+this.el.removeClass(['fade','top','bottom','left','right','in']);if(!this.title.length){this.el.select('.popover-title',true).hide();}var B=typeof this.placement=='function'?this.placement.call(this,this.el,A):this.placement;var C=/\s?auto?\s?/i;var D=C.test(B);if(D){B=B.replace(C,'')||'top';}
+this.el.show();this.el.dom.style.display='block';this.el.addClass(B);var p=this.getPosition();var E=this.el.getBox();if(D){}var F=Roo.bootstrap.Popover.alignment[B];this.el.alignTo(A,F[0],F[1]);this.el.addClass('in');this.hoverState=null;if(this.el.hasClass('fade')){}},hide:function(){this.el.setXY([0,0]);this.el.removeClass('in');this.el.hide();}});Roo.bootstrap.Popover.alignment={'left':['r-l',[-10,0],'right'],'right':['l-r',[10,0],'left'],'bottom':['t-b',[0,10],'top'],'top':['b-t',[0,-10],'bottom']};
+//Roo/bootstrap/Progress.js
+Roo.bootstrap.Progress=function(A){Roo.bootstrap.Progress.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Progress,Roo.bootstrap.Component,{striped:false,active:false,getAutoCreate:function(){var A={tag:'div',cls:'progress'};if(this.striped){A.cls+=' progress-striped';}if(this.active){A.cls+=' active';}return A;}});
+//Roo/bootstrap/ProgressBar.js
+Roo.bootstrap.ProgressBar=function(A){Roo.bootstrap.ProgressBar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.ProgressBar,Roo.bootstrap.Component,{aria_valuenow:0,aria_valuemin:0,aria_valuemax:100,label:false,panel:false,role:false,sr_only:false,getAutoCreate:function(){var A={tag:'div',cls:'progress-bar',style:'width:'+Math.ceil((this.aria_valuenow/this.aria_valuemax)*100)+'%'};if(this.sr_only){A.cn={tag:'span',cls:'sr-only',html:this.sr_only}}if(this.role){A.role=this.role;}if(this.aria_valuenow){A['aria-valuenow']=this.aria_valuenow;}if(this.aria_valuemin){A['aria-valuemin']=this.aria_valuemin;}if(this.aria_valuemax){A['aria-valuemax']=this.aria_valuemax;}if(this.label&&!this.sr_only){A.html=this.label;}if(this.panel){A.cls+=' progress-bar-'+this.panel;}return A;},update:function(A){this.aria_valuenow=A;this.el.setStyle('width',Math.ceil((this.aria_valuenow/this.aria_valuemax)*100)+'%');}});
+//Roo/bootstrap/TabGroup.js
+Roo.bootstrap.TabGroup=function(A){Roo.bootstrap.TabGroup.superclass.constructor.call(this,A);if(!this.navId){this.navId=Roo.id();}
+this.tabs=[];Roo.bootstrap.TabGroup.register(this);};Roo.extend(Roo.bootstrap.TabGroup,Roo.bootstrap.Column,{carousel:false,transition:false,getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TabGroup.superclass.getAutoCreate.call(this));A.cls+=' tab-content';if(this.carousel){A.cls+=' carousel slide';A.cn=[{cls:'carousel-inner'}]}return A;},getChildContainer:function(){return this.carousel?this.el.select('.carousel-inner',true).first():this.el;},register:function(A){this.tabs.push(A);A.navId=this.navId;},getActivePanel:function(){var r=false;Roo.each(this.tabs,function(t){if(t.active){r=t;return false;}return null;});return r;},getPanelByName:function(n){var r=false;Roo.each(this.tabs,function(t){if(t.tabId==n){r=t;return false;}return null;});return r;},indexOfPanel:function(p){var r=false;Roo.each(this.tabs,function(t,i){if(t.tabId==p.tabId){r=i;return false;}return null;});return r;},showPanel:function(A){if(typeof(A)=='number'){A=this.tabs[A];}if(typeof(A)=='string'){A=this.getPanelByName(A);}if(A.tabId==this.getActivePanel().tabId){return true;}var B=this.getActivePanel();if(false===B.fireEvent('beforedeactivate')){return false;}if(this.carousel&&typeof(Roo.get(document.body).dom.style.transition)!='undefined'){this.transition=true;var C=this.indexOfPanel(A)>this.indexOfPanel(B)?'next':'prev';var lr=C=='next'?'left':'right';A.el.addClass(C);A.el.dom.offsetWidth;B.el.addClass(lr);A.el.addClass(lr);var D=this;B.el.on('transitionend',function(){Roo.log("trans end?");A.el.removeClass([lr,C]);A.setActive(true);B.el.removeClass([lr]);B.setActive(false);D.transition=false;},this,{single:true});return true;}
+B.setActive(false);A.setActive(true);return true;},showPanelNext:function(){var i=this.indexOfPanel(this.getActivePanel());if(i>this.tabs.length){return;}
+this.showPanel(this.tabs[i+1]);},showPanelPrev:function(){var i=this.indexOfPanel(this.getActivePanel());if(i<1){return;}
+this.showPanel(this.tabs[i-1]);}});Roo.apply(Roo.bootstrap.TabGroup,{groups:{},register:function(A){this.groups[A.navId]=A;},get:function(A){if(typeof(this.groups[A])=='undefined'){this.register(new Roo.bootstrap.TabGroup({navId:A}));}return this.groups[A];}});
+//Roo/bootstrap/TabPanel.js
+Roo.bootstrap.TabPanel=function(A){Roo.bootstrap.TabPanel.superclass.constructor.call(this,A);this.addEvents({'changed':true,'beforedeactivate':true});this.tabId=this.tabId||Roo.id();};Roo.extend(Roo.bootstrap.TabPanel,Roo.bootstrap.Component,{active:false,html:false,tabId:false,navId:false,getAutoCreate:function(){var A={tag:'div',cls:'tab-pane item',html:this.html||''};if(this.active){A.cls+=' active';}if(this.tabId){A.tabId=this.tabId;}return A;},initEvents:function(){Roo.log('-------- init events on tab panel ---------');var p=this.parent();this.navId=this.navId||p.navId;if(typeof(this.navId)!='undefined'){var tg=Roo.bootstrap.TabGroup.get(this.navId);Roo.log(['register',tg,this]);tg.register(this);}},onRender:function(ct,A){Roo.bootstrap.TabPanel.superclass.onRender.call(this,ct,A);},setActive:function(A){Roo.log("panel - set active "+this.tabId+"="+A);this.active=A;if(!A){this.el.removeClass('active');}else if(!this.el.hasClass('active')){this.el.addClass('active');}
+this.fireEvent('changed',this,A);}});
+//Roo/bootstrap/DateField.js
+Roo.bootstrap.DateField=function(A){Roo.bootstrap.DateField.superclass.constructor.call(this,A);this.addEvents({show:true,hide:true,select:true});};Roo.extend(Roo.bootstrap.DateField,Roo.bootstrap.Input,{format:"m/d/y",altFormats:"m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d",weekStart:0,viewMode:'',minViewMode:'',todayHighlight:false,todayBtn:false,language:'en',keyboardNavigation:true,calendarWeeks:false,startDate:-Infinity,endDate:Infinity,daysOfWeekDisabled:[],_events:[],singleMode:false,UTCDate:function(){return new Date(Date.UTC.apply(Date,arguments));},UTCToday:function(){var A=new Date();return this.UTCDate(A.getUTCFullYear(),A.getUTCMonth(),A.getUTCDate());},getDate:function(){var d=this.getUTCDate();return new Date(d.getTime()+(d.getTimezoneOffset()*60000));},getUTCDate:function(){return this.date;},setDate:function(d){this.setUTCDate(new Date(d.getTime()-(d.getTimezoneOffset()*60000)));},setUTCDate:function(d){this.date=d;this.setValue(this.formatDate(this.date));},onRender:function(ct,A){Roo.bootstrap.DateField.superclass.onRender.call(this,ct,A);this.language=this.language||'en';this.language=this.language in Roo.bootstrap.DateField.dates?this.language:this.language.split('-')[0];this.language=this.language in Roo.bootstrap.DateField.dates?this.language:"en";this.isRTL=Roo.bootstrap.DateField.dates[this.language].rtl||false;this.format=this.format||'m/d/y';this.isInline=false;this.isInput=true;this.component=this.el.select('.add-on',true).first()||false;this.component=(this.component&&this.component.length===0)?false:this.component;this.hasInput=this.component&&this.inputEL().length;if(typeof(this.minViewMode==='string')){switch(this.minViewMode){case 'months':this.minViewMode=1;break;case 'years':this.minViewMode=2;break;default:this.minViewMode=0;break;}}if(typeof(this.viewMode==='string')){switch(this.viewMode){case 'months':this.viewMode=1;break;case 'years':this.viewMode=2;break;default:this.viewMode=0;break;}}
+this.pickerEl=Roo.get(document.body).createChild(Roo.bootstrap.DateField.template);this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.picker().on('mousedown',this.onMousedown,this);this.picker().on('click',this.onClick,this);this.picker().addClass('datepicker-dropdown');this.startViewMode=this.viewMode;if(this.singleMode){Roo.each(this.picker().select('thead > tr > th',true).elements,function(v){v.setVisibilityMode(Roo.Element.DISPLAY)
+v.hide();});Roo.each(this.picker().select('tbody > tr > td',true).elements,function(v){v.setStyle('width','189px');});}
+Roo.each(this.picker().select('tfoot th.today',true).elements,function(v){if(!this.calendarWeeks){v.remove();return;}
+v.dom.innerHTML=Roo.bootstrap.DateField.dates[this.language].today;v.attr('colspan',function(i,B){return parseInt(B)+1;});})
+this.weekEnd=this.weekStart===0?6:this.weekStart-1;this.setStartDate(this.startDate);this.setEndDate(this.endDate);this.setDaysOfWeekDisabled(this.daysOfWeekDisabled);this.fillDow();this.fillMonths();this.update();this.showMode();if(this.isInline){this.show();}},picker:function(){return this.pickerEl;},fillDow:function(){var A=this.weekStart;var B={tag:'tr',cn:[]};if(this.calendarWeeks){B.cn.push({tag:'th',cls:'cw',html:'&nbsp;'})}while(A<this.weekStart+7){B.cn.push({tag:'th',cls:'dow',html:Roo.bootstrap.DateField.dates[this.language].daysMin[(A++)%7]});}
+this.picker().select('>.datepicker-days thead',true).first().createChild(B);},fillMonths:function(){var i=0;var A=this.picker().select('>.datepicker-months td',true).first();A.dom.innerHTML='';while(i<12){var B={tag:'span',cls:'month',html:Roo.bootstrap.DateField.dates[this.language].monthsShort[i++]}
+A.createChild(B);}},update:function(){this.date=(typeof(this.date)==='undefined'||((typeof(this.date)==='string')&&!this.date.length))?this.UTCToday():(typeof(this.date)==='string')?this.parseDate(this.date):this.date;if(this.date<this.startDate){this.viewDate=new Date(this.startDate);}else if(this.date>this.endDate){this.viewDate=new Date(this.endDate);}else {this.viewDate=new Date(this.date);}
+this.fill();},fill:function(){var d=new Date(this.viewDate),A=d.getUTCFullYear(),B=d.getUTCMonth(),C=this.startDate!==-Infinity?this.startDate.getUTCFullYear():-Infinity,D=this.startDate!==-Infinity?this.startDate.getUTCMonth():-Infinity,E=this.endDate!==Infinity?this.endDate.getUTCFullYear():Infinity,F=this.endDate!==Infinity?this.endDate.getUTCMonth():Infinity,G=this.date&&this.date.valueOf(),H=this.UTCToday();this.picker().select('>.datepicker-days thead th.switch',true).first().dom.innerHTML=Roo.bootstrap.DateField.dates[this.language].months[B]+' '+A;this.updateNavArrows();this.fillMonths();var I=this.UTCDate(A,B-1,28,0,0,0,0),J=I.getDaysInMonth(I.getUTCFullYear(),I.getUTCMonth());I.setUTCDate(J);I.setUTCDate(J-(I.getUTCDay()-this.weekStart+7)%7);var K=new Date(I);K.setUTCDate(K.getUTCDate()+42);K=K.valueOf();var L=false;this.picker().select('>.datepicker-days tbody',true).first().dom.innerHTML='';while(I.valueOf()<K){var M='';if(I.getUTCDay()===this.weekStart){if(L){this.picker().select('>.datepicker-days tbody',true).first().createChild(L);}
+L={tag:'tr',cn:[]};if(this.calendarWeeks){var ws=new Date(+I+(this.weekStart-I.getUTCDay()-7)%7*864e5),th=new Date(+ws+(7+4-ws.getUTCDay())%7*864e5),N=new Date(+(N=this.UTCDate(th.getUTCFullYear(),0,1))+(7+4-N.getUTCDay())%7*864e5),O=(th-N)/864e5/7+1;L.cn.push({tag:'td',cls:'cw',html:O});}}if(I.getUTCFullYear()<A||(I.getUTCFullYear()==A&&I.getUTCMonth()<B)){M+=' old';}else if(I.getUTCFullYear()>A||(I.getUTCFullYear()==A&&I.getUTCMonth()>B)){M+=' new';}if(this.todayHighlight&&I.getUTCFullYear()==H.getFullYear()&&I.getUTCMonth()==H.getMonth()&&I.getUTCDate()==H.getDate()){M+=' today';}if(G&&I.valueOf()===G){M+=' active';}if(I.valueOf()<this.startDate||I.valueOf()>this.endDate||this.daysOfWeekDisabled.indexOf(I.getUTCDay())!==-1){M+=' disabled';}
+L.cn.push({tag:'td',cls:'day '+M,html:I.getDate()})
+I.setDate(I.getDate()+1);}var P=this.date&&this.date.getUTCFullYear();var Q=this.date&&this.date.getUTCMonth();this.picker().select('>.datepicker-months th.switch',true).first().dom.innerHTML=A;Roo.each(this.picker().select('>.datepicker-months tbody span',true).elements,function(v,k){v.removeClass('active');if(P===A&&k===Q){v.addClass('active');}if(A<C||A>E||(A==C&&k<D)||(A==E&&k>F)){v.addClass('disabled');}});A=parseInt(A/10,10)*10;this.picker().select('>.datepicker-years th.switch',true).first().dom.innerHTML=A+'-'+(A+9);this.picker().select('>.datepicker-years tbody td',true).first().dom.innerHTML='';A-=1;for(var i=-1;i<11;i++){this.picker().select('>.datepicker-years tbody td',true).first().createChild({tag:'span',cls:'year'+(i===-1||i===10?' old':'')+(P===A?' active':'')+(A<C||A>E?' disabled':''),html:A})
+A+=1;}},showMode:function(A){if(A){this.viewMode=Math.max(this.minViewMode,Math.min(2,this.viewMode+A));}
+Roo.each(this.picker().select('>div',true).elements,function(v){v.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';v.hide();});this.picker().select('>.datepicker-'+Roo.bootstrap.DateField.modes[this.viewMode].clsName,true).first().show();},place:function(){if(this.isInline)return;this.picker().removeClass(['bottom','top']);if((Roo.lib.Dom.getViewHeight()+Roo.get(document.body).getScroll().top)-(this.inputEl().getBottom()+this.picker().getHeight())<0){this.picker().addClass('top');this.picker().setTop(this.inputEl().getTop()-this.picker().getHeight()).setLeft(this.inputEl().getLeft());return;}
+this.picker().addClass('bottom');this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());},parseDate:function(A){if(!A||A instanceof Date){return A;}var v=Date.parseDate(A,this.format);if(!v&&(this.useIso||A.match(/^(\d{4})-0?(\d+)-0?(\d+)/))){v=Date.parseDate(A,'Y-m-d');}if(!v&&this.altFormats){if(!this.altFormatsArray){this.altFormatsArray=this.altFormats.split("|");}for(var i=0,B=this.altFormatsArray.length;i<B&&!v;i++){v=Date.parseDate(A,this.altFormatsArray[i]);}}return v;},formatDate:function(A,B){return (!A||!(A instanceof Date))?A:A.dateFormat(B||this.format);},onFocus:function(){Roo.bootstrap.DateField.superclass.onFocus.call(this);this.show();},onBlur:function(){Roo.bootstrap.DateField.superclass.onBlur.call(this);var d=this.inputEl().getValue();this.setValue(d);this.hide();},show:function(){this.picker().show();this.update();this.place();this.fireEvent('show',this,this.date);},hide:function(){if(this.isInline)return;this.picker().hide();this.viewMode=this.startViewMode;this.showMode();this.fireEvent('hide',this,this.date);},onMousedown:function(e){e.stopPropagation();e.preventDefault();},keyup:function(e){Roo.bootstrap.DateField.superclass.keyup.call(this);this.update();},setValue:function(v){var d=new Date(this.parseDate(v)).clearTime();if(isNaN(d.getTime())){this.date=this.viewDate='';Roo.bootstrap.DateField.superclass.setValue.call(this,'');return;}
+v=this.formatDate(d);Roo.bootstrap.DateField.superclass.setValue.call(this,v);this.date=new Date(d.getTime()-d.getTimezoneOffset()*60000);this.update();this.fireEvent('select',this,this.date);},getValue:function(){return this.formatDate(this.date);},fireKey:function(e){if(!this.picker().isVisible()){if(e.keyCode==27)this.show();return;}var A=false,B,C,D,E,F;switch(e.keyCode){case 27:this.hide();e.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;B=e.keyCode==37?-1:1;if(e.ctrlKey){E=this.moveYear(this.date,B);F=this.moveYear(this.viewDate,B);}else if(e.shiftKey){E=this.moveMonth(this.date,B);F=this.moveMonth(this.viewDate,B);}else {E=new Date(this.date);E.setUTCDate(this.date.getUTCDate()+B);F=new Date(this.viewDate);F.setUTCDate(this.viewDate.getUTCDate()+B);}if(this.dateWithinRange(E)){this.date=E;this.viewDate=F;this.setValue(this.formatDate(this.date));e.preventDefault();A=true;}break;case 38:case 40:if(!this.keyboardNavigation)break;B=e.keyCode==38?-1:1;if(e.ctrlKey){E=this.moveYear(this.date,B);F=this.moveYear(this.viewDate,B);}else if(e.shiftKey){E=this.moveMonth(this.date,B);F=this.moveMonth(this.viewDate,B);}else {E=new Date(this.date);E.setUTCDate(this.date.getUTCDate()+B*7);F=new Date(this.viewDate);F.setUTCDate(this.viewDate.getUTCDate()+B*7);}if(this.dateWithinRange(E)){this.date=E;this.viewDate=F;this.setValue(this.formatDate(this.date));e.preventDefault();A=true;}break;case 13:this.setValue(this.formatDate(this.date));this.hide();e.preventDefault();break;case 9:this.setValue(this.formatDate(this.date));this.hide();break;case 16:case 17:case 18:break;default:this.hide();}},onClick:function(e){e.stopPropagation();e.preventDefault();var A=e.getTarget();if(A.nodeName.toLowerCase()==='i'){A=Roo.get(A).dom.parentNode;}var B=A.nodeName;var C=A.className;var D=A.innerHTML;switch(B.toLowerCase()){case 'th':switch(C){case 'switch':this.showMode(1);break;case 'prev':case 'next':var E=Roo.bootstrap.DateField.modes[this.viewMode].navStep*(C=='prev'?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,E);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,E);break;}
+this.fill();break;case 'today':var F=new Date();this.date=this.UTCDate(F.getFullYear(),F.getMonth(),F.getDate(),0,0,0);this.setValue(this.formatDate(this.date));this.hide();break;}break;case 'span':if(C.indexOf('disabled')<0){this.viewDate.setUTCDate(1);if(C.indexOf('month')>-1){this.viewDate.setUTCMonth(Roo.bootstrap.DateField.dates[this.language].monthsShort.indexOf(D));}else {var G=parseInt(D,10)||0;this.viewDate.setUTCFullYear(G);}if(this.singleMode){this.setValue(this.formatDate(this.viewDate));this.hide();return;}
+this.showMode(-1);this.fill();}break;case 'td':if(C.indexOf('day')>-1&&C.indexOf('disabled')<0){var H=parseInt(D,10)||1;var G=this.viewDate.getUTCFullYear(),I=this.viewDate.getUTCMonth();if(C.indexOf('old')>-1){if(I===0){I=11;G-=1;}else {I-=1;}}else if(C.indexOf('new')>-1){if(I==11){I=0;G+=1;}else {I+=1;}}
+this.date=this.UTCDate(G,I,H,0,0,0,0);this.viewDate=this.UTCDate(G,I,Math.min(28,H),0,0,0,0);this.setValue(this.formatDate(this.date));this.hide();}break;}},setStartDate:function(A){this.startDate=A||-Infinity;if(this.startDate!==-Infinity){this.startDate=this.parseDate(this.startDate);}
+this.update();this.updateNavArrows();},setEndDate:function(A){this.endDate=A||Infinity;if(this.endDate!==Infinity){this.endDate=this.parseDate(this.endDate);}
+this.update();this.updateNavArrows();},setDaysOfWeekDisabled:function(A){this.daysOfWeekDisabled=A||[];if(typeof(this.daysOfWeekDisabled)!=='object'){this.daysOfWeekDisabled=this.daysOfWeekDisabled.split(/,\s*/);}
+this.daysOfWeekDisabled=this.daysOfWeekDisabled.map(function(d){return parseInt(d,10);});this.update();this.updateNavArrows();},updateNavArrows:function(){if(this.singleMode){return;}var d=new Date(this.viewDate),A=d.getUTCFullYear(),B=d.getUTCMonth();Roo.each(this.picker().select('.prev',true).elements,function(v){v.show();switch(this.viewMode){case 0:if(this.startDate!==-Infinity&&A<=this.startDate.getUTCFullYear()&&B<=this.startDate.getUTCMonth()){v.hide();}break;case 1:case 2:if(this.startDate!==-Infinity&&A<=this.startDate.getUTCFullYear()){v.hide();}break;}});Roo.each(this.picker().select('.next',true).elements,function(v){v.show();switch(this.viewMode){case 0:if(this.endDate!==Infinity&&A>=this.endDate.getUTCFullYear()&&B>=this.endDate.getUTCMonth()){v.hide();}break;case 1:case 2:if(this.endDate!==Infinity&&A>=this.endDate.getUTCFullYear()){v.hide();}break;}})},moveMonth:function(A,B){if(!B)return A;var C=new Date(A.valueOf()),D=C.getUTCDate(),E=C.getUTCMonth(),F=Math.abs(B),G,H;B=B>0?1:-1;if(F==1){H=B==-1?function(){return C.getUTCMonth()==E;}:function(){return C.getUTCMonth()!=G;};G=E+B;C.setUTCMonth(G);if(G<0||G>11)G=(G+12)%12;}else {for(var i=0;i<F;i++)C=this.moveMonth(C,B);G=C.getUTCMonth();C.setUTCDate(D);H=function(){return G!=C.getUTCMonth();};}while(H()){C.setUTCDate(--D);C.setUTCMonth(G);}return C;},moveYear:function(A,B){return this.moveMonth(A,B*12);},dateWithinRange:function(A){return A>=this.startDate&&A<=this.endDate;},remove:function(){this.picker().remove();}});Roo.apply(Roo.bootstrap.DateField,{head:{tag:'thead',cn:[{tag:'tr',cn:[{tag:'th',cls:'prev',html:'<i class="fa fa-arrow-left"/>'},{tag:'th',cls:'switch',colspan:'5'},{tag:'th',cls:'next',html:'<i class="fa fa-arrow-right"/>'}]}]},content:{tag:'tbody',cn:[{tag:'tr',cn:[{tag:'td',colspan:'7'}]}]},footer:{tag:'tfoot',cn:[{tag:'tr',cn:[{tag:'th',colspan:'7',cls:'today'}]}]},dates:{en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today"}},modes:[{clsName:'days',navFnc:'Month',navStep:1},{clsName:'months',navFnc:'FullYear',navStep:1},{clsName:'years',navFnc:'FullYear',navStep:10}]});Roo.apply(Roo.bootstrap.DateField,{template:{tag:'div',cls:'datepicker dropdown-menu roo-dynamic',cn:[{tag:'div',cls:'datepicker-days',cn:[{tag:'table',cls:'table-condensed',cn:[Roo.bootstrap.DateField.head,{tag:'tbody'},Roo.bootstrap.DateField.footer]}]},{tag:'div',cls:'datepicker-months',cn:[{tag:'table',cls:'table-condensed',cn:[Roo.bootstrap.DateField.head,Roo.bootstrap.DateField.content,Roo.bootstrap.DateField.footer]}]},{tag:'div',cls:'datepicker-years',cn:[{tag:'table',cls:'table-condensed',cn:[Roo.bootstrap.DateField.head,Roo.bootstrap.DateField.content,Roo.bootstrap.DateField.footer]}]}]}});
+//Roo/bootstrap/TimeField.js
+Roo.bootstrap.TimeField=function(A){Roo.bootstrap.TimeField.superclass.constructor.call(this,A);this.addEvents({show:true,hide:true,select:true});};Roo.extend(Roo.bootstrap.TimeField,Roo.bootstrap.Input,{format:"H:i",onRender:function(ct,A){Roo.bootstrap.TimeField.superclass.onRender.call(this,ct,A);this.el.select('>.input-group',true).first().createChild(Roo.bootstrap.TimeField.template);this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.pop=this.picker().select('>.datepicker-time',true).first();this.pop.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.picker().on('mousedown',this.onMousedown,this);this.picker().on('click',this.onClick,this);this.picker().addClass('datepicker-dropdown');this.fillTime();this.update();this.pop.select('span.hours-up',true).first().on('click',this.onIncrementHours,this);this.pop.select('span.hours-down',true).first().on('click',this.onDecrementHours,this);this.pop.select('span.minutes-up',true).first().on('click',this.onIncrementMinutes,this);this.pop.select('span.minutes-down',true).first().on('click',this.onDecrementMinutes,this);this.pop.select('button.period',true).first().on('click',this.onTogglePeriod,this);this.pop.select('button.ok',true).first().on('click',this.setTime,this);},fireKey:function(e){if(!this.picker().isVisible()){if(e.keyCode==27){this.show();}return;}
+e.preventDefault();switch(e.keyCode){case 27:this.hide();break;case 37:case 39:this.onTogglePeriod();break;case 38:this.onIncrementMinutes();break;case 40:this.onDecrementMinutes();break;case 13:case 9:this.setTime();break;}},onClick:function(e){e.stopPropagation();e.preventDefault();},picker:function(){return this.el.select('.datepicker',true).first();},fillTime:function(){var A=this.pop.select('tbody',true).first();A.dom.innerHTML='';A.createChild({tag:'tr',cn:[{tag:'td',cn:[{tag:'a',href:'#',cls:'btn',cn:[{tag:'span',cls:'hours-up glyphicon glyphicon-chevron-up'}]}]},{tag:'td',cls:'separator'},{tag:'td',cn:[{tag:'a',href:'#',cls:'btn',cn:[{tag:'span',cls:'minutes-up glyphicon glyphicon-chevron-up'}]}]},{tag:'td',cls:'separator'}]});A.createChild({tag:'tr',cn:[{tag:'td',cn:[{tag:'span',cls:'timepicker-hour',html:'00'}]},{tag:'td',cls:'separator',html:':'},{tag:'td',cn:[{tag:'span',cls:'timepicker-minute',html:'00'}]},{tag:'td',cls:'separator'},{tag:'td',cn:[{tag:'button',type:'button',cls:'btn btn-primary period',html:'AM'}]}]});A.createChild({tag:'tr',cn:[{tag:'td',cn:[{tag:'a',href:'#',cls:'btn',cn:[{tag:'span',cls:'hours-down glyphicon glyphicon-chevron-down'}]}]},{tag:'td',cls:'separator'},{tag:'td',cn:[{tag:'a',href:'#',cls:'btn',cn:[{tag:'span',cls:'minutes-down glyphicon glyphicon-chevron-down'}]}]},{tag:'td',cls:'separator'}]});},update:function(){this.time=(typeof(this.time)==='undefined')?new Date():this.time;this.fill();},fill:function(){var A=this.time.getHours();var B=this.time.getMinutes();var C='AM';if(A>11){C='PM';}if(A==0){A=12;}if(A>12){A=A-12;}if(A<10){A='0'+A;}if(B<10){B='0'+B;}
+this.pop.select('.timepicker-hour',true).first().dom.innerHTML=A;this.pop.select('.timepicker-minute',true).first().dom.innerHTML=B;this.pop.select('button',true).first().dom.innerHTML=C;},place:function(){this.picker().removeClass(['bottom-left','bottom-right','top-left','top-right']);var A=['bottom'];if((Roo.lib.Dom.getViewHeight()+Roo.get(document.body).getScroll().top)-(this.inputEl().getBottom()+this.picker().getHeight())<0){A.pop();A.push('top');}
+A.push('right');if((Roo.lib.Dom.getViewWidth()+Roo.get(document.body).getScroll().left)-(this.inputEl().getLeft()+this.picker().getWidth())<0){A.pop();A.push('left');}
+this.picker().addClass(A.join('-'));var B=this;Roo.each(A,function(c){if(c=='bottom'){B.picker().setTop(B.inputEl().getHeight());return;}if(c=='top'){B.picker().setTop(0-B.picker().getHeight());return;}if(c=='left'){B.picker().setLeft(B.inputEl().getLeft()+B.inputEl().getWidth()-B.el.getLeft()-B.picker().getWidth());return;}if(c=='right'){B.picker().setLeft(B.inputEl().getLeft()-B.el.getLeft());return;}});},onFocus:function(){Roo.bootstrap.TimeField.superclass.onFocus.call(this);this.show();},onBlur:function(){Roo.bootstrap.TimeField.superclass.onBlur.call(this);this.hide();},show:function(){this.picker().show();this.pop.show();this.update();this.place();this.fireEvent('show',this,this.date);},hide:function(){this.picker().hide();this.pop.hide();this.fireEvent('hide',this,this.date);},setTime:function(){this.hide();this.setValue(this.time.format(this.format));this.fireEvent('select',this,this.date);},onMousedown:function(e){e.stopPropagation();e.preventDefault();},onIncrementHours:function(){Roo.log('onIncrementHours');this.time=this.time.add(Date.HOUR,1);this.update();},onDecrementHours:function(){Roo.log('onDecrementHours');this.time=this.time.add(Date.HOUR,-1);this.update();},onIncrementMinutes:function(){Roo.log('onIncrementMinutes');this.time=this.time.add(Date.MINUTE,1);this.update();},onDecrementMinutes:function(){Roo.log('onDecrementMinutes');this.time=this.time.add(Date.MINUTE,-1);this.update();},onTogglePeriod:function(){Roo.log('onTogglePeriod');this.time=this.time.add(Date.HOUR,12);this.update();}});Roo.apply(Roo.bootstrap.TimeField,{content:{tag:'tbody',cn:[{tag:'tr',cn:[{tag:'td',colspan:'7'}]}]},footer:{tag:'tfoot',cn:[{tag:'tr',cn:[{tag:'th',colspan:'7',cls:'',cn:[{tag:'button',cls:'btn btn-info ok',html:'OK'}]}]}]}});Roo.apply(Roo.bootstrap.TimeField,{template:{tag:'div',cls:'datepicker dropdown-menu',cn:[{tag:'div',cls:'datepicker-time',cn:[{tag:'table',cls:'table-condensed',cn:[Roo.bootstrap.TimeField.content,Roo.bootstrap.TimeField.footer]}]}]}});
+//Roo/bootstrap/MonthField.js
+Roo.bootstrap.MonthField=function(A){Roo.bootstrap.MonthField.superclass.constructor.call(this,A);this.addEvents({show:true,hide:true,select:true});};Roo.extend(Roo.bootstrap.MonthField,Roo.bootstrap.Input,{onRender:function(ct,A){Roo.bootstrap.MonthField.superclass.onRender.call(this,ct,A);this.language=this.language||'en';this.language=this.language in Roo.bootstrap.MonthField.dates?this.language:this.language.split('-')[0];this.language=this.language in Roo.bootstrap.MonthField.dates?this.language:"en";this.isRTL=Roo.bootstrap.MonthField.dates[this.language].rtl||false;this.isInline=false;this.isInput=true;this.component=this.el.select('.add-on',true).first()||false;this.component=(this.component&&this.component.length===0)?false:this.component;this.hasInput=this.component&&this.inputEL().length;this.pickerEl=Roo.get(document.body).createChild(Roo.bootstrap.MonthField.template);this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.picker().on('mousedown',this.onMousedown,this);this.picker().on('click',this.onClick,this);this.picker().addClass('datepicker-dropdown');Roo.each(this.picker().select('tbody > tr > td',true).elements,function(v){v.setStyle('width','189px');});this.fillMonths();this.update();if(this.isInline){this.show();}},setValue:function(v){Roo.bootstrap.MonthField.superclass.setValue.call(this,v);this.update();this.fireEvent('select',this,this.date);},getValue:function(){return this.value;},onClick:function(e){e.stopPropagation();e.preventDefault();var A=e.getTarget();if(A.nodeName.toLowerCase()==='i'){A=Roo.get(A).dom.parentNode;}var B=A.nodeName;var C=A.className;var D=A.innerHTML;if(B.toLowerCase()!='span'||C.indexOf('disabled')>-1||C.indexOf('month')==-1){return;}
+this.vIndex=Roo.bootstrap.MonthField.dates[this.language].monthsShort.indexOf(D);this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);this.hide();},picker:function(){return this.pickerEl;},fillMonths:function(){var i=0;var A=this.picker().select('>.datepicker-months td',true).first();A.dom.innerHTML='';while(i<12){var B={tag:'span',cls:'month',html:Roo.bootstrap.MonthField.dates[this.language].monthsShort[i++]}
+A.createChild(B);}},update:function(){var A=this;if(typeof(this.vIndex)=='undefined'&&this.value.length){this.vIndex=Roo.bootstrap.MonthField.dates[this.language].months.indexOf(this.value);}
+Roo.each(this.pickerEl.select('> .datepicker-months tbody > tr > td > span',true).elements,function(e,k){e.removeClass('active');if(typeof(A.vIndex)!='undefined'&&k==A.vIndex){e.addClass('active');}})},place:function(){if(this.isInline)return;this.picker().removeClass(['bottom','top']);if((Roo.lib.Dom.getViewHeight()+Roo.get(document.body).getScroll().top)-(this.inputEl().getBottom()+this.picker().getHeight())<0){this.picker().addClass('top');this.picker().setTop(this.inputEl().getTop()-this.picker().getHeight()).setLeft(this.inputEl().getLeft());return;}
+this.picker().addClass('bottom');this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());},onFocus:function(){Roo.bootstrap.MonthField.superclass.onFocus.call(this);this.show();},onBlur:function(){Roo.bootstrap.MonthField.superclass.onBlur.call(this);var d=this.inputEl().getValue();this.setValue(d);this.hide();},show:function(){this.picker().show();this.picker().select('>.datepicker-months',true).first().show();this.update();this.place();this.fireEvent('show',this,this.date);},hide:function(){if(this.isInline)return;this.picker().hide();this.fireEvent('hide',this,this.date);},onMousedown:function(e){e.stopPropagation();e.preventDefault();},keyup:function(e){Roo.bootstrap.MonthField.superclass.keyup.call(this);this.update();},fireKey:function(e){if(!this.picker().isVisible()){if(e.keyCode==27)this.show();return;}var A;switch(e.keyCode){case 27:this.hide();e.preventDefault();break;case 37:case 39:A=e.keyCode==37?-1:1;this.vIndex=this.vIndex+A;if(this.vIndex<0){this.vIndex=0;}if(this.vIndex>11){this.vIndex=11;}if(isNaN(this.vIndex)){this.vIndex=0;}
+this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);break;case 38:case 40:A=e.keyCode==38?-1:1;this.vIndex=this.vIndex+A*4;if(this.vIndex<0){this.vIndex=0;}if(this.vIndex>11){this.vIndex=11;}if(isNaN(this.vIndex)){this.vIndex=0;}
+this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);break;case 13:if(typeof(this.vIndex)!='undefined'&&!isNaN(this.vIndex)){this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);}
+this.hide();e.preventDefault();break;case 9:if(typeof(this.vIndex)!='undefined'&&!isNaN(this.vIndex)){this.setValue(Roo.bootstrap.MonthField.dates[this.language].months[this.vIndex]);}
+this.hide();break;case 16:case 17:case 18:break;default:this.hide();}},remove:function(){this.picker().remove();}});Roo.apply(Roo.bootstrap.MonthField,{content:{tag:'tbody',cn:[{tag:'tr',cn:[{tag:'td',colspan:'7'}]}]},dates:{en:{months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}}});Roo.apply(Roo.bootstrap.MonthField,{template:{tag:'div',cls:'datepicker dropdown-menu roo-dynamic',cn:[{tag:'div',cls:'datepicker-months',cn:[{tag:'table',cls:'table-condensed',cn:[Roo.bootstrap.DateField.content]}]}]}});
+//Roo/bootstrap/CheckBox.js
+Roo.bootstrap.CheckBox=function(A){Roo.bootstrap.CheckBox.superclass.constructor.call(this,A);this.addEvents({check:true});};Roo.extend(Roo.bootstrap.CheckBox,Roo.bootstrap.Input,{inputType:'checkbox',inputValue:1,valueOff:0,boxLabel:false,checked:false,weight:false,inline:false,getAutoCreate:function(){var A=(!this.labelAlign)?this.parentLabelAlign():this.labelAlign;var id=Roo.id();var B={};B.cls='form-group '+this.inputType;if(this.inline){B.cls+=' '+this.inputType+'-inline';}var C={tag:'input',id:id,type:this.inputType,value:this.inputType=='radio'?this.inputValue:((!this.checked)?this.valueOff:this.inputValue),cls:'roo-'+this.inputType,placeholder:this.placeholder||''};if(this.weight){B.cls+=" "+this.inputType+"-"+this.weight;}if(this.disabled){C.disabled=true;}if(this.checked){C.checked=this.checked;}if(this.name){C.name=this.name;}if(this.size){C.cls+=' input-'+this.size;}var D=this;['xs','sm','md','lg'].map(function(G){if(D[G]){B.cls+=' col-'+G+'-'+D[G];}});var E=C;if(this.before||this.after){E={cls:'input-group',cn:[]};if(this.before){E.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
+E.cn.push(C);if(this.after){E.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}}if(A==='left'&&this.fieldLabel.length){Roo.log("left and has label");B.cn=[{tag:'label','for':id,cls:'control-label col-md-'+this.labelWidth,html:this.fieldLabel},{cls:"col-md-"+(12-this.labelWidth),cn:[E]}];}else if(this.fieldLabel.length){Roo.log(" label");B.cn=[{tag:this.boxLabel?'span':'label','for':id,cls:'control-label box-input-label',html:this.fieldLabel},E];}else {Roo.log(" no label && no align");B.cn=[E];}if(this.boxLabel){var F={tag:'label',cls:'box-label',html:this.boxLabel};if(this.tooltip){F.tooltip=this.tooltip;}
+B.cn.push(F);}return B;},inputEl:function(){return this.el.select('input.roo-'+this.inputType,true).first();},labelEl:function(){return this.el.select('label.control-label',true).first();},label:function(){return this.labelEl();},initEvents:function(){this.inputEl().on('click',this.onClick,this);if(this.boxLabel){this.el.select('label.box-label',true).first().on('click',this.onClick,this);}},onClick:function(){this.setChecked(!this.checked);},setChecked:function(A,B){var C=this.inputEl().dom.checked;if(this.inputType=='radio'){Roo.each(this.el.up('form').select('input[name='+this.name+']',true).elements,function(e){e.dom.checked=false;});this.inputEl().dom.checked=true;this.inputEl().dom.value=this.inputValue;if(B!==true){this.fireEvent('check',this,true,C);}return;}
+this.checked=A;this.inputEl().dom.checked=A;this.inputEl().dom.value=A?this.inputValue:this.valueOff;if(B!==true){this.fireEvent('check',this,A,C);}},getValue:function(){if(this.inputType=='radio'){return this.getGroupValue();}return this.inputEl().getValue();},getGroupValue:function(){if(typeof(this.el.up('form').child('input[name='+this.name+']:checked',true))=='undefined'){return '';}return this.el.up('form').child('input[name='+this.name+']:checked',true).value;},setValue:function(v,A){if(this.inputType=='radio'){this.setGroupValue(v,A);return;}
+this.setChecked(((typeof(v)=='undefined')?this.checked:(String(v)===String(this.inputValue))),A);},setGroupValue:function(v,A){var B=this.inputEl().dom.checked;Roo.each(this.el.up('form').select('input[name='+this.name+']',true).elements,function(e){e.dom.checked=false;if(e.dom.value==v){e.dom.checked=true;}});if(A!==true){this.fireEvent('check',this,true,B);}return;}});
+//Roo/bootstrap/Radio.js
+Roo.bootstrap.Radio=function(A){Roo.bootstrap.Radio.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Radio,Roo.bootstrap.CheckBox,{inputType:'radio',inputValue:'',valueOff:'',getAutoCreate:function(){var A=(!this.labelAlign)?this.parentLabelAlign():this.labelAlign;A=A||'left';var id=Roo.id();var B={tag:this.inline?'span':'div',cls:'',cn:[]};var C=this.inline?' radio-inline':'';var D={tag:'label','for':id,cls:'control-label box-label'+C,cn:[]};var E=this.labelWidth?this.labelWidth*1:100;var F={tag:'label',html:this.fieldLabel,style:'width:'+E+'px;line-height:1;vertical-align:bottom;cursor:default;'};var G={tag:'input',id:id,type:this.inputType,value:this.inputValue,cls:'roo-radio',placeholder:this.placeholder||''};if(this.weight){G.cls+=" radio-"+this.weight;}if(this.disabled){G.disabled=true;}if(this.checked){G.checked=this.checked;}if(this.name){G.name=this.name;}if(this.size){G.cls+=' input-'+this.size;}var H=this;['xs','sm','md','lg'].map(function(K){if(H[K]){B.cls+=' col-'+K+'-'+H[K];}});var I=G;if(this.before||this.after){I={cls:'input-group',tag:'span',cn:[]};if(this.before){I.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
+I.cn.push(G);if(this.after){I.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}};if(this.fieldLabel&&this.fieldLabel.length){B.cn.push(F);}var J={tag:'span',cls:'radio'+C,cn:[I,D]};B.cn.push(J);if(this.boxLabel){D.cn.push({tag:'span',html:this.boxLabel})}return B;},initEvents:function(){this.inputEl().on('click',this.onClick,this);if(this.boxLabel){Roo.log('find label')
+this.el.select('span.radio label span',true).first().on('click',this.onClick,this);}},inputEl:function(){return this.el.select('input.roo-radio',true).first();},onClick:function(){Roo.log("click");this.setChecked(true);},setChecked:function(A,B){if(A){Roo.each(this.inputEl().up('form').select('input[name='+this.inputEl().dom.name+']',true).elements,function(v){v.dom.checked=false;});}
+Roo.log(this.inputEl().dom);this.checked=A;this.inputEl().dom.checked=A;if(B!==true){this.fireEvent('check',this,A);}},getGroupValue:function(){var A='';Roo.each(this.inputEl().up('form').select('input[name='+this.inputEl().dom.name+']',true).elements,function(v){if(v.dom.checked==true){A=v.dom.value;}});return A;},getValue:function(){return this.getGroupValue();}});
+//Roo/HtmlEditorCore.js
+Roo.HtmlEditorCore=function(A){Roo.HtmlEditorCore.superclass.constructor.call(this,A);this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editorevent:true});this.applyBlacklists();};Roo.extend(Roo.HtmlEditorCore,Roo.Component,{owner:false,resizable:false,height:300,width:500,stylesheets:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,sourceEditMode:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',clearUp:true,black:false,white:false,getDocMarkup:function(){var st='';if(this.stylesheets===false){Roo.get(document.head).select('style').each(function(A){st+=A.dom.outerHTML||new XMLSerializer().serializeToString(A.dom);});Roo.get(document.head).select('link').each(function(A){st+=A.dom.outerHTML||new XMLSerializer().serializeToString(A.dom);});}else if(!this.stylesheets.length){st='<style type="text/css">'+'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}'+'</style>';}else {}
+st+='<style type="text/css">'+'IMG { cursor: pointer } '+'</style>';return '<html><head>'+st+' </head><body class="roo-htmleditor-body"></body></html>';},onRender:function(ct,A){var _t=this;this.el=this.owner.inputEl?this.owner.inputEl():this.owner.el;this.el.dom.style.border='0 none';this.el.dom.setAttribute('tabIndex',-1);this.el.addClass('x-hidden hide');if(Roo.isIE){this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')}
+this.frameId=Roo.id();var B=this.owner.wrap.createChild({tag:'iframe',cls:'form-control',id:this.frameId,name:this.frameId,frameBorder:'no','src':Roo.SSL_SECURE_URL?Roo.SSL_SECURE_URL:"javascript:false"},this.el);this.iframe=B.dom;this.assignDocWin();this.doc.designMode='on';this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var C={run:function(){this.assignDocWin();if(this.doc.body||this.doc.readyState=='complete'){try{this.doc.designMode="on";}catch(e){return;}
+Roo.TaskMgr.stop(C);this.initEditor.defer(10,this);}},interval:10,duration:10000,scope:this};Roo.TaskMgr.start(C);},onResize:function(w,h){Roo.log('resize: '+w+','+h);if(!this.iframe){return;}if(typeof w=='number'){this.iframe.style.width=w+'px';}if(typeof h=='number'){this.iframe.style.height=h+'px';if(this.doc){(this.doc.body||this.doc.documentElement).style.height=(h-(this.iframePad*2))+'px';}}},toggleSourceEdit:function(A){this.sourceEditMode=A===true;if(this.sourceEditMode){Roo.get(this.iframe).addClass(['x-hidden','hide']);}else {Roo.get(this.iframe).removeClass(['x-hidden','hide']);this.deferFocus();}},cleanHtml:function(A){A=String(A);if(A.length>5){if(Roo.isSafari){A=A.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,'');}}if(A=='&nbsp;'){A='';}return A;},syncValue:function(){if(this.initialized){var bd=(this.doc.body||this.doc.documentElement);var A=bd.innerHTML;if(Roo.isSafari){var bs=bd.getAttribute('style');var m=bs?bs.match(/text-align:(.*?);/i):false;if(m&&m[1]){A='<div style="'+m[0]+'">'+A+'</div>';}}
+A=this.cleanHtml(A);A=A.replace(/([\x80-\uffff])/g,function(a,b){var cc=b.charCodeAt();if((cc>=0x4E00&&cc<0xA000)||(cc>=0x3400&&cc<0x4E00)||(cc>=0xf900&&cc<0xfb00)){return b;}return "&#"+cc+";"});if(this.owner.fireEvent('beforesync',this,A)!==false){this.el.dom.value=A;this.owner.fireEvent('sync',this,A);}}},pushValue:function(){if(this.initialized){var v=this.el.dom.value.trim();if(this.owner.fireEvent('beforepush',this,v)!==false){var d=(this.doc.body||this.doc.documentElement);d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.owner.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else {this.el.focus();}},assignDocWin:function(){var A=this.iframe;if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}else {if(!Roo.get(this.frameId)&&!A.contentDocument){return;}
+this.doc=(A.contentDocument||Roo.get(this.frameId).dom.document);this.win=(A.contentWindow||Roo.get(this.frameId).dom.contentWindow);}},initEditor:function(){this.assignDocWin();this.doc.designMode="on";this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var A=(this.doc.body||this.doc.documentElement);A.bgProperties='fixed';Roo.EventManager.on(this.doc,{'mouseup':this.onEditorEvent,'dblclick':this.onEditorEvent,'click':this.onEditorEvent,'keyup':this.onEditorEvent,buffer:100,scope:this});if(Roo.isGecko){Roo.EventManager.on(this.doc,'keypress',this.mozKeyPress,this);}if(Roo.isIE||Roo.isSafari||Roo.isOpera){Roo.EventManager.on(this.doc,'keydown',this.fixKeys,this);}
+this.initialized=true;this.owner.fireEvent('initialize',this);this.pushValue();},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();this.activated=true;if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);this.execCmd('styleWithCSS',false);}catch(e){}}
+this.owner.fireEvent('activate',this);},adjustFont:function(A){var B=A.cmd=='increasefontsize'?1:-1;var v=parseInt(this.doc.queryCommandValue('FontSize')||3,10);if(Roo.isSafari){var sm={10:1,13:2,16:3,18:4,24:5,32:6,48:7};v=(v<10)?10:v;v=(v>48)?48:v;v=typeof(sm[v])=='undefined'?1:sm[v];}
+v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.owner.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){if(tg.toLowerCase()=='span'||tg.toLowerCase()=='code'){range=this.createRange(this.getSelection());var A=this.doc.createElement(tg.toLowerCase());A.appendChild(range.extractContents());range.insertNode(A);return;}
+this.execCmd("formatblock",tg);},insertText:function(A){var B=this.createRange();B.deleteContents();B.insertNode(this.doc.createTextNode(A));},relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.owner.fireEvent('editorevent',this);this.owner.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;D.document.selection.createRange().pasteHTML(E);}else {var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;case 'v':this.cleanUpPaste.defer(100,this);return;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br />');r.collapse(false);r.select();}}}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}
+a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}
+B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);continue;}if(!this.rangeIntersectsNode(A,ar[i])||(this.rangeCompareNode(A,ar[i])==0)){continue;}
+F=true;}if(!D.length&&E.length){D=E;}if(F||!D.length||(D.length>1)){return false;}return D[0];},createRange:function(A){if(typeof A!="undefined"){try{return A.getRangeAt?A.getRangeAt(0):A.createRange();}catch(e){return this.doc.createRange();}}else {return this.doc.createRange();}},getParentElement:function(){this.assignDocWin();var A=Roo.isIE?this.doc.selection:this.win.getSelection();var B=this.createRange(A);try{var p=B.commonAncestorContainer;while(p.nodeType==3){p=p.parentNode;}return p;}catch(e){return null;}},rangeIntersectsNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){C.selectNodeContents(B);}var D=A.cloneRange();D.collapse(true);var E=A.cloneRange();E.collapse(false);var F=C.cloneRange();F.collapse(true);var G=C.cloneRange();G.collapse(false);return D.compareBoundaryPoints(Range.START_TO_START,G)==-1&&E.compareBoundaryPoints(Range.START_TO_START,F)==1;},rangeCompareNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){C.selectNodeContents(B);}
+A.collapse(true);C.collapse(true);var ss=A.compareBoundaryPoints(Range.START_TO_START,C);var ee=A.compareBoundaryPoints(Range.END_TO_END,C);var D=ss==1;var E=ee==-1;if(D&&E)return 0;if(!D&&E)return 1;if(D&&!E)return 2;return 3;},cleanUpPaste:function(){Roo.log('cleanuppaste');this.cleanUpChildren(this.doc.body);var A=this.cleanWordChars(this.doc.body.innerHTML);if(A!=this.doc.body.innerHTML){this.doc.body.innerHTML=A;}},cleanWordChars:function(A){var he=Roo.HtmlEditorCore;var B=A;Roo.each(he.swapCodes,function(sw){var C=new RegExp("\\u"+sw[0].toString(16),"g");B=B.replace(C,sw[1]);});return B;},cleanUpChildren:function(n){if(!n.childNodes.length){return;}for(var i=n.childNodes.length-1;i>-1;i--){this.cleanUpChild(n.childNodes[i]);}},cleanUpChild:function(A){var ed=this;if(A.nodeName=="#text"){return;}if(A.nodeName=="#comment"){A.parentNode.removeChild(A);return;}var B=A.tagName.toLowerCase();if(this.black.indexOf(B)>-1&&this.clearUp){A.parentNode.removeChild(A);return;}var C=Roo.HtmlEditorCore.remove.indexOf(A.tagName.toLowerCase())>-1;if(C){this.cleanUpChildren(A);while(A.childNodes.length){var cn=A.childNodes[0];A.removeChild(cn);A.parentNode.insertBefore(cn,A);}
+A.parentNode.removeChild(A);return;}if(!A.attributes||!A.attributes.length){this.cleanUpChildren(A);return;}function cleanAttr(n,v){if(v.match(/^\./)||v.match(/^\//)){return;}if(v.match(/^(http|https):\/\//)||v.match(/^mailto:/)){return;}if(v.match(/^#/)){return;}
+A.removeAttribute(n);}var D=this.cwhite;var E=this.cblack;function cleanStyle(n,v){if(v.match(/expression/)){A.removeAttribute(n);return;}var F=v.split(/;/);var G=[];Roo.each(F,function(p){p=p.replace(/^\s+/g,'').replace(/\s+$/g,'');if(!p.length){return true;}var l=p.split(':').shift().replace(/\s+/g,'');l=l.replace(/^\s+/g,'').replace(/\s+$/g,'');if(D.length&&E.indexOf(l)>-1){return true;}if(D.length&&D.indexOf(l)<0){return true;}
+G.push(p);return true;});if(G.length){A.setAttribute(n,G.join(';'));}else {A.removeAttribute(n);}}for(var i=A.attributes.length-1;i>-1;i--){var a=A.attributes[i];if(a.name.toLowerCase().substr(0,2)=='on'){A.removeAttribute(a.name);continue;}if(Roo.HtmlEditorCore.ablack.indexOf(a.name.toLowerCase())>-1){A.removeAttribute(a.name);continue;}if(Roo.HtmlEditorCore.aclean.indexOf(a.name.toLowerCase())>-1){cleanAttr(a.name,a.value);continue;}if(a.name=='style'){cleanStyle(a.name,a.value);continue;}if(a.name=='class'){if(a.value.match(/^Mso/)){A.className='';}if(a.value.match(/body/)){A.className='';}continue;}}
+this.cleanUpChildren(A);},cleanWord:function(A){var _t=this;var B=function(){if(!A.childNodes.length){return;}for(var i=A.childNodes.length-1;i>-1;i--){_t.cleanWord(A.childNodes[i]);}};if(!A){this.cleanWord(this.doc.body);return;}if(A.nodeName=="#text"){return;}if(A.nodeName=="#comment"){A.parentNode.removeChild(A);return;}if(A.tagName.toLowerCase().match(/^(style|script|applet|embed|noframes|noscript)$/)){A.parentNode.removeChild(A);return;}if(A.tagName.toLowerCase().match(/^(meta|link|\\?xml:|st1:|o:|font)/)){while(A.childNodes.length){var cn=A.childNodes[0];A.removeChild(cn);A.parentNode.insertBefore(cn,A);}
+A.parentNode.removeChild(A);B();return;}if(A.className.length){var cn=A.className.split(/\W+/);var cna=[];Roo.each(cn,function(C){if(C.match(/Mso[a-zA-Z]+/)){return;}
+cna.push(C);});A.className=cna.length?cna.join(' '):'';if(!cna.length){A.removeAttribute("class");}}if(A.hasAttribute("lang")){A.removeAttribute("lang");}if(A.hasAttribute("style")){var styles=A.getAttribute("style").split(";");var nstyle=[];Roo.each(styles,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");if(kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)){return;}
+nstyle.push(s);});A.setAttribute("style",nstyle.length?nstyle.join(';'):'');if(!nstyle.length){A.removeAttribute('style');}}
+B();},domToHTML:function(A,B,C){B=B||0;C=C||false;if(!A){return this.domToHTML(this.doc.body);}var j;var D=false;var E=A.nodeName;var F=Roo.util.Format.htmlEncode(A.tagName);if(E=='#text'){return C?A.nodeValue:A.nodeValue.trim();}var G='';if(E!='BODY'){var i=0;if(F){var H=[];for(i=0;i<A.attributes.length;i++){var I=A.attributes.item(i).name;if(!A.attributes.item(i).value.length){continue;}
+H.push(I+'="'+Roo.util.Format.htmlEncode(A.attributes.item(i).value)+'"');}
+G="<"+A.tagName+(H.length?(' '+H.join(' ')):'')+">";}else {}}else {F=false;}if(['IMG','BR','HR','INPUT'].indexOf(F)>-1){return G;}if(['PRE','TEXTAREA','TD','A','SPAN'].indexOf(F)>-1){C=true;}
+i=0;var J=A.childNodes.item(i);var D=true;var K='';lastnode='';while(J){var L=C;if(lastnode=='SPAN'){L=true;}if(J.nodeName=='#text'){var M=Roo.util.Format.htmlEncode(J.nodeValue);M=C?M:M.trim();if(!L&&M.length>80){K+="\n"+(new Array(B+1)).join("  ");}
+K+=M;i++;J=A.childNodes.item(i);lastNode='';continue;}
+D=false;K+=L?'':"\n"+(new Array(B+1)).join("  ");K+=this.domToHTML(J,B+1,C);lastnode=J.nodeName;i++;J=A.childNodes.item(i);}
+G+=K;if(!D){G+=C?'':"\n"+(new Array(B)).join("  ");}if(F){G+="</"+F+">";}return G;},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];var b=typeof(this.owner.black)!='undefined'&&this.owner.black?this.owner.black:[];this.white=[];this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}
+this.white.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}
+this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;}
+this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.black.indexOf(A)>-1){return;}
+this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];this.cwhite=[];this.cblack=[];Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}
+this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}
+this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;}
+this.cblack.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.cblack.indexOf(A)>-1){return;}
+this.cblack.push(A);},this);},setStylesheets:function(A){if(typeof(A)=='string'){Roo.get(this.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:A});return;}var B=this;Roo.each(A,function(s){if(!s.length){return;}
+Roo.get(B.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:s});});},removeStylesheets:function(){var A=this;Roo.each(Roo.get(A.iframe.contentDocument.head).select('link[rel=stylesheet]',true).elements,function(s){s.remove();});}});Roo.HtmlEditorCore.white=['area','br','img','input','hr','wbr','address','blockquote','center','dd','dir','div','dl','dt','h1','h2','h3','h4','h5','h6','hr','isindex','listing','marquee','menu','multicol','ol','p','plaintext','pre','table','ul','xmp','caption','col','colgroup','tbody','td','tfoot','th','thead','tr','dir','menu','ol','ul','dl','embed','object'];Roo.HtmlEditorCore.black=['applet','base','basefont','bgsound','blink','body','frame','frameset','head','html','ilayer','iframe','layer','link','meta','object','script','style','title','xml'];Roo.HtmlEditorCore.clean=['script','style','title','xml'];Roo.HtmlEditorCore.remove=['font'];Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[];Roo.HtmlEditorCore.swapCodes=[[8211,"--"],[8212,"--"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];
+//Roo/bootstrap/HtmlEditor.js
+Roo.bootstrap.HtmlEditor=function(A){Roo.bootstrap.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}
+this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true});};Roo.extend(Roo.bootstrap.HtmlEditor,Roo.bootstrap.TextArea,{toolbars:false,resizable:false,height:300,width:false,stylesheets:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',tbContainer:false,toolbarContainer:function(){return this.wrap.select('.x-html-editor-tb',true).first();},createToolbar:function(){Roo.log("create toolbars");this.toolbars=[new Roo.bootstrap.htmleditor.ToolbarStandard({editor:this})];this.toolbars[0].render(this.toolbarContainer());return;},onRender:function(ct,A){var _t=this;Roo.bootstrap.HtmlEditor.superclass.onRender.call(this,ct,A);this.wrap=this.inputEl().wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}});this.editorcore.onRender(ct,A);if(this.resizable){this.resizeEl=new Roo.Resizable(this.wrap,{pinned:true,wrap:true,dynamic:true,minHeight:this.height,height:this.height,handles:this.resizable,width:this.width,listeners:{resize:function(r,w,h){_t.onResize(w,h);}}});}
+this.createToolbar(this);if(!this.width&&this.resizable){this.setSize(this.wrap.getSize());}if(this.resizeEl){this.resizeEl.resizeTo.defer(100,this.resizeEl,[this.width,this.height]);}},onResize:function(w,h){Roo.log('resize: '+w+','+h);Roo.bootstrap.HtmlEditor.superclass.onResize.apply(this,arguments);var ew=false;var eh=false;if(this.inputEl()){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr');this.inputEl().setWidth(this.adjustWidth('textarea',aw));ew=aw;}if(typeof h=='number'){var A=-11;for(var i=0;i<this.toolbars.length;i++){A+=this.toolbars[i].el.getHeight();}var ah=h-this.wrap.getFrameWidth('tb')-A;ah-=5;this.inputEl().setHeight(this.adjustWidth('textarea',ah));var eh=ah;}}
+Roo.log('onResize:'+[w,h,ew,eh].join(','));this.editorcore.onResize(ew,eh);},toggleSourceEdit:function(A){this.editorcore.toggleSourceEdit(A);if(this.editorcore.sourceEditMode){Roo.log('editor - showing textarea');this.syncValue();this.inputEl().removeClass(['hide','x-hidden']);this.inputEl().dom.removeAttribute('tabIndex');this.inputEl().focus();}else {Roo.log('editor - hiding textarea');this.pushValue();this.inputEl().addClass(['hide','x-hidden']);this.inputEl().dom.setAttribute('tabIndex',-1);}if(this.resizable){this.setSize(this.wrap.getSize());}
+this.fireEvent('editmodechange',this,this.editorcore.sourceEditMode);},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.wrap;},getPositionEl:function(){return this.wrap;},initEvents:function(){this.originalValue=this.getValue();},setValue:function(v){Roo.bootstrap.HtmlEditor.superclass.setValue.call(this,v);this.editorcore.pushValue();},deferFocus:function(){this.focus.defer(10,this);},focus:function(){this.editorcore.focus();},onDestroy:function(){if(this.rendered){for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onDestroy();}
+this.wrap.dom.innerHTML='';this.wrap.remove();}},onFirstFocus:function(){this.editorcore.onFirstFocus();for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onFirstFocus();}},syncValue:function(){this.editorcore.syncValue();},pushValue:function(){this.editorcore.pushValue();}});
+//Roo/bootstrap/htmleditor/ToolbarStandard.js
+Roo.namespace('Roo.bootstrap.htmleditor');Roo.bootstrap.htmleditor.ToolbarStandard=function(A){Roo.apply(this,A);this.disable=this.disable||{};Roo.applyIf(this.disable,{fontSize:true,colors:true,specialElements:true});Roo.bootstrap.htmleditor.ToolbarStandard.superclass.constructor.call(this,A);this.editor=A.editor;this.editorcore=A.editor.editorcore;this.buttons=new Roo.util.MixedCollection(false,function(o){return o.cmd;});}
+Roo.extend(Roo.bootstrap.htmleditor.ToolbarStandard,Roo.bootstrap.NavSimplebar,{bar:true,editor:false,editorcore:false,formats:["p","h1","h2","h3","h4","h5","h6","pre","code","abbr","acronym","address","cite","samp","var",'div','span'],onRender:function(ct,A){Roo.bootstrap.htmleditor.ToolbarStandard.superclass.onRender.call(this,ct,A);Roo.log(this.el);this.el.dom.style.marginBottom='0';var B=this;var C=this.editorcore;var D=this.editor;var E=[];var F=function(id,G,H,I){var J=H?'toggle':'click';var a={size:'sm',xtype:'Button',xns:Roo.bootstrap,glyphicon:id,cmd:id||G,enableToggle:H!==false,pressed:H?false:null,listeners:{}}
+a.listeners[H?'toggle':'click']=function(){I?I.call(B,this):B.onBtnClick.call(B,G||id);}
+E.push(a);return a;};var style={xtype:'Button',size:'sm',xns:Roo.bootstrap,glyphicon:'font',menu:{xtype:'Menu',xns:Roo.bootstrap,items:[]}};Roo.each(this.formats,function(f){style.menu.items.push({xtype:'MenuItem',xns:Roo.bootstrap,html:'<'+f+' style="margin:2px">'+f+'</'+f+'>',tagname:f,listeners:{click:function(){C.insertTag(this.tagname);D.focus();}}});});E.push(style);F('bold',false,true);F('italic',false,true);F('align-left','justifyleft',true);F('align-center','justifycenter',true);F('align-right','justifyright',true);F('link',false,false,function(G){var H=prompt(this.createLinkText,this.defaultLinkValue);if(H&&H!='http:/'+'/'){this.editorcore.relayCmd('createlink',H);}}),F('list','insertunorderedlist',true);F('pencil',false,true,function(G){Roo.log(this);this.toggleSourceEdit(G.pressed);});this.xtype='NavSimplebar';for(var i=0;i<E.length;i++){this.buttons.add(this.addxtypeChild(E[i]));}
+D.on('editorevent',this.updateToolbar,this);},onBtnClick:function(id){this.editorcore.relayCmd(id);this.editorcore.focus();},updateToolbar:function(){if(!this.editorcore.activated){this.editor.onFirstFocus();return;}var A=this.buttons;var B=this.editorcore.doc;A.get('bold').setActive(B.queryCommandState('bold'));A.get('italic').setActive(B.queryCommandState('italic'));A.get('align-left').setActive(B.queryCommandState('justifyleft'));A.get('align-center').setActive(B.queryCommandState('justifycenter'));A.get('align-right').setActive(B.queryCommandState('justifyright'));A.get('list').setActive(B.queryCommandState('insertunorderedlist'));Roo.bootstrap.MenuMgr.hideAll();},onFirstFocus:function(){this.buttons.each(function(A){A.enable();});},toggleSourceEdit:function(A){if(A){Roo.log("disabling buttons");this.buttons.each(function(B){if(B.cmd!='pencil'){B.disable();}});}else {Roo.log("enabling buttons");if(this.editorcore.initialized){this.buttons.each(function(B){B.enable();});}}
+Roo.log("calling toggole on editor");this.editor.toggleSourceEdit(A);}});
+//Roo/bootstrap/Table/AbstractSelectionModel.js
+Roo.bootstrap.Table.AbstractSelectionModel=function(){this.locked=false;Roo.bootstrap.Table.AbstractSelectionModel.superclass.constructor.call(this);};Roo.extend(Roo.bootstrap.Table.AbstractSelectionModel,Roo.util.Observable,{init:function(A){this.grid=A;this.initEvents();},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;}});
+//Roo/bootstrap/Table/RowSelectionModel.js
+Roo.bootstrap.Table.RowSelectionModel=function(A){Roo.apply(this,A);this.selections=new Roo.util.MixedCollection(false,function(o){return o.id;});this.last=false;this.lastActive=false;this.addEvents({"selectionchange":true,"afterselectionchange":true,"beforerowselect":true,"rowselect":true,"rowdeselect":true});Roo.bootstrap.Table.RowSelectionModel.superclass.constructor.call(this);this.locked=false;};Roo.extend(Roo.bootstrap.Table.RowSelectionModel,Roo.bootstrap.Table.AbstractSelectionModel,{singleSelect:false,initEvents:function(){if(!this.grid.enableDragDrop&&!this.grid.enableDrag){this.grid.on("mousedown",this.handleMouseDown,this);}else {this.grid.on("rowclick",this.handleDragableRowClick,this);}
+this.rowNav=new Roo.KeyNav(this.grid.getGridEl(),{"up":function(e){if(!e.shiftKey){this.selectPrevious(e.shiftKey);}else if(this.last!==false&&this.lastActive!==false){var B=this.last;this.selectRange(this.last,this.lastActive-1);this.grid.getView().focusRow(this.lastActive);if(B!==false){this.last=B;}}else {this.selectFirstRow();}
+this.fireEvent("afterselectionchange",this);},"down":function(e){if(!e.shiftKey){this.selectNext(e.shiftKey);}else if(this.last!==false&&this.lastActive!==false){var B=this.last;this.selectRange(this.last,this.lastActive+1);this.grid.getView().focusRow(this.lastActive);if(B!==false){this.last=B;}}else {this.selectFirstRow();}
+this.fireEvent("afterselectionchange",this);},scope:this});var A=this.grid.view;A.on("refresh",this.onRefresh,this);A.on("rowupdated",this.onRowUpdated,this);A.on("rowremoved",this.onRemove,this);},onRefresh:function(){var ds=this.grid.dataSource,i,v=this.grid.view;var s=this.selections;s.each(function(r){if((i=ds.indexOfId(r.id))!=-1){v.onRowSelect(i);}else {s.remove(r);}});},onRemove:function(v,A,r){this.selections.remove(r);},onRowUpdated:function(v,A,r){if(this.isSelected(r)){v.onRowSelect(A);}},selectRecords:function(A,B){if(!B){this.clearSelections();}var ds=this.grid.dataSource;for(var i=0,C=A.length;i<C;i++){this.selectRow(ds.indexOf(A[i]),true);}},getCount:function(){return this.selections.length;},selectFirstRow:function(){this.selectRow(0);},selectLastRow:function(A){this.selectRow(this.grid.dataSource.getCount()-1,A);},selectNext:function(A){if(this.last!==false&&(this.last+1)<this.grid.dataSource.getCount()){this.selectRow(this.last+1,A);this.grid.getView().focusRow(this.last);}},selectPrevious:function(A){if(this.last){this.selectRow(this.last-1,A);this.grid.getView().focusRow(this.last);}},getSelections:function(){return [].concat(this.selections.items);},getSelected:function(){return this.selections.itemAt(0);},clearSelections:function(A){if(this.locked)return;if(A!==true){var ds=this.grid.dataSource;var s=this.selections;s.each(function(r){this.deselectRow(ds.indexOfId(r.id));},this);s.clear();}else {this.selections.clear();}
+this.last=false;},selectAll:function(){if(this.locked)return;this.selections.clear();for(var i=0,A=this.grid.dataSource.getCount();i<A;i++){this.selectRow(i,true);}},hasSelection:function(){return this.selections.length>0;},isSelected:function(A){var r=typeof A=="number"?this.grid.dataSource.getAt(A):A;return (r&&this.selections.key(r.id)?true:false);},isIdSelected:function(id){return (this.selections.key(id)?true:false);},handleMouseDown:function(e,t){var A=this.grid.getView(),B;if(this.isLocked()||(B=A.findRowIndex(t))===false){return;};if(e.shiftKey&&this.last!==false){var C=this.last;this.selectRange(C,B,e.ctrlKey);this.last=C;A.focusRow(B);}else {var D=this.isSelected(B);if(e.button!==0&&D){A.focusRow(B);}else if(e.ctrlKey&&D){this.deselectRow(B);}else if(!D){this.selectRow(B,e.button===0&&(e.ctrlKey||e.shiftKey));A.focusRow(B);}}
+this.fireEvent("afterselectionchange",this);},handleDragableRowClick:function(A,B,e){if(e.button===0&&!e.shiftKey&&!e.ctrlKey){this.selectRow(B,false);A.view.focusRow(B);this.fireEvent("afterselectionchange",this);}},selectRows:function(A,B){if(!B){this.clearSelections();}for(var i=0,C=A.length;i<C;i++){this.selectRow(A[i],true);}},selectRange:function(A,B,C){if(this.locked)return;if(!C){this.clearSelections();}if(A<=B){for(var i=A;i<=B;i++){this.selectRow(i,true);}}else {for(var i=A;i>=B;i--){this.selectRow(i,true);}}},deselectRange:function(A,B,C){if(this.locked)return;for(var i=A;i<=B;i++){this.deselectRow(i,C);}},selectRow:function(A,B,C){if(this.locked||(A<0||A>=this.grid.dataSource.getCount()))return;if(this.fireEvent("beforerowselect",this,A,B)!==false){if(!B||this.singleSelect){this.clearSelections();}var r=this.grid.dataSource.getAt(A);this.selections.add(r);this.last=this.lastActive=A;if(!C){this.grid.getView().onRowSelect(A);}
+this.fireEvent("rowselect",this,A,r);this.fireEvent("selectionchange",this);}},deselectRow:function(A,B){if(this.locked)return;if(this.last==A){this.last=false;}if(this.lastActive==A){this.lastActive=false;}var r=this.grid.dataSource.getAt(A);this.selections.remove(r);if(!B){this.grid.getView().onRowDeselect(A);}
+this.fireEvent("rowdeselect",this,A);this.fireEvent("selectionchange",this);},restoreLast:function(){if(this._last){this.last=this._last;}},acceptsNav:function(A,B,cm){return !cm.isHidden(B)&&cm.isCellEditable(B,A);},onEditorKey:function(A,e){var k=e.getKey(),B,g=this.grid,ed=g.activeEditor;if(k==e.TAB){e.stopEvent();ed.completeEdit();if(e.shiftKey){B=g.walkCells(ed.row,ed.col-1,-1,this.acceptsNav,this);}else {B=g.walkCells(ed.row,ed.col+1,1,this.acceptsNav,this);}}else if(k==e.ENTER&&!e.ctrlKey){e.stopEvent();ed.completeEdit();if(e.shiftKey){B=g.walkCells(ed.row-1,ed.col,-1,this.acceptsNav,this);}else {B=g.walkCells(ed.row+1,ed.col,1,this.acceptsNav,this);}}else if(k==e.ESC){ed.cancelEdit();}if(B){g.startEditing(B[0],B[1]);}}});
+//Roo/bootstrap/PagingToolbar.js
+Roo.bootstrap.PagingToolbar=function(A){var ds=A.dataSource;this.toolbarItems=[];if(A.items){this.toolbarItems=A.items;}
+Roo.bootstrap.PagingToolbar.superclass.constructor.call(this,A);this.ds=ds;this.cursor=0;if(ds){this.bind(ds);}
+this.navgroup=new Roo.bootstrap.NavGroup({cls:'pagination'});};Roo.extend(Roo.bootstrap.PagingToolbar,Roo.bootstrap.NavSimplebar,{pageSize:20,displayMsg:'Displaying {0} - {1} of {2}',emptyMsg:'No data to display',beforePageText:"Page",afterPageText:"of {0}",firstText:"First Page",prevText:"Previous Page",nextText:"Next Page",lastText:"Last Page",refreshText:"Refresh",buttons:false,onRender:function(ct,A){Roo.bootstrap.PagingToolbar.superclass.onRender.call(this,ct,A);this.navgroup.parentId=this.id;this.navgroup.onRender(this.el,null);if(this.displayInfo){Roo.log(this.el.select('ul.navbar-nav',true).first());this.el.select('ul.navbar-nav',true).first().createChild({cls:'x-paging-info'});this.displayEl=this.el.select('.x-paging-info',true).first();}var B=this;if(this.buttons){Roo.each(B.buttons,function(e){Roo.factory(e).onRender(B.el,null);});}
+Roo.each(B.toolbarItems,function(e){B.navgroup.addItem(e);});this.first=this.navgroup.addItem({tooltip:this.firstText,cls:"prev",icon:'fa fa-backward',disabled:true,preventDefault:true,listeners:{click:this.onClick.createDelegate(this,["first"])}});this.prev=this.navgroup.addItem({tooltip:this.prevText,cls:"prev",icon:'fa fa-step-backward',disabled:true,preventDefault:true,listeners:{click:this.onClick.createDelegate(this,["prev"])}});var C=this.navgroup.addItem({tagtype:'span',cls:'x-paging-position',html:this.beforePageText+'<input type="text" size="3" value="1" class="x-grid-page-number">'+'<span class="x-paging-after">'+String.format(this.afterPageText,1)+'</span>'});this.field=C.el.select('input',true).first();this.field.on("keydown",this.onPagingKeydown,this);this.field.on("focus",function(){this.dom.select();});this.afterTextEl=C.el.select('.x-paging-after',true).first();this.next=this.navgroup.addItem({tooltip:this.nextText,cls:"next",html:' <i class="fa fa-step-forward">',disabled:true,preventDefault:true,listeners:{click:this.onClick.createDelegate(this,["next"])}});this.last=this.navgroup.addItem({tooltip:this.lastText,icon:'fa fa-forward',cls:"next",disabled:true,preventDefault:true,listeners:{click:this.onClick.createDelegate(this,["last"])}});this.loading=this.navgroup.addItem({tooltip:this.refreshText,icon:'fa fa-refresh',preventDefault:true,listeners:{click:this.onClick.createDelegate(this,["refresh"])}});},updateInfo:function(){if(this.displayEl){var A=(typeof(this.getCount)=='undefined')?this.ds.getCount():this.getCount();var B=A==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+A,this.ds.getTotalCount());this.displayEl.update(B);}},onLoad:function(ds,r,o){this.cursor=o.params?o.params.start:0;var d=this.getPageData(),ap=d.activePage,ps=d.pages;this.afterTextEl.dom.innerHTML=String.format(this.afterPageText,d.pages);this.field.dom.value=ap;this.first.setDisabled(ap==1);this.prev.setDisabled(ap==1);this.next.setDisabled(ap==ps);this.last.setDisabled(ap==ps);this.loading.enable();this.updateInfo();},getPageData:function(){var A=this.ds.getTotalCount();return {total:A,activePage:Math.ceil((this.cursor+this.pageSize)/this.pageSize),pages:A<this.pageSize?1:Math.ceil(A/this.pageSize)};},onLoadError:function(){this.loading.enable();},onPagingKeydown:function(e){var k=e.getKey();var d=this.getPageData();if(k==e.RETURN ){var v=this.field.dom.value,A;if(!v||isNaN(A=parseInt(v,10))){this.field.dom.value=d.activePage;return;}
+A=Math.min(Math.max(1,A),d.pages)-1;this.ds.load({params:{start:A*this.pageSize,limit:this.pageSize}});e.stopEvent();}else if(k==e.HOME||(k==e.UP&&e.ctrlKey)||(k==e.PAGEUP&&e.ctrlKey)||(k==e.RIGHT&&e.ctrlKey)||k==e.END||(k==e.DOWN&&e.ctrlKey)||(k==e.LEFT&&e.ctrlKey)||(k==e.PAGEDOWN&&e.ctrlKey)){var A=(k==e.HOME||(k==e.DOWN&&e.ctrlKey)||(k==e.LEFT&&e.ctrlKey)||(k==e.PAGEDOWN&&e.ctrlKey))?1:d.pages;this.field.dom.value=A;this.ds.load({params:{start:(A-1)*this.pageSize,limit:this.pageSize}});e.stopEvent();}else if(k==e.UP||k==e.RIGHT||k==e.PAGEUP||k==e.DOWN||k==e.LEFT||k==e.PAGEDOWN){var v=this.field.dom.value,A;var B=(e.shiftKey)?10:1;if(k==e.DOWN||k==e.LEFT||k==e.PAGEDOWN)B*=-1;if(!v||isNaN(A=parseInt(v,10))){this.field.dom.value=d.activePage;return;}else if(parseInt(v,10)+B>=1&parseInt(v,10)+B<=d.pages){this.field.dom.value=parseInt(v,10)+B;A=Math.min(Math.max(1,A+B),d.pages)-1;this.ds.load({params:{start:A*this.pageSize,limit:this.pageSize}});}
+e.stopEvent();}},beforeLoad:function(){if(this.loading){this.loading.disable();}},onClick:function(A){var ds=this.ds;if(!ds){return;}switch(A){case "first":ds.load({params:{start:0,limit:this.pageSize}});break;case "prev":ds.load({params:{start:Math.max(0,this.cursor-this.pageSize),limit:this.pageSize}});break;case "next":ds.load({params:{start:this.cursor+this.pageSize,limit:this.pageSize}});break;case "last":var B=ds.getTotalCount();var C=B%this.pageSize;var D=C?(B-C):B-this.pageSize;ds.load({params:{start:D,limit:this.pageSize}});break;case "refresh":ds.load({params:{start:this.cursor,limit:this.pageSize}});break;}},unbind:function(ds){ds.un("beforeload",this.beforeLoad,this);ds.un("load",this.onLoad,this);ds.un("loadexception",this.onLoadError,this);ds.un("remove",this.updateInfo,this);ds.un("add",this.updateInfo,this);this.ds=undefined;},bind:function(ds){ds.on("beforeload",this.beforeLoad,this);ds.on("load",this.onLoad,this);ds.on("loadexception",this.onLoadError,this);ds.on("remove",this.updateInfo,this);ds.on("add",this.updateInfo,this);this.ds=ds;}});
+//Roo/bootstrap/MessageBar.js
+Roo.bootstrap.MessageBar=function(A){Roo.bootstrap.MessageBar.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.MessageBar,Roo.bootstrap.Component,{html:'',weight:'info',closable:false,fixed:false,beforeClass:'bootstrap-sticky-wrap',getAutoCreate:function(){var A={tag:'div',cls:'alert alert-dismissable alert-'+this.weight,cn:[{tag:'span',cls:'message',html:this.html||''}]};if(this.fixed){A.cls+=' alert-messages-fixed';}if(this.closable){A.cn.push({tag:'button',cls:'close',html:'x'});}return A;},onRender:function(ct,A){Roo.bootstrap.Component.superclass.onRender.call(this,ct,A);if(!this.el){var B=Roo.apply({},this.getAutoCreate());B.id=Roo.id();if(this.cls){B.cls+=' '+this.cls;}if(this.style){B.style=this.style;}
+this.el=Roo.get(document.body).createChild(B,Roo.select('.'+this.beforeClass,true).first());this.el.setVisibilityMode(Roo.Element.DISPLAY);}
+this.el.select('>button.close').on('click',this.hide,this);},show:function(){if(!this.rendered){this.render();}
+this.el.show();this.fireEvent('show',this);},hide:function(){if(!this.rendered){this.render();}
+this.el.hide();this.fireEvent('hide',this);},update:function(){this.el.select('>.message',true).first().dom.innerHTML=this.html||'';}});
+//Roo/bootstrap/Graph.js
+Roo.bootstrap.Graph=function(A){Roo.bootstrap.Graph.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.Graph,Roo.bootstrap.Component,{sm:4,md:5,graphtype:'bar',g_height:250,g_width:400,g_x:50,g_y:50,g_r:30,opts:{g_type:'soft',g_gutter:'20%'},title:false,getAutoCreate:function(){var A={tag:'div',html:null};return A;},onRender:function(ct,A){Roo.bootstrap.Graph.superclass.onRender.call(this,ct,A);this.raphael=Raphael(this.el.dom);},load:function(A,B,C){this.raphael.clear();if(!A){A=this.graphtype;}if(!C){C=this.opts;}var r=this.raphael,D=function(){this.flag=r.popup(this.bar.x,this.bar.y,this.bar.value||"0").insertBefore(this);},E=function(){this.flag.animate({opacity:0},300,function(){this.remove();});},F=function(){this.sector.stop();this.sector.scale(1.1,1.1,this.cx,this.cy);if(this.label){this.label[0].stop();this.label[0].attr({r:7.5});this.label[1].attr({"font-weight":800});}},G=function(){this.sector.animate({transform:'s1 1 '+this.cx+' '+this.cy},500,"bounce");if(this.label){this.label[0].animate({r:5},500,"bounce");this.label[1].attr({"font-weight":400});}};switch(A){case 'bar':this.raphael.barchart(this.g_x,this.g_y,this.g_width,this.g_height,B,C).hover(D,E);break;case 'hbar':this.raphael.hbarchart(this.g_x,this.g_y,this.g_width,this.g_height,B,C).hover(D,E);break;case 'pie':this.raphael.piechart(this.g_x,this.g_y,this.g_r,B,C).hover(F,G);break;}if(this.title){this.raphael.text(this.title.x,this.title.y,this.title.text).attr(this.title.attr);}},setTitle:function(o){this.title=o;},initEvents:function(){if(!this.href){this.el.on('click',this.onClick,this);}},onClick:function(e){Roo.log('img onclick');this.fireEvent('click',this,e);}});
+//Roo/bootstrap/dash/NumberBox.js
+Roo.bootstrap.dash=Roo.bootstrap.dash||{};Roo.bootstrap.dash.NumberBox=function(A){Roo.bootstrap.dash.NumberBox.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.dash.NumberBox,Roo.bootstrap.Component,{headline:'',content:'',icon:'',footer:'',fhref:'',ficon:'',getAutoCreate:function(){var A={tag:'div',cls:'small-box ',cn:[{tag:'div',cls:'inner',cn:[{tag:'h3',cls:'roo-headline',html:this.headline},{tag:'p',cls:'roo-content',html:this.content}]}]};if(this.icon){A.cn.push({tag:'div',cls:'icon',cn:[{tag:'i',cls:'ion '+this.icon}]});}if(this.footer){var footer={tag:'a',cls:'small-box-footer',href:this.fhref||'#',html:this.footer};A.cn.push(footer);}return A;},onRender:function(ct,A){Roo.bootstrap.dash.NumberBox.superclass.onRender.call(this,ct,A);},setHeadline:function(A){this.el.select('.roo-headline',true).first().dom.innerHTML=A;},setFooter:function(A,B){this.el.select('a.small-box-footer',true).first().dom.innerHTML=A;if(B){this.el.select('a.small-box-footer',true).first().attr('href',B);}},setContent:function(A){this.el.select('.roo-content',true).first().dom.innerHTML=A;},initEvents:function(){}});
+//Roo/bootstrap/dash/TabBox.js
+Roo.bootstrap.dash=Roo.bootstrap.dash||{};Roo.bootstrap.dash.TabBox=function(A){Roo.bootstrap.dash.TabBox.superclass.constructor.call(this,A);this.addEvents({"addpane":true,"activatepane":true});this.panes=[];};Roo.extend(Roo.bootstrap.dash.TabBox,Roo.bootstrap.Component,{title:'',icon:false,showtabs:true,tabScrollable:false,getChildContainer:function(){return this.el.select('.tab-content',true).first();},getAutoCreate:function(){var A={tag:'li',cls:'pull-left header',html:this.title,cn:[]};if(this.icon){A.cn.push({tag:'i',cls:'fa '+this.icon});}var h={tag:'ul',cls:'nav nav-tabs pull-right',cn:[A]};if(this.tabScrollable){h={tag:'div',cls:'tab-header',cn:[{tag:'ul',cls:'nav nav-tabs pull-right',cn:[A]}]}}var B={tag:'div',cls:'nav-tabs-custom',cn:[h,{tag:'div',cls:'tab-content no-padding',cn:[]}]};return B;},initEvents:function(){this.on('addpane',this.onAddPane,this);},setTitle:function(A){this.el.select('.nav-tabs .header',true).first().dom.innerHTML=A;},onAddPane:function(A){this.panes.push(A);if(!this.showtabs){return;}var B=this.el.select('.nav-tabs',true).first();var C=B.select('.nav-tab',true);var D=C.getCount();;var E=B.createChild({tag:'li',cls:'nav-tab'+(D?'':' active'),cn:[{tag:'a',href:'#',html:A.title}]},D?C.first().dom:B.select('.header',true).first().dom);A.tab=E;E.on('click',this.onTabClick.createDelegate(this,[A],true));if(!D){A.el.addClass('active');}},onTabClick:function(ev,un,ob,A){ev.preventDefault();this.el.select('.nav-tabs li.nav-tab',true).removeClass('active');A.tab.addClass('active');this.getChildContainer().select('.tab-pane',true).removeClass('active');this.fireEvent('activatepane',A);A.el.addClass('active');A.fireEvent('activate');},getActivePane:function(){var r=false;Roo.each(this.panes,function(p){if(p.el.hasClass('active')){r=p;return false;}return;});return r;}});
+//Roo/bootstrap/dash/TabPane.js
+Roo.bootstrap.dash=Roo.bootstrap.dash||{};Roo.bootstrap.dash.TabPane=function(A){Roo.bootstrap.dash.TabPane.superclass.constructor.call(this,A);this.addEvents({"activate":true});};Roo.extend(Roo.bootstrap.dash.TabPane,Roo.bootstrap.Component,{active:false,title:'',tab:false,getAutoCreate:function(){var A={tag:'div',cls:'tab-pane'};if(this.active){A.cls+=' active';}return A;},initEvents:function(){this.parent().fireEvent('addpane',this)},setTitle:function(A){if(!this.tab){return;}
+this.title=A;this.tab.select('a',true).first().dom.innerHTML=A;}});
+//Roo/bootstrap/menu/Menu.js
+Roo.bootstrap.menu=Roo.bootstrap.menu||{};Roo.bootstrap.menu.Menu=function(A){Roo.bootstrap.menu.Menu.superclass.constructor.call(this,A);this.addEvents({beforeshow:true,beforehide:true,show:true,hide:true,click:true});};Roo.extend(Roo.bootstrap.menu.Menu,Roo.bootstrap.Component,{submenu:false,html:'',weight:'default',icon:false,pos:'bottom',getChildContainer:function(){if(this.isSubMenu){return this.el;}return this.el.select('ul.dropdown-menu',true).first();},getAutoCreate:function(){var A=[{tag:'span',cls:'roo-menu-text',html:this.html}];if(this.icon){A.unshift({tag:'i',cls:'fa '+this.icon})}var B={tag:'div',cls:'btn-group',cn:[{tag:'button',cls:'dropdown-button btn btn-'+this.weight,cn:A},{tag:'button',cls:'dropdown-toggle btn btn-'+this.weight,cn:[{tag:'span',cls:'caret'}]},{tag:'ul',cls:'dropdown-menu'}]};if(this.pos=='top'){B.cls+=' dropup';}if(this.isSubMenu){B={tag:'ul',cls:'dropdown-menu'}}return B;},onRender:function(ct,A){this.isSubMenu=ct.hasClass('dropdown-submenu');Roo.bootstrap.menu.Menu.superclass.onRender.call(this,ct,A);},initEvents:function(){if(this.isSubMenu){return;}
+this.hidden=true;this.triggerEl=this.el.select('button.dropdown-toggle',true).first();this.triggerEl.on('click',this.onTriggerPress,this);this.buttonEl=this.el.select('button.dropdown-button',true).first();this.buttonEl.on('click',this.onClick,this);},list:function(){if(this.isSubMenu){return this.el;}return this.el.select('ul.dropdown-menu',true).first();},onClick:function(e){this.fireEvent("click",this,e);},onTriggerPress:function(e){if(this.isVisible()){this.hide();}else {this.show();}},isVisible:function(){return !this.hidden;},show:function(){this.fireEvent("beforeshow",this);this.hidden=false;this.el.addClass('open');Roo.get(document).on("mouseup",this.onMouseUp,this);this.fireEvent("show",this);},hide:function(){this.fireEvent("beforehide",this);this.hidden=true;this.el.removeClass('open');Roo.get(document).un("mouseup",this.onMouseUp);this.fireEvent("hide",this);},onMouseUp:function(){this.hide();}});
+//Roo/bootstrap/menu/Item.js
+Roo.bootstrap.menu=Roo.bootstrap.menu||{};Roo.bootstrap.menu.Item=function(A){Roo.bootstrap.menu.Item.superclass.constructor.call(this,A);this.addEvents({mouseover:true,mouseout:true,click:true});};Roo.extend(Roo.bootstrap.menu.Item,Roo.bootstrap.Component,{submenu:false,href:'',html:'',preventDefault:true,disable:false,icon:false,pos:'right',getAutoCreate:function(){var A=[{tag:'span',cls:'roo-menu-item-text',html:this.html}];if(this.icon){A.unshift({tag:'i',cls:'fa '+this.icon})}var B={tag:'li',cn:[{tag:'a',href:this.href||'#',cn:A}]};if(this.disable){B.cls=(typeof(B.cls)=='undefined')?'disabled':(B.cls+' disabled');}if(this.submenu){B.cls=(typeof(B.cls)=='undefined')?'dropdown-submenu':(B.cls+' dropdown-submenu');if(this.pos=='left'){B.cls=(typeof(B.cls)=='undefined')?'pull-left':(B.cls+' pull-left');}}return B;},initEvents:function(){this.el.on('mouseover',this.onMouseOver,this);this.el.on('mouseout',this.onMouseOut,this);this.el.select('a',true).first().on('click',this.onClick,this);},onClick:function(e){if(this.preventDefault){e.preventDefault();}
+this.fireEvent("click",this,e);},onMouseOver:function(e){if(this.submenu&&this.pos=='left'){this.el.select('ul.dropdown-menu',true).first().setLeft(this.el.select('ul.dropdown-menu',true).first().getWidth()*-1);}
+this.fireEvent("mouseover",this,e);},onMouseOut:function(e){this.fireEvent("mouseout",this,e);}});
+//Roo/bootstrap/menu/Separator.js
+Roo.bootstrap.menu=Roo.bootstrap.menu||{};Roo.bootstrap.menu.Separator=function(A){Roo.bootstrap.menu.Separator.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.menu.Separator,Roo.bootstrap.Component,{getAutoCreate:function(){var A={tag:'li',cls:'divider'};return A;}});
+//Roo/bootstrap/Tooltip.js
+Roo.bootstrap.Tooltip=function(A){Roo.bootstrap.Tooltip.superclass.constructor.call(this,A);};Roo.apply(Roo.bootstrap.Tooltip,{currentEl:false,currentTip:false,currentRegion:false,init:function(){Roo.get(document).on('mouseover',this.enter,this);Roo.get(document).on('mouseout',this.leave,this);this.currentTip=new Roo.bootstrap.Tooltip();},enter:function(ev){var A=ev.getTarget();var el=Roo.fly(A);if(this.currentEl){if(this.currentEl==el){return;}if(A!=this.currentEl.dom&&this.currentEl.contains(A)){return;}}if(this.currentTip.el){this.currentTip.el.hide();}if(!el.attr('tooltip')){return;}
+this.currentEl=el;this.currentTip.bind(el);this.currentRegion=Roo.lib.Region.getRegion(A);this.currentTip.enter();},leave:function(ev){var A=ev.getTarget();if(!this.currentEl){return;}if(A!=this.currentEl.dom){return;}var xy=ev.getXY();if(this.currentRegion.contains(new Roo.lib.Region(xy[1],xy[0],xy[1],xy[0]))){return;}if(this.currentTip){this.currentTip.leave();}
+this.currentEl=false;},alignment:{'left':['r-l',[-2,0],'right'],'right':['l-r',[2,0],'left'],'bottom':['t-b',[0,2],'top'],'top':['b-t',[0,-2],'bottom']}});Roo.extend(Roo.bootstrap.Tooltip,Roo.bootstrap.Component,{bindEl:false,delay:null,timeout:null,hoverState:null,placement:'bottom',getAutoCreate:function(){var A={cls:'tooltip',role:'tooltip',cn:[{cls:'tooltip-arrow'},{cls:'tooltip-inner'}]};return A;},bind:function(el){this.bindEl=el;},enter:function(){if(this.timeout!=null){clearTimeout(this.timeout);}
+this.hoverState='in';if(!this.delay||!this.delay.show){this.show();return;}var _t=this;this.timeout=setTimeout(function(){if(_t.hoverState=='in'){_t.show();}},this.delay.show);},leave:function(){clearTimeout(this.timeout);this.hoverState='out';if(!this.delay||!this.delay.hide){this.hide();return}var _t=this;this.timeout=setTimeout(function(){if(_t.hoverState=='out'){_t.hide();Roo.bootstrap.Tooltip.currentEl=false;}},delay)},show:function(){if(!this.el){this.render(document.body);}
+this.el.select('.tooltip-inner',true).first().dom.innerHTML=this.bindEl.attr('tooltip');this.el.removeClass(['fade','top','bottom','left','right','in']);var A=typeof this.placement=='function'?this.placement.call(this,this.el,on_el):this.placement;var B=/\s?auto?\s?/i;var C=B.test(A);if(C){A=A.replace(B,'')||'top';}
+this.el.show();this.el.addClass(A);var p=this.getPosition();var D=this.el.getBox();if(C){}var E=Roo.bootstrap.Tooltip.alignment[A];this.el.alignTo(this.bindEl,E[0],E[1]);this.el.addClass('in fade');this.hoverState=null;if(this.el.hasClass('fade')){}},hide:function(){if(!this.el){return;}
+this.el.removeClass('in');}});
+//Roo/bootstrap/LocationPicker.js
+Roo.bootstrap.LocationPicker=function(A){Roo.bootstrap.LocationPicker.superclass.constructor.call(this,A);this.addEvents({initial:true,positionchanged:true,resize:true,show:true,hide:true,mapClick:true,mapRightClick:true,markerClick:true,markerRightClick:true,OverlayViewDraw:true,OverlayViewOnAdd:true,OverlayViewOnRemove:true,OverlayViewShow:true,OverlayViewHide:true});};Roo.extend(Roo.bootstrap.LocationPicker,Roo.bootstrap.Component,{gMapContext:false,latitude:0,longitude:0,zoom:15,mapTypeId:false,mapTypeControl:false,disableDoubleClickZoom:false,scrollwheel:true,streetViewControl:false,radius:0,locationName:'',draggable:true,enableAutocomplete:false,enableReverseGeocode:true,markerTitle:'',getAutoCreate:function(){var A={tag:'div',cls:'roo-location-picker'};return A},initEvents:function(ct,A){if(!this.el.getWidth()||this.isApplied()){return;}
+this.el.setVisibilityMode(Roo.Element.DISPLAY);this.initial();},initial:function(){if(!this.mapTypeId){this.mapTypeId=google.maps.MapTypeId.ROADMAP;}
+this.gMapContext=this.GMapContext();this.initOverlayView();this.OverlayView=new Roo.bootstrap.LocationPicker.OverlayView(this.gMapContext.map);var A=this;google.maps.event.addListener(this.gMapContext.marker,"dragend",function(B){A.setPosition(A.gMapContext.marker.position);});google.maps.event.addListener(this.gMapContext.map,'click',function(B){A.fireEvent('mapClick',this,B);});google.maps.event.addListener(this.gMapContext.map,'rightclick',function(B){A.fireEvent('mapRightClick',this,B);});google.maps.event.addListener(this.gMapContext.marker,'click',function(B){A.fireEvent('markerClick',this,B);});google.maps.event.addListener(this.gMapContext.marker,'rightclick',function(B){A.fireEvent('markerRightClick',this,B);});this.setPosition(this.gMapContext.location);this.fireEvent('initial',this,this.gMapContext.location);},initOverlayView:function(){var A=this;Roo.bootstrap.LocationPicker.OverlayView.prototype=Roo.apply(new google.maps.OverlayView(),{draw:function(){A.fireEvent('OverlayViewDraw',A);},onAdd:function(){A.fireEvent('OverlayViewOnAdd',A);},onRemove:function(){A.fireEvent('OverlayViewOnRemove',A);},show:function(B){A.fireEvent('OverlayViewShow',A,B);},hide:function(){A.fireEvent('OverlayViewHide',A);}});},fromLatLngToContainerPixel:function(A){return this.OverlayView.getProjection().fromLatLngToContainerPixel(A.latLng);},isApplied:function(){return this.getGmapContext()==false?false:true;},getGmapContext:function(){return this.gMapContext},GMapContext:function(){var A=new google.maps.Map(this.el.dom,this);var B=new google.maps.Marker({position:new google.maps.LatLng(this.latitude,this.longitude),map:A,title:this.markerTitle,draggable:this.draggable});return {map:A,marker:B,circle:null,location:B.position,radius:this.radius,locationName:this.locationName,addressComponents:{formatted_address:null,addressLine1:null,addressLine2:null,streetName:null,streetNumber:null,city:null,district:null,state:null,stateOrProvince:null},settings:this,domContainer:this.el.dom,geodecoder:new google.maps.Geocoder()};},drawCircle:function(A,B,C){if(this.gMapContext.circle!=null){this.gMapContext.circle.setMap(null);}if(B>0){B*=1;C=Roo.apply({},C,{strokeColor:"#0000FF",strokeOpacity:.35,strokeWeight:2,fillColor:"#0000FF",fillOpacity:.2});C.map=this.gMapContext.map;C.radius=B;C.center=A;this.gMapContext.circle=new google.maps.Circle(C);return this.gMapContext.circle;}return null;},setPosition:function(A){this.gMapContext.location=A;this.gMapContext.marker.setPosition(A);this.gMapContext.map.panTo(A);this.drawCircle(A,this.gMapContext.radius,{});var B=this;if(this.gMapContext.settings.enableReverseGeocode){this.gMapContext.geodecoder.geocode({latLng:this.gMapContext.location},function(C,D){if(D==google.maps.GeocoderStatus.OK&&C.length>0){B.gMapContext.locationName=C[0].formatted_address;B.gMapContext.addressComponents=B.address_component_from_google_geocode(C[0].address_components);B.fireEvent('positionchanged',this,A);}});return;}
+this.fireEvent('positionchanged',this,A);},resize:function(){google.maps.event.trigger(this.gMapContext.map,"resize");this.gMapContext.map.setCenter(this.gMapContext.marker.position);this.fireEvent('resize',this);},setPositionByLatLng:function(A,B){this.setPosition(new google.maps.LatLng(A,B));},getCurrentPosition:function(){return {latitude:this.gMapContext.location.lat(),longitude:this.gMapContext.location.lng()};},getAddressName:function(){return this.gMapContext.locationName;},getAddressComponents:function(){return this.gMapContext.addressComponents;},address_component_from_google_geocode:function(A){var B={};for(var i=0;i<A.length;i++){var C=A[i];if(C.types.indexOf("postal_code")>=0){B.postalCode=C.short_name;}else if(C.types.indexOf("street_number")>=0){B.streetNumber=C.short_name;}else if(C.types.indexOf("route")>=0){B.streetName=C.short_name;}else if(C.types.indexOf("neighborhood")>=0){B.city=C.short_name;}else if(C.types.indexOf("locality")>=0){B.city=C.short_name;}else if(C.types.indexOf("sublocality")>=0){B.district=C.short_name;}else if(C.types.indexOf("administrative_area_level_1")>=0){B.stateOrProvince=C.short_name;}else if(C.types.indexOf("country")>=0){B.country=C.short_name;}}
+B.addressLine1=[B.streetNumber,B.streetName].join(" ").trim();B.addressLine2="";return B;},setZoomLevel:function(A){this.gMapContext.map.setZoom(A);},show:function(){if(!this.el){return;}
+this.el.show();this.resize();this.fireEvent('show',this);},hide:function(){if(!this.el){return;}
+this.el.hide();this.fireEvent('hide',this);}});Roo.apply(Roo.bootstrap.LocationPicker,{OverlayView:function(A,B){B=B||{};this.setMap(A);}});
+//Roo/bootstrap/Alert.js
+Roo.bootstrap.Alert=function(A){Roo.bootstrap.Alert.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Alert,Roo.bootstrap.Component,{title:'',html:'',weight:false,faicon:false,getAutoCreate:function(){var A={tag:'div',cls:'alert',cn:[{tag:'i',cls:'roo-alert-icon'},{tag:'b',cls:'roo-alert-title',html:this.title},{tag:'span',cls:'roo-alert-text',html:this.html}]};if(this.faicon){A.cn[0].cls+=' fa '+this.faicon;}if(this.weight){A.cls+=' alert-'+this.weight;}return A;},initEvents:function(){this.el.setVisibilityMode(Roo.Element.DISPLAY);},setTitle:function(A){this.el.select('.roo-alert-title',true).first().dom.innerHTML=A;},setText:function(A){this.el.select('.roo-alert-text',true).first().dom.innerHTML=A;},setWeight:function(A){if(this.weight){this.el.select('.alert',true).first().removeClass('alert-'+this.weight);}
+this.weight=A;this.el.select('.alert',true).first().addClass('alert-'+this.weight);},setIcon:function(A){if(this.faicon){this.el.select('.roo-alert-icon',true).first().removeClass(['fa','fa-'+this.faicon]);}
+this.faicon=Athis.el.select('.roo-alert-icon',true).first().addClass(['fa','fa-'+this.faicon]);},hide:function(){this.el.hide();},show:function(){this.el.show();}});