ext-yui-adapter-debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:77k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. // for old browsers
  8. window.undefined = window.undefined;
  9. /**
  10.  * @class Ext
  11.  * Ext core utilities and functions.
  12.  * @singleton
  13.  */
  14. Ext = {
  15.     /**
  16.      * The version of the framework
  17.      * @type String
  18.      */
  19.     version : '3.1.0'
  20. };
  21. /**
  22.  * Copies all the properties of config to obj.
  23.  * @param {Object} obj The receiver of the properties
  24.  * @param {Object} config The source of the properties
  25.  * @param {Object} defaults A different object that will also be applied for default values
  26.  * @return {Object} returns obj
  27.  * @member Ext apply
  28.  */
  29. Ext.apply = function(o, c, defaults){
  30.     // no "this" reference for friendly out of scope calls
  31.     if(defaults){
  32.         Ext.apply(o, defaults);
  33.     }
  34.     if(o && c && typeof c == 'object'){
  35.         for(var p in c){
  36.             o[p] = c[p];
  37.         }
  38.     }
  39.     return o;
  40. };
  41. (function(){
  42.     var idSeed = 0,
  43.         toString = Object.prototype.toString,
  44.         ua = navigator.userAgent.toLowerCase(),
  45.         check = function(r){
  46.             return r.test(ua);
  47.         },
  48.         DOC = document,
  49.         isStrict = DOC.compatMode == "CSS1Compat",
  50.         isOpera = check(/opera/),
  51.         isChrome = check(/chrome/),
  52.         isWebKit = check(/webkit/),
  53.         isSafari = !isChrome && check(/safari/),
  54.         isSafari2 = isSafari && check(/applewebkit/4/), // unique to Safari 2
  55.         isSafari3 = isSafari && check(/version/3/),
  56.         isSafari4 = isSafari && check(/version/4/),
  57.         isIE = !isOpera && check(/msie/),
  58.         isIE7 = isIE && check(/msie 7/),
  59.         isIE8 = isIE && check(/msie 8/),
  60.         isIE6 = isIE && !isIE7 && !isIE8,
  61.         isGecko = !isWebKit && check(/gecko/),
  62.         isGecko2 = isGecko && check(/rv:1.8/),
  63.         isGecko3 = isGecko && check(/rv:1.9/),
  64.         isBorderBox = isIE && !isStrict,
  65.         isWindows = check(/windows|win32/),
  66.         isMac = check(/macintosh|mac os x/),
  67.         isAir = check(/adobeair/),
  68.         isLinux = check(/linux/),
  69.         isSecure = /^https/i.test(window.location.protocol);
  70.     // remove css image flicker
  71.     if(isIE6){
  72.         try{
  73.             DOC.execCommand("BackgroundImageCache", false, true);
  74.         }catch(e){}
  75.     }
  76.     Ext.apply(Ext, {
  77.         /**
  78.          * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
  79.          * the IE insecure content warning (<tt>'about:blank'</tt>, except for IE in secure mode, which is <tt>'javascript:""'</tt>).
  80.          * @type String
  81.          */
  82.         SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
  83.         /**
  84.          * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
  85.          * @type Boolean
  86.          */
  87.         isStrict : isStrict,
  88.         /**
  89.          * True if the page is running over SSL
  90.          * @type Boolean
  91.          */
  92.         isSecure : isSecure,
  93.         /**
  94.          * True when the document is fully initialized and ready for action
  95.          * @type Boolean
  96.          */
  97.         isReady : false,
  98.         /**
  99.          * True if the {@link Ext.Fx} Class is available
  100.          * @type Boolean
  101.          * @property enableFx
  102.          */
  103.         /**
  104.          * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
  105.          * @type Boolean
  106.          */
  107.         enableGarbageCollector : true,
  108.         /**
  109.          * True to automatically purge event listeners during garbageCollection (defaults to false).
  110.          * @type Boolean
  111.          */
  112.         enableListenerCollection : false,
  113.         /**
  114.          * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed.
  115.          * Currently not optimized for performance.
  116.          * @type Boolean
  117.          */
  118.         enableNestedListenerRemoval : false,
  119.         /**
  120.          * Indicates whether to use native browser parsing for JSON methods.
  121.          * This option is ignored if the browser does not support native JSON methods.
  122.          * <b>Note: Native JSON methods will not work with objects that have functions.
  123.          * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
  124.          * @type Boolean
  125.          */
  126.         USE_NATIVE_JSON : false,
  127.         /**
  128.          * Copies all the properties of config to obj if they don't already exist.
  129.          * @param {Object} obj The receiver of the properties
  130.          * @param {Object} config The source of the properties
  131.          * @return {Object} returns obj
  132.          */
  133.         applyIf : function(o, c){
  134.             if(o){
  135.                 for(var p in c){
  136.                     if(!Ext.isDefined(o[p])){
  137.                         o[p] = c[p];
  138.                     }
  139.                 }
  140.             }
  141.             return o;
  142.         },
  143.         /**
  144.          * Generates unique ids. If the element already has an id, it is unchanged
  145.          * @param {Mixed} el (optional) The element to generate an id for
  146.          * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
  147.          * @return {String} The generated Id.
  148.          */
  149.         id : function(el, prefix){
  150.             return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);
  151.         },
  152.         /**
  153.          * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method
  154.          * also adds the function "override()" to the subclass that can be used to override members of the class.</p>
  155.          * For example, to create a subclass of Ext GridPanel:
  156.          * <pre><code>
  157. MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
  158.     constructor: function(config) {
  159. //      Create configuration for this Grid.
  160.         var store = new Ext.data.Store({...});
  161.         var colModel = new Ext.grid.ColumnModel({...});
  162. //      Create a new config object containing our computed properties
  163. //      *plus* whatever was in the config parameter.
  164.         config = Ext.apply({
  165.             store: store,
  166.             colModel: colModel
  167.         }, config);
  168.         MyGridPanel.superclass.constructor.call(this, config);
  169. //      Your postprocessing here
  170.     },
  171.     yourMethod: function() {
  172.         // etc.
  173.     }
  174. });
  175. </code></pre>
  176.          *
  177.          * <p>This function also supports a 3-argument call in which the subclass's constructor is
  178.          * passed as an argument. In this form, the parameters are as follows:</p>
  179.          * <div class="mdetail-params"><ul>
  180.          * <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li>
  181.          * <li><code>superclass</code> : Function <div class="sub-desc">The constructor of class being extended</div></li>
  182.          * <li><code>overrides</code> : Object <div class="sub-desc">A literal with members which are copied into the subclass's
  183.          * prototype, and are therefore shared among all instances of the new class.</div></li>
  184.          * </ul></div>
  185.          *
  186.          * @param {Function} superclass The constructor of class being extended.
  187.          * @param {Object} overrides <p>A literal with members which are copied into the subclass's
  188.          * prototype, and are therefore shared between all instances of the new class.</p>
  189.          * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used
  190.          * to define the constructor of the new class, and is returned. If this property is
  191.          * <i>not</i> specified, a constructor is generated and returned which just calls the
  192.          * superclass's constructor passing on its parameters.</p>
  193.          * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p>
  194.          * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided.
  195.          */
  196.         extend : function(){
  197.             // inline overrides
  198.             var io = function(o){
  199.                 for(var m in o){
  200.                     this[m] = o[m];
  201.                 }
  202.             };
  203.             var oc = Object.prototype.constructor;
  204.             return function(sb, sp, overrides){
  205.                 if(Ext.isObject(sp)){
  206.                     overrides = sp;
  207.                     sp = sb;
  208.                     sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
  209.                 }
  210.                 var F = function(){},
  211.                     sbp,
  212.                     spp = sp.prototype;
  213.                 F.prototype = spp;
  214.                 sbp = sb.prototype = new F();
  215.                 sbp.constructor=sb;
  216.                 sb.superclass=spp;
  217.                 if(spp.constructor == oc){
  218.                     spp.constructor=sp;
  219.                 }
  220.                 sb.override = function(o){
  221.                     Ext.override(sb, o);
  222.                 };
  223.                 sbp.superclass = sbp.supr = (function(){
  224.                     return spp;
  225.                 });
  226.                 sbp.override = io;
  227.                 Ext.override(sb, overrides);
  228.                 sb.extend = function(o){return Ext.extend(sb, o);};
  229.                 return sb;
  230.             };
  231.         }(),
  232.         /**
  233.          * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
  234.          * Usage:<pre><code>
  235. Ext.override(MyClass, {
  236.     newMethod1: function(){
  237.         // etc.
  238.     },
  239.     newMethod2: function(foo){
  240.         // etc.
  241.     }
  242. });
  243. </code></pre>
  244.          * @param {Object} origclass The class to override
  245.          * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
  246.          * containing one or more methods.
  247.          * @method override
  248.          */
  249.         override : function(origclass, overrides){
  250.             if(overrides){
  251.                 var p = origclass.prototype;
  252.                 Ext.apply(p, overrides);
  253.                 if(Ext.isIE && overrides.hasOwnProperty('toString')){
  254.                     p.toString = overrides.toString;
  255.                 }
  256.             }
  257.         },
  258.         /**
  259.          * Creates namespaces to be used for scoping variables and classes so that they are not global.
  260.          * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  261.          * <pre><code>
  262. Ext.namespace('Company', 'Company.data');
  263. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  264. Company.Widget = function() { ... }
  265. Company.data.CustomStore = function(config) { ... }
  266. </code></pre>
  267.          * @param {String} namespace1
  268.          * @param {String} namespace2
  269.          * @param {String} etc
  270.          * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
  271.          * @method namespace
  272.          */
  273.         namespace : function(){
  274.             var o, d;
  275.             Ext.each(arguments, function(v) {
  276.                 d = v.split(".");
  277.                 o = window[d[0]] = window[d[0]] || {};
  278.                 Ext.each(d.slice(1), function(v2){
  279.                     o = o[v2] = o[v2] || {};
  280.                 });
  281.             });
  282.             return o;
  283.         },
  284.         /**
  285.          * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2".  Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
  286.          * @param {Object} o
  287.          * @param {String} pre (optional) A prefix to add to the url encoded string
  288.          * @return {String}
  289.          */
  290.         urlEncode : function(o, pre){
  291.             var empty,
  292.                 buf = [],
  293.                 e = encodeURIComponent;
  294.             Ext.iterate(o, function(key, item){
  295.                 empty = Ext.isEmpty(item);
  296.                 Ext.each(empty ? key : item, function(val){
  297.                     buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : '');
  298.                 });
  299.             });
  300.             if(!pre){
  301.                 buf.shift();
  302.                 pre = '';
  303.             }
  304.             return pre + buf.join('');
  305.         },
  306.         /**
  307.          * Takes an encoded URL and and converts it to an object. Example: <pre><code>
  308. Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
  309. Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
  310. </code></pre>
  311.          * @param {String} string
  312.          * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
  313.          * @return {Object} A literal with members
  314.          */
  315.         urlDecode : function(string, overwrite){
  316.             if(Ext.isEmpty(string)){
  317.                 return {};
  318.             }
  319.             var obj = {},
  320.                 pairs = string.split('&'),
  321.                 d = decodeURIComponent,
  322.                 name,
  323.                 value;
  324.             Ext.each(pairs, function(pair) {
  325.                 pair = pair.split('=');
  326.                 name = d(pair[0]);
  327.                 value = d(pair[1]);
  328.                 obj[name] = overwrite || !obj[name] ? value :
  329.                             [].concat(obj[name]).concat(value);
  330.             });
  331.             return obj;
  332.         },
  333.         /**
  334.          * Appends content to the query string of a URL, handling logic for whether to place
  335.          * a question mark or ampersand.
  336.          * @param {String} url The URL to append to.
  337.          * @param {String} s The content to append to the URL.
  338.          * @return (String) The resulting URL
  339.          */
  340.         urlAppend : function(url, s){
  341.             if(!Ext.isEmpty(s)){
  342.                 return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
  343.             }
  344.             return url;
  345.         },
  346.         /**
  347.          * Converts any iterable (numeric indices and a length property) into a true array
  348.          * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
  349.          * For strings, use this instead: "abc".match(/./g) => [a,b,c];
  350.          * @param {Iterable} the iterable object to be turned into a true Array.
  351.          * @return (Array) array
  352.          */
  353.          toArray : function(){
  354.              return isIE ?
  355.                  function(a, i, j, res){
  356.                      res = [];
  357.                      for(var x = 0, len = a.length; x < len; x++) {
  358.                          res.push(a[x]);
  359.                      }
  360.                      return res.slice(i || 0, j || res.length);
  361.                  } :
  362.                  function(a, i, j){
  363.                      return Array.prototype.slice.call(a, i || 0, j || a.length);
  364.                  }
  365.          }(),
  366.         isIterable : function(v){
  367.             //check for array or arguments
  368.             if(Ext.isArray(v) || v.callee){
  369.                 return true;
  370.             }
  371.             //check for node list type
  372.             if(/NodeList|HTMLCollection/.test(toString.call(v))){
  373.                 return true;
  374.             }
  375.             //NodeList has an item and length property
  376.             //IXMLDOMNodeList has nextNode method, needs to be checked first.
  377.             return ((v.nextNode || v.item) && Ext.isNumber(v.length));
  378.         },
  379.         /**
  380.          * Iterates an array calling the supplied function.
  381.          * @param {Array/NodeList/Mixed} array The array to be iterated. If this
  382.          * argument is not really an array, the supplied function is called once.
  383.          * @param {Function} fn The function to be called with each item. If the
  384.          * supplied function returns false, iteration stops and this method returns
  385.          * the current <code>index</code>. This function is called with
  386.          * the following arguments:
  387.          * <div class="mdetail-params"><ul>
  388.          * <li><code>item</code> : <i>Mixed</i>
  389.          * <div class="sub-desc">The item at the current <code>index</code>
  390.          * in the passed <code>array</code></div></li>
  391.          * <li><code>index</code> : <i>Number</i>
  392.          * <div class="sub-desc">The current index within the array</div></li>
  393.          * <li><code>allItems</code> : <i>Array</i>
  394.          * <div class="sub-desc">The <code>array</code> passed as the first
  395.          * argument to <code>Ext.each</code>.</div></li>
  396.          * </ul></div>
  397.          * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed.
  398.          * Defaults to the <code>item</code> at the current <code>index</code>
  399.          * within the passed <code>array</code>.
  400.          * @return See description for the fn parameter.
  401.          */
  402.         each : function(array, fn, scope){
  403.             if(Ext.isEmpty(array, true)){
  404.                 return;
  405.             }
  406.             if(!Ext.isIterable(array) || Ext.isPrimitive(array)){
  407.                 array = [array];
  408.             }
  409.             for(var i = 0, len = array.length; i < len; i++){
  410.                 if(fn.call(scope || array[i], array[i], i, array) === false){
  411.                     return i;
  412.                 };
  413.             }
  414.         },
  415.         /**
  416.          * Iterates either the elements in an array, or each of the properties in an object.
  417.          * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
  418.          * @param {Object/Array} object The object or array to be iterated
  419.          * @param {Function} fn The function to be called for each iteration.
  420.          * The iteration will stop if the supplied function returns false, or
  421.          * all array elements / object properties have been covered. The signature
  422.          * varies depending on the type of object being interated:
  423.          * <div class="mdetail-params"><ul>
  424.          * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
  425.          * <div class="sub-desc">
  426.          * When iterating an array, the supplied function is called with each item.</div></li>
  427.          * <li>Objects : <tt>(String key, Object value, Object)</tt>
  428.          * <div class="sub-desc">
  429.          * When iterating an object, the supplied function is called with each key-value pair in
  430.          * the object, and the iterated object</div></li>
  431.          * </ul></div>
  432.          * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to
  433.          * the <code>object</code> being iterated.
  434.          */
  435.         iterate : function(obj, fn, scope){
  436.             if(Ext.isEmpty(obj)){
  437.                 return;
  438.             }
  439.             if(Ext.isIterable(obj)){
  440.                 Ext.each(obj, fn, scope);
  441.                 return;
  442.             }else if(Ext.isObject(obj)){
  443.                 for(var prop in obj){
  444.                     if(obj.hasOwnProperty(prop)){
  445.                         if(fn.call(scope || obj, prop, obj[prop], obj) === false){
  446.                             return;
  447.                         };
  448.                     }
  449.                 }
  450.             }
  451.         },
  452.         /**
  453.          * Return the dom node for the passed String (id), dom node, or Ext.Element.
  454.          * Here are some examples:
  455.          * <pre><code>
  456. // gets dom node based on id
  457. var elDom = Ext.getDom('elId');
  458. // gets dom node based on the dom node
  459. var elDom1 = Ext.getDom(elDom);
  460. // If we don&#39;t know if we are working with an
  461. // Ext.Element or a dom node use Ext.getDom
  462. function(el){
  463.     var dom = Ext.getDom(el);
  464.     // do something with the dom node
  465. }
  466.          * </code></pre>
  467.          * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
  468.          * when this method is called to be successful.
  469.          * @param {Mixed} el
  470.          * @return HTMLElement
  471.          */
  472.         getDom : function(el){
  473.             if(!el || !DOC){
  474.                 return null;
  475.             }
  476.             return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
  477.         },
  478.         /**
  479.          * Returns the current document body as an {@link Ext.Element}.
  480.          * @return Ext.Element The document body
  481.          */
  482.         getBody : function(){
  483.             return Ext.get(DOC.body || DOC.documentElement);
  484.         },
  485.         /**
  486.          * Removes a DOM node from the document.
  487.          */
  488.         /**
  489.          * <p>Removes this element from the document, removes all DOM event listeners, and deletes the cache reference.
  490.          * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval} is
  491.          * <code>true</code>, then DOM event listeners are also removed from all child nodes. The body node
  492.          * will be ignored if passed in.</p>
  493.          * @param {HTMLElement} node The node to remove
  494.          */
  495.         removeNode : isIE && !isIE8 ? function(){
  496.             var d;
  497.             return function(n){
  498.                 if(n && n.tagName != 'BODY'){
  499.                     (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
  500.                     d = d || DOC.createElement('div');
  501.                     d.appendChild(n);
  502.                     d.innerHTML = '';
  503.                     delete Ext.elCache[n.id];
  504.                 }
  505.             }
  506.         }() : function(n){
  507.             if(n && n.parentNode && n.tagName != 'BODY'){
  508.                 (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
  509.                 n.parentNode.removeChild(n);
  510.                 delete Ext.elCache[n.id];
  511.             }
  512.         },
  513.         /**
  514.          * <p>Returns true if the passed value is empty.</p>
  515.          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  516.          * <li>null</li>
  517.          * <li>undefined</li>
  518.          * <li>an empty array</li>
  519.          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  520.          * </ul></div>
  521.          * @param {Mixed} value The value to test
  522.          * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
  523.          * @return {Boolean}
  524.          */
  525.         isEmpty : function(v, allowBlank){
  526.             return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
  527.         },
  528.         /**
  529.          * Returns true if the passed value is a JavaScript array, otherwise false.
  530.          * @param {Mixed} value The value to test
  531.          * @return {Boolean}
  532.          */
  533.         isArray : function(v){
  534.             return toString.apply(v) === '[object Array]';
  535.         },
  536.         /**
  537.          * Returns true if the passed object is a JavaScript date object, otherwise false.
  538.          * @param {Object} object The object to test
  539.          * @return {Boolean}
  540.          */
  541.         isDate : function(v){
  542.             return toString.apply(v) === '[object Date]';
  543.         },
  544.         /**
  545.          * Returns true if the passed value is a JavaScript Object, otherwise false.
  546.          * @param {Mixed} value The value to test
  547.          * @return {Boolean}
  548.          */
  549.         isObject : function(v){
  550.             return !!v && Object.prototype.toString.call(v) === '[object Object]';
  551.         },
  552.         /**
  553.          * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
  554.          * @param {Mixed} value The value to test
  555.          * @return {Boolean}
  556.          */
  557.         isPrimitive : function(v){
  558.             return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
  559.         },
  560.         /**
  561.          * Returns true if the passed value is a JavaScript Function, otherwise false.
  562.          * @param {Mixed} value The value to test
  563.          * @return {Boolean}
  564.          */
  565.         isFunction : function(v){
  566.             return toString.apply(v) === '[object Function]';
  567.         },
  568.         /**
  569.          * Returns true if the passed value is a number. Returns false for non-finite numbers.
  570.          * @param {Mixed} value The value to test
  571.          * @return {Boolean}
  572.          */
  573.         isNumber : function(v){
  574.             return typeof v === 'number' && isFinite(v);
  575.         },
  576.         /**
  577.          * Returns true if the passed value is a string.
  578.          * @param {Mixed} value The value to test
  579.          * @return {Boolean}
  580.          */
  581.         isString : function(v){
  582.             return typeof v === 'string';
  583.         },
  584.         /**
  585.          * Returns true if the passed value is a boolean.
  586.          * @param {Mixed} value The value to test
  587.          * @return {Boolean}
  588.          */
  589.         isBoolean : function(v){
  590.             return typeof v === 'boolean';
  591.         },
  592.         /**
  593.          * Returns true if the passed value is an HTMLElement
  594.          * @param {Mixed} value The value to test
  595.          * @return {Boolean}
  596.          */
  597.         isElement : function(v) {
  598.             return !!v && v.tagName;
  599.         },
  600.         /**
  601.          * Returns true if the passed value is not undefined.
  602.          * @param {Mixed} value The value to test
  603.          * @return {Boolean}
  604.          */
  605.         isDefined : function(v){
  606.             return typeof v !== 'undefined';
  607.         },
  608.         /**
  609.          * True if the detected browser is Opera.
  610.          * @type Boolean
  611.          */
  612.         isOpera : isOpera,
  613.         /**
  614.          * True if the detected browser uses WebKit.
  615.          * @type Boolean
  616.          */
  617.         isWebKit : isWebKit,
  618.         /**
  619.          * True if the detected browser is Chrome.
  620.          * @type Boolean
  621.          */
  622.         isChrome : isChrome,
  623.         /**
  624.          * True if the detected browser is Safari.
  625.          * @type Boolean
  626.          */
  627.         isSafari : isSafari,
  628.         /**
  629.          * True if the detected browser is Safari 3.x.
  630.          * @type Boolean
  631.          */
  632.         isSafari3 : isSafari3,
  633.         /**
  634.          * True if the detected browser is Safari 4.x.
  635.          * @type Boolean
  636.          */
  637.         isSafari4 : isSafari4,
  638.         /**
  639.          * True if the detected browser is Safari 2.x.
  640.          * @type Boolean
  641.          */
  642.         isSafari2 : isSafari2,
  643.         /**
  644.          * True if the detected browser is Internet Explorer.
  645.          * @type Boolean
  646.          */
  647.         isIE : isIE,
  648.         /**
  649.          * True if the detected browser is Internet Explorer 6.x.
  650.          * @type Boolean
  651.          */
  652.         isIE6 : isIE6,
  653.         /**
  654.          * True if the detected browser is Internet Explorer 7.x.
  655.          * @type Boolean
  656.          */
  657.         isIE7 : isIE7,
  658.         /**
  659.          * True if the detected browser is Internet Explorer 8.x.
  660.          * @type Boolean
  661.          */
  662.         isIE8 : isIE8,
  663.         /**
  664.          * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
  665.          * @type Boolean
  666.          */
  667.         isGecko : isGecko,
  668.         /**
  669.          * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
  670.          * @type Boolean
  671.          */
  672.         isGecko2 : isGecko2,
  673.         /**
  674.          * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
  675.          * @type Boolean
  676.          */
  677.         isGecko3 : isGecko3,
  678.         /**
  679.          * True if the detected browser is Internet Explorer running in non-strict mode.
  680.          * @type Boolean
  681.          */
  682.         isBorderBox : isBorderBox,
  683.         /**
  684.          * True if the detected platform is Linux.
  685.          * @type Boolean
  686.          */
  687.         isLinux : isLinux,
  688.         /**
  689.          * True if the detected platform is Windows.
  690.          * @type Boolean
  691.          */
  692.         isWindows : isWindows,
  693.         /**
  694.          * True if the detected platform is Mac OS.
  695.          * @type Boolean
  696.          */
  697.         isMac : isMac,
  698.         /**
  699.          * True if the detected platform is Adobe Air.
  700.          * @type Boolean
  701.          */
  702.         isAir : isAir
  703.     });
  704.     /**
  705.      * Creates namespaces to be used for scoping variables and classes so that they are not global.
  706.      * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  707.      * <pre><code>
  708. Ext.namespace('Company', 'Company.data');
  709. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  710. Company.Widget = function() { ... }
  711. Company.data.CustomStore = function(config) { ... }
  712. </code></pre>
  713.      * @param {String} namespace1
  714.      * @param {String} namespace2
  715.      * @param {String} etc
  716.      * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
  717.      * @method ns
  718.      */
  719.     Ext.ns = Ext.namespace;
  720. })();
  721. Ext.ns("Ext.util", "Ext.lib", "Ext.data");
  722. Ext.elCache = {};
  723. /**
  724.  * @class Function
  725.  * These functions are available on every Function object (any JavaScript function).
  726.  */
  727. Ext.apply(Function.prototype, {
  728.      /**
  729.      * Creates an interceptor function. The passed function is called before the original one. If it returns false,
  730.      * the original one is not called. The resulting function returns the results of the original function.
  731.      * The passed function is called with the parameters of the original function. Example usage:
  732.      * <pre><code>
  733. var sayHi = function(name){
  734.     alert('Hi, ' + name);
  735. }
  736. sayHi('Fred'); // alerts "Hi, Fred"
  737. // create a new function that validates input without
  738. // directly modifying the original function:
  739. var sayHiToFriend = sayHi.createInterceptor(function(name){
  740.     return name == 'Brian';
  741. });
  742. sayHiToFriend('Fred');  // no alert
  743. sayHiToFriend('Brian'); // alerts "Hi, Brian"
  744. </code></pre>
  745.      * @param {Function} fcn The function to call before the original
  746.      * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
  747.      * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
  748.      * @return {Function} The new function
  749.      */
  750.     createInterceptor : function(fcn, scope){
  751.         var method = this;
  752.         return !Ext.isFunction(fcn) ?
  753.                 this :
  754.                 function() {
  755.                     var me = this,
  756.                         args = arguments;
  757.                     fcn.target = me;
  758.                     fcn.method = method;
  759.                     return (fcn.apply(scope || me || window, args) !== false) ?
  760.                             method.apply(me || window, args) :
  761.                             null;
  762.                 };
  763.     },
  764.      /**
  765.      * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
  766.      * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
  767.      * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
  768.      * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
  769.      * executes in the window scope.
  770.      * <p>This method is required when you want to pass arguments to a callback function.  If no arguments
  771.      * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
  772.      * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
  773.      * would simply execute immediately when the code is parsed. Example usage:
  774.      * <pre><code>
  775. var sayHi = function(name){
  776.     alert('Hi, ' + name);
  777. }
  778. // clicking the button alerts "Hi, Fred"
  779. new Ext.Button({
  780.     text: 'Say Hi',
  781.     renderTo: Ext.getBody(),
  782.     handler: sayHi.createCallback('Fred')
  783. });
  784. </code></pre>
  785.      * @return {Function} The new function
  786.     */
  787.     createCallback : function(/*args...*/){
  788.         // make args available, in function below
  789.         var args = arguments,
  790.             method = this;
  791.         return function() {
  792.             return method.apply(window, args);
  793.         };
  794.     },
  795.     /**
  796.      * Creates a delegate (callback) that sets the scope to obj.
  797.      * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
  798.      * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
  799.      * callback points to obj. Example usage:
  800.      * <pre><code>
  801. var sayHi = function(name){
  802.     // Note this use of "this.text" here.  This function expects to
  803.     // execute within a scope that contains a text property.  In this
  804.     // example, the "this" variable is pointing to the btn object that
  805.     // was passed in createDelegate below.
  806.     alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
  807. }
  808. var btn = new Ext.Button({
  809.     text: 'Say Hi',
  810.     renderTo: Ext.getBody()
  811. });
  812. // This callback will execute in the scope of the
  813. // button instance. Clicking the button alerts
  814. // "Hi, Fred. You clicked the "Say Hi" button."
  815. btn.on('click', sayHi.createDelegate(btn, ['Fred']));
  816. </code></pre>
  817.      * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
  818.      * <b>If omitted, defaults to the browser window.</b>
  819.      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  820.      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  821.      * if a number the args are inserted at the specified position
  822.      * @return {Function} The new function
  823.      */
  824.     createDelegate : function(obj, args, appendArgs){
  825.         var method = this;
  826.         return function() {
  827.             var callArgs = args || arguments;
  828.             if (appendArgs === true){
  829.                 callArgs = Array.prototype.slice.call(arguments, 0);
  830.                 callArgs = callArgs.concat(args);
  831.             }else if (Ext.isNumber(appendArgs)){
  832.                 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
  833.                 var applyArgs = [appendArgs, 0].concat(args); // create method call params
  834.                 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
  835.             }
  836.             return method.apply(obj || window, callArgs);
  837.         };
  838.     },
  839.     /**
  840.      * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
  841.      * <pre><code>
  842. var sayHi = function(name){
  843.     alert('Hi, ' + name);
  844. }
  845. // executes immediately:
  846. sayHi('Fred');
  847. // executes after 2 seconds:
  848. sayHi.defer(2000, this, ['Fred']);
  849. // this syntax is sometimes useful for deferring
  850. // execution of an anonymous function:
  851. (function(){
  852.     alert('Anonymous');
  853. }).defer(100);
  854. </code></pre>
  855.      * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
  856.      * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
  857.      * <b>If omitted, defaults to the browser window.</b>
  858.      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  859.      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  860.      * if a number the args are inserted at the specified position
  861.      * @return {Number} The timeout id that can be used with clearTimeout
  862.      */
  863.     defer : function(millis, obj, args, appendArgs){
  864.         var fn = this.createDelegate(obj, args, appendArgs);
  865.         if(millis > 0){
  866.             return setTimeout(fn, millis);
  867.         }
  868.         fn();
  869.         return 0;
  870.     }
  871. });
  872. /**
  873.  * @class String
  874.  * These functions are available on every String object.
  875.  */
  876. Ext.applyIf(String, {
  877.     /**
  878.      * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
  879.      * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
  880.      * <pre><code>
  881. var cls = 'my-class', text = 'Some text';
  882. var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
  883. // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
  884.      * </code></pre>
  885.      * @param {String} string The tokenized string to be formatted
  886.      * @param {String} value1 The value to replace token {0}
  887.      * @param {String} value2 Etc...
  888.      * @return {String} The formatted string
  889.      * @static
  890.      */
  891.     format : function(format){
  892.         var args = Ext.toArray(arguments, 1);
  893.         return format.replace(/{(d+)}/g, function(m, i){
  894.             return args[i];
  895.         });
  896.     }
  897. });
  898. /**
  899.  * @class Array
  900.  */
  901. Ext.applyIf(Array.prototype, {
  902.     /**
  903.      * Checks whether or not the specified object exists in the array.
  904.      * @param {Object} o The object to check for
  905.      * @param {Number} from (Optional) The index at which to begin the search
  906.      * @return {Number} The index of o in the array (or -1 if it is not found)
  907.      */
  908.     indexOf : function(o, from){
  909.         var len = this.length;
  910.         from = from || 0;
  911.         from += (from < 0) ? len : 0;
  912.         for (; from < len; ++from){
  913.             if(this[from] === o){
  914.                 return from;
  915.             }
  916.         }
  917.         return -1;
  918.     },
  919.     /**
  920.      * Removes the specified object from the array.  If the object is not found nothing happens.
  921.      * @param {Object} o The object to remove
  922.      * @return {Array} this array
  923.      */
  924.     remove : function(o){
  925.         var index = this.indexOf(o);
  926.         if(index != -1){
  927.             this.splice(index, 1);
  928.         }
  929.         return this;
  930.     }
  931. });
  932. /**
  933.  * @class Ext
  934.  */
  935. Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
  936.        "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
  937.     /**
  938.      * Namespace alloted for extensions to the framework.
  939.      * @property ux
  940.      * @type Object
  941.      */
  942. Ext.apply(Ext, function(){
  943.     var E = Ext, 
  944.         idSeed = 0,
  945.         scrollWidth = null;
  946.     return {
  947.         /**
  948.         * A reusable empty function
  949.         * @property
  950.         * @type Function
  951.         */
  952.         emptyFn : function(){},
  953.         /**
  954.          * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. 
  955.          * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
  956.          * For other browsers it uses an inline data URL.
  957.          * @type String
  958.          */
  959.         BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
  960.                             'http:/' + '/extjs.com/s.gif' :
  961.                             'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
  962.         extendX : function(supr, fn){
  963.             return Ext.extend(supr, fn(supr.prototype));
  964.         },
  965.         /**
  966.          * Returns the current HTML document object as an {@link Ext.Element}.
  967.          * @return Ext.Element The document
  968.          */
  969.         getDoc : function(){
  970.             return Ext.get(document);
  971.         },
  972.         /**
  973.          * Utility method for validating that a value is numeric, returning the specified default value if it is not.
  974.          * @param {Mixed} value Should be a number, but any type will be handled appropriately
  975.          * @param {Number} defaultValue The value to return if the original value is non-numeric
  976.          * @return {Number} Value, if numeric, else defaultValue
  977.          */
  978.         num : function(v, defaultValue){
  979.             v = Number(Ext.isEmpty(v) || Ext.isBoolean(v) ? NaN : v);
  980.             return isNaN(v) ? defaultValue : v;
  981.         },
  982.         /**
  983.          * <p>Utility method for returning a default value if the passed value is empty.</p>
  984.          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  985.          * <li>null</li>
  986.          * <li>undefined</li>
  987.          * <li>an empty array</li>
  988.          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  989.          * </ul></div>
  990.          * @param {Mixed} value The value to test
  991.          * @param {Mixed} defaultValue The value to return if the original value is empty
  992.          * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
  993.          * @return {Mixed} value, if non-empty, else defaultValue
  994.          */
  995.         value : function(v, defaultValue, allowBlank){
  996.             return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
  997.         },
  998.         /**
  999.          * Escapes the passed string for use in a regular expression
  1000.          * @param {String} str
  1001.          * @return {String}
  1002.          */
  1003.         escapeRe : function(s) {
  1004.             return s.replace(/([-.*+?^${}()|[]/\])/g, "\$1");
  1005.         },
  1006.         sequence : function(o, name, fn, scope){
  1007.             o[name] = o[name].createSequence(fn, scope);
  1008.         },
  1009.         /**
  1010.          * Applies event listeners to elements by selectors when the document is ready.
  1011.          * The event name is specified with an <tt>&#64;</tt> suffix.
  1012.          * <pre><code>
  1013. Ext.addBehaviors({
  1014.     // add a listener for click on all anchors in element with id foo
  1015.     '#foo a&#64;click' : function(e, t){
  1016.         // do something
  1017.     },
  1018.     
  1019.     // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
  1020.     '#foo a, #bar span.some-class&#64;mouseover' : function(){
  1021.         // do something
  1022.     }
  1023. });
  1024.          * </code></pre> 
  1025.          * @param {Object} obj The list of behaviors to apply
  1026.          */
  1027.         addBehaviors : function(o){
  1028.             if(!Ext.isReady){
  1029.                 Ext.onReady(function(){
  1030.                     Ext.addBehaviors(o);
  1031.                 });
  1032.             } else {
  1033.                 var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
  1034.                     parts,
  1035.                     b,
  1036.                     s;
  1037.                 for (b in o) {
  1038.                     if ((parts = b.split('@'))[1]) { // for Object prototype breakers
  1039.                         s = parts[0];
  1040.                         if(!cache[s]){
  1041.                             cache[s] = Ext.select(s);
  1042.                         }
  1043.                         cache[s].on(parts[1], o[b]);
  1044.                     }
  1045.                 }
  1046.                 cache = null;
  1047.             }
  1048.         },
  1049.         
  1050.         /**
  1051.          * Utility method for getting the width of the browser scrollbar. This can differ depending on
  1052.          * operating system settings, such as the theme or font size.
  1053.          * @param {Boolean} force (optional) true to force a recalculation of the value.
  1054.          * @return {Number} The width of the scrollbar.
  1055.          */
  1056.         getScrollBarWidth: function(force){
  1057.             if(!Ext.isReady){
  1058.                 return 0;
  1059.             }
  1060.             
  1061.             if(force === true || scrollWidth === null){
  1062.                     // Append our div, do our calculation and then remove it
  1063.                 var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
  1064.                     child = div.child('div', true);
  1065.                 var w1 = child.offsetWidth;
  1066.                 div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
  1067.                 var w2 = child.offsetWidth;
  1068.                 div.remove();
  1069.                 // Need to add 2 to ensure we leave enough space
  1070.                 scrollWidth = w1 - w2 + 2;
  1071.             }
  1072.             return scrollWidth;
  1073.         },
  1074.         // deprecated
  1075.         combine : function(){
  1076.             var as = arguments, l = as.length, r = [];
  1077.             for(var i = 0; i < l; i++){
  1078.                 var a = as[i];
  1079.                 if(Ext.isArray(a)){
  1080.                     r = r.concat(a);
  1081.                 }else if(a.length !== undefined && !a.substr){
  1082.                     r = r.concat(Array.prototype.slice.call(a, 0));
  1083.                 }else{
  1084.                     r.push(a);
  1085.                 }
  1086.             }
  1087.             return r;
  1088.         },
  1089.         /**
  1090.          * Copies a set of named properties fom the source object to the destination object.
  1091.          * <p>example:<pre><code>
  1092. ImageComponent = Ext.extend(Ext.BoxComponent, {
  1093.     initComponent: function() {
  1094.         this.autoEl = { tag: 'img' };
  1095.         MyComponent.superclass.initComponent.apply(this, arguments);
  1096.         this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
  1097.     }
  1098. });
  1099.          * </code></pre> 
  1100.          * @param {Object} The destination object.
  1101.          * @param {Object} The source object.
  1102.          * @param {Array/String} Either an Array of property names, or a comma-delimited list
  1103.          * of property names to copy.
  1104.          * @return {Object} The modified object.
  1105.         */
  1106.         copyTo : function(dest, source, names){
  1107.             if(Ext.isString(names)){
  1108.                 names = names.split(/[,;s]/);
  1109.             }
  1110.             Ext.each(names, function(name){
  1111.                 if(source.hasOwnProperty(name)){
  1112.                     dest[name] = source[name];
  1113.                 }
  1114.             }, this);
  1115.             return dest;
  1116.         },
  1117.         /**
  1118.          * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
  1119.          * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
  1120.          * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
  1121.          * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
  1122.          * passed into this function in a single call as separate arguments.
  1123.          * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
  1124.          * @param {Mixed} arg2 (optional)
  1125.          * @param {Mixed} etc... (optional)
  1126.          */
  1127.         destroy : function(){
  1128.             Ext.each(arguments, function(arg){
  1129.                 if(arg){
  1130.                     if(Ext.isArray(arg)){
  1131.                         this.destroy.apply(this, arg);
  1132.                     }else if(Ext.isFunction(arg.destroy)){
  1133.                         arg.destroy();
  1134.                     }else if(arg.dom){
  1135.                         arg.remove();
  1136.                     }    
  1137.                 }
  1138.             }, this);
  1139.         },
  1140.         /**
  1141.          * Attempts to destroy and then remove a set of named properties of the passed object.
  1142.          * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
  1143.          * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
  1144.          * @param {Mixed} etc... More property names to destroy and remove.
  1145.          */
  1146.         destroyMembers : function(o, arg1, arg2, etc){
  1147.             for(var i = 1, a = arguments, len = a.length; i < len; i++) {
  1148.                 Ext.destroy(o[a[i]]);
  1149.                 delete o[a[i]];
  1150.             }
  1151.         },
  1152.         /**
  1153.          * Creates a copy of the passed Array with falsy values removed.
  1154.          * @param {Array/NodeList} arr The Array from which to remove falsy values.
  1155.          * @return {Array} The new, compressed Array.
  1156.          */
  1157.         clean : function(arr){
  1158.             var ret = [];
  1159.             Ext.each(arr, function(v){
  1160.                 if(!!v){
  1161.                     ret.push(v);
  1162.                 }
  1163.             });
  1164.             return ret;
  1165.         },
  1166.         /**
  1167.          * Creates a copy of the passed Array, filtered to contain only unique values.
  1168.          * @param {Array} arr The Array to filter
  1169.          * @return {Array} The new Array containing unique values.
  1170.          */
  1171.         unique : function(arr){
  1172.             var ret = [],
  1173.                 collect = {};
  1174.             Ext.each(arr, function(v) {
  1175.                 if(!collect[v]){
  1176.                     ret.push(v);
  1177.                 }
  1178.                 collect[v] = true;
  1179.             });
  1180.             return ret;
  1181.         },
  1182.         /**
  1183.          * Recursively flattens into 1-d Array. Injects Arrays inline.
  1184.          * @param {Array} arr The array to flatten
  1185.          * @return {Array} The new, flattened array.
  1186.          */
  1187.         flatten : function(arr){
  1188.             var worker = [];
  1189.             function rFlatten(a) {
  1190.                 Ext.each(a, function(v) {
  1191.                     if(Ext.isArray(v)){
  1192.                         rFlatten(v);
  1193.                     }else{
  1194.                         worker.push(v);
  1195.                     }
  1196.                 });
  1197.                 return worker;
  1198.             }
  1199.             return rFlatten(arr);
  1200.         },
  1201.         /**
  1202.          * Returns the minimum value in the Array.
  1203.          * @param {Array|NodeList} arr The Array from which to select the minimum value.
  1204.          * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
  1205.          *                   If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1206.          * @return {Object} The minimum value in the Array.
  1207.          */
  1208.         min : function(arr, comp){
  1209.             var ret = arr[0];
  1210.             comp = comp || function(a,b){ return a < b ? -1 : 1; };
  1211.             Ext.each(arr, function(v) {
  1212.                 ret = comp(ret, v) == -1 ? ret : v;
  1213.             });
  1214.             return ret;
  1215.         },
  1216.         /**
  1217.          * Returns the maximum value in the Array
  1218.          * @param {Array|NodeList} arr The Array from which to select the maximum value.
  1219.          * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
  1220.          *                   If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1221.          * @return {Object} The maximum value in the Array.
  1222.          */
  1223.         max : function(arr, comp){
  1224.             var ret = arr[0];
  1225.             comp = comp || function(a,b){ return a > b ? 1 : -1; };
  1226.             Ext.each(arr, function(v) {
  1227.                 ret = comp(ret, v) == 1 ? ret : v;
  1228.             });
  1229.             return ret;
  1230.         },
  1231.         /**
  1232.          * Calculates the mean of the Array
  1233.          * @param {Array} arr The Array to calculate the mean value of.
  1234.          * @return {Number} The mean.
  1235.          */
  1236.         mean : function(arr){
  1237.            return Ext.sum(arr) / arr.length;
  1238.         },
  1239.         /**
  1240.          * Calculates the sum of the Array
  1241.          * @param {Array} arr The Array to calculate the sum value of.
  1242.          * @return {Number} The sum.
  1243.          */
  1244.         sum : function(arr){
  1245.            var ret = 0;
  1246.            Ext.each(arr, function(v) {
  1247.                ret += v;
  1248.            });
  1249.            return ret;
  1250.         },
  1251.         /**
  1252.          * Partitions the set into two sets: a true set and a false set.
  1253.          * Example: 
  1254.          * Example2: 
  1255.          * <pre><code>
  1256. // Example 1:
  1257. Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
  1258. // Example 2:
  1259. Ext.partition(
  1260.     Ext.query("p"),
  1261.     function(val){
  1262.         return val.className == "class1"
  1263.     }
  1264. );
  1265. // true are those paragraph elements with a className of "class1",
  1266. // false set are those that do not have that className.
  1267.          * </code></pre>
  1268.          * @param {Array|NodeList} arr The array to partition
  1269.          * @param {Function} truth (optional) a function to determine truth.  If this is omitted the element
  1270.          *                   itself must be able to be evaluated for its truthfulness.
  1271.          * @return {Array} [true<Array>,false<Array>]
  1272.          */
  1273.         partition : function(arr, truth){
  1274.             var ret = [[],[]];
  1275.             Ext.each(arr, function(v, i, a) {
  1276.                 ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
  1277.             });
  1278.             return ret;
  1279.         },
  1280.         /**
  1281.          * Invokes a method on each item in an Array.
  1282.          * <pre><code>
  1283. // Example:
  1284. Ext.invoke(Ext.query("p"), "getAttribute", "id");
  1285. // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
  1286.          * </code></pre>
  1287.          * @param {Array|NodeList} arr The Array of items to invoke the method on.
  1288.          * @param {String} methodName The method name to invoke.
  1289.          * @param {Anything} ... Arguments to send into the method invocation.
  1290.          * @return {Array} The results of invoking the method on each item in the array.
  1291.          */
  1292.         invoke : function(arr, methodName){
  1293.             var ret = [],
  1294.                 args = Array.prototype.slice.call(arguments, 2);
  1295.             Ext.each(arr, function(v,i) {
  1296.                 if (v && Ext.isFunction(v[methodName])) {
  1297.                     ret.push(v[methodName].apply(v, args));
  1298.                 } else {
  1299.                     ret.push(undefined);
  1300.                 }
  1301.             });
  1302.             return ret;
  1303.         },
  1304.         /**
  1305.          * Plucks the value of a property from each item in the Array
  1306.          * <pre><code>
  1307. // Example:
  1308. Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
  1309.          * </code></pre>
  1310.          * @param {Array|NodeList} arr The Array of items to pluck the value from.
  1311.          * @param {String} prop The property name to pluck from each element.
  1312.          * @return {Array} The value from each item in the Array.
  1313.          */
  1314.         pluck : function(arr, prop){
  1315.             var ret = [];
  1316.             Ext.each(arr, function(v) {
  1317.                 ret.push( v[prop] );
  1318.             });
  1319.             return ret;
  1320.         },
  1321.         /**
  1322.          * <p>Zips N sets together.</p>
  1323.          * <pre><code>
  1324. // Example 1:
  1325. Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
  1326. // Example 2:
  1327. Ext.zip(
  1328.     [ "+", "-", "+"],
  1329.     [  12,  10,  22],
  1330.     [  43,  15,  96],
  1331.     function(a, b, c){
  1332.         return "$" + a + "" + b + "." + c
  1333.     }
  1334. ); // ["$+12.43", "$-10.15", "$+22.96"]
  1335.          * </code></pre>
  1336.          * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
  1337.          * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
  1338.          * @return {Array} The zipped set.
  1339.          */
  1340.         zip : function(){
  1341.             var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
  1342.                 arrs = parts[0],
  1343.                 fn = parts[1][0],
  1344.                 len = Ext.max(Ext.pluck(arrs, "length")),
  1345.                 ret = [];
  1346.             for (var i = 0; i < len; i++) {
  1347.                 ret[i] = [];
  1348.                 if(fn){
  1349.                     ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
  1350.                 }else{
  1351.                     for (var j = 0, aLen = arrs.length; j < aLen; j++){
  1352.                         ret[i].push( arrs[j][i] );
  1353.                     }
  1354.                 }
  1355.             }
  1356.             return ret;
  1357.         },
  1358.         /**
  1359.          * This is shorthand reference to {@link Ext.ComponentMgr#get}.
  1360.          * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
  1361.          * @param {String} id The component {@link Ext.Component#id id}
  1362.          * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
  1363.          * Class was found.
  1364.         */
  1365.         getCmp : function(id){
  1366.             return Ext.ComponentMgr.get(id);
  1367.         },
  1368.         /**
  1369.          * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
  1370.          * you may want to set this to true.
  1371.          * @type Boolean
  1372.          */
  1373.         useShims: E.isIE6 || (E.isMac && E.isGecko2),
  1374.         // inpired by a similar function in mootools library
  1375.         /**
  1376.          * Returns the type of object that is passed in. If the object passed in is null or undefined it
  1377.          * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
  1378.          * <li><b>string</b>: If the object passed is a string</li>
  1379.          * <li><b>number</b>: If the object passed is a number</li>
  1380.          * <li><b>boolean</b>: If the object passed is a boolean value</li>
  1381.          * <li><b>date</b>: If the object passed is a Date object</li>
  1382.          * <li><b>function</b>: If the object passed is a function reference</li>
  1383.          * <li><b>object</b>: If the object passed is an object</li>
  1384.          * <li><b>array</b>: If the object passed is an array</li>
  1385.          * <li><b>regexp</b>: If the object passed is a regular expression</li>
  1386.          * <li><b>element</b>: If the object passed is a DOM Element</li>
  1387.          * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
  1388.          * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
  1389.          * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
  1390.          * </ul></div>
  1391.          * @param {Mixed} object
  1392.          * @return {String}
  1393.          */
  1394.         type : function(o){
  1395.             if(o === undefined || o === null){
  1396.                 return false;
  1397.             }
  1398.             if(o.htmlElement){
  1399.                 return 'element';
  1400.             }
  1401.             var t = typeof o;
  1402.             if(t == 'object' && o.nodeName) {
  1403.                 switch(o.nodeType) {
  1404.                     case 1: return 'element';
  1405.                     case 3: return (/S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
  1406.                 }
  1407.             }
  1408.             if(t == 'object' || t == 'function') {
  1409.                 switch(o.constructor) {
  1410.                     case Array: return 'array';
  1411.                     case RegExp: return 'regexp';
  1412.                     case Date: return 'date';
  1413.                 }
  1414.                 if(Ext.isNumber(o.length) && Ext.isFunction(o.item)) {
  1415.                     return 'nodelist';
  1416.                 }
  1417.             }
  1418.             return t;
  1419.         },
  1420.         intercept : function(o, name, fn, scope){
  1421.             o[name] = o[name].createInterceptor(fn, scope);
  1422.         },
  1423.         // internal
  1424.         callback : function(cb, scope, args, delay){
  1425.             if(Ext.isFunction(cb)){
  1426.                 if(delay){
  1427.                     cb.defer(delay, scope, args || []);
  1428.                 }else{
  1429.                     cb.apply(scope, args || []);
  1430.                 }
  1431.             }
  1432.         }
  1433.     };
  1434. }());
  1435. /**
  1436.  * @class Function
  1437.  * These functions are available on every Function object (any JavaScript function).
  1438.  */
  1439. Ext.apply(Function.prototype, {
  1440.     /**
  1441.      * Create a combined function call sequence of the original function + the passed function.
  1442.      * The resulting function returns the results of the original function.
  1443.      * The passed fcn is called with the parameters of the original function. Example usage:
  1444.      * <pre><code>
  1445. var sayHi = function(name){
  1446.     alert('Hi, ' + name);
  1447. }
  1448. sayHi('Fred'); // alerts "Hi, Fred"
  1449. var sayGoodbye = sayHi.createSequence(function(name){
  1450.     alert('Bye, ' + name);
  1451. });
  1452. sayGoodbye('Fred'); // both alerts show
  1453. </code></pre>
  1454.      * @param {Function} fcn The function to sequence
  1455.      * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
  1456.      * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
  1457.      * @return {Function} The new function
  1458.      */
  1459.     createSequence : function(fcn, scope){
  1460.         var method = this;
  1461.         return !Ext.isFunction(fcn) ?
  1462.                 this :
  1463.                 function(){
  1464.                     var retval = method.apply(this || window, arguments);
  1465.                     fcn.apply(scope || this || window, arguments);
  1466.                     return retval;
  1467.                 };
  1468.     }
  1469. });
  1470. /**
  1471.  * @class String
  1472.  * These functions are available as static methods on the JavaScript String object.
  1473.  */
  1474. Ext.applyIf(String, {
  1475.     /**
  1476.      * Escapes the passed string for ' and 
  1477.      * @param {String} string The string to escape
  1478.      * @return {String} The escaped string
  1479.      * @static
  1480.      */
  1481.     escape : function(string) {
  1482.         return string.replace(/('|\)/g, "\$1");
  1483.     },
  1484.     /**
  1485.      * Pads the left side of a string with a specified character.  This is especially useful
  1486.      * for normalizing number and date strings.  Example usage:
  1487.      * <pre><code>
  1488. var s = String.leftPad('123', 5, '0');
  1489. // s now contains the string: '00123'
  1490.      * </code></pre>
  1491.      * @param {String} string The original string
  1492.      * @param {Number} size The total length of the output string
  1493.      * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
  1494.      * @return {String} The padded string
  1495.      * @static
  1496.      */
  1497.     leftPad : function (val, size, ch) {
  1498.         var result = String(val);
  1499.         if(!ch) {
  1500.             ch = " ";
  1501.         }
  1502.         while (result.length < size) {
  1503.             result = ch + result;
  1504.         }
  1505.         return result;
  1506.     }
  1507. });
  1508. /**
  1509.  * Utility function that allows you to easily switch a string between two alternating values.  The passed value
  1510.  * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
  1511.  * they are already different, the first value passed in is returned.  Note that this method returns the new value
  1512.  * but does not change the current string.
  1513.  * <pre><code>
  1514. // alternate sort directions
  1515. sort = sort.toggle('ASC', 'DESC');
  1516. // instead of conditional logic:
  1517. sort = (sort == 'ASC' ? 'DESC' : 'ASC');
  1518. </code></pre>
  1519.  * @param {String} value The value to compare to the current string
  1520.  * @param {String} other The new value to use if the string already equals the first value passed in
  1521.  * @return {String} The new value
  1522.  */
  1523. String.prototype.toggle = function(value, other){
  1524.     return this == value ? other : value;
  1525. };
  1526. /**
  1527.  * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
  1528.  * <pre><code>
  1529. var s = '  foo bar  ';
  1530. alert('-' + s + '-');         //alerts "- foo bar -"
  1531. alert('-' + s.trim() + '-');  //alerts "-foo bar-"
  1532. </code></pre>
  1533.  * @return {String} The trimmed string
  1534.  */
  1535. String.prototype.trim = function(){
  1536.     var re = /^s+|s+$/g;
  1537.     return function(){ return this.replace(re, ""); };
  1538. }();
  1539. // here to prevent dependency on Date.js
  1540. /**
  1541.  Returns the number of milliseconds between this date and date
  1542.  @param {Date} date (optional) Defaults to now
  1543.  @return {Number} The diff in milliseconds
  1544.  @member Date getElapsed
  1545.  */
  1546. Date.prototype.getElapsed = function(date) {
  1547.     return Math.abs((date || new Date()).getTime()-this.getTime());
  1548. };
  1549. /**
  1550.  * @class Number
  1551.  */
  1552. Ext.applyIf(Number.prototype, {
  1553.     /**
  1554.      * Checks whether or not the current number is within a desired range.  If the number is already within the
  1555.      * range it is returned, otherwise the min or max value is returned depending on which side of the range is
  1556.      * exceeded.  Note that this method returns the constrained value but does not change the current number.
  1557.      * @param {Number} min The minimum number in the range
  1558.      * @param {Number} max The maximum number in the range
  1559.      * @return {Number} The constrained value if outside the range, otherwise the current value
  1560.      */
  1561.     constrain : function(min, max){
  1562.         return Math.min(Math.max(this, min), max);
  1563.     }
  1564. });
  1565. /**
  1566.  * @class Ext.util.TaskRunner
  1567.  * Provides the ability to execute one or more arbitrary tasks in a multithreaded
  1568.  * manner.  Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
  1569.  * if needed, you can create separate instances of TaskRunner.  Any number of
  1570.  * separate tasks can be started at any time and will run independently of each
  1571.  * other. Example usage:
  1572.  * <pre><code>
  1573. // Start a simple clock task that updates a div once per second
  1574. var updateClock = function(){
  1575.     Ext.fly('clock').update(new Date().format('g:i:s A'));
  1576. var task = {
  1577.     run: updateClock,
  1578.     interval: 1000 //1 second
  1579. }
  1580. var runner = new Ext.util.TaskRunner();
  1581. runner.start(task);
  1582. // equivalent using TaskMgr
  1583. Ext.TaskMgr.start({
  1584.     run: updateClock,
  1585.     interval: 1000
  1586. });
  1587.  * </code></pre>
  1588.  * Also see {@link Ext.util.DelayedTask}. 
  1589.  * 
  1590.  * @constructor
  1591.  * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
  1592.  * (defaults to 10)
  1593.  */
  1594. Ext.util.TaskRunner = function(interval){
  1595.     interval = interval || 10;
  1596.     var tasks = [], 
  1597.      removeQueue = [],
  1598.      id = 0,
  1599.      running = false,
  1600.      // private
  1601.      stopThread = function(){
  1602.         running = false;
  1603.         clearInterval(id);
  1604.         id = 0;
  1605.     },
  1606.      // private
  1607.      startThread = function(){
  1608.         if(!running){
  1609.             running = true;
  1610.             id = setInterval(runTasks, interval);
  1611.         }
  1612.     },
  1613.      // private
  1614.      removeTask = function(t){
  1615.         removeQueue.push(t);
  1616.         if(t.onStop){
  1617.             t.onStop.apply(t.scope || t);
  1618.         }
  1619.     },
  1620.     
  1621.      // private
  1622.      runTasks = function(){
  1623.      var rqLen = removeQueue.length,
  1624.      now = new Date().getTime();          
  1625.     
  1626.         if(rqLen > 0){
  1627.             for(var i = 0; i < rqLen; i++){
  1628.                 tasks.remove(removeQueue[i]);
  1629.             }
  1630.             removeQueue = [];
  1631.             if(tasks.length < 1){
  1632.                 stopThread();
  1633.                 return;
  1634.             }
  1635.         }         
  1636.         for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
  1637.             t = tasks[i];
  1638.             itime = now - t.taskRunTime;
  1639.             if(t.interval <= itime){
  1640.                 rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
  1641.                 t.taskRunTime = now;
  1642.                 if(rt === false || t.taskRunCount === t.repeat){
  1643.                     removeTask(t);
  1644.                     return;
  1645.                 }
  1646.             }
  1647.             if(t.duration && t.duration <= (now - t.taskStartTime)){
  1648.                 removeTask(t);
  1649.             }
  1650.         }
  1651.     };
  1652.     /**
  1653.      * Starts a new task.
  1654.      * @method start
  1655.      * @param {Object} task A config object that supports the following properties:<ul>
  1656.      * <li><code>run</code> : Function<div class="sub-desc">The function to execute each time the task is run. The
  1657.      * function will be called at each interval and passed the <code>args</code> argument if specified.  If a
  1658.      * particular scope is required, be sure to specify it using the <code>scope</code> argument.</div></li>
  1659.      * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
  1660.      * should be executed.</div></li>
  1661.      * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
  1662.      * specified by <code>run</code>.</div></li>
  1663.      * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
  1664.      * <code>run</code> function. Defaults to the task config object.</div></li>
  1665.      * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to execute
  1666.      * the task before stopping automatically (defaults to indefinite).</div></li>
  1667.      * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to execute the task before
  1668.      * stopping automatically (defaults to indefinite).</div></li>
  1669.      * </ul>
  1670.      * @return {Object} The task
  1671.      */
  1672.     this.start = function(task){
  1673.         tasks.push(task);
  1674.         task.taskStartTime = new Date().getTime();
  1675.         task.taskRunTime = 0;
  1676.         task.taskRunCount = 0;
  1677.         startThread();
  1678.         return task;
  1679.     };
  1680.     /**
  1681.      * Stops an existing running task.
  1682.      * @method stop
  1683.      * @param {Object} task The task to stop
  1684.      * @return {Object} The task
  1685.      */
  1686.     this.stop = function(task){
  1687.         removeTask(task);
  1688.         return task;
  1689.     };
  1690.     /**
  1691.      * Stops all tasks that are currently running.
  1692.      * @method stopAll
  1693.      */
  1694.     this.stopAll = function(){
  1695.         stopThread();
  1696.         for(var i = 0, len = tasks.length; i < len; i++){
  1697.             if(tasks[i].onStop){
  1698.                 tasks[i].onStop();
  1699.             }
  1700.         }
  1701.         tasks = [];
  1702.         removeQueue = [];
  1703.     };
  1704. };
  1705. /**
  1706.  * @class Ext.TaskMgr
  1707.  * @extends Ext.util.TaskRunner
  1708.  * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks.  See
  1709.  * {@link Ext.util.TaskRunner} for supported methods and task config properties.
  1710.  * <pre><code>
  1711. // Start a simple clock task that updates a div once per second
  1712. var task = {
  1713.     run: function(){
  1714.         Ext.fly('clock').update(new Date().format('g:i:s A'));
  1715.     },
  1716.     interval: 1000 //1 second
  1717. }
  1718. Ext.TaskMgr.start(task);
  1719. </code></pre>
  1720.  * @singleton
  1721.  */
  1722. Ext.TaskMgr = new Ext.util.TaskRunner();if(typeof YAHOO == "undefined"){
  1723.     throw "Unable to load Ext, core YUI utilities (yahoo, dom, event) not found.";
  1724. }
  1725. (function(){
  1726.     var E = YAHOO.util.Event,
  1727.         D = YAHOO.util.Dom,
  1728.         CN = YAHOO.util.Connect,
  1729.         ES = YAHOO.util.Easing,
  1730.         A = YAHOO.util.Anim,
  1731.         libFlyweight,
  1732.         version = YAHOO.env.getVersion('yahoo').version.split('.'),
  1733.         mouseEnterSupported = parseInt(version[0]) >= 3,
  1734.         mouseCache = {},
  1735.         elContains = function(parent, child){
  1736.             if(parent && parent.firstChild){
  1737.                 while(child){
  1738.                     if(child === parent){
  1739.                         return true;
  1740.                     }
  1741.                     child = child.parentNode;
  1742.                     if(child && (child.nodeType != 1)){
  1743.                         child = null;
  1744.                     }
  1745.                 }
  1746.             }
  1747.             return false;
  1748.         }, checkRelatedTarget = function(e){
  1749.             return !elContains(e.currentTarget, Ext.lib.Event.getRelatedTarget(e));
  1750.         };
  1751. Ext.lib.Dom = {
  1752.     getViewWidth : function(full){
  1753.         return full ? D.getDocumentWidth() : D.getViewportWidth();
  1754.     },
  1755.     getViewHeight : function(full){
  1756.         return full ? D.getDocumentHeight() : D.getViewportHeight();
  1757.     },
  1758.     isAncestor : function(haystack, needle){
  1759.         return D.isAncestor(haystack, needle);
  1760.     },
  1761.     getRegion : function(el){
  1762.         return D.getRegion(el);
  1763.     },
  1764.     getY : function(el){
  1765.         return this.getXY(el)[1];
  1766.     },
  1767.     getX : function(el){
  1768.         return this.getXY(el)[0];
  1769.     },
  1770.     // original version based on YahooUI getXY
  1771.     // this version fixes several issues in Safari and FF
  1772.     // and boosts performance by removing the batch overhead, repetitive dom lookups and array index calls
  1773.     getXY : function(el){
  1774.         var p, pe, b, scroll, bd = (document.body || document.documentElement);
  1775.         el = Ext.getDom(el);
  1776.         if(el == bd){
  1777.             return [0, 0];
  1778.         }
  1779.         if (el.getBoundingClientRect) {
  1780.             b = el.getBoundingClientRect();
  1781.             scroll = fly(document).getScroll();
  1782.             return [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)];
  1783.         }
  1784.         var x = 0, y = 0;
  1785.         p = el;
  1786.         var hasAbsolute = fly(el).getStyle("position") == "absolute";
  1787.         while (p) {
  1788.             x += p.offsetLeft;
  1789.             y += p.offsetTop;
  1790.             if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
  1791.                 hasAbsolute = true;
  1792.             }
  1793.             if (Ext.isGecko) {
  1794.                 pe = fly(p);
  1795.                 var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
  1796.                 var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
  1797.                 x += bl;
  1798.                 y += bt;
  1799.                 if (p != el && pe.getStyle('overflow') != 'visible') {
  1800.                     x += bl;
  1801.                     y += bt;
  1802.                 }
  1803.             }
  1804.             p = p.offsetParent;
  1805.         }
  1806.         if (Ext.isSafari && hasAbsolute) {
  1807.             x -= bd.offsetLeft;
  1808.             y -= bd.offsetTop;
  1809.         }
  1810.         if (Ext.isGecko && !hasAbsolute) {
  1811.             var dbd = fly(bd);
  1812.             x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
  1813.             y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
  1814.         }
  1815.         p = el.parentNode;
  1816.         while (p && p != bd) {
  1817.             if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
  1818.                 x -= p.scrollLeft;
  1819.                 y -= p.scrollTop;
  1820.             }
  1821.             p = p.parentNode;
  1822.         }
  1823.         return [x, y];
  1824.     },
  1825.     setXY : function(el, xy){
  1826.         el = Ext.fly(el, '_setXY');
  1827.         el.position();
  1828.         var pts = el.translatePoints(xy);
  1829.         if(xy[0] !== false){
  1830.             el.dom.style.left = pts.left + "px";
  1831.         }
  1832.         if(xy[1] !== false){
  1833.             el.dom.style.top = pts.top + "px";
  1834.         }
  1835.     },
  1836.     setX : function(el, x){
  1837.         this.setXY(el, [x, false]);
  1838.     },
  1839.     setY : function(el, y){
  1840.         this.setXY(el, [false, y]);
  1841.     }
  1842. };
  1843. Ext.lib.Event = {
  1844.     getPageX : function(e){
  1845.         return E.getPageX(e.browserEvent || e);
  1846.     },
  1847.     getPageY : function(e){
  1848.         return E.getPageY(e.browserEvent || e);
  1849.     },
  1850.     getXY : function(e){
  1851.         return E.getXY(e.browserEvent || e);
  1852.     },
  1853.     getTarget : function(e){
  1854.         return E.getTarget(e.browserEvent || e);
  1855.     },
  1856.     getRelatedTarget : function(e){
  1857.         return E.getRelatedTarget(e.browserEvent || e);
  1858.     },
  1859.     on : function(el, eventName, fn, scope, override){
  1860.         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
  1861.             var item = mouseCache[el.id] || (mouseCache[el.id] = {});
  1862.             item[eventName] = fn;
  1863.             fn = fn.createInterceptor(checkRelatedTarget);
  1864.             eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
  1865.         }
  1866.         E.on(el, eventName, fn, scope, override);
  1867.     },
  1868.     un : function(el, eventName, fn){
  1869.         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
  1870.             var item = mouseCache[el.id], 
  1871.                 ev = item && item[eventName];
  1872.             if(ev){
  1873.                 fn = ev.fn;
  1874.                 delete item[eventName];
  1875.                 eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
  1876.             }
  1877.         }
  1878.         E.removeListener(el, eventName, fn);;
  1879.     },
  1880.     purgeElement : function(el){
  1881.         E.purgeElement(el);
  1882.     },
  1883.     preventDefault : function(e){
  1884.         E.preventDefault(e.browserEvent || e);
  1885.     },
  1886.     stopPropagation : function(e){
  1887.         E.stopPropagation(e.browserEvent || e);
  1888.     },
  1889.     stopEvent : function(e){
  1890.         E.stopEvent(e.browserEvent || e);
  1891.     },
  1892.     onAvailable : function(el, fn, scope, override){
  1893.         return E.onAvailable(el, fn, scope, override);
  1894.     }
  1895. };
  1896. Ext.lib.Ajax = {
  1897.     request : function(method, uri, cb, data, options){
  1898.         if(options){
  1899.             var hs = options.headers;
  1900.             if(hs){
  1901.                 for(var h in hs){
  1902.                     if(hs.hasOwnProperty(h)){
  1903.                         CN.initHeader(h, hs[h], false);
  1904.                     }
  1905.                 }
  1906.             }
  1907.             if(options.xmlData){
  1908.                 if (!hs || !hs['Content-Type']){
  1909.                     CN.initHeader('Content-Type', 'text/xml', false);
  1910.                 }
  1911.                 method = (method ? method : (options.method ? options.method : 'POST'));
  1912.                 data = options.xmlData;
  1913.             }else if(options.jsonData){
  1914.                 if (!hs || !hs['Content-Type']){
  1915.                     CN.initHeader('Content-Type', 'application/json', false);
  1916.                 }
  1917.                 method = (method ? method : (options.method ? options.method : 'POST'));
  1918.                 data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
  1919.             }
  1920.         }
  1921.         return CN.asyncRequest(method, uri, cb, data);
  1922.     },
  1923.     formRequest : function(form, uri, cb, data, isUpload, sslUri){
  1924.         CN.setForm(form, isUpload, sslUri);
  1925.         return CN.asyncRequest(Ext.getDom(form).method ||'POST', uri, cb, data);
  1926.     },
  1927.     isCallInProgress : function(trans){
  1928.         return CN.isCallInProgress(trans);
  1929.     },
  1930.     abort : function(trans){
  1931.         return CN.abort(trans);
  1932.     },
  1933.     serializeForm : function(form){
  1934.         var d = CN.setForm(form.dom || form);
  1935.         CN.resetFormState();
  1936.         return d;
  1937.     }
  1938. };
  1939. Ext.lib.Region = YAHOO.util.Region;
  1940. Ext.lib.Point = YAHOO.util.Point;
  1941. Ext.lib.Anim = {
  1942.     scroll : function(el, args, duration, easing, cb, scope){
  1943.         this.run(el, args, duration, easing, cb, scope, YAHOO.util.Scroll);
  1944.     },
  1945.     motion : function(el, args, duration, easing, cb, scope){
  1946.         this.run(el, args, duration, easing, cb, scope, YAHOO.util.Motion);
  1947.     },
  1948.     color : function(el, args, duration, easing, cb, scope){
  1949.         this.run(el, args, duration, easing, cb, scope, YAHOO.util.ColorAnim);
  1950.     },
  1951.     run : function(el, args, duration, easing, cb, scope, type){
  1952.         type = type || YAHOO.util.Anim;
  1953.         if(typeof easing == "string"){
  1954.             easing = YAHOO.util.Easing[easing];
  1955.         }
  1956.         var anim = new type(el, args, duration, easing);
  1957.         anim.animateX(function(){
  1958.             Ext.callback(cb, scope);
  1959.         });
  1960.         return anim;
  1961.     }
  1962. };
  1963. // all lib flyweight calls use their own flyweight to prevent collisions with developer flyweights
  1964. function fly(el){
  1965.     if(!libFlyweight){
  1966.         libFlyweight = new Ext.Element.Flyweight();
  1967.     }
  1968.     libFlyweight.dom = el;
  1969.     return libFlyweight;
  1970. }
  1971. // prevent IE leaks
  1972. if(Ext.isIE) {
  1973.     function fnCleanUp() {
  1974.         var p = Function.prototype;
  1975.         delete p.createSequence;
  1976.         delete p.defer;
  1977.         delete p.createDelegate;
  1978.         delete p.createCallback;
  1979.         delete p.createInterceptor;
  1980.         window.detachEvent("onunload", fnCleanUp);
  1981.     }
  1982.     window.attachEvent("onunload", fnCleanUp);
  1983. }
  1984. // various overrides
  1985. // add ability for callbacks with animations
  1986. if(YAHOO.util.Anim){
  1987.     YAHOO.util.Anim.prototype.animateX = function(callback, scope){
  1988.         var f = function(){
  1989.             this.onComplete.unsubscribe(f);
  1990.             if(typeof callback == "function"){
  1991.                 callback.call(scope || this, this);
  1992.             }
  1993.         };
  1994.         this.onComplete.subscribe(f, this, true);
  1995.         this.animate();
  1996.     };
  1997. }
  1998. if(YAHOO.util.DragDrop && Ext.dd.DragDrop){
  1999.     YAHOO.util.DragDrop.defaultPadding = Ext.dd.DragDrop.defaultPadding;
  2000.     YAHOO.util.DragDrop.constrainTo = Ext.dd.DragDrop.constrainTo;
  2001. }
  2002. YAHOO.util.Dom.getXY = function(el) {
  2003.     var f = function(el) {
  2004.         return Ext.lib.Dom.getXY(el);
  2005.     };
  2006.     return YAHOO.util.Dom.batch(el, f, YAHOO.util.Dom, true);
  2007. };
  2008. // workaround for Safari anim duration speed problems
  2009. if(YAHOO.util.AnimMgr){
  2010.     YAHOO.util.AnimMgr.fps = 1000;
  2011. }
  2012. YAHOO.util.Region.prototype.adjust = function(t, l, b, r){
  2013.     this.top += t;
  2014.     this.left += l;
  2015.     this.right += r;
  2016.     this.bottom += b;
  2017.     return this;
  2018. };
  2019.     
  2020. YAHOO.util.Region.prototype.constrainTo = function(r) {
  2021.     this.top = this.top.constrain(r.top, r.bottom);
  2022.     this.bottom = this.bottom.constrain(r.top, r.bottom);
  2023.     this.left = this.left.constrain(r.left, r.right);
  2024.     this.right = this.right.constrain(r.left, r.right);
  2025.     return this;
  2026. };
  2027. })();