/*
  Copyright (c) 2003-2005 Jan-Klaas Kollhof
  
  This file is part of the JavaScript o lait library(jsolait).
  
  jsolait is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.
 
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public License
  along with this software; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/**    
    Evaluates script in a global scope.
    @param [0]  The code to evaluate.
*/
globalEval=function(){
    return eval(arguments[0]);
};


/**
    Creates a new class object which inherits from superClass.
    @param className="anonymous"  The name of the new class.
                                                  If the created class is a public member of a module then 
                                                  the className is automatically set.
    @param superClass=Object        The class to inherit from (super class).
    @param classScope                  A function which is executed for class construction.
                                                As 1st parameter it will get the new class' protptype for 
                                                overrideing or extending the super class. As 2nd parameter it will get
                                                the super class' wrapper for calling inherited methods.
*/
Class = function(className, superClass, classScope){
    if(arguments.length == 2){
        classScope = superClass;
        if(typeof className != "string"){
            superClass = className;
            className = "anonymous";
        }else{
            superClass = Object;
        }
    }else if(arguments.length == 1){
        classScope = className;
        superClass = Object;
        className = "anonymous";
    };
    
    //this is the constructor for the new objects created from the new class.
    //if and only if it is NOT used for prototyping/subclassing the init method of the newly created object will be called.
    var NewClass = function(calledBy){
        if(calledBy !== Class){
            return this.init.apply(this, arguments);
        }
    };
    //This will create a new prototype object of the new class.
    NewClass.createPrototype = function(){
        return new NewClass(Class);
    };
    //setting class properties for the new class.
    NewClass.superClass = superClass;
    NewClass.className=className; 
    NewClass.toString = function(){
        return "[class %s]".format(NewClass.className);
    };
    if(superClass.createPrototype!=null){//see if the super class can create prototypes. (creating an object without calling init())
        NewClass.prototype = superClass.createPrototype();
    }else{//just create an object of the super class
        NewClass.prototype = new superClass();
    };
    //reset the constructor for new objects to the actual constructor.
    NewClass.prototype.constructor = NewClass;
    
    if(superClass == Object){//all other objects already have a nice toString method.
        NewClass.prototype.toString = function(){
            return "[object %s]".format(this.constructor.className);
        }
    };
    //make sure the new class has an init method if it does not exist yet in the super class
    if(NewClass.prototype.init==null){
        NewClass.prototype.init=function(){
        }
    };
       
    //create a supr  function to be used to call methods of the super class
    var supr = function(self){
        //set up super class functionality so a call to super(this) will return an object with all super class methods 
        //the methods can be called like super(this).foo and the this object will be bound to that method
        var wrapper = {};
        var superProto = superClass.prototype;
        for(var n in superProto){
            if(typeof superProto[n] == "function"){
                 wrapper[n] = function(){
                    var f = arguments.callee;
                    return superProto[f._name].apply(self, arguments);
                };
                wrapper[n]._name = n;
            }
        }
        return wrapper;
    };
        
    //execute the scope of the class
    classScope(NewClass.prototype, supr);
    
    return NewClass;
};    
Class.toString = function(){
    return "[object Class]";
};
Class.createPrototype=function(){ 
    throw "Can't use Class as a super class.";
};

/**
    Creates a new module and registers it.
    @param name              The name of the module.
    @param version            The version of a module.
    @param moduleScope    A function which is executed for module creation.
                                     As 1st parameter it will get the module variable.                                     
*/
Module = function(name, version, moduleScope){
    var mod = new Object();
    mod.version = version;
    mod.name = name;
    mod.toString=function(){
        return "[module '%s' version: %s]".format(mod.name, mod.version);
    };
    
    /**
        Base class for all module-Exceptions.
    */
    mod.Exception=Class("Exception", function(publ){
        /**
            Initializes a new Exception.
            @param msg           The error message for the user.
            @param trace=null   The error causing this Exception if available.
        */
        publ.init=function(msg, trace){
            this.name = this.constructor.className;
            this.message = msg;
            this.trace = trace;
        };
        
        publ.toString=function(){
            var s = "%s %s\n\n".format(this.name, this.module);
            s += this.message;
            return s;
        };
        /**
            Returns the complete trace of the exception.
            @return The error trace.
        */
        publ.toTraceString=function(){
            var s = "%s %s:\n    ".format(this.name, this.module );
            s+="%s\n\n".format(this.message);
            if(this.trace){
                if(this.trace.toTraceString){
                    s+= this.trace.toTraceString();
                }else{
                    s+= this.trace;
                }
            }
            return s;
        };
        ///The name of the Exception(className).
        publ.name;
        ///The error message.
        publ.message;
        ///The module the Exception belongs to.
        publ.module = mod;
        ///The error which caused the Exception or null.
        publ.trace;      
    });
    
    //execute the scope of the module
    moduleScope(mod);
    
    //todo: set classNames for anonymous classes.
    for(var n in mod){
        if(mod[n].className == "anonymous"){
            mod[n].className = n;
        }
    }
    
    if(name != "jsolait"){
        jsolait.registerModule(mod);
    }
    return mod;
};
Module.toString = function(){
    return "[object Module]";
};
Module.createPrototype=function(){ 
    throw "Can't use Module as a super class.";
};


//docstart

/**
    The root module for jsolait.
    It provides some global functionality for loading modules,
    some String enhancements.
*/
Module("jsolait", "0.1.0", function(mod){
    ///The global jsolait object.
    jsolait=mod;
    
    ///base url for user modules.
    mod.baseURL=".";
    ///The URL where jsolait is installed.
    mod.libURL ="./jsolait";
    ///Collection of all loaded modules.(module cache)
    mod.modules = new Array();
    ///The URLs of there the modules, part of jsolait.
    mod.moduleURLs = {urllib:"%(libURL)s/lib/urllib.js",
                                      xml:"%(libURL)s/lib/xml.js",
                                      crypto:"%(libURL)s/lib/crypto.js",
                                      codecs:"%(libURL)s/lib/codecs.js",
                                      jsonrpc:"%(libURL)s/lib/jsonrpc.js",
                                      lang:"%(libURL)s/lib/lang.js",
                                      iter:"%(libURL)s/lib/iter.js",
                                      xmlrpc:"%(libURL)s/lib/xmlrpc.js"};
   
    mod.init=function(){
        //make jsolait work with WScript
        var ws = null;
        try{//see if WScript is available
            ws = WScript;
        }catch(e){
        }
        if(ws != null){
            initWS();
        }
    };
    
    ///initializes jsolait for using it with WScript
    var initWS = function(){
        print=function(msg){
            WScript.echo(msg);
        };
        alert=function(msg){
            print(msg);
        };
        var args = WScript.arguments;
        try{
            
            //get script to execute
            if(args(0) == "--test"){
                var fileURL = args(1);
                var doTest = true;
            }else{
                var fileURL = args(0);
                var doTest = false;
            }
            var baseURL = fileURL.replace(/\\/g, "/");
            baseURL = baseURL.split("/");
            baseURL = baseURL.slice(0, baseURL.length-1);
            //set base for user module loading
            mod.baseURL = baseURL.join("/");
        }catch(e){
            throw new mod.Exception("Missing script filename to be run.", e);
        }
        
        //location of jsolait/init.js
        urlInit = WScript.ScriptFullName;
                
        urlInit = urlInit.replace(/\\/g, "/");
        urlInit = urlInit.split("/");
        urlInit = urlInit.slice(0, urlInit.length-1);
        mod.libURL = "file://" + urlInit.join("/");
        
        try{
            mod.loadScript(fileURL);
        }catch(e){
            WScript.stdErr.write("%s(1,1) jsolait runtime error:\n%s\n".format(args(0).replace("file://",""), e.toTraceString()));
        }
        
        if(doTest){
            var modName = fileURL.split("\\");
            modName = modName.pop();
            /*if(mod.libURL.toLowerCase() == mod.baseURL.slice(0, mod.libURL.length).toLowerCase()){
                var modName = fileURL.slice(mod.libURL.length + 5);
            */
                modName = modName.slice(0, modName.length -3);
                modName.replace(/\//g, ".");
                print("importing module: %s".format(modName));
                var m = importModule(modName);
                print("%s imported\ntesting...\n".format(m));
                m.test();
                print("\nfinished testing.".format(modName));
            //}
        }
        
    };
    
    
    /**
       Imports a module given its name(someModule.someSubModule).
       A module's file location is determined by treating each module name as a directory.
       Only the last one points to a file.
       If the module's URL is not known to jsolait then it will be searched for in jsolait.baseURL which is "." by default.
       @param name   The name of the module to load.
       @return           The module object.
    */
    mod.importModule = function(name){

        if (mod.modules[name]){ //module already loaded
            return mod.modules[name];
        }else{
            var src,modURL;
            //check if jsolait already knows the url of the module(moduleURLs contains urls to modules)
            if(mod.moduleURLs[name]){
                modURL = mod.moduleURLs[name].format(mod);
            }else{//assume it's a user module and located at baseURL
                modURL = "%s/%s.js".format(mod.baseURL, name.split(".").join("/"));
            }  
            try{//to load module from location calculated above
                src = getFile(modURL);
            }catch(e){//module could not be found at the location.
                throw new mod.ModuleImportFailed(name, modURL, e);
            }
            
            try{//interpret the script
                globalEval(src);
            }catch(e){
                throw new mod.ModuleImportFailed(name, modURL, e);
            }
            //the module should have registered itself
            return mod.modules[name]; 
        }
    };
    //make it global
    importModule = mod.importModule;
    
    /**
        Loads and interprets a script file.
        @param url  The url of the script to load.
    */
    mod.loadScript=function(url){
        var src = getFile(url);
        try{//to interpret the source 
            globalEval(src);
        }catch(e){
            throw new mod.EvalFailed(url, e);
        }
    };
    /**
        Registers a new module. 
        Registered modules can be imported with importModule(...).
        @param module  The module to register.
    */
    mod.registerModule = function(module){
        this.modules[module.name] = module;
    };
    
    /**
        Creates an HTTP request object for retreiving files.
        @return HTTP request object.
    */
    var getHTTP=function() {
        var obj;
        try{ //to get the mozilla httprequest object
            obj = new XMLHttpRequest();
        }catch(e){
            try{ //to get MS HTTP request object
                obj=new ActiveXObject("Msxml2.XMLHTTP.4.0");
            }catch(e){
                try{ //to get MS HTTP request object
                    obj=new ActiveXObject("Msxml2.XMLHTTP");
                }catch(e){
                    try{// to get the old MS HTTP request object
                        obj = new ActiveXObject("microsoft.XMLHTTP"); 
                    }catch(e){
                        throw new mod.Exception("Unable to get an HTTP request object.");
                    }
                }    
            }
        }
        return obj;
    };
    /**
        Retrieves a file given its URL.
        @param url             The url to load.
        @param headers=[]  The headers to use.
        @return                 The content of the file.
    */
    var getFile=function(url, headers) { 
        //if callback is defined then the operation is done async
        headers = (headers != null) ? headers : [];
        //setup the request
        try{
            var xmlhttp= getHTTP();
            xmlhttp.open("GET", url, false);
            for(var i=0;i< headers.length;i++){
                xmlhttp.setRequestHeader(headers[i][0], headers[i][1]);    
            }
            xmlhttp.send("");
        }catch(e){
            throw new mod.Exception("Unable to load URL: '%s'.".format(url), e);
        }
        if(xmlhttp.status == 200 || xmlhttp.status == 0){
            return xmlhttp.responseText;
        }else{
             throw new mod.Exception("File not loaded: '%s'.".format(url));
        }
    };
    
    Error.prototype.toTraceString = function(){
        if(this.message){
            return "%s\n".format(this.message);
        }
        if (this.description){
           return "%s\n".format(this.description);
        }
        return "unknown error\n"; 
    };
   
    
    /**
        Thrown when a module could not be found.
    */
    mod.ModuleImportFailed=Class(mod.Exception, function(publ, supr){
        /**
            Initializes a new ModuleImportFailed Exception.
            @param name      The name of the module.
            @param url          The url of the module.
            @param trace      The error cousing this Exception.
        */
        publ.init=function(moduleName, url, trace){
            supr(this).init("Failed to import module: '%s' from URL:'%s'".format(moduleName, url), trace);
            this.moduleName = moduleName;
            this.url = url;
        };
        ///The  name of the module that was not found.
        publ.moduleName;
        ///The url the module was expected to be found at.
        publ.url;
    });
    
    /**
        Thrown when a source could not be loaded due to an interpretation error.
    */
    mod.EvalFailed=Class(mod.Exception, function(publ, supr){
        /**
            Initializes a new EvalFailed exception.
            @param url                   The url of the module.
            @param trace               The exception that was thrown while interpreting the module's source code.
        */
        publ.init=function(url, trace){
            supr(this).init("File '%s' Eval of script failed.".format(url), trace);
            this.url = url;
        };
        ///The url the module was expected to be found at.
        publ.url;
    });
    
    /**
        Displays an exception and it's trace.
        This works better than alert(e) because traces are taken into account.
        @param exception  The exception to display.
    */
    mod.reportException=function(exception){
        if(exception.toTraceString){
            var s= exception.toTraceString();
        }else{
            var s = exception.toString();
        }
        var ws = null;
        try{//see if WScript is available
            ws = WScript;
        }catch(e){
        }
        if(ws != null){
            WScript.stderr.write(s);
        }else{
            alert(s);
        }
    };    
    ///The global exception report method;
    reportException = mod.reportException;
});

//stringmod
/**
    String formatting module.
    It allows python like string formatting ("some text %s" % "something").
    Also similar to sprintf from C.
*/
Module("stringformat", "0.1.0", function(mod){
    /**
        Creates a format specifier object. 
    */
    var FormatSpecifier=function(s){
        var s = s.match(/%(\(\w+\)){0,1}([ 0-]){0,1}(\+){0,1}(\d+){0,1}(\.\d+){0,1}(.)/);
        if(s[1]){
            this.key=s[1].slice(1,-1);
        }else{
            this.key = null;
        }
        this.paddingFlag = s[2];
        if(this.paddingFlag==""){
            this.paddingFlag =" " 
        }
        this.signed=(s[3] == "+");
        this.minLength = parseInt(s[4]);
        if(isNaN(this.minLength)){
            this.minLength=0;
        }
        if(s[5]){
            this.percision = parseInt(s[5].slice(1,s[5].length));
        }else{
            this.percision=-1;
        }
        this.type = s[6];
    };

    /**
        Formats a string replacing formatting specifiers with values provided as arguments
        which are formatted according to the specifier.
        This is an implementation of  python's % operator for strings and is similar to sprintf from C.
        Usage:
            resultString = formatString.format(value1, v2, ...);
        
        Each formatString can contain any number of formatting specifiers which are
        replaced with the formated values.
        
        specifier([...]-items are optional): 
            "%(key)[flag][sign][min][percision]typeOfValue"
            
            (key)  If specified the 1st argument is treated as an object/associative array and the formating values 
                     are retrieved from that object using the key.
                
            flag:
                0      Use 0s for padding.
                -      Left justify result, padding it with spaces.
                        Use spaces for padding.
            sign:
                +      Numeric values will contain a +|- infront of the number.
            min:
                l      The string will be padded with the padding character until it has a minimum length of l. 
            percision:
               .x     Where x is the percision for floating point numbers and the lenght for 0 padding for integers.
            typeOfValue:
                d    Signed integer decimal.  	 
                i     Signed integer decimal. 	 
                b    Unsigned binary.                       //This does not exist in python!
                o    Unsigned octal. 	
                u    Unsigned decimal. 	 
                x    Unsigned hexidecimal (lowercase). 	
                X   Unsigned hexidecimal (uppercase). 	
                e   Floating point exponential format (lowercase). 	 
                E   Floating point exponential format (uppercase). 	 
                f    Floating point decimal format. 	 
                F   Floating point decimal format. 	 
                c   Single character (accepts byte or single character string). 	 
                s   String (converts any object using object.toString()). 	
        
        Examples:
            "%02d".format(8) == "08"
            "%05.2f".format(1.234) == "01.23"
            "123 in binary is: %08b".format(123) == "123 in binary is: 01111011"
            
        @param *  Each parameter is treated as a formating value. 
        @return The formated String.
    */
    String.prototype.format=function(){
        var sf = this.match(/(%(\(\w+\)){0,1}[ 0-]{0,1}(\+){0,1}(\d+){0,1}(\.\d+){0,1}[dibouxXeEfFgGcrs%])|([^%]+)/g);
        if(sf){
            if(sf.join("") != this){
                throw new mod.Exception("Unsupported formating string.");
            }
        }else{
            throw new mod.Exception("Unsupported formating string.");
        }
        var rslt ="";
        var s;
        var obj;
        var cnt=0;
        var frmt;
        var sign="";
        
        for(var i=0;i<sf.length;i++){
            s=sf[i];
            if(s == "%%"){
                s = "%";
            }else if(s.slice(0,1) == "%"){
                frmt = new FormatSpecifier(s);//get the formating object
                if(frmt.key){//an object was given as formating value
                    if((typeof arguments[0]) == "object" && arguments.length == 1){
                        obj = arguments[0][frmt.key];
                    }else{
                        throw new mod.Exception("Object or associative array expected as formating value.");
                    }
                }else{//get the current value
                    if(cnt>=arguments.length){
                        throw new mod.Exception("Not enough arguments for format string");
                    }else{
                        obj=arguments[cnt];
                        cnt++;
                    }
                }
                    
                if(frmt.type == "s"){//String
                    if (obj == null){
                        obj = "null";
                    }
                    s=obj.toString().pad(frmt.paddingFlag, frmt.minLength);
                    
                }else if(frmt.type == "c"){//Character
                    if(frmt.paddingFlag == "0"){
                        frmt.paddingFlag=" ";//padding only spaces
                    }
                    if(typeof obj == "number"){//get the character code
                        s = String.fromCharCode(obj).pad(frmt.paddingFlag , frmt.minLength) ;
                    }else if(typeof obj == "string"){
                        if(obj.length == 1){//make sure it's a single character
                            s=obj.pad(frmt.paddingFlag, frmt.minLength);
                        }else{
                            throw new mod.Exception("Character of length 1 required.");
                        }
                    }else{
                        throw new mod.Exception("Character or Byte required.");
                    }
                }else if(typeof obj == "number"){
                    //get sign of the number
                    if(obj < 0){
                        obj = -obj;
                        sign = "-"; //negative signs are always needed
                    }else if(frmt.signed){
                        sign = "+"; // if sign is always wanted add it 
                    }else{
                        sign = "";
                    }
                    //do percision padding and number conversions
                    switch(frmt.type){
                        case "f": //floats
                        case "F":
                            if(frmt.percision > -1){
                                s = obj.toFixed(frmt.percision).toString();
                            }else{
                                s = obj.toString();
                            }
                            break;
                        case "E"://exponential
                        case "e":
                            if(frmt.percision > -1){
                                s = obj.toExponential(frmt.percision);
                            }else{
                                s = obj.toExponential();
                            }
                            s = s.replace("e", frmt.type);
                            break;
                        case "b"://binary
                            s = obj.toString(2);
                            s = s.pad("0", frmt.percision);
                            break;
                        case "o"://octal
                            s = obj.toString(8);
                            s = s.pad("0", frmt.percision);
                            break;
                        case "x"://hexadecimal
                            s = obj.toString(16).toLowerCase();
                            s = s.pad("0", frmt.percision);
                            break;
                        case "X"://hexadecimal
                            s = obj.toString(16).toUpperCase();
                            s = s.pad("0", frmt.percision);
                            break;
                        default://integers
                            s = parseInt(obj).toString();
                            s = s.pad("0", frmt.percision);
                            break;
                    }
                    if(frmt.paddingFlag == "0"){//do 0-padding
                        //make sure that the length of the possible sign is not ignored
                        s=s.pad("0", frmt.minLength - sign.length);
                    }
                    s=sign + s;//add sign
                    s=s.pad(frmt.paddingFlag, frmt.minLength);//do padding and justifiing
                }else{
                    throw new mod.Exception("Number required.");
                }
            }
            rslt += s;
        }
        return rslt;
    };
    
    /**
        Padds a String with a character to have a minimum length.
        
        @param flag   "-":      to padd with " " and left justify the string.
                            Other: the character to use for padding. 
        @param len    The minimum length of the resulting string.
    */
    String.prototype.pad = function(flag, len){
        var s = "";
        if(flag == "-"){
            var c = " ";
        }else{
            var c = flag;
        }
        for(var i=0;i<len-this.length;i++){
            s += c;
        }
        if(flag == "-"){
            s = this + s;
        }else{
            s += this;
        }
        return s;
    };
    
    /**
        Repeats a string.
        @param c  The count how often the string should be repeated.
    */
    String.prototype.mul = function(c){
        var a = new Array(this.length * c);
        var s=""+ this;
        for(var i=0;i<c;i++){
            a[i] = s;
        }
        return a.join("");
    };
});

//let jsolait do some startup initialization
jsolait.init();

;
/*
  Copyright (c) 2003 Jan-Klaas Kollhof
  
  This file is part of the JavaScript o lait library(jsolait).
  
  jsolait is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.
 
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public License
  along with this software; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/**
   Provides methods for making HTTP requests.
   @creator Jan-Klaas Kollhof
   @created 2003-07-10
*/
Module("urllib","1.1.4", function(mod){
    /**
        Thrown if no request object could be instanciated.
    */
    mod.NoHTTPRequestObject=Class("NoHTTPRequestObject", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param trace The error causing this exception.
        */
        publ.init=function(trace){
            supr(this).init( "Could not create an HTTP request object", trace);
        };
    });
    
    /**
        Thrown if an HTTP request could not be opened.
    */
    mod.RequestOpenFailed = Class("RequestOpenFailed", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param trace The error causing this exception.
        */
        publ.init=function(trace){
            supr(this).init( "Opening of HTTP request failed.", trace);
        };
    });
    
    /**
        Thrown is arequest could not be sent to the server.
    */
    mod.SendFailed=Class("SendFailed", mod.Exception, function(publ, supr){
         /**
            Initializes the Exception.
            @param trace The error causing this exception.
        */
        publ.init = function(trace){
            supr(this).init( "Sending of HTTP request failed.", trace);
        };
    });
    
    /**
        Mimics the HTTPRequest object using Adobe's SVG Viewer's postURL and getURL.
        It can only process asyncronous connection and the only header that's supported is 'Content-Type'.
    */
    var ASVRequest=Class("ASVRequest", function(publ){
        /**
            Initializes the ASVRequest.
        */
        publ.init = function(){
            if((getURL==null) || (postURL==null)){
                throw "getURL and postURL are not available!";
            }else{
                this.readyState=0;
                this.responseText="";
                this.__contType ="";
                this.status=200;
            }
        };
        /**
            Mimics the open method without actually opening a connection.
            @param type          "GET" or "POST".
            @param url             The url to open.
            @param async=true True for async. connection. Otherwhise an exception is thrown.
        */
        publ.open=function(type,url,async){
            if (async == false){
                throw "Can only open asynchronous connections!";
            }
            this.__type = type;
            this.__url = url;
            this.readyState=0;
        };
        /**
            Sets a header.
            @param name  The header name. All but "Content-Type" are ignored.
            @param value  The value of the header.
        */
        publ.setRequestHeader=function(name, value){
            if (name=="Content-Type"){
                this.__contType =value;
            }
        };
        /**
            Sends the request.
            @param data   The data to send when doing a post.
        */
        publ.send=function(data){
            var self=this;
            var cbh=new Object();
            cbh.operationComplete = function(rsp){
                self.readyState=4;
                self.responseText=rsp.content;
                if(this.ignoreComplete == false){
                    if(self.onreadystatechange){
                        self.onreadystatechange();
                    }
                }
            };
            cbh.ignoreComplete = false;
            try{
                if(this.__type =="GET"){
                    getURL(this.__url,cbh);
                }else if (this.__type == "POST"){
                    postURL(this.__url, data, cbh, this.__contType);
                }
            }catch(e){
                cbh.ignoreComplete=true;
                throw e;
            }
        };
    });
    
    /**
        Creates an HTTP request object for retreiving files.
        @return  HTTP request object.
    */    
    var getHTTP=function() {
        var obj;
        try{ //to get the mozilla httprequest object
            obj = new XMLHttpRequest();
        }catch(e){
            try{ //to get MS HTTP request object
                obj=new ActiveXObject("Msxml2.XMLHTTP.4.0");
            }catch(e){
                try{ //to get MS HTTP request object
                    obj=new ActiveXObject("Msxml2.XMLHTTP")
                }catch(e){
                    try{// to get the old MS HTTP request object
                        obj = new ActiveXObject("microsoft.XMLHTTP"); 
                    }catch(e){
                        try{//to create the ASV request object.
                            obj = new ASVRequest();
                        }catch(e){
                            throw new mod.NoHTTPRequestObject("Neither Mozilla, IE nor ASV found. Can't do HTTP request without them.");
                        }
                    }
                }    
            }
        }
        return obj;
    };
    /**
        Sends a request to a server.
        To explain the way the optional arguments work I will give examples:
        simple:
            sendRequest("get", "url")
            sendRequest("post", "url", "data")
        
        with headers:
            sendRequest("get", "url", [["headername","value"]])
            sendRequest("post", "url", "data", [["headername","value"]])
        
        with user information:
            sendRequest("get", "url", "user", "pass")
            sendRequest("post", "url", "user", "pass", "data")
        
        with headers and user information:
            sendRequest("get", "url", "user", "pass", [["headername","value"]])
            sendRequest("post", "url", "user", "pass", "data", [["headername","value"]])
        
        To make the request asynchronous just add a callback function as the last argument to the calls above.
 
        @param type              Type of connection (GET, POST, ...).
        @param url                 The URL to retrieve.
        @param user=null        The username for auth.
        @param pass=null        The password. (must be set if user is set!)
        @param data=""          The data to send with the request.
        @param headers=[]      Array of headers. Each element in the array should be another array containing [headername,value].
        @param callback=null   Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
        @return                     HTTP request object.
    */
    mod.sendRequest=function(type, url, user, pass, data, headers, callback){
        var async=false;
        //check if the last argument is a function and treat it as callback;
        if(arguments[arguments.length-1]  instanceof Function){
            var async=true;
            callback = arguments[arguments.length-1];
        }
        //treat sencond last(if callback)/last(if no callback) argument as headers
        var headindex=arguments.length-((async || arguments[arguments.length-1] == null) ?2:1);
        //is it an array then it's headers
        if(arguments[headindex] instanceof Array){
            headers=arguments[headindex];
        }else{
            headers=[];
        }
        //are user AND password not specified then assume data as 3rd argument.
        if(typeof user == "string" && typeof pass == "string"){
            if(typeof data != "string"){
                data="";
            }
        }else if (typeof user == "string"){
            data = user;
            user=null;
            pass=null;
        }else{
            user=null;
            pass=null;
        }
        var xmlhttp= getHTTP();
        try{
            if(user!=null){
                xmlhttp.open(type, url, async, user, pass);
            }else{
                xmlhttp.open(type, url, async);
            }
        }catch(e){
            throw new mod.RequestOpenFailed(e);
        }
        //set headers
        for(var i=0;i< headers.length;i++){
            try{//opera 8b does not support setRequestHeader todo:
                xmlhttp.setRequestHeader(headers[i][0], headers[i][1]);    
            }catch(e){
            }
        }
        
        if(async){//set up a callback
            xmlhttp.onreadystatechange=function(){
                if (xmlhttp.readyState==4) {
                    callback(xmlhttp);
                    xmlhttp = null; //help IE with garbage collection
                }else if (xmlhttp.readyState==2){
                    //status property should be available (MS IXMLHTTPRequest documentation) 
                    //in Mozilla it is not if the request failed(server not reachable)
                    //in IE it is not available at all ?!
                    try{//see if it is mozilla otherwise don't care.
                        var isNetscape = netscape;
                        try{//if status is not available the request failed.
                            var s=xmlhttp.status;
                        }catch(e){//call the callback because Mozilla will not get to readystate 4
                            callback(xmlhttp);
                            xmlhttp = null;
                        }
                    }catch(e){
                        
                    }
                }
            }
        }
        
        try{
            xmlhttp.send(data);
        }catch(e){            
            if(async){
                callback(xmlhttp, e);
                xmlhttp=null;
            }else{
                throw new mod.SendFailed(e);
            }
        }
        return xmlhttp;
    };
    /**
        Shorthand for a GET request.
        It calls sendRequest with "GET" as first argument.
        See the sendRequest method for more information.
        @param url                 The URL to retrieve.
        @param user=null        The username for auth.
        @param pass=null        The password. (must be set if user is set!)
        @param headers=[]      Array of headers. Each element in the array should be another array containing [headername,value].
        @param callback=null   Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
        @return                     HTTP request object.
    */
    mod.getURL=function(url, user, pass, headers, callback) { 
        var a=  new Array("GET");
        for(var i=0;i<arguments.length;i++){
            a.push(arguments[i]);
        }
        return mod.sendRequest.apply(this,a)
    };
    /**
        Shorthand for a POST request.
        It calls sendRequest with "POST" as first argument.
        See the sendRequest method for more information.
        @param url                 The URL to retrieve.
        @param user=null        The username for auth.
        @param pass=null        The password. (must be set if user is set!)
        @param data=""          The data to send with the request.
        @param headers=[]      Array of headers. Each element in the array should be another array containing [headername,value].
        @param callback=null   Callback for asynchronous connections. The callback is called after completion and is passed the request object as 1st Parameter.
        @return                     HTTP request object.
    */
    mod.postURL=function(url, user, pass, data, headers, callback) { 
        var a=  new Array("POST");
        for(var i=0;i<arguments.length;i++){
            a.push(arguments[i]);
        }
        return mod.sendRequest.apply(this,a)
    };
});

;
/*
  Copyright (c) 2003 Jan-Klaas Kollhof
  
  This file is part of the JavaScript o lait library(jsolait).
  
  jsolait is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.
 
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public License
  along with this software; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


/**
   Provides parseXML and an importNode implementation.
   @creator Jan-Klaas Kollhof
   @created 2003-07-10
*/
Module("xml","1.1.2", function(mod){
    /**
        Thrown if no parser could be instanciated.
    */
    mod.NoXMLParser=Class("NoXMLParser", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param trace  The error causing the Exception.
        */
        publ.init=function(trace){
            supr(this).init("Could not create an XML parser.", trace);
        };
    });
    /**
        Thrown if a document could not be parsed.
    */
    mod.ParsingFailed=Class("ParsingFailed", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param xml    The xml source which could not be parsed.
            @param trace The error causing this Exception.
        */
        publ.init=function(xml,trace){
             supr(this).init("Failed parsing XML document.",trace);
            this.xml = xml;
        };
        ///The xml source which could not be parsed.
        publ.xml;
    });
    /**
        Parses an xml document.
        @param xml     The xml text.
        @return          A DOM of the xml document.
    */
    mod.parseXML=function(xml){
        var obj=null;
        var isMoz=false;
        var isIE=false;
        var isASV=false;
        
        try{//to get Adobe's SVG parseXML
            var p=window.parseXML;
            if(p==null){
                throw "No ASV paseXML";
            }
            isASV=true;
        }catch(e){
            try{//to get the mozilla parser
                obj = new DOMParser();
                isMoz=true;
            }catch(e){
                try{//to get the MS XML parser
                    obj = new ActiveXObject("Msxml2.DomDocument.4.0"); 
                    isIE=true;
                }catch(e){
                    try{//to get the MS XML parser
                        obj = new ActiveXObject("Msxml2.DomDocument"); 
                        isIE=true;
                    }catch(e){
                        try{//to get the old MS XML parser
                            obj = new ActiveXObject("microsoft.XMLDOM"); 
                            isIE=true;
                        }catch(e){
                            throw new mod.NoXMLParser(e);
                        }
                    }
                }
            }
        }
        try{
            if(isMoz){
                obj = obj.parseFromString(xml, "text/xml");
                return obj;
            }else if(isIE){
                obj.loadXML(xml);
                return obj;
            }else if(isASV){
                return window.parseXML(xml, null);
            }
        }catch(e){
            throw new mod.ParsingFailed(xml,e);
        }
    };
    /**
        DOM2 implimentation of document.importNode().
        This will import into the current document. In SVG it will create SVG nodes in HTML it will create HTML nodes....
        This might become customizable in the future.
        @param importedNode   The node to import.
        @param deep=true        Import all childNodes recursively.
        @return                      The imported Node.
    */
    mod.importNode=function(importedNode, deep){
        deep = (deep==null) ? true : deep;
        //constants from doom2
        var ELEMENT_NODE = 1;
        var ATTRIBUTE_NODE = 2;
        var TEXT_NODE = 3;
        var CDATA_SECTION_NODE = 4;
        var ENTITY_REFERENCE_NODE = 5;
        var ENTITY_NODE = 6;
        var PROCESSING_INSTRUCTION_NODE = 7;
        var COMMENT_NODE = 8;
        var DOCUMENT_NODE = 9;
        var DOCUMENT_TYPE_NODE = 10;
        var DOCUMENT_FRAGMENT_NODE = 11;
        var NOTATION_NODE = 12;
        var importChildren=function(srcNode, parent){
            if(deep){
                 for(var i=0; i<srcNode.childNodes.length; i++){
                    var n=mod.importNode(srcNode.childNodes.item(i), true);
                    parent.appendChild(n);
                }
            }
        };
        var node=null;
        switch(importedNode.nodeType){
            case ATTRIBUTE_NODE:
                node=document.createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
                node.value=importedNode.value;
                break;
            case DOCUMENT_FRAGMENT_NODE:
                node=document.createDocumentFragment();
                importChildren(importedNode,node);
                break;
            case ELEMENT_NODE:
                node=document.createElementNS(importedNode.namespaceURI, importedNode.tagName);
                //import all attributes
                for(var i=0; i<importedNode.attributes.length; i++){
                    var attr=this.importNode(importedNode.attributes.item(i), deep);
                    node.setAttributeNodeNS(attr);
                }
                importChildren(importedNode,node);
                break;
            case ENTITY_REFERENCE_NODE:
                node=importedNode;
                break;
            case PROCESSING_INSTRUCTION_NODE:
                node=document.createProcessingInstruction(importedNode.target, importedNode.data);
                break;
            case TEXT_NODE:
            case CDATA_SECTION_NODE:
            case COMMENT_NODE:
                node=document.createTextNode(importedNode.nodeValue);
                break;
            case DOCUMENT_NODE:
                //Document nodes cannot be imported.
            case DOCUMENT_TYPE_NODE:
                //DocumentType nodes cannot be imported.
            case NOTATION_NODE:
                //readonly in DOM2
            case ENTITY_NODE:
                //readonly in DOM2
                throw "not supported in DOM2";
                break;
        }
        return node;
    };
    /**
        Turns an XML document into a String.
        @param node   The node to print.
        @return           A string containing the text for the XML.
    */
    mod.node2XML = function(node){
        var ELEMENT_NODE = 1;
        var ATTRIBUTE_NODE = 2;
        var TEXT_NODE = 3;
        var CDATA_SECTION_NODE = 4;
        var ENTITY_REFERENCE_NODE = 5;
        var ENTITY_NODE = 6;
        var PROCESSING_INSTRUCTION_NODE = 7;
        var COMMENT_NODE = 8;
        var DOCUMENT_NODE = 9;
        var DOCUMENT_TYPE_NODE = 10;
        var DOCUMENT_FRAGMENT_NODE = 11;
        var NOTATION_NODE = 12;
        var s="";
        switch(node.nodeType){
            case ATTRIBUTE_NODE:
                s+=node.nodeName+'="' + node.value + '"';
                break;
            case DOCUMENT_NODE:
                s+=this.node2XML(node.documentElement);
                break;
            case ELEMENT_NODE:
                s+="<" + node.tagName;
                //attributes
                for(var i=0; i<node.attributes.length; i++){
                    s+=" " + this.node2XML(node.attributes.item(i));
                }
                //children
                if(node.childNodes.length==0){
                    s+="/>\n";
                }else{
                    s+=">";
                    for(var i=0; i<node.childNodes.length; i++){
                        s+=this.node2XML(node.childNodes.item(i));
                    }
                    s+="</" + node.tagName+ ">\n";
                }
                break;
            case PROCESSING_INSTRUCTION_NODE:
                s+="<?" + node.target + " " + node.data + " ?>";
                break;
            case TEXT_NODE:
                s+=node.nodeValue;
                break;
            case CDATA_SECTION_NODE:
                s+="<" +"![CDATA[" + node.nodeValue + "]" + "]>";
                break;
            case COMMENT_NODE:
                s+="<!--" + node.nodeValue + "-->";
                break;
            case ENTITY_REFERENCE_NODE:
            case DOCUMENT_FRAGMENT_NODE:
            case DOCUMENT_TYPE_NODE:
            case NOTATION_NODE:
            case ENTITY_NODE:
                throw new mod.Exception("Nodetype(%s) not supported.".format(node.nodeType));
                break;
        }
        return s;
    };
});
;
/*
  Copyright (c) 2003-2004 Jan-Klaas Kollhof
  
  This file is part of the JavaScript o lait library(jsolait).
  
  jsolait is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.
 
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public License
  along with this software; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

        
/**
    Provides an XML-RPC imlementation.
    It is similar to python's xmlrpclib module.
    @creator Jan-Klaas Kollhof
    @created 2003-07-10
*/
Module("xmlrpc","1.3.3", function(mod){
    var xmlext = importModule("xml");
    var urllib = importModule("urllib");
    /**
        Thrown if a  server did not respond with response status 200 (OK).
    */
    mod.InvalidServerResponse = Class("InvalidServerResponse", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param status       The status returned by the server.
        */
        publ.init= function(status){
            supr(this).init("The server did not respond with a status 200 (OK) but with: " + status);
            this.status = status;
        };
         ///The status returned by the server.
        publ.status;
    });
    
    /**
        Thrown if an XML-RPC response is not well formed.
    */
    mod.MalformedXmlRpc = Class("MalformedXmlRpc", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param msg          The error message of the user.
            @param xml           The xml document's source.
            @param trace=null  The error causing this Exception
        */
        publ.init= function(msg, xml, trace){
            supr(this).init(msg,trace);
            this.xml = xml;
        };
         ///The xml source which was mal formed.
        publ.xml;
    });
    /**
        Thrown if the RPC response is a Fault.        
    */
    mod.Fault = Class("Fault", mod.Exception, function(publ, supr){
        /**
            Initializes the Exception.
            @param faultCode       The fault code returned by the rpc call.
            @param faultString      The fault string returned by the rpc call.
        */
        publ.init= function(faultCode, faultString){
            supr(this).init("XML-RPC Fault: " +  faultCode + "\n\n" + faultString);
            this.faultCode = faultCode;
            this.faultString = faultString;
        };
        ///The fault code returned from the rpc call.
        publ.faultCode;
        ///The fault string returned from the rpc call.
        publ.faultString;
    });

    /**
        Marshalls an object to XML-RPC.(Converts an object into XML-RPC conforming xml.)
        It just calls the toXmlRpc function of the objcect.
        So, to customize serialization of objects one just needs to specify/override the toXmlRpc method 
        which should return an xml string conforming with XML-RPC spec.
        @param obj    The object to marshall
        @return         An xml representation of the object.
    */
    mod.marshall = function(obj){
        if(obj.toXmlRpc){
            return obj.toXmlRpc();
        }else{
            var s = "<struct>";
            for(var attr in obj){
                if(typeof obj[attr] != "function"){
                    s += "<member><name>" + attr + "</name><value>" + mod.marshall(obj[attr]) + "</value></member>";
                }
            }
            s += "</struct>";
            return s;
        }
    };
    
    /**
        Unmarshalls an XML document to a JavaScript object. (Converts xml to JavaScript object.)
        It parses the xml source and creates a JavaScript object.
        @param xml    The xml document source to unmarshall.
        @return         The JavaScript object created from the XML.
    */
    mod.unmarshall = function(xml){
        try {//try to parse xml ... this will throw an Exception if failed
            var doc = xmlext.parseXML(xml);
        }catch(e){
            throw new mod.MalformedXmlRpc("The server's response could not be parsed.", xml, e);
        }
        var rslt = mod.unmarshallDoc(doc, xml);
        doc=null;
        return rslt;
    };
    
    /**
        Unmarshalls an XML document to a JavaScript object like unmarshall but expects a DOM document as parameter.
        It parses the xml source and creates a JavaScript object.
        @param doc   The xml document(DOM compatible) to unmarshall.
        @return         The JavaScript object created from the XML.
    */
    mod.unmarshallDoc = function(doc, xml){
        try{
            var node = doc.documentElement;
            if(node==null){//just in case parse xml didn't throw an Exception but returned nothing usefull.
                throw new mod.MalformedXmlRpc("No documentElement found.", xml);
            }
            switch(node.tagName){
                case "methodResponse":
                    return parseMethodResponse(node);
                case "methodCall":
                    return parseMethodCall(node);
                default://nothing usefull returned by parseXML.
                    throw new mod.MalformedXmlRpc("'methodCall' or 'methodResponse' element expected.\nFound: '" + node.tagName + "'", xml);
            }
        }catch(e){
            if(e instanceof mod.Fault){//just rethrow the fault.
                throw e;
            }else {
                throw new mod.MalformedXmlRpc("Unmarshalling of XML failed.", xml, e);    
            }
        }
    };
    
    /**
        Parses a methodeResponse element.
        @param node  The methodResponse element.
        @return          The return value of the XML-RPC.
    */
    var parseMethodResponse=function(node){
        try{
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "fault": //a fault is thrown as an Exception
                            throw parseFault(child);
                        case "params":
                            var params = parseParams(child);
                            if(params.length == 1){//params should only have one param
                                return params[0];
                            }else{
                                throw new mod.MalformedXmlRpc("'params' element inside 'methodResponse' must have exactly ONE 'param' child element.\nFound: " + params.length);
                            }
                        default:
                            throw new mod.MalformedXmlRpc("'fault' or 'params' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            //no child elements found
            throw new mod.MalformedXmlRpc("No child elements found.");    
        }catch(e){
            if(e instanceof mod.Fault){
                throw e;
            }else{
                throw new mod.MalformedXmlRpc("'methodResponse' element could not be parsed.",null,e);    
            }
        }
    };
    /**
        Parses a methodCall element.
        @param node  The methodCall element.
        @return          Array [methodName,params]. 
    */        
    var parseMethodCall = function(node){
        try{
            var methodName = null;
            var params = new Array();//default is no parameters
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "methodName":
                            methodName = new String(child.firstChild.nodeValue);
                            break;
                        case "params":
                            params = parseParams(child);
                            break;
                        default:
                            throw new mod.MalformedXmlRpc("'methodName' or 'params' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            if(methodName==null){
                throw new mod.MalformedXmlRpc("'methodName' element expected.");
            }else{
                return new Array(methodName, params);
            }
        }catch(e){
            throw new mod.MalformedXmlRpc("'methodCall' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a params element.
        @param node  The params element.
        @return          Array of params values. 
    */
    var parseParams = function(node){
        try{
            var params=new Array();
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "param":
                            params.push(parseParam(child));
                            break;
                        default:
                            throw new mod.MalformedXmlRpc("'param' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            //the specs say a 'params' element can contain any number of 'param' elements. That includes 0 ?!
            return params;
        }catch(e){
            throw new mod.MalformedXmlRpc("'params' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a param element.
        @param node  The param node.
        @return          The value of the param.
    */
    var parseParam = function(node){
        try{
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "value":
                            return parseValue(child);
                        default:
                            throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            //no child elements found, that's an error
            throw new mod.MalformedXmlRpc("'value' element expected.But none found.");
        }catch(e){
            throw new mod.MalformedXmlRpc("'param' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a value element.
        @param node  The value element.
        @return         The value.
    */
    var parseValue = function(node){
        try{
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "string":
                            var s=""; 
                            //Mozilla has many textnodes with a size of 4096 chars each instead of one large one.
                            //They all need to be concatenated.
                            for(var j=0;j<child.childNodes.length;j++){
                                s+=new String(child.childNodes.item(j).nodeValue);
                            }
                            return s;
                        case "int":
                        case "i4":
                        case "double":
                            return (child.firstChild) ? new Number(child.firstChild.nodeValue) : 0;
                        case "boolean":
                            return Boolean(isNaN(parseInt(child.firstChild.nodeValue)) ? (child.firstChild.nodeValue == "true") : parseInt(child.firstChild.nodeValue));
                        case "base64":
                            return parseBase64(child);
                        case "dateTime.iso8601":
                            return parseDateTime(child);
                        case "array":
                            return parseArray(child);
                        case "struct":
                            return parseStruct(child);
                        case "nil": //for python None todo: ??? is this valid XML-RPC
                            return null;
                        default:
                            throw new mod.MalformedXmlRpc("'string','int','i4','double','boolean','base64','dateTime.iso8601','array' or 'struct' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            if(node.firstChild){
                var s="";
                //Mozilla has many textnodes with a size of 4096 chars each instead of one large one.
                //They all need to be concatenated.
                for(var j=0;j<node.childNodes.length;j++){
                    s+=new String(node.childNodes.item(j).nodeValue);
                }
                return s;
            }else{
                return "";
            }
        }catch(e){
            throw new mod.MalformedXmlRpc("'value' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a base64 element.
        @param node   The base64 element.
        @return          A string with the decoded base64.
    */
    var parseBase64=function(node){
        try{
            var s = node.firstChild.nodeValue;
            return s.decode("base64");
        }catch(e){
            throw new mod.MalformedXmlRpc("'base64' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a dateTime.iso8601 element.
        @param node   The dateTime.iso8601 element.
        @return           A JavaScript date.
    */
    var parseDateTime=function(node){
        try{
            if(/^(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})/.test(node.firstChild.nodeValue)){
                return new Date(Date.UTC(RegExp.$1, RegExp.$2-1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6));
            }else{ //todo error message
                throw new mod.MalformedXmlRpc("Could not convert the given date.");
            }
        }catch(e){
            throw new mod.MalformedXmlRpc("'dateTime.iso8601' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses an array element.
        @param node   The array element.
        @return           An Array.
    */
    var parseArray=function(node){
        try{
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "data":
                            return parseData(child);
                        default:
                            throw new mod.MalformedXmlRpc("'data' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            throw new mod.MalformedXmlRpc("'data' element expected. But not found.");   
        }catch(e){
            throw new mod.MalformedXmlRpc("'array' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a data element.
        @param node   The data element.
        @return           The value of a data element.
    */
    var parseData=function(node){
        try{
            var rslt = new Array();
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "value":
                            rslt.push(parseValue(child));
                            break;
                        default:
                            throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            return rslt;
        }catch(e){
            throw new mod.MalformedXmlRpc("'data' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a struct element.
        @param node   The struct element.
        @return           A JavaScript object. Struct memembers are properties of the object.
    */
    var parseStruct=function(node){
        try{
            var struct = new Object();
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "member":
                            var member = parseMember(child); //returns [name, value]
                            if(member[0] != ""){
                                struct[member[0]] = member[1];
                            }
                            break;
                        default:
                            throw new mod.MalformedXmlRpc("'data' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            return struct;
        }catch(e){
            throw new mod.MalformedXmlRpc("'struct' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a member element.
        @param node  The member element.
        @return          Array containing [memberName, value].
    */
    var parseMember=function(node){
        try{
            var name="";
            var value=null;
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "value":
                            value = parseValue(child); 
                            break;
                        case "name":
                            if(child.hasChildNodes()){
                                name = new String(child.firstChild.nodeValue);
                            }
                            break;
                        default:
                            throw new mod.MalformedXmlRpc("'value' or 'name' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            /*if(name == ""){
                throw new mod.MalformedXmlRpc("Name for member not found/convertable.");
            }else{
                return new Array(name, value);
            }*/
            return [name, value];
        }catch(e){
            throw new mod.MalformedXmlRpc("'member' element could not be parsed.",null,e);    
        }
    };
    /**
        Parses a fault element.
        @param node  The fault element.
        @return          A Fault Exception object.
    */
    var parseFault = function(node){
        try{
            for(var i=0;i<node.childNodes.length;i++){
                var child = node.childNodes.item(i);
                if (child.nodeType == 1){
                    switch (child.tagName){
                        case "value":
                            var flt = parseValue(child); 
                            return new mod.Fault(flt.faultCode, flt.faultString);
                        default:
                            throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'");                        
                    }
                }
            }
            throw new mod.MalformedXmlRpc("'value' element expected. But not found.");                        
        }catch(e){
            throw new mod.MalformedXmlRpc("'fault' element could not be parsed.",null,e);    
        }
    };

    /**
        Class for creating XML-RPC methods.
        Calling the created method will result in an XML-RPC call to the service.
        The return value of this call will be the return value of the RPC call.
        RPC-Faults will be raised as Exceptions.
        
        Asynchronous operation:
        If the last parameter passed to the method is an XMLRPCAsyncCallback object, 
        then the remote method will be called asynchronously. 
        The results and errors are passed to the callback.
    */
    mod.XMLRPCMethod =Class("XMLRPCMethod", function(publ){
        
        var postData = function(url, user, pass, data, callback){
            if(callback == null){
                var rslt = urllib.postURL(url, user, pass, data, [["Content-Type", "text/xml"]]);
                return rslt;
            }else{
                urllib.postURL(url, user, pass, data, [["Content-Type", "text/xml"]], callback);
            }
        };
        
        var handleResponse=function(resp){
            var status=null;
            try{//see if the server responded with a response code 200 OK.
                status = resp.status;
            }catch(e){
            }
            if(status == 200){
                var respDoc=null;
                try{
                    respDoc = resp.responseXML;
                }catch(e){
                }
                var respTxt = ""; 
                try{                 
                    respTxt=resp.responseText;
                }catch(e){
                }
                if(respDoc == null){
                    if(respTxt == null || respTxt == ""){
                        throw new mod.MalformedXmlRpc("The server responded with an empty document.", "");
                    }else{
                        return mod.unmarshall(respTxt);
                    }
                }else{ //use the respDoc directly so the xml does not have to be parsed.
                    return mod.unmarshallDoc(respDoc, respTxt);
                }
            }else{
                throw new mod.InvalidServerResponse(status);
            }
        };
        
        var getXML = function(methodName, args){
            var data='<?xml version="1.0"?><methodCall><methodName>' + methodName + '</methodName>';
            if (args.length>0){
                data += "<params>";
                for(var i=0;i<args.length;i++){
                    data += '<param><value>' + mod.marshall(args[i]) + '</value></param>';
                }
                data += '</params>';
            }
            data += '</methodCall>';
            return data;
        };
        /**
            Initializes the XML-RPC method.
            @param url                 The URL of the service providing the method.
            @param methodName   The name of the method to invoke.
            @param user=null             The user name to use for HTTP authentication.
            @param pass=null             The password to use for HTTP authentication.
        */
        publ.init = function(url, methodName, user, pass){
            
            //this is pretty much a hack.
            //we create a function which mimics this class and return it instead of really instanciating an object. 
            var fn=function(){
                //sync or async call
                if(typeof arguments[arguments.length-1] != "function"){
                    var data=getXML(fn.methodName,arguments);
                    var resp = postData(fn.url, fn.user, fn.password, data);
                    
                    return handleResponse(resp);
                }else{
                    var args=new Array();
                    for(var i=0;i<arguments.length;i++){
                        args.push(arguments[i]);
                    }
                    var cb = args.pop();
                    var data=getXML(fn.methodName, args);
                    postData(fn.url, fn.user, fn.password, data, function(resp){
                        var rslt = null;
                        var exc =null;
                        try{
                            rslt = handleResponse(resp);
                        }catch(e){
                            exc = e;
                        }
                        try{//call the callback for the async call.
                            cb(rslt,exc);
                        }catch(e){
                        }
                        args = null;
                        resp = null;
                    });
                }
            };
            //make sure the function has the same property as an object created from this class.
            fn.methodName = methodName;
            fn.url = url;
            fn.user = user;
            fn.password=pass;
            fn.toMulticall = this.toMulticall;
            fn.toString = this.toString;
            fn.setAuthentication=this.setAuthentication;
            fn.constructor = this.constructor;
            return fn;
        };
                
        /**
            Returns the method representation for system.multicall.
            @param   All params will be passed to the remote method.
            @return   An object containing a member methodName and a member params(As required by system.multicall).
        */
        publ.toMulticall = function(){
            var multiCallable = new Object();
            multiCallable.methodName = this.methodName;
            var params = [];
            for(var i=0;i<arguments.length;i++){
                params[i] = arguments[i];
            }
            multiCallable.params = params;
            return multiCallable;
        };
        /**
            Sets username and password for HTTP Authentication.
            @param user    The user name.
            @param pass    The password.
        */
        publ.setAuthentication = function(user, pass){
            this.user = user;
            this.password = pass;
        };
        ///The name of the remote method.
        publ.methodName;
        ///The url of the remote service containing the method.
        publ.url;
        ///The user name used for HTTP authorization.
        publ.user;
        ///The password used for HTTP authorization.
        publ.password;
    });
    
    /**
        Creates proxy objects which resemble the remote service.
        Method calls of this proxy will result in calls to the service.
    */
    mod.ServiceProxy=Class("ServiceProxy", function(publ){
        /**
            Initializes a new ServerProxy.
            The arguments are interpreted as shown in the examples:
            ServerProxy("url")
            ServerProxy("url", ["methodName1",...])
            ServerProxy("url", ["methodName1",...], "user", "pass")
            ServerProxy("url", "user", "pass")
            
            @param url                     The url of the service.
            @param methodNames=[]  Array of names of methods that can be called on the server.
                                                If no methods are given then introspection is used to get the methodnames from the server.
            @param user=null             The user name to use for HTTP authentication.
            @param pass=null             The password to use for HTTP authentication.
        */
        publ.init = function(url, methodNames, user, pass){
            if(methodNames instanceof Array){
                if(methodNames.length > 0){
                    var tryIntrospection=false;
                }else{
                    var tryIntrospection=true;
                }
            }else{
                pass=user;
                user=methodNames;
                methodNames=[];
                var tryIntrospection=true;
            }
            this._url = url;
            this._user = user;
            this._password = pass;
            this._addMethodNames(methodNames);
            if(tryIntrospection){
                try{//it's ok if it fails.
                    this._introspect();
                }catch(e){
                }
            }
        };
        
        /**
            Adds new XMLRPCMethods to the proxy server which can then be invoked.
            @param methodNames   Array of names of methods that can be called on the server.
        */
        publ._addMethodNames = function(methodNames){
            for(var i=0;i<methodNames.length;i++){
                var obj = this;
                //setup obj.childobj...method
                var names = methodNames[i].split(".");
                for(var n=0;n<names.length-1;n++){
                    var name = names[n];
                    if(obj[name]){
                        obj = obj[name];
                    }else{
                        obj[name]  = new Object();
                        obj = obj[name];
                    }
                }
                var name = names[names.length-1];
                if(obj[name]){
                }else{
                    var mth = new mod.XMLRPCMethod(this._url, methodNames[i], this._user, this._password);
                    obj[name] = mth;
                    this._methods.push(mth);
                }
            }
        };
        
        /**
            Sets username and password for HTTP Authentication for all methods of this service.
            @param user    The user name.
            @param pass    The password.
        */
        publ._setAuthentication = function(user, pass){
            this._user = user;
            this._password = pass;
            for(var i=0;i<this._methods.length;i++){
                this._methods[i].setAuthentication(user, pass);
            }
        };
        
        /**
            Initiate XML-RPC introspection to retrieve methodnames from the server
            and add them to the server proxy.
        */
        publ._introspect = function(){
            this._addMethodNames(["system.listMethods","system.methodHelp", "system.methodSignature"]);
            var m = this.system.listMethods();
            this._addMethodNames(m);
        };
        ///The url of the service to resemble.
        publ._url;
        ///The user used for HTTP authentication.
        publ._user;
        ///The password used for HTTP authentication.
        publ._password;
        ///All methods.
        publ._methods=new Array();
    });
    
    ///@deprecated  Use ServiceProxy instead.
    mod.ServerProxy= mod.ServiceProxy;
    
    /**
        XML-RPC representation of a string.
        All '&' and '<' are replaced with the '&amp;'  and  '&lt'.
        @return  A string containing the String's representation in XML.
    */
    String.prototype.toXmlRpc = function(){
        return "<string>" + this.replace(/&/g, "&amp;").replace(/</g, "&lt;") + "</string>";
    };
    /**
        XML-RPC representation of a number.
        @return A string containing the Number's representation in XML.
    */
    Number.prototype.toXmlRpc = function(){
        if(this == parseInt(this)){
            return "<int>" + this + "</int>";
        }else if(this == parseFloat(this)){
            return "<double>" + this + "</double>";
        }else{
            return false.toXmlRpc();
        }
    };
    /**
        XML-RPC representation of a boolean.
        @return A string containing the Boolean's representation in XML.
    */
    Boolean.prototype.toXmlRpc = function(){
        if(this == true) {
            return "<boolean>1</boolean>";
        }else{
            return "<boolean>0</boolean>";
        }
    };
    /**
        XML-RPC representation of a date(iso 8601).
        @return A string containing the Date's representation in XML.
    */
    Date.prototype.toXmlRpc = function(){
        var padd=function(s, p){
            s=p+s;
            return s.substring(s.length - p.length);
        };
        var y = padd(this.getUTCFullYear(), "0000");
        var m = padd(this.getUTCMonth() + 1, "00");
        var d = padd(this.getUTCDate(), "00");
        var h = padd(this.getUTCHours(), "00");
        var min = padd(this.getUTCMinutes(), "00");
        var s = padd(this.getUTCSeconds(), "00");
        
        var isodate = y +  m  + d + "T" + h +  ":" + min + ":" + s;
    
        return "<dateTime.iso8601>" + isodate + "</dateTime.iso8601>";
    };
    /**
        XML-RPC representation of an array.
        Each entry in the array is a value in the XML-RPC.
        @return A string containing the Array's representation in XML.
    */
    Array.prototype.toXmlRpc = function(){
        var retstr = "<array><data>";
        for(var i=0;i<this.length;i++){
            retstr += "<value>" + mod.marshall(this[i]) + "</value>";
        }
        return retstr + "</data></array>";
    };


    mod.test = function(){
        print("creating ServiceProxy object using introspection for method construction...\n");
        var s = new mod.ServiceProxy("http://localhost/testx.py");
        print("%s created\n".format(s));
        print("creating and marshalling test data:\n");
        var o = [1.234, 5, {a:"Hello & < ", b:new Date()}];
        print(mod.marshall(o));
        print("\ncalling echo() on remote service...\n");
        var r = s.echo(o);
        print("service returned data(marshalled again):\n");
        print(mod.marshall(r));
    };
});
;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

if(typeof YAHOO=="undefined"){var YAHOO={};}
YAHOO.namespace=function(){var a=arguments,o=null,i,j,d;for(i=0;i<a.length;i=i+1){d=a[i].split(".");o=YAHOO;for(j=(d[0]=="YAHOO")?1:0;j<d.length;j=j+1){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}
return o;};YAHOO.log=function(msg,cat,src){var l=YAHOO.widget.Logger;if(l&&l.log){return l.log(msg,cat,src);}else{return false;}};YAHOO.init=function(){this.namespace("util","widget","example");if(typeof YAHOO_config!="undefined"){var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i;if(l){for(i=0;i<ls.length;i=i+1){if(ls[i]==l){unique=false;break;}}
if(unique){ls.push(l);}}}};YAHOO.register=function(name,mainClass,data){var mods=YAHOO.env.modules;if(!mods[name]){mods[name]={versions:[],builds:[]};}
var m=mods[name],v=data.version,b=data.build,ls=YAHOO.env.listeners;m.name=name;m.version=v;m.build=b;m.versions.push(v);m.builds.push(b);m.mainClass=mainClass;for(var i=0;i<ls.length;i=i+1){ls[i](m);}
if(mainClass){mainClass.VERSION=v;mainClass.BUILD=b;}else{YAHOO.log("mainClass is undefined for module "+name,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[],getVersion:function(name){return YAHOO.env.modules[name]||null;}};YAHOO.lang={isArray:function(obj){if(obj&&obj.constructor&&obj.constructor.toString().indexOf('Array')>-1){return true;}else{return YAHOO.lang.isObject(obj)&&obj.constructor==Array;}},isBoolean:function(obj){return typeof obj=='boolean';},isFunction:function(obj){return typeof obj=='function';},isNull:function(obj){return obj===null;},isNumber:function(obj){return typeof obj=='number'&&isFinite(obj);},isObject:function(obj){return obj&&(typeof obj=='object'||YAHOO.lang.isFunction(obj));},isString:function(obj){return typeof obj=='string';},isUndefined:function(obj){return typeof obj=='undefined';},hasOwnProperty:function(obj,prop){if(Object.prototype.hasOwnProperty){return obj.hasOwnProperty(prop);}
return!YAHOO.lang.isUndefined(obj[prop])&&obj.constructor.prototype[prop]!==obj[prop];},extend:function(subc,superc,overrides){if(!superc||!subc){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}
var F=function(){};F.prototype=superc.prototype;subc.prototype=new F();subc.prototype.constructor=subc;subc.superclass=superc.prototype;if(superc.prototype.constructor==Object.prototype.constructor){superc.prototype.constructor=superc;}
if(overrides){for(var i in overrides){subc.prototype[i]=overrides[i];}}},augment:function(r,s){if(!s||!r){throw new Error("YAHOO.lang.augment failed, please check that "+"all dependencies are included.");}
var rp=r.prototype,sp=s.prototype,a=arguments,i,p;if(a[2]){for(i=2;i<a.length;i=i+1){rp[a[i]]=sp[a[i]];}}else{for(p in sp){if(!rp[p]){rp[p]=sp[p];}}}}};YAHOO.init();YAHOO.util.Lang=YAHOO.lang;YAHOO.augment=YAHOO.lang.augment;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

YAHOO.util.Connect={_msxml_progid:['MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:'application/x-www-form-urlencoded; charset=UTF-8',_use_default_xhr_header:true,_default_xhr_header:'XMLHttpRequest',_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function()
{if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,'click',function(e){var obj=YAHOO.util.Event.getTarget(e);if(obj.type=='submit'){YAHOO.util.Connect._submitElementValue=encodeURIComponent(obj.name)+"="+encodeURIComponent(obj.value);}})
return true;}
return false;})(),setProgId:function(id)
{this._msxml_progid.unshift(id);},setDefaultPostHeader:function(b)
{this._use_default_post_header=b;},setDefaultXhrHeader:function(b)
{this._use_default_xhr_header=b;},setPollingInterval:function(i)
{if(typeof i=='number'&&isFinite(i)){this._polling_interval=i;}},createXhrObject:function(transactionId)
{var obj,http;try
{http=new XMLHttpRequest();obj={conn:http,tId:transactionId};}
catch(e)
{for(var i=0;i<this._msxml_progid.length;++i){try
{http=new ActiveXObject(this._msxml_progid[i]);obj={conn:http,tId:transactionId};break;}
catch(e){}}}
finally
{return obj;}},getConnectionObject:function()
{var o;var tId=this._transaction_id;try
{o=this.createXhrObject(tId);if(o){this._transaction_id++;}}
catch(e){}
finally
{return o;}},asyncRequest:function(method,uri,callback,postData)
{var o=this.getConnectionObject();if(!o){return null;}
else{if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(o.tId,callback,uri,postData);this.releaseObject(o);return;}
if(method.toUpperCase()=='GET'){if(this._sFormData.length!=0){uri+=((uri.indexOf('?')==-1)?'?':'&')+this._sFormData;}
else{uri+="?"+this._sFormData;}}
else if(method.toUpperCase()=='POST'){postData=postData?this._sFormData+"&"+postData:this._sFormData;}}
o.conn.open(method,uri,true);if(this._use_default_xhr_header){if(!this._default_headers['X-Requested-With']){this.initHeader('X-Requested-With',this._default_xhr_header,true);}}
if(this._isFormSubmit||(postData&&this._use_default_post_header)){this.initHeader('Content-Type',this._default_post_header);if(this._isFormSubmit){this.resetFormState();}}
if(this._has_default_headers||this._has_http_headers){this.setHeader(o);}
this.handleReadyState(o,callback);o.conn.send(postData||null);return o;}},handleReadyState:function(o,callback)
{var oConn=this;if(callback&&callback.timeout){this._timeOut[o.tId]=window.setTimeout(function(){oConn.abort(o,callback,true);},callback.timeout);}
this._poll[o.tId]=window.setInterval(function(){if(o.conn&&o.conn.readyState===4){window.clearInterval(oConn._poll[o.tId]);delete oConn._poll[o.tId];if(callback&&callback.timeout){delete oConn._timeOut[o.tId];}
oConn.handleTransactionResponse(o,callback);}},this._polling_interval);},handleTransactionResponse:function(o,callback,isAbort)
{if(!callback){this.releaseObject(o);return;}
var httpStatus,responseObject;try
{if(o.conn.status!==undefined&&o.conn.status!==0){httpStatus=o.conn.status;}
else{httpStatus=13030;}}
catch(e){httpStatus=13030;}
if(httpStatus>=200&&httpStatus<300||httpStatus===1223){responseObject=this.createResponseObject(o,callback.argument);if(callback.success){if(!callback.scope){callback.success(responseObject);}
else{callback.success.apply(callback.scope,[responseObject]);}}}
else{switch(httpStatus){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:responseObject=this.createExceptionObject(o.tId,callback.argument,(isAbort?isAbort:false));if(callback.failure){if(!callback.scope){callback.failure(responseObject);}
else{callback.failure.apply(callback.scope,[responseObject]);}}
break;default:responseObject=this.createResponseObject(o,callback.argument);if(callback.failure){if(!callback.scope){callback.failure(responseObject);}
else{callback.failure.apply(callback.scope,[responseObject]);}}}}
this.releaseObject(o);responseObject=null;},createResponseObject:function(o,callbackArg)
{var obj={};var headerObj={};try
{var headerStr=o.conn.getAllResponseHeaders();var header=headerStr.split('\n');for(var i=0;i<header.length;i++){var delimitPos=header[i].indexOf(':');if(delimitPos!=-1){headerObj[header[i].substring(0,delimitPos)]=header[i].substring(delimitPos+2);}}}
catch(e){}
obj.tId=o.tId;obj.status=(o.conn.status==1223)?204:o.conn.status;obj.statusText=(o.conn.status==1223)?"No Content":o.conn.statusText;obj.getResponseHeader=headerObj;obj.getAllResponseHeaders=headerStr;obj.responseText=o.conn.responseText;obj.responseXML=o.conn.responseXML;if(typeof callbackArg!==undefined){obj.argument=callbackArg;}
return obj;},createExceptionObject:function(tId,callbackArg,isAbort)
{var COMM_CODE=0;var COMM_ERROR='communication failure';var ABORT_CODE=-1;var ABORT_ERROR='transaction aborted';var obj={};obj.tId=tId;if(isAbort){obj.status=ABORT_CODE;obj.statusText=ABORT_ERROR;}
else{obj.status=COMM_CODE;obj.statusText=COMM_ERROR;}
if(callbackArg){obj.argument=callbackArg;}
return obj;},initHeader:function(label,value,isDefault)
{var headerObj=(isDefault)?this._default_headers:this._http_headers;if(headerObj[label]===undefined){headerObj[label]=value;}
else{headerObj[label]=value+","+headerObj[label];}
if(isDefault){this._has_default_headers=true;}
else{this._has_http_headers=true;}},setHeader:function(o)
{if(this._has_default_headers){for(var prop in this._default_headers){if(YAHOO.lang.hasOwnProperty(this._default_headers,prop)){o.conn.setRequestHeader(prop,this._default_headers[prop]);}}}
if(this._has_http_headers){for(var prop in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,prop)){o.conn.setRequestHeader(prop,this._http_headers[prop]);}}
delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers
this._default_headers={};this._has_default_headers=false;},setForm:function(formId,isUpload,secureUri)
{this.resetFormState();var oForm;if(typeof formId=='string'){oForm=(document.getElementById(formId)||document.forms[formId]);}
else if(typeof formId=='object'){oForm=formId;}
else{return;}
if(isUpload){this.createFrame(secureUri?secureUri:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=oForm;return;}
var oElement,oName,oValue,oDisabled;var hasSubmit=false;for(var i=0;i<oForm.elements.length;i++){oElement=oForm.elements[i];oDisabled=oForm.elements[i].disabled;oName=oForm.elements[i].name;oValue=oForm.elements[i].value;if(!oDisabled&&oName)
{switch(oElement.type)
{case'select-one':case'select-multiple':for(var j=0;j<oElement.options.length;j++){if(oElement.options[j].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oElement.options[j].attributes['value'].specified?oElement.options[j].value:oElement.options[j].text)+'&';}
else{this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oElement.options[j].hasAttribute('value')?oElement.options[j].value:oElement.options[j].text)+'&';}}}
break;case'radio':case'checkbox':if(oElement.checked){this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';}
break;case'file':case undefined:case'reset':case'button':break;case'submit':if(hasSubmit===false){if(this._hasSubmitListener){this._sFormData+=this._submitElementValue+'&';}
else{this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';}
hasSubmit=true;}
break;default:this._sFormData+=encodeURIComponent(oName)+'='+encodeURIComponent(oValue)+'&';break;}}}
this._isFormSubmit=true;this._sFormData=this._sFormData.substr(0,this._sFormData.length-1);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(secureUri){var frameId='yuiIO'+this._transaction_id;if(window.ActiveXObject){var io=document.createElement('<iframe id="'+frameId+'" name="'+frameId+'" />');if(typeof secureUri=='boolean'){io.src='javascript:false';}
else if(typeof secureURI=='string'){io.src=secureUri;}}
else{var io=document.createElement('iframe');io.id=frameId;io.name=frameId;}
io.style.position='absolute';io.style.top='-1000px';io.style.left='-1000px';document.body.appendChild(io);},appendPostData:function(postData)
{var formElements=[];var postMessage=postData.split('&');for(var i=0;i<postMessage.length;i++){var delimitPos=postMessage[i].indexOf('=');if(delimitPos!=-1){formElements[i]=document.createElement('input');formElements[i].type='hidden';formElements[i].name=postMessage[i].substring(0,delimitPos);formElements[i].value=postMessage[i].substring(delimitPos+1);this._formNode.appendChild(formElements[i]);}}
return formElements;},uploadFile:function(id,callback,uri,postData){var frameId='yuiIO'+id;var uploadEncoding='multipart/form-data';var io=document.getElementById(frameId);this._formNode.setAttribute('action',uri);this._formNode.setAttribute('method','POST');this._formNode.setAttribute("target",frameId);if(this._formNode.encoding){this._formNode.encoding=uploadEncoding;}
else{this._formNode.enctype=uploadEncoding;}
if(postData){var oElements=this.appendPostData(postData);}
this._formNode.submit();if(oElements&&oElements.length>0){for(var i=0;i<oElements.length;i++){this._formNode.removeChild(oElements[i]);}}
this.resetFormState();var uploadCallback=function()
{var obj={};obj.tId=id;obj.argument=callback.argument;try
{obj.responseText=io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;obj.responseXML=io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;}
catch(e){}
if(callback&&callback.upload){if(!callback.scope){callback.upload(obj);}
else{callback.upload.apply(callback.scope,[obj]);}}
if(YAHOO.util.Event){YAHOO.util.Event.removeListener(io,"load",uploadCallback);}
else if(window.detachEvent){io.detachEvent('onload',uploadCallback);}
else{io.removeEventListener('load',uploadCallback,false);}
setTimeout(function(){document.body.removeChild(io);},100);};if(YAHOO.util.Event){YAHOO.util.Event.addListener(io,"load",uploadCallback);}
else if(window.attachEvent){io.attachEvent('onload',uploadCallback);}
else{io.addEventListener('load',uploadCallback,false);}},abort:function(o,callback,isTimeout)
{if(this.isCallInProgress(o)){o.conn.abort();window.clearInterval(this._poll[o.tId]);delete this._poll[o.tId];if(isTimeout){delete this._timeOut[o.tId];}
this.handleTransactionResponse(o,callback,true);return true;}
else{return false;}},isCallInProgress:function(o)
{if(o.conn){return o.conn.readyState!==4&&o.conn.readyState!==0;}
else{return false;}},releaseObject:function(o)
{o.conn=null;o=null;}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

(function(){var Y=YAHOO.util,getStyle,setStyle,id_counter=0,propertyCache={};var ua=navigator.userAgent.toLowerCase(),isOpera=(ua.indexOf('opera')>-1),isSafari=(ua.indexOf('safari')>-1),isGecko=(!isOpera&&!isSafari&&ua.indexOf('gecko')>-1),isIE=(!isOpera&&ua.indexOf('msie')>-1);var patterns={HYPHEN:/(-[a-z])/i,ROOT_TAG:/body|html/i};var toCamel=function(property){if(!patterns.HYPHEN.test(property)){return property;}
if(propertyCache[property]){return propertyCache[property];}
var converted=property;while(patterns.HYPHEN.exec(converted)){converted=converted.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}
propertyCache[property]=converted;return converted;};if(document.defaultView&&document.defaultView.getComputedStyle){getStyle=function(el,property){var value=null;if(property=='float'){property='cssFloat';}
var computed=document.defaultView.getComputedStyle(el,'');if(computed){value=computed[toCamel(property)];}
return el.style[property]||value;};}else if(document.documentElement.currentStyle&&isIE){getStyle=function(el,property){switch(toCamel(property)){case'opacity':var val=100;try{val=el.filters['DXImageTransform.Microsoft.Alpha'].opacity;}catch(e){try{val=el.filters('alpha').opacity;}catch(e){}}
return val/100;break;case'float':property='styleFloat';default:var value=el.currentStyle?el.currentStyle[property]:null;return(el.style[property]||value);}};}else{getStyle=function(el,property){return el.style[property];};}
if(isIE){setStyle=function(el,property,val){switch(property){case'opacity':if(YAHOO.lang.isString(el.style.filter)){el.style.filter='alpha(opacity='+val*100+')';if(!el.currentStyle||!el.currentStyle.hasLayout){el.style.zoom=1;}}
break;case'float':property='styleFloat';default:el.style[property]=val;}};}else{setStyle=function(el,property,val){if(property=='float'){property='cssFloat';}
el.style[property]=val;};}
YAHOO.util.Dom={get:function(el){if(YAHOO.lang.isString(el)){return document.getElementById(el);}
if(YAHOO.lang.isArray(el)){var c=[];for(var i=0,len=el.length;i<len;++i){c[c.length]=Y.Dom.get(el[i]);}
return c;}
if(el){return el;}
return null;},getStyle:function(el,property){property=toCamel(property);var f=function(element){return getStyle(element,property);};return Y.Dom.batch(el,f,Y.Dom,true);},setStyle:function(el,property,val){property=toCamel(property);var f=function(element){setStyle(element,property,val);};Y.Dom.batch(el,f,Y.Dom,true);},getXY:function(el){var f=function(el){if((el.parentNode===null||el.offsetParent===null||this.getStyle(el,'display')=='none')&&el!=document.body){return false;}
var parentNode=null;var pos=[];var box;if(el.getBoundingClientRect){box=el.getBoundingClientRect();var doc=document;if(!this.inDocument(el)&&parent.document!=document){doc=parent.document;if(!this.isAncestor(doc.documentElement,el)){return false;}}
var scrollTop=Math.max(doc.documentElement.scrollTop,doc.body.scrollTop);var scrollLeft=Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft);return[box.left+scrollLeft,box.top+scrollTop];}
else{pos=[el.offsetLeft,el.offsetTop];parentNode=el.offsetParent;var hasAbs=this.getStyle(el,'position')=='absolute';if(parentNode!=el){while(parentNode){pos[0]+=parentNode.offsetLeft;pos[1]+=parentNode.offsetTop;if(isSafari&&!hasAbs&&this.getStyle(parentNode,'position')=='absolute'){hasAbs=true;}
parentNode=parentNode.offsetParent;}}
if(isSafari&&hasAbs){pos[0]-=document.body.offsetLeft;pos[1]-=document.body.offsetTop;}}
parentNode=el.parentNode;while(parentNode.tagName&&!patterns.ROOT_TAG.test(parentNode.tagName))
{if(Y.Dom.getStyle(parentNode,'display')!='inline'){pos[0]-=parentNode.scrollLeft;pos[1]-=parentNode.scrollTop;}
parentNode=parentNode.parentNode;}
return pos;};return Y.Dom.batch(el,f,Y.Dom,true);},getX:function(el){var f=function(el){return Y.Dom.getXY(el)[0];};return Y.Dom.batch(el,f,Y.Dom,true);},getY:function(el){var f=function(el){return Y.Dom.getXY(el)[1];};return Y.Dom.batch(el,f,Y.Dom,true);},setXY:function(el,pos,noRetry){var f=function(el){var style_pos=this.getStyle(el,'position');if(style_pos=='static'){this.setStyle(el,'position','relative');style_pos='relative';}
var pageXY=this.getXY(el);if(pageXY===false){return false;}
var delta=[parseInt(this.getStyle(el,'left'),10),parseInt(this.getStyle(el,'top'),10)];if(isNaN(delta[0])){delta[0]=(style_pos=='relative')?0:el.offsetLeft;}
if(isNaN(delta[1])){delta[1]=(style_pos=='relative')?0:el.offsetTop;}
if(pos[0]!==null){el.style.left=pos[0]-pageXY[0]+delta[0]+'px';}
if(pos[1]!==null){el.style.top=pos[1]-pageXY[1]+delta[1]+'px';}
if(!noRetry){var newXY=this.getXY(el);if((pos[0]!==null&&newXY[0]!=pos[0])||(pos[1]!==null&&newXY[1]!=pos[1])){this.setXY(el,pos,true);}}};Y.Dom.batch(el,f,Y.Dom,true);},setX:function(el,x){Y.Dom.setXY(el,[x,null]);},setY:function(el,y){Y.Dom.setXY(el,[null,y]);},getRegion:function(el){var f=function(el){var region=new Y.Region.getRegion(el);return region;};return Y.Dom.batch(el,f,Y.Dom,true);},getClientWidth:function(){return Y.Dom.getViewportWidth();},getClientHeight:function(){return Y.Dom.getViewportHeight();},getElementsByClassName:function(className,tag,root){var method=function(el){return Y.Dom.hasClass(el,className);};return Y.Dom.getElementsBy(method,tag,root);},hasClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)');var f=function(el){return re.test(el.className);};return Y.Dom.batch(el,f,Y.Dom,true);},addClass:function(el,className){var f=function(el){if(this.hasClass(el,className)){return;}
el.className=[el.className,className].join(' ');};Y.Dom.batch(el,f,Y.Dom,true);},removeClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,className)){return;}
var c=el.className;el.className=c.replace(re,' ');if(this.hasClass(el,className)){this.removeClass(el,className);}};Y.Dom.batch(el,f,Y.Dom,true);},replaceClass:function(el,oldClassName,newClassName){if(oldClassName===newClassName){return false;}
var re=new RegExp('(?:^|\\s+)'+oldClassName+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,oldClassName)){this.addClass(el,newClassName);return;}
el.className=el.className.replace(re,' '+newClassName+' ');if(this.hasClass(el,oldClassName)){this.replaceClass(el,oldClassName,newClassName);}};Y.Dom.batch(el,f,Y.Dom,true);},generateId:function(el,prefix){prefix=prefix||'yui-gen';el=el||{};var f=function(el){if(el){el=Y.Dom.get(el);}else{el={};}
if(!el.id){el.id=prefix+id_counter++;}
return el.id;};return Y.Dom.batch(el,f,Y.Dom,true);},isAncestor:function(haystack,needle){haystack=Y.Dom.get(haystack);if(!haystack||!needle){return false;}
var f=function(needle){if(haystack.contains&&!isSafari){return haystack.contains(needle);}
else if(haystack.compareDocumentPosition){return!!(haystack.compareDocumentPosition(needle)&16);}
else{var parent=needle.parentNode;while(parent){if(parent==haystack){return true;}
else if(!parent.tagName||parent.tagName.toUpperCase()=='HTML'){return false;}
parent=parent.parentNode;}
return false;}};return Y.Dom.batch(needle,f,Y.Dom,true);},inDocument:function(el){var f=function(el){return this.isAncestor(document.documentElement,el);};return Y.Dom.batch(el,f,Y.Dom,true);},getElementsBy:function(method,tag,root){tag=tag||'*';var nodes=[];if(root){root=Y.Dom.get(root);if(!root){return nodes;}}else{root=document;}
var elements=root.getElementsByTagName(tag);if(!elements.length&&(tag=='*'&&root.all)){elements=root.all;}
for(var i=0,len=elements.length;i<len;++i){if(method(elements[i])){nodes[nodes.length]=elements[i];}}
return nodes;},batch:function(el,method,o,override){var id=el;el=Y.Dom.get(el);var scope=(override)?o:window;if(!el||el.tagName||!el.length){if(!el){return false;}
return method.call(scope,el,o);}
var collection=[];for(var i=0,len=el.length;i<len;++i){if(!el[i]){id=el[i];}
collection[collection.length]=method.call(scope,el[i],o);}
return collection;},getDocumentHeight:function(){var scrollHeight=(document.compatMode!='CSS1Compat')?document.body.scrollHeight:document.documentElement.scrollHeight;var h=Math.max(scrollHeight,Y.Dom.getViewportHeight());return h;},getDocumentWidth:function(){var scrollWidth=(document.compatMode!='CSS1Compat')?document.body.scrollWidth:document.documentElement.scrollWidth;var w=Math.max(scrollWidth,Y.Dom.getViewportWidth());return w;},getViewportHeight:function(){var height=self.innerHeight;var mode=document.compatMode;if((mode||isIE)&&!isOpera){height=(mode=='CSS1Compat')?document.documentElement.clientHeight:document.body.clientHeight;}
return height;},getViewportWidth:function(){var width=self.innerWidth;var mode=document.compatMode;if(mode||isIE){width=(mode=='CSS1Compat')?document.documentElement.clientWidth:document.body.clientWidth;}
return width;}};})();YAHOO.util.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};YAHOO.util.Region.prototype.contains=function(region){return(region.left>=this.left&&region.right<=this.right&&region.top>=this.top&&region.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(region){var t=Math.max(this.top,region.top);var r=Math.min(this.right,region.right);var b=Math.min(this.bottom,region.bottom);var l=Math.max(this.left,region.left);if(b>=t&&r>=l){return new YAHOO.util.Region(t,r,b,l);}else{return null;}};YAHOO.util.Region.prototype.union=function(region){var t=Math.min(this.top,region.top);var r=Math.max(this.right,region.right);var b=Math.max(this.bottom,region.bottom);var l=Math.min(this.left,region.left);return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(el){var p=YAHOO.util.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}
this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

YAHOO.util.CustomEvent=function(type,oScope,silent,signature){this.type=type;this.scope=oScope||window;this.silent=silent;this.signature=signature||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}
var onsubscribeType="_YUICEOnSubscribe";if(type!==onsubscribeType){this.subscribeEvent=new YAHOO.util.CustomEvent(onsubscribeType,this,true);}};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(fn,obj,override){if(!fn){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}
if(this.subscribeEvent){this.subscribeEvent.fire(fn,obj,override);}
this.subscribers.push(new YAHOO.util.Subscriber(fn,obj,override));},unsubscribe:function(fn,obj){if(!fn){return this.unsubscribeAll();}
var found=false;for(var i=0,len=this.subscribers.length;i<len;++i){var s=this.subscribers[i];if(s&&s.contains(fn,obj)){this._delete(i);found=true;}}
return found;},fire:function(){var len=this.subscribers.length;if(!len&&this.silent){return true;}
var args=[],ret=true,i;for(i=0;i<arguments.length;++i){args.push(arguments[i]);}
var argslength=args.length;if(!this.silent){}
for(i=0;i<len;++i){var s=this.subscribers[i];if(s){if(!this.silent){}
var scope=s.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var param=null;if(args.length>0){param=args[0];}
ret=s.fn.call(scope,param,s.obj);}else{ret=s.fn.call(scope,this.type,args,s.obj);}
if(false===ret){if(!this.silent){}
return false;}}}
return true;},unsubscribeAll:function(){for(var i=0,len=this.subscribers.length;i<len;++i){this._delete(len-1-i);}
return i;},_delete:function(index){var s=this.subscribers[index];if(s){delete s.fn;delete s.obj;}
this.subscribers.splice(index,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(fn,obj,override){this.fn=fn;this.obj=obj||null;this.override=override;};YAHOO.util.Subscriber.prototype.getScope=function(defaultScope){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}
return defaultScope;};YAHOO.util.Subscriber.prototype.contains=function(fn,obj){if(obj){return(this.fn==fn&&this.obj==obj);}else{return(this.fn==fn);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+(this.obj||"")+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var loadComplete=false;var DOMReady=false;var listeners=[];var unloadListeners=[];var legacyEvents=[];var legacyHandlers=[];var retryCount=0;var onAvailStack=[];var legacyMap=[];var counter=0;var lastError=null;return{POLL_RETRYS:200,POLL_INTERVAL:10,EL:0,TYPE:1,FN:2,WFN:3,OBJ:3,ADJ_SCOPE:4,isSafari:(/KHTML/gi).test(navigator.userAgent),webkit:function(){var v=navigator.userAgent.match(/AppleWebKit\/([^ ]*)/);if(v&&v[1]){return v[1];}
return null;}(),isIE:(!this.webkit&&!navigator.userAgent.match(/opera/gi)&&navigator.userAgent.match(/msie/gi)),_interval:null,startInterval:function(){if(!this._interval){var self=this;var callback=function(){self._tryPreloadAttach();};this._interval=setInterval(callback,this.POLL_INTERVAL);}},onAvailable:function(p_id,p_fn,p_obj,p_override){onAvailStack.push({id:p_id,fn:p_fn,obj:p_obj,override:p_override,checkReady:false});retryCount=this.POLL_RETRYS;this.startInterval();},onDOMReady:function(p_fn,p_obj,p_override){this.DOMReadyEvent.subscribe(p_fn,p_obj,p_override);},onContentReady:function(p_id,p_fn,p_obj,p_override){onAvailStack.push({id:p_id,fn:p_fn,obj:p_obj,override:p_override,checkReady:true});retryCount=this.POLL_RETRYS;this.startInterval();},addListener:function(el,sType,fn,obj,override){if(!fn||!fn.call){return false;}
if(this._isValidCollection(el)){var ok=true;for(var i=0,len=el.length;i<len;++i){ok=this.on(el[i],sType,fn,obj,override)&&ok;}
return ok;}else if(typeof el=="string"){var oEl=this.getEl(el);if(oEl){el=oEl;}else{this.onAvailable(el,function(){YAHOO.util.Event.on(el,sType,fn,obj,override);});return true;}}
if(!el){return false;}
if("unload"==sType&&obj!==this){unloadListeners[unloadListeners.length]=[el,sType,fn,obj,override];return true;}
var scope=el;if(override){if(override===true){scope=obj;}else{scope=override;}}
var wrappedFn=function(e){return fn.call(scope,YAHOO.util.Event.getEvent(e),obj);};var li=[el,sType,fn,wrappedFn,scope];var index=listeners.length;listeners[index]=li;if(this.useLegacyEvent(el,sType)){var legacyIndex=this.getLegacyIndex(el,sType);if(legacyIndex==-1||el!=legacyEvents[legacyIndex][0]){legacyIndex=legacyEvents.length;legacyMap[el.id+sType]=legacyIndex;legacyEvents[legacyIndex]=[el,sType,el["on"+sType]];legacyHandlers[legacyIndex]=[];el["on"+sType]=function(e){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(e),legacyIndex);};}
legacyHandlers[legacyIndex].push(li);}else{try{this._simpleAdd(el,sType,wrappedFn,false);}catch(ex){this.lastError=ex;this.removeListener(el,sType,fn);return false;}}
return true;},fireLegacyEvent:function(e,legacyIndex){var ok=true,le,lh,li,scope,ret;lh=legacyHandlers[legacyIndex];for(var i=0,len=lh.length;i<len;++i){li=lh[i];if(li&&li[this.WFN]){scope=li[this.ADJ_SCOPE];ret=li[this.WFN].call(scope,e);ok=(ok&&ret);}}
le=legacyEvents[legacyIndex];if(le&&le[2]){le[2](e);}
return ok;},getLegacyIndex:function(el,sType){var key=this.generateId(el)+sType;if(typeof legacyMap[key]=="undefined"){return-1;}else{return legacyMap[key];}},useLegacyEvent:function(el,sType){if(this.webkit&&("click"==sType||"dblclick"==sType)){var v=parseInt(this.webkit,10);if(!isNaN(v)&&v<418){return true;}}
return false;},removeListener:function(el,sType,fn){var i,len;if(typeof el=="string"){el=this.getEl(el);}else if(this._isValidCollection(el)){var ok=true;for(i=0,len=el.length;i<len;++i){ok=(this.removeListener(el[i],sType,fn)&&ok);}
return ok;}
if(!fn||!fn.call){return this.purgeElement(el,false,sType);}
if("unload"==sType){for(i=0,len=unloadListeners.length;i<len;i++){var li=unloadListeners[i];if(li&&li[0]==el&&li[1]==sType&&li[2]==fn){unloadListeners.splice(i,1);return true;}}
return false;}
var cacheItem=null;var index=arguments[3];if("undefined"==typeof index){index=this._getCacheIndex(el,sType,fn);}
if(index>=0){cacheItem=listeners[index];}
if(!el||!cacheItem){return false;}
if(this.useLegacyEvent(el,sType)){var legacyIndex=this.getLegacyIndex(el,sType);var llist=legacyHandlers[legacyIndex];if(llist){for(i=0,len=llist.length;i<len;++i){li=llist[i];if(li&&li[this.EL]==el&&li[this.TYPE]==sType&&li[this.FN]==fn){llist.splice(i,1);break;}}}}else{try{this._simpleRemove(el,sType,cacheItem[this.WFN],false);}catch(ex){this.lastError=ex;return false;}}
delete listeners[index][this.WFN];delete listeners[index][this.FN];listeners.splice(index,1);return true;},getTarget:function(ev,resolveTextNode){var t=ev.target||ev.srcElement;return this.resolveTextNode(t);},resolveTextNode:function(node){if(node&&3==node.nodeType){return node.parentNode;}else{return node;}},getPageX:function(ev){var x=ev.pageX;if(!x&&0!==x){x=ev.clientX||0;if(this.isIE){x+=this._getScrollLeft();}}
return x;},getPageY:function(ev){var y=ev.pageY;if(!y&&0!==y){y=ev.clientY||0;if(this.isIE){y+=this._getScrollTop();}}
return y;},getXY:function(ev){return[this.getPageX(ev),this.getPageY(ev)];},getRelatedTarget:function(ev){var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else if(ev.type=="mouseover"){t=ev.fromElement;}}
return this.resolveTextNode(t);},getTime:function(ev){if(!ev.time){var t=new Date().getTime();try{ev.time=t;}catch(ex){this.lastError=ex;return t;}}
return ev.time;},stopEvent:function(ev){this.stopPropagation(ev);this.preventDefault(ev);},stopPropagation:function(ev){if(ev.stopPropagation){ev.stopPropagation();}else{ev.cancelBubble=true;}},preventDefault:function(ev){if(ev.preventDefault){ev.preventDefault();}else{ev.returnValue=false;}},getEvent:function(e){var ev=e||window.event;if(!ev){var c=this.getEvent.caller;while(c){ev=c.arguments[0];if(ev&&Event==ev.constructor){break;}
c=c.caller;}}
return ev;},getCharCode:function(ev){return ev.charCode||ev.keyCode||0;},_getCacheIndex:function(el,sType,fn){for(var i=0,len=listeners.length;i<len;++i){var li=listeners[i];if(li&&li[this.FN]==fn&&li[this.EL]==el&&li[this.TYPE]==sType){return i;}}
return-1;},generateId:function(el){var id=el.id;if(!id){id="yuievtautoid-"+counter;++counter;el.id=id;}
return id;},_isValidCollection:function(o){return(o&&o.length&&typeof o!="string"&&!o.tagName&&!o.alert&&typeof o[0]!="undefined");},elCache:{},getEl:function(id){return document.getElementById(id);},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(e){if(!loadComplete){loadComplete=true;var EU=YAHOO.util.Event;EU._ready();if(this.isIE){EU._simpleRemove(window,"load",EU._load);}}},_ready:function(e){if(!DOMReady){DOMReady=true;var EU=YAHOO.util.Event;EU.DOMReadyEvent.fire();EU._simpleRemove(document,"DOMContentLoaded",EU._ready);}},_tryPreloadAttach:function(){if(this.locked){return false;}
if(this.isIE&&!DOMReady){return false;}
this.locked=true;var tryAgain=!loadComplete;if(!tryAgain){tryAgain=(retryCount>0);}
var notAvail=[];var executeItem=function(el,item){var scope=el;if(item.override){if(item.override===true){scope=item.obj;}else{scope=item.override;}}
item.fn.call(scope,item.obj);};var i,len,item,el;for(i=0,len=onAvailStack.length;i<len;++i){item=onAvailStack[i];if(item&&!item.checkReady){el=this.getEl(item.id);if(el){executeItem(el,item);onAvailStack[i]=null;}else{notAvail.push(item);}}}
for(i=0,len=onAvailStack.length;i<len;++i){item=onAvailStack[i];if(item&&item.checkReady){el=this.getEl(item.id);if(el){if(loadComplete||el.nextSibling){executeItem(el,item);onAvailStack[i]=null;}}else{notAvail.push(item);}}}
retryCount=(notAvail.length===0)?0:retryCount-1;if(tryAgain){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}
this.locked=false;return true;},purgeElement:function(el,recurse,sType){var elListeners=this.getListeners(el,sType);if(elListeners){for(var i=0,len=elListeners.length;i<len;++i){var l=elListeners[i];this.removeListener(el,l.type,l.fn);}}
if(recurse&&el&&el.childNodes){for(i=0,len=el.childNodes.length;i<len;++i){this.purgeElement(el.childNodes[i],recurse,sType);}}},getListeners:function(el,sType){var results=[],searchLists;if(!sType){searchLists=[listeners,unloadListeners];}else if(sType=="unload"){searchLists=[unloadListeners];}else{searchLists=[listeners];}
for(var j=0;j<searchLists.length;++j){var searchList=searchLists[j];if(searchList&&searchList.length>0){for(var i=0,len=searchList.length;i<len;++i){var l=searchList[i];if(l&&l[this.EL]===el&&(!sType||sType===l[this.TYPE])){results.push({type:l[this.TYPE],fn:l[this.FN],obj:l[this.OBJ],adjust:l[this.ADJ_SCOPE],index:i});}}}}
return(results.length)?results:null;},_unload:function(e){var EU=YAHOO.util.Event,i,j,l,len,index;for(i=0,len=unloadListeners.length;i<len;++i){l=unloadListeners[i];if(l){var scope=window;if(l[EU.ADJ_SCOPE]){if(l[EU.ADJ_SCOPE]===true){scope=l[EU.OBJ];}else{scope=l[EU.ADJ_SCOPE];}}
l[EU.FN].call(scope,EU.getEvent(e),l[EU.OBJ]);unloadListeners[i]=null;l=null;scope=null;}}
unloadListeners=null;if(listeners&&listeners.length>0){j=listeners.length;while(j){index=j-1;l=listeners[index];if(l){EU.removeListener(l[EU.EL],l[EU.TYPE],l[EU.FN],index);}
j=j-1;}
l=null;EU.clearCache();}
for(i=0,len=legacyEvents.length;i<len;++i){legacyEvents[i][0]=null;legacyEvents[i]=null;}
legacyEvents=null;EU._simpleRemove(window,"unload",EU._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var dd=document.documentElement,db=document.body;if(dd&&(dd.scrollTop||dd.scrollLeft)){return[dd.scrollTop,dd.scrollLeft];}else if(db){return[db.scrollTop,db.scrollLeft];}else{return[0,0];}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(el,sType,fn,capture){el.addEventListener(sType,fn,(capture));};}else if(window.attachEvent){return function(el,sType,fn,capture){el.attachEvent("on"+sType,fn);};}else{return function(){};}}(),_simpleRemove:function(){if(window.removeEventListener){return function(el,sType,fn,capture){el.removeEventListener(sType,fn,(capture));};}else if(window.detachEvent){return function(el,sType,fn){el.detachEvent("on"+sType,fn);};}else{return function(){};}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;if(EU.isIE){document.write('<scr'+'ipt id="_yui_eu_dr" defer="true" src="//:"></script>');var el=document.getElementById("_yui_eu_dr");el.onreadystatechange=function(){if("complete"==this.readyState){this.parentNode.removeChild(this);YAHOO.util.Event._ready();}};el=null;YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);}else if(EU.webkit){EU._drwatch=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._drwatch);EU._drwatch=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}
EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}
YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(p_type,p_fn,p_obj,p_override){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){ce.subscribe(p_fn,p_obj,p_override);}else{this.__yui_subscribers=this.__yui_subscribers||{};var subs=this.__yui_subscribers;if(!subs[p_type]){subs[p_type]=[];}
subs[p_type].push({fn:p_fn,obj:p_obj,override:p_override});}},unsubscribe:function(p_type,p_fn,p_obj){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){return ce.unsubscribe(p_fn,p_obj);}else{return false;}},unsubscribeAll:function(p_type){return this.unsubscribe(p_type);},createEvent:function(p_type,p_config){this.__yui_events=this.__yui_events||{};var opts=p_config||{};var events=this.__yui_events;if(events[p_type]){}else{var scope=opts.scope||this;var silent=opts.silent||null;var ce=new YAHOO.util.CustomEvent(p_type,scope,silent,YAHOO.util.CustomEvent.FLAT);events[p_type]=ce;if(opts.onSubscribeCallback){ce.subscribeEvent.subscribe(opts.onSubscribeCallback);}
this.__yui_subscribers=this.__yui_subscribers||{};var qs=this.__yui_subscribers[p_type];if(qs){for(var i=0;i<qs.length;++i){ce.subscribe(qs[i].fn,qs[i].obj,qs[i].override);}}}
return events[p_type];},fireEvent:function(p_type,arg1,arg2,etc){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){var args=[];for(var i=1;i<arguments.length;++i){args.push(arguments[i]);}
return ce.fire.apply(ce,args);}else{return null;}},hasEvent:function(type){if(this.__yui_events){if(this.__yui_events[type]){return true;}}
return false;}};YAHOO.util.KeyListener=function(attachTo,keyData,handler,event){if(!attachTo){}else if(!keyData){}else if(!handler){}
if(!event){event=YAHOO.util.KeyListener.KEYDOWN;}
var keyEvent=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof attachTo=='string'){attachTo=document.getElementById(attachTo);}
if(typeof handler=='function'){keyEvent.subscribe(handler);}else{keyEvent.subscribe(handler.fn,handler.scope,handler.correctScope);}
function handleKeyPress(e,obj){if(!keyData.shift){keyData.shift=false;}
if(!keyData.alt){keyData.alt=false;}
if(!keyData.ctrl){keyData.ctrl=false;}
if(e.shiftKey==keyData.shift&&e.altKey==keyData.alt&&e.ctrlKey==keyData.ctrl){var dataItem;var keyPressed;if(keyData.keys instanceof Array){for(var i=0;i<keyData.keys.length;i++){dataItem=keyData.keys[i];if(dataItem==e.charCode){keyEvent.fire(e.charCode,e);break;}else if(dataItem==e.keyCode){keyEvent.fire(e.keyCode,e);break;}}}else{dataItem=keyData.keys;if(dataItem==e.charCode){keyEvent.fire(e.charCode,e);}else if(dataItem==e.keyCode){keyEvent.fire(e.keyCode,e);}}}}
this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(attachTo,event,handleKeyPress);this.enabledEvent.fire(keyData);}
this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(attachTo,event,handleKeyPress);this.disabledEvent.fire(keyData);}
this.enabled=false;};this.toString=function(){return"KeyListener ["+keyData.keys+"] "+attachTo.tagName+
(attachTo.id?"["+attachTo.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.register("event",YAHOO.util.Event,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

YAHOO.util.Anim=function(el,attributes,duration,method){if(el){this.init(el,attributes,duration,method);}};YAHOO.util.Anim.prototype={toString:function(){var el=this.getEl();var id=el.id||el.tagName;return("Anim "+id);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(attr,start,end){return this.method(this.currentFrame,start,end-start,this.totalFrames);},setAttribute:function(attr,val,unit){if(this.patterns.noNegatives.test(attr)){val=(val>0)?val:0;}
YAHOO.util.Dom.setStyle(this.getEl(),attr,val+unit);},getAttribute:function(attr){var el=this.getEl();var val=YAHOO.util.Dom.getStyle(el,attr);if(val!=='auto'&&!this.patterns.offsetUnit.test(val)){return parseFloat(val);}
var a=this.patterns.offsetAttribute.exec(attr)||[];var pos=!!(a[3]);var box=!!(a[2]);if(box||(YAHOO.util.Dom.getStyle(el,'position')=='absolute'&&pos)){val=el['offset'+a[0].charAt(0).toUpperCase()+a[0].substr(1)];}else{val=0;}
return val;},getDefaultUnit:function(attr){if(this.patterns.defaultUnit.test(attr)){return'px';}
return'';},setRuntimeAttribute:function(attr){var start;var end;var attributes=this.attributes;this.runtimeAttributes[attr]={};var isset=function(prop){return(typeof prop!=='undefined');};if(!isset(attributes[attr]['to'])&&!isset(attributes[attr]['by'])){return false;}
start=(isset(attributes[attr]['from']))?attributes[attr]['from']:this.getAttribute(attr);if(isset(attributes[attr]['to'])){end=attributes[attr]['to'];}else if(isset(attributes[attr]['by'])){if(start.constructor==Array){end=[];for(var i=0,len=start.length;i<len;++i){end[i]=start[i]+attributes[attr]['by'][i];}}else{end=start+attributes[attr]['by'];}}
this.runtimeAttributes[attr].start=start;this.runtimeAttributes[attr].end=end;this.runtimeAttributes[attr].unit=(isset(attributes[attr].unit))?attributes[attr]['unit']:this.getDefaultUnit(attr);},init:function(el,attributes,duration,method){var isAnimated=false;var startTime=null;var actualFrames=0;el=YAHOO.util.Dom.get(el);this.attributes=attributes||{};this.duration=duration||1;this.method=method||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.getEl=function(){return el;};this.isAnimated=function(){return isAnimated;};this.getStartTime=function(){return startTime;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}
this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;YAHOO.util.AnimMgr.registerElement(this);};this.stop=function(finish){if(finish){this.currentFrame=this.totalFrames;this._onTween.fire();}
YAHOO.util.AnimMgr.stop(this);};var onStart=function(){this.onStart.fire();this.runtimeAttributes={};for(var attr in this.attributes){this.setRuntimeAttribute(attr);}
isAnimated=true;actualFrames=0;startTime=new Date();};var onTween=function(){var data={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};data.toString=function(){return('duration: '+data.duration+', currentFrame: '+data.currentFrame);};this.onTween.fire(data);var runtimeAttributes=this.runtimeAttributes;for(var attr in runtimeAttributes){this.setAttribute(attr,this.doMethod(attr,runtimeAttributes[attr].start,runtimeAttributes[attr].end),runtimeAttributes[attr].unit);}
actualFrames+=1;};var onComplete=function(){var actual_duration=(new Date()-startTime)/1000;var data={duration:actual_duration,frames:actualFrames,fps:actualFrames/actual_duration};data.toString=function(){return('duration: '+data.duration+', frames: '+data.frames+', fps: '+data.fps);};isAnimated=false;actualFrames=0;this.onComplete.fire(data);};this._onStart=new YAHOO.util.CustomEvent('_start',this,true);this.onStart=new YAHOO.util.CustomEvent('start',this);this.onTween=new YAHOO.util.CustomEvent('tween',this);this._onTween=new YAHOO.util.CustomEvent('_tween',this,true);this.onComplete=new YAHOO.util.CustomEvent('complete',this);this._onComplete=new YAHOO.util.CustomEvent('_complete',this,true);this._onStart.subscribe(onStart);this._onTween.subscribe(onTween);this._onComplete.subscribe(onComplete);}};YAHOO.util.AnimMgr=new function(){var thread=null;var queue=[];var tweenCount=0;this.fps=1000;this.delay=1;this.registerElement=function(tween){queue[queue.length]=tween;tweenCount+=1;tween._onStart.fire();this.start();};this.unRegister=function(tween,index){tween._onComplete.fire();index=index||getIndex(tween);if(index!=-1){queue.splice(index,1);}
tweenCount-=1;if(tweenCount<=0){this.stop();}};this.start=function(){if(thread===null){thread=setInterval(this.run,this.delay);}};this.stop=function(tween){if(!tween){clearInterval(thread);for(var i=0,len=queue.length;i<len;++i){if(queue[0].isAnimated()){this.unRegister(queue[0],0);}}
queue=[];thread=null;tweenCount=0;}
else{this.unRegister(tween);}};this.run=function(){for(var i=0,len=queue.length;i<len;++i){var tween=queue[i];if(!tween||!tween.isAnimated()){continue;}
if(tween.currentFrame<tween.totalFrames||tween.totalFrames===null)
{tween.currentFrame+=1;if(tween.useSeconds){correctFrame(tween);}
tween._onTween.fire();}
else{YAHOO.util.AnimMgr.stop(tween,i);}}};var getIndex=function(anim){for(var i=0,len=queue.length;i<len;++i){if(queue[i]==anim){return i;}}
return-1;};var correctFrame=function(tween){var frames=tween.totalFrames;var frame=tween.currentFrame;var expected=(tween.currentFrame*tween.duration*1000/tween.totalFrames);var elapsed=(new Date()-tween.getStartTime());var tweak=0;if(elapsed<tween.duration*1000){tweak=Math.round((elapsed/expected-1)*tween.currentFrame);}else{tweak=frames-(frame+1);}
if(tweak>0&&isFinite(tweak)){if(tween.currentFrame+tweak>=frames){tweak=frames-(frame+1);}
tween.currentFrame+=tweak;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(points,t){var n=points.length;var tmp=[];for(var i=0;i<n;++i){tmp[i]=[points[i][0],points[i][1]];}
for(var j=1;j<n;++j){for(i=0;i<n-j;++i){tmp[i][0]=(1-t)*tmp[i][0]+t*tmp[parseInt(i+1,10)][0];tmp[i][1]=(1-t)*tmp[i][1]+t*tmp[parseInt(i+1,10)][1];}}
return[tmp[0][0],tmp[0][1]];};};(function(){YAHOO.util.ColorAnim=function(el,attributes,duration,method){YAHOO.util.ColorAnim.superclass.constructor.call(this,el,attributes,duration,method);};YAHOO.extend(YAHOO.util.ColorAnim,YAHOO.util.Anim);var Y=YAHOO.util;var superclass=Y.ColorAnim.superclass;var proto=Y.ColorAnim.prototype;proto.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return("ColorAnim "+id);};proto.patterns.color=/color$/i;proto.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;proto.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;proto.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;proto.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;proto.parseColor=function(s){if(s.length==3){return s;}
var c=this.patterns.hex.exec(s);if(c&&c.length==4){return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];}
c=this.patterns.rgb.exec(s);if(c&&c.length==4){return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];}
c=this.patterns.hex3.exec(s);if(c&&c.length==4){return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];}
return null;};proto.getAttribute=function(attr){var el=this.getEl();if(this.patterns.color.test(attr)){var val=YAHOO.util.Dom.getStyle(el,attr);if(this.patterns.transparent.test(val)){var parent=el.parentNode;val=Y.Dom.getStyle(parent,attr);while(parent&&this.patterns.transparent.test(val)){parent=parent.parentNode;val=Y.Dom.getStyle(parent,attr);if(parent.tagName.toUpperCase()=='HTML'){val='#fff';}}}}else{val=superclass.getAttribute.call(this,attr);}
return val;};proto.doMethod=function(attr,start,end){var val;if(this.patterns.color.test(attr)){val=[];for(var i=0,len=start.length;i<len;++i){val[i]=superclass.doMethod.call(this,attr,start[i],end[i]);}
val='rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';}
else{val=superclass.doMethod.call(this,attr,start,end);}
return val;};proto.setRuntimeAttribute=function(attr){superclass.setRuntimeAttribute.call(this,attr);if(this.patterns.color.test(attr)){var attributes=this.attributes;var start=this.parseColor(this.runtimeAttributes[attr].start);var end=this.parseColor(this.runtimeAttributes[attr].end);if(typeof attributes[attr]['to']==='undefined'&&typeof attributes[attr]['by']!=='undefined'){end=this.parseColor(attributes[attr].by);for(var i=0,len=start.length;i<len;++i){end[i]=start[i]+end[i];}}
this.runtimeAttributes[attr].start=start;this.runtimeAttributes[attr].end=end;}};})();YAHOO.util.Easing={easeNone:function(t,b,c,d){return c*t/d+b;},easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeBoth:function(t,b,c,d){if((t/=d/2)<1){return c/2*t*t+b;}
return-c/2*((--t)*(t-2)-1)+b;},easeInStrong:function(t,b,c,d){return c*(t/=d)*t*t*t+b;},easeOutStrong:function(t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b;},easeBothStrong:function(t,b,c,d){if((t/=d/2)<1){return c/2*t*t*t*t+b;}
return-c/2*((t-=2)*t*t*t-2)+b;},elasticIn:function(t,b,c,d,a,p){if(t==0){return b;}
if((t/=d)==1){return b+c;}
if(!p){p=d*.3;}
if(!a||a<Math.abs(c)){a=c;var s=p/4;}
else{var s=p/(2*Math.PI)*Math.asin(c/a);}
return-(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;},elasticOut:function(t,b,c,d,a,p){if(t==0){return b;}
if((t/=d)==1){return b+c;}
if(!p){p=d*.3;}
if(!a||a<Math.abs(c)){a=c;var s=p/4;}
else{var s=p/(2*Math.PI)*Math.asin(c/a);}
return a*Math.pow(2,-10*t)*Math.sin((t*d-s)*(2*Math.PI)/p)+c+b;},elasticBoth:function(t,b,c,d,a,p){if(t==0){return b;}
if((t/=d/2)==2){return b+c;}
if(!p){p=d*(.3*1.5);}
if(!a||a<Math.abs(c)){a=c;var s=p/4;}
else{var s=p/(2*Math.PI)*Math.asin(c/a);}
if(t<1){return-.5*(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;}
return a*Math.pow(2,-10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p)*.5+c+b;},backIn:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;}
return c*(t/=d)*t*((s+1)*t-s)+b;},backOut:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;}
return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b;},backBoth:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;}
if((t/=d/2)<1){return c/2*(t*t*(((s*=(1.525))+1)*t-s))+b;}
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2)+b;},bounceIn:function(t,b,c,d){return c-YAHOO.util.Easing.bounceOut(d-t,0,c,d)+b;},bounceOut:function(t,b,c,d){if((t/=d)<(1/2.75)){return c*(7.5625*t*t)+b;}else if(t<(2/2.75)){return c*(7.5625*(t-=(1.5/2.75))*t+.75)+b;}else if(t<(2.5/2.75)){return c*(7.5625*(t-=(2.25/2.75))*t+.9375)+b;}
return c*(7.5625*(t-=(2.625/2.75))*t+.984375)+b;},bounceBoth:function(t,b,c,d){if(t<d/2){return YAHOO.util.Easing.bounceIn(t*2,0,c,d)*.5+b;}
return YAHOO.util.Easing.bounceOut(t*2-d,0,c,d)*.5+c*.5+b;}};(function(){YAHOO.util.Motion=function(el,attributes,duration,method){if(el){YAHOO.util.Motion.superclass.constructor.call(this,el,attributes,duration,method);}};YAHOO.extend(YAHOO.util.Motion,YAHOO.util.ColorAnim);var Y=YAHOO.util;var superclass=Y.Motion.superclass;var proto=Y.Motion.prototype;proto.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return("Motion "+id);};proto.patterns.points=/^points$/i;proto.setAttribute=function(attr,val,unit){if(this.patterns.points.test(attr)){unit=unit||'px';superclass.setAttribute.call(this,'left',val[0],unit);superclass.setAttribute.call(this,'top',val[1],unit);}else{superclass.setAttribute.call(this,attr,val,unit);}};proto.getAttribute=function(attr){if(this.patterns.points.test(attr)){var val=[superclass.getAttribute.call(this,'left'),superclass.getAttribute.call(this,'top')];}else{val=superclass.getAttribute.call(this,attr);}
return val;};proto.doMethod=function(attr,start,end){var val=null;if(this.patterns.points.test(attr)){var t=this.method(this.currentFrame,0,100,this.totalFrames)/100;val=Y.Bezier.getPosition(this.runtimeAttributes[attr],t);}else{val=superclass.doMethod.call(this,attr,start,end);}
return val;};proto.setRuntimeAttribute=function(attr){if(this.patterns.points.test(attr)){var el=this.getEl();var attributes=this.attributes;var start;var control=attributes['points']['control']||[];var end;var i,len;if(control.length>0&&!(control[0]instanceof Array)){control=[control];}else{var tmp=[];for(i=0,len=control.length;i<len;++i){tmp[i]=control[i];}
control=tmp;}
if(Y.Dom.getStyle(el,'position')=='static'){Y.Dom.setStyle(el,'position','relative');}
if(isset(attributes['points']['from'])){Y.Dom.setXY(el,attributes['points']['from']);}
else{Y.Dom.setXY(el,Y.Dom.getXY(el));}
start=this.getAttribute('points');if(isset(attributes['points']['to'])){end=translateValues.call(this,attributes['points']['to'],start);var pageXY=Y.Dom.getXY(this.getEl());for(i=0,len=control.length;i<len;++i){control[i]=translateValues.call(this,control[i],start);}}else if(isset(attributes['points']['by'])){end=[start[0]+attributes['points']['by'][0],start[1]+attributes['points']['by'][1]];for(i=0,len=control.length;i<len;++i){control[i]=[start[0]+control[i][0],start[1]+control[i][1]];}}
this.runtimeAttributes[attr]=[start];if(control.length>0){this.runtimeAttributes[attr]=this.runtimeAttributes[attr].concat(control);}
this.runtimeAttributes[attr][this.runtimeAttributes[attr].length]=end;}
else{superclass.setRuntimeAttribute.call(this,attr);}};var translateValues=function(val,start){var pageXY=Y.Dom.getXY(this.getEl());val=[val[0]-pageXY[0]+start[0],val[1]-pageXY[1]+start[1]];return val;};var isset=function(prop){return(typeof prop!=='undefined');};})();(function(){YAHOO.util.Scroll=function(el,attributes,duration,method){if(el){YAHOO.util.Scroll.superclass.constructor.call(this,el,attributes,duration,method);}};YAHOO.extend(YAHOO.util.Scroll,YAHOO.util.ColorAnim);var Y=YAHOO.util;var superclass=Y.Scroll.superclass;var proto=Y.Scroll.prototype;proto.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return("Scroll "+id);};proto.doMethod=function(attr,start,end){var val=null;if(attr=='scroll'){val=[this.method(this.currentFrame,start[0],end[0]-start[0],this.totalFrames),this.method(this.currentFrame,start[1],end[1]-start[1],this.totalFrames)];}else{val=superclass.doMethod.call(this,attr,start,end);}
return val;};proto.getAttribute=function(attr){var val=null;var el=this.getEl();if(attr=='scroll'){val=[el.scrollLeft,el.scrollTop];}else{val=superclass.getAttribute.call(this,attr);}
return val;};proto.setAttribute=function(attr,val,unit){var el=this.getEl();if(attr=='scroll'){el.scrollLeft=val[0];el.scrollTop=val[1];}else{superclass.setAttribute.call(this,attr,val,unit);}};})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var Event=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initalized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(sMethod,args){for(var i in this.ids){for(var j in this.ids[i]){var oDD=this.ids[i][j];if(!this.isTypeOfDD(oDD)){continue;}
oDD[sMethod].apply(oDD,args);}}},_onLoad:function(){this.init();Event.on(document,"mouseup",this.handleMouseUp,this,true);Event.on(document,"mousemove",this.handleMouseMove,this,true);Event.on(window,"unload",this._onUnload,this,true);Event.on(window,"resize",this._onResize,this,true);},_onResize:function(e){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,regDragDrop:function(oDD,sGroup){if(!this.initialized){this.init();}
if(!this.ids[sGroup]){this.ids[sGroup]={};}
this.ids[sGroup][oDD.id]=oDD;},removeDDFromGroup:function(oDD,sGroup){if(!this.ids[sGroup]){this.ids[sGroup]={};}
var obj=this.ids[sGroup];if(obj&&obj[oDD.id]){delete obj[oDD.id];}},_remove:function(oDD){for(var g in oDD.groups){if(g&&this.ids[g][oDD.id]){delete this.ids[g][oDD.id];}}
delete this.handleIds[oDD.id];},regHandle:function(sDDId,sHandleId){if(!this.handleIds[sDDId]){this.handleIds[sDDId]={};}
this.handleIds[sDDId][sHandleId]=sHandleId;},isDragDrop:function(id){return(this.getDDById(id))?true:false;},getRelated:function(p_oDD,bTargetsOnly){var oDDs=[];for(var i in p_oDD.groups){for(j in this.ids[i]){var dd=this.ids[i][j];if(!this.isTypeOfDD(dd)){continue;}
if(!bTargetsOnly||dd.isTarget){oDDs[oDDs.length]=dd;}}}
return oDDs;},isLegalTarget:function(oDD,oTargetDD){var targets=this.getRelated(oDD,true);for(var i=0,len=targets.length;i<len;++i){if(targets[i].id==oTargetDD.id){return true;}}
return false;},isTypeOfDD:function(oDD){return(oDD&&oDD.__ygDragDrop);},isHandle:function(sDDId,sHandleId){return(this.handleIds[sDDId]&&this.handleIds[sDDId][sHandleId]);},getDDById:function(id){for(var i in this.ids){if(this.ids[i][id]){return this.ids[i][id];}}
return null;},handleMouseDown:function(e,oDD){this.currentTarget=YAHOO.util.Event.getTarget(e);this.dragCurrent=oDD;var el=oDD.getEl();this.startX=YAHOO.util.Event.getPageX(e);this.startY=YAHOO.util.Event.getPageY(e);this.deltaX=this.startX-el.offsetLeft;this.deltaY=this.startY-el.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var DDM=YAHOO.util.DDM;DDM.startDrag(DDM.startX,DDM.startY);},this.clickTimeThresh);},startDrag:function(x,y){clearTimeout(this.clickTimeout);if(this.dragCurrent){this.dragCurrent.b4StartDrag(x,y);this.dragCurrent.startDrag(x,y);}
this.dragThreshMet=true;},handleMouseUp:function(e){if(!this.dragCurrent){return;}
clearTimeout(this.clickTimeout);if(this.dragThreshMet){this.fireEvents(e,true);}else{}
this.stopDrag(e);this.stopEvent(e);},stopEvent:function(e){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(e);}
if(this.preventDefault){YAHOO.util.Event.preventDefault(e);}},stopDrag:function(e){if(this.dragCurrent){if(this.dragThreshMet){this.dragCurrent.b4EndDrag(e);this.dragCurrent.endDrag(e);}
this.dragCurrent.onMouseUp(e);}
this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(e){if(!this.dragCurrent){return true;}
if(YAHOO.util.Event.isIE&&!e.button){this.stopEvent(e);return this.handleMouseUp(e);}
if(!this.dragThreshMet){var diffX=Math.abs(this.startX-YAHOO.util.Event.getPageX(e));var diffY=Math.abs(this.startY-YAHOO.util.Event.getPageY(e));if(diffX>this.clickPixelThresh||diffY>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}
if(this.dragThreshMet){this.dragCurrent.b4Drag(e);this.dragCurrent.onDrag(e);this.fireEvents(e,false);}
this.stopEvent(e);return true;},fireEvents:function(e,isDrop){var dc=this.dragCurrent;if(!dc||dc.isLocked()){return;}
var x=YAHOO.util.Event.getPageX(e);var y=YAHOO.util.Event.getPageY(e);var pt=new YAHOO.util.Point(x,y);var pos=dc.getTargetCoord(pt.x,pt.y);var el=dc.getDragEl();curRegion=new YAHOO.util.Region(pos.y,pos.x+el.offsetWidth,pos.y+el.offsetHeight,pos.x);var oldOvers=[];var outEvts=[];var overEvts=[];var dropEvts=[];var enterEvts=[];for(var i in this.dragOvers){var ddo=this.dragOvers[i];if(!this.isTypeOfDD(ddo)){continue;}
if(!this.isOverTarget(pt,ddo,this.mode,curRegion)){outEvts.push(ddo);}
oldOvers[i]=true;delete this.dragOvers[i];}
for(var sGroup in dc.groups){if("string"!=typeof sGroup){continue;}
for(i in this.ids[sGroup]){var oDD=this.ids[sGroup][i];if(!this.isTypeOfDD(oDD)){continue;}
if(oDD.isTarget&&!oDD.isLocked()&&oDD!=dc){if(this.isOverTarget(pt,oDD,this.mode,curRegion)){if(isDrop){dropEvts.push(oDD);}else{if(!oldOvers[oDD.id]){enterEvts.push(oDD);}else{overEvts.push(oDD);}
this.dragOvers[oDD.id]=oDD;}}}}}
this.interactionInfo={out:outEvts,enter:enterEvts,over:overEvts,drop:dropEvts,point:pt,draggedRegion:curRegion,sourceRegion:this.locationCache[dc.id],validDrop:isDrop};if(isDrop&&!dropEvts.length){this.interactionInfo.validDrop=false;dc.onInvalidDrop(e);}
if(this.mode){if(outEvts.length){dc.b4DragOut(e,outEvts);dc.onDragOut(e,outEvts);}
if(enterEvts.length){dc.onDragEnter(e,enterEvts);}
if(overEvts.length){dc.b4DragOver(e,overEvts);dc.onDragOver(e,overEvts);}
if(dropEvts.length){dc.b4DragDrop(e,dropEvts);dc.onDragDrop(e,dropEvts);}}else{var len=0;for(i=0,len=outEvts.length;i<len;++i){dc.b4DragOut(e,outEvts[i].id);dc.onDragOut(e,outEvts[i].id);}
for(i=0,len=enterEvts.length;i<len;++i){dc.onDragEnter(e,enterEvts[i].id);}
for(i=0,len=overEvts.length;i<len;++i){dc.b4DragOver(e,overEvts[i].id);dc.onDragOver(e,overEvts[i].id);}
for(i=0,len=dropEvts.length;i<len;++i){dc.b4DragDrop(e,dropEvts[i].id);dc.onDragDrop(e,dropEvts[i].id);}}},getBestMatch:function(dds){var winner=null;var len=dds.length;if(len==1){winner=dds[0];}else{for(var i=0;i<len;++i){var dd=dds[i];if(this.mode==this.INTERSECT&&dd.cursorIsOver){winner=dd;break;}else{if(!winner||!winner.overlap||(dd.overlap&&winner.overlap.getArea()<dd.overlap.getArea())){winner=dd;}}}}
return winner;},refreshCache:function(groups){var g=groups||this.ids;for(var sGroup in g){if("string"!=typeof sGroup){continue;}
for(var i in this.ids[sGroup]){var oDD=this.ids[sGroup][i];if(this.isTypeOfDD(oDD)){var loc=this.getLocation(oDD);if(loc){this.locationCache[oDD.id]=loc;}else{delete this.locationCache[oDD.id];}}}}},verifyEl:function(el){try{if(el){var parent=el.offsetParent;if(parent){return true;}}}catch(e){}
return false;},getLocation:function(oDD){if(!this.isTypeOfDD(oDD)){return null;}
var el=oDD.getEl(),pos,x1,x2,y1,y2,t,r,b,l;try{pos=YAHOO.util.Dom.getXY(el);}catch(e){}
if(!pos){return null;}
x1=pos[0];x2=x1+el.offsetWidth;y1=pos[1];y2=y1+el.offsetHeight;t=y1-oDD.padding[0];r=x2+oDD.padding[1];b=y2+oDD.padding[2];l=x1-oDD.padding[3];return new YAHOO.util.Region(t,r,b,l);},isOverTarget:function(pt,oTarget,intersect,curRegion){var loc=this.locationCache[oTarget.id];if(!loc||!this.useCache){loc=this.getLocation(oTarget);this.locationCache[oTarget.id]=loc;}
if(!loc){return false;}
oTarget.cursorIsOver=loc.contains(pt);var dc=this.dragCurrent;if(!dc||(!intersect&&!dc.constrainX&&!dc.constrainY)){return oTarget.cursorIsOver;}
oTarget.overlap=null;if(!curRegion){var pos=dc.getTargetCoord(pt.x,pt.y);var el=dc.getDragEl();curRegion=new YAHOO.util.Region(pos.y,pos.x+el.offsetWidth,pos.y+el.offsetHeight,pos.x);}
var overlap=curRegion.intersect(loc);if(overlap){oTarget.overlap=overlap;return(intersect)?true:oTarget.cursorIsOver;}else{return false;}},_onUnload:function(e,me){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null;}
this._execOnAll("unreg",[]);for(i in this.elementCache){delete this.elementCache[i];}
this.elementCache={};this.ids={};},elementCache:{},getElWrapper:function(id){var oWrapper=this.elementCache[id];if(!oWrapper||!oWrapper.el){oWrapper=this.elementCache[id]=new this.ElementWrapper(YAHOO.util.Dom.get(id));}
return oWrapper;},getElement:function(id){return YAHOO.util.Dom.get(id);},getCss:function(id){var el=YAHOO.util.Dom.get(id);return(el)?el.style:null;},ElementWrapper:function(el){this.el=el||null;this.id=this.el&&el.id;this.css=this.el&&el.style;},getPosX:function(el){return YAHOO.util.Dom.getX(el);},getPosY:function(el){return YAHOO.util.Dom.getY(el);},swapNode:function(n1,n2){if(n1.swapNode){n1.swapNode(n2);}else{var p=n2.parentNode;var s=n2.nextSibling;if(s==n1){p.insertBefore(n1,n2);}else if(n2==n1.nextSibling){p.insertBefore(n2,n1);}else{n1.parentNode.replaceChild(n2,n1);p.insertBefore(n1,s);}}},getScroll:function(){var t,l,dde=document.documentElement,db=document.body;if(dde&&(dde.scrollTop||dde.scrollLeft)){t=dde.scrollTop;l=dde.scrollLeft;}else if(db){t=db.scrollTop;l=db.scrollLeft;}else{}
return{top:t,left:l};},getStyle:function(el,styleProp){return YAHOO.util.Dom.getStyle(el,styleProp);},getScrollTop:function(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(moveEl,targetEl){var aCoord=YAHOO.util.Dom.getXY(targetEl);YAHOO.util.Dom.setXY(moveEl,aCoord);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(a,b){return(a-b);},_timeoutCount:0,_addListeners:function(){var DDM=YAHOO.util.DDM;if(YAHOO.util.Event&&document){DDM._onLoad();}else{if(DDM._timeoutCount>2000){}else{setTimeout(DDM._addListeners,10);if(document&&document.body){DDM._timeoutCount+=1;}}}},handleWasClicked:function(node,id){if(this.isHandle(id,node.id)){return true;}else{var p=node.parentNode;while(p){if(this.isHandle(id,p.id)){return true;}else{p=p.parentNode;}}}
return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}
(function(){var Event=YAHOO.util.Event;var Dom=YAHOO.util.Dom;YAHOO.util.DragDrop=function(id,sGroup,config){if(id){this.init(id,sGroup,config);}};YAHOO.util.DragDrop.prototype={id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,deltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,b4StartDrag:function(x,y){},startDrag:function(x,y){},b4Drag:function(e){},onDrag:function(e){},onDragEnter:function(e,id){},b4DragOver:function(e){},onDragOver:function(e,id){},b4DragOut:function(e){},onDragOut:function(e,id){},b4DragDrop:function(e){},onDragDrop:function(e,id){},onInvalidDrop:function(e){},b4EndDrag:function(e){},endDrag:function(e){},b4MouseDown:function(e){},onMouseDown:function(e){},onMouseUp:function(e){},onAvailable:function(){},getEl:function(){if(!this._domRef){this._domRef=Dom.get(this.id);}
return this._domRef;},getDragEl:function(){return Dom.get(this.dragElId);},init:function(id,sGroup,config){this.initTarget(id,sGroup,config);Event.on(this.id,"mousedown",this.handleMouseDown,this,true);},initTarget:function(id,sGroup,config){this.config=config||{};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof id!=="string"){id=Dom.generateId(id);}
this.id=id;this.addToGroup((sGroup)?sGroup:"default");this.handleElId=id;Event.onAvailable(id,this.handleOnAvailable,this,true);this.setDragElId(id);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(iTop,iRight,iBot,iLeft){if(!iRight&&0!==iRight){this.padding=[iTop,iTop,iTop,iTop];}else if(!iBot&&0!==iBot){this.padding=[iTop,iRight,iTop,iRight];}else{this.padding=[iTop,iRight,iBot,iLeft];}},setInitPosition:function(diffX,diffY){var el=this.getEl();if(!this.DDM.verifyEl(el)){return;}
var dx=diffX||0;var dy=diffY||0;var p=Dom.getXY(el);this.initPageX=p[0]-dx;this.initPageY=p[1]-dy;this.lastPageX=p[0];this.lastPageY=p[1];this.setStartPosition(p);},setStartPosition:function(pos){var p=pos||Dom.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=p[0];this.startPageY=p[1];},addToGroup:function(sGroup){this.groups[sGroup]=true;this.DDM.regDragDrop(this,sGroup);},removeFromGroup:function(sGroup){if(this.groups[sGroup]){delete this.groups[sGroup];}
this.DDM.removeDDFromGroup(this,sGroup);},setDragElId:function(id){this.dragElId=id;},setHandleElId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);}
this.handleElId=id;this.DDM.regHandle(this.id,id);},setOuterHandleElId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);}
Event.on(id,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(id);this.hasOuterHandles=true;},unreg:function(){Event.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(e,oDD){var button=e.which||e.button;if(this.primaryButtonOnly&&button>1){return;}
if(this.isLocked()){return;}
this.b4MouseDown(e);this.onMouseDown(e);this.DDM.refreshCache(this.groups);var pt=new YAHOO.util.Point(Event.getPageX(e),Event.getPageY(e));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(pt,this)){}else{if(this.clickValidator(e)){this.setStartPosition();this.DDM.handleMouseDown(e,this);this.DDM.stopEvent(e);}else{}}},clickValidator:function(e){var target=Event.getTarget(e);return(this.isValidHandleChild(target)&&(this.id==this.handleElId||this.DDM.handleWasClicked(target,this.id)));},getTargetCoord:function(iPageX,iPageY){var x=iPageX-this.deltaX;var y=iPageY-this.deltaY;if(this.constrainX){if(x<this.minX){x=this.minX;}
if(x>this.maxX){x=this.maxX;}}
if(this.constrainY){if(y<this.minY){y=this.minY;}
if(y>this.maxY){y=this.maxY;}}
x=this.getTick(x,this.xTicks);y=this.getTick(y,this.yTicks);return{x:x,y:y};},addInvalidHandleType:function(tagName){var type=tagName.toUpperCase();this.invalidHandleTypes[type]=type;},addInvalidHandleId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);}
this.invalidHandleIds[id]=id;},addInvalidHandleClass:function(cssClass){this.invalidHandleClasses.push(cssClass);},removeInvalidHandleType:function(tagName){var type=tagName.toUpperCase();delete this.invalidHandleTypes[type];},removeInvalidHandleId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);}
delete this.invalidHandleIds[id];},removeInvalidHandleClass:function(cssClass){for(var i=0,len=this.invalidHandleClasses.length;i<len;++i){if(this.invalidHandleClasses[i]==cssClass){delete this.invalidHandleClasses[i];}}},isValidHandleChild:function(node){var valid=true;var nodeName;try{nodeName=node.nodeName.toUpperCase();}catch(e){nodeName=node.nodeName;}
valid=valid&&!this.invalidHandleTypes[nodeName];valid=valid&&!this.invalidHandleIds[node.id];for(var i=0,len=this.invalidHandleClasses.length;valid&&i<len;++i){valid=!Dom.hasClass(node,this.invalidHandleClasses[i]);}
return valid;},setXTicks:function(iStartX,iTickSize){this.xTicks=[];this.xTickSize=iTickSize;var tickMap={};for(var i=this.initPageX;i>=this.minX;i=i-iTickSize){if(!tickMap[i]){this.xTicks[this.xTicks.length]=i;tickMap[i]=true;}}
for(i=this.initPageX;i<=this.maxX;i=i+iTickSize){if(!tickMap[i]){this.xTicks[this.xTicks.length]=i;tickMap[i]=true;}}
this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(iStartY,iTickSize){this.yTicks=[];this.yTickSize=iTickSize;var tickMap={};for(var i=this.initPageY;i>=this.minY;i=i-iTickSize){if(!tickMap[i]){this.yTicks[this.yTicks.length]=i;tickMap[i]=true;}}
for(i=this.initPageY;i<=this.maxY;i=i+iTickSize){if(!tickMap[i]){this.yTicks[this.yTicks.length]=i;tickMap[i]=true;}}
this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(iLeft,iRight,iTickSize){this.leftConstraint=parseInt(iLeft,10);this.rightConstraint=parseInt(iRight,10);this.minX=this.initPageX-this.leftConstraint;this.maxX=this.initPageX+this.rightConstraint;if(iTickSize){this.setXTicks(this.initPageX,iTickSize);}
this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(iUp,iDown,iTickSize){this.topConstraint=parseInt(iUp,10);this.bottomConstraint=parseInt(iDown,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint;if(iTickSize){this.setYTicks(this.initPageY,iTickSize);}
this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var dx=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var dy=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(dx,dy);}else{this.setInitPosition();}
if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}
if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(val,tickArray){if(!tickArray){return val;}else if(tickArray[0]>=val){return tickArray[0];}else{for(var i=0,len=tickArray.length;i<len;++i){var next=i+1;if(tickArray[next]&&tickArray[next]>=val){var diff1=val-tickArray[i];var diff2=tickArray[next]-val;return(diff2>diff1)?tickArray[i]:tickArray[next];}}
return tickArray[tickArray.length-1];}},toString:function(){return("DragDrop "+this.id);}};})();YAHOO.util.DD=function(id,sGroup,config){if(id){this.init(id,sGroup,config);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(iPageX,iPageY){var x=iPageX-this.startPageX;var y=iPageY-this.startPageY;this.setDelta(x,y);},setDelta:function(iDeltaX,iDeltaY){this.deltaX=iDeltaX;this.deltaY=iDeltaY;},setDragElPos:function(iPageX,iPageY){var el=this.getDragEl();this.alignElWithMouse(el,iPageX,iPageY);},alignElWithMouse:function(el,iPageX,iPageY){var oCoord=this.getTargetCoord(iPageX,iPageY);if(!this.deltaSetXY){var aCoord=[oCoord.x,oCoord.y];YAHOO.util.Dom.setXY(el,aCoord);var newLeft=parseInt(YAHOO.util.Dom.getStyle(el,"left"),10);var newTop=parseInt(YAHOO.util.Dom.getStyle(el,"top"),10);this.deltaSetXY=[newLeft-oCoord.x,newTop-oCoord.y];}else{YAHOO.util.Dom.setStyle(el,"left",(oCoord.x+this.deltaSetXY[0])+"px");YAHOO.util.Dom.setStyle(el,"top",(oCoord.y+this.deltaSetXY[1])+"px");}
this.cachePosition(oCoord.x,oCoord.y);this.autoScroll(oCoord.x,oCoord.y,el.offsetHeight,el.offsetWidth);},cachePosition:function(iPageX,iPageY){if(iPageX){this.lastPageX=iPageX;this.lastPageY=iPageY;}else{var aCoord=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=aCoord[0];this.lastPageY=aCoord[1];}},autoScroll:function(x,y,h,w){if(this.scroll){var clientH=this.DDM.getClientHeight();var clientW=this.DDM.getClientWidth();var st=this.DDM.getScrollTop();var sl=this.DDM.getScrollLeft();var bot=h+y;var right=w+x;var toBot=(clientH+st-y-this.deltaY);var toRight=(clientW+sl-x-this.deltaX);var thresh=40;var scrAmt=(document.all)?80:30;if(bot>clientH&&toBot<thresh){window.scrollTo(sl,st+scrAmt);}
if(y<st&&st>0&&y-st<thresh){window.scrollTo(sl,st-scrAmt);}
if(right>clientW&&toRight<thresh){window.scrollTo(sl+scrAmt,st);}
if(x<sl&&sl>0&&x-sl<thresh){window.scrollTo(sl-scrAmt,st);}}},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(e){this.setStartPosition();this.autoOffset(YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e));},b4Drag:function(e){this.setDragElPos(YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e));},toString:function(){return("DD "+this.id);}});YAHOO.util.DDProxy=function(id,sGroup,config){if(id){this.init(id,sGroup,config);this.initFrame();}};YAHOO.util.DDProxy.dragElId="ygddfdiv";YAHOO.extend(YAHOO.util.DDProxy,YAHOO.util.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var self=this;var body=document.body;if(!body||!body.firstChild){setTimeout(function(){self.createFrame();},50);return;}
var div=this.getDragEl();if(!div){div=document.createElement("div");div.id=this.dragElId;var s=div.style;s.position="absolute";s.visibility="hidden";s.cursor="move";s.border="2px solid #aaa";s.zIndex=999;body.insertBefore(div,body.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){YAHOO.util.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||YAHOO.util.DDProxy.dragElId);},showFrame:function(iPageX,iPageY){var el=this.getEl();var dragEl=this.getDragEl();var s=dragEl.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(s.width,10)/2),Math.round(parseInt(s.height,10)/2));}
this.setDragElPos(iPageX,iPageY);YAHOO.util.Dom.setStyle(dragEl,"visibility","visible");},_resizeProxy:function(){if(this.resizeFrame){var DOM=YAHOO.util.Dom;var el=this.getEl();var dragEl=this.getDragEl();var bt=parseInt(DOM.getStyle(dragEl,"borderTopWidth"),10);var br=parseInt(DOM.getStyle(dragEl,"borderRightWidth"),10);var bb=parseInt(DOM.getStyle(dragEl,"borderBottomWidth"),10);var bl=parseInt(DOM.getStyle(dragEl,"borderLeftWidth"),10);if(isNaN(bt)){bt=0;}
if(isNaN(br)){br=0;}
if(isNaN(bb)){bb=0;}
if(isNaN(bl)){bl=0;}
var newWidth=Math.max(0,el.offsetWidth-br-bl);var newHeight=Math.max(0,el.offsetHeight-bt-bb);DOM.setStyle(dragEl,"width",newWidth+"px");DOM.setStyle(dragEl,"height",newHeight+"px");}},b4MouseDown:function(e){this.setStartPosition();var x=YAHOO.util.Event.getPageX(e);var y=YAHOO.util.Event.getPageY(e);this.autoOffset(x,y);this.setDragElPos(x,y);},b4StartDrag:function(x,y){this.showFrame(x,y);},b4EndDrag:function(e){YAHOO.util.Dom.setStyle(this.getDragEl(),"visibility","hidden");},endDrag:function(e){var DOM=YAHOO.util.Dom;var lel=this.getEl();var del=this.getDragEl();DOM.setStyle(del,"visibility","");DOM.setStyle(lel,"visibility","hidden");YAHOO.util.DDM.moveToEl(lel,del);DOM.setStyle(del,"visibility","hidden");DOM.setStyle(lel,"visibility","");},toString:function(){return("DDProxy "+this.id);}});YAHOO.util.DDTarget=function(id,sGroup,config){if(id){this.initTarget(id,sGroup,config);}};YAHOO.extend(YAHOO.util.DDTarget,YAHOO.util.DragDrop,{toString:function(){return("DDTarget "+this.id);}});YAHOO.register("dragdrop",YAHOO.util.DragDropMgr,{version:"2.2.2",build:"204"});;
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.2
*/

YAHOO.util.Config=function(owner){if(owner){this.init(owner);}};YAHOO.util.Config.CONFIG_CHANGED_EVENT="configChanged";YAHOO.util.Config.BOOLEAN_TYPE="boolean";YAHOO.util.Config.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,checkBoolean:function(val){return(typeof val==YAHOO.util.Config.BOOLEAN_TYPE);},checkNumber:function(val){return(!isNaN(val));},fireEvent:function(key,value){var property=this.config[key];if(property&&property.event){property.event.fire(value);}},addProperty:function(key,propertyObject){key=key.toLowerCase();this.config[key]=propertyObject;propertyObject.event=new YAHOO.util.CustomEvent(key,this.owner);propertyObject.key=key;if(propertyObject.handler){propertyObject.event.subscribe(propertyObject.handler,this.owner);}
this.setProperty(key,propertyObject.value,true);if(!propertyObject.suppressEvent){this.queueProperty(key,propertyObject.value);}},getConfig:function(){var cfg={};for(var prop in this.config){var property=this.config[prop];if(property&&property.event){cfg[prop]=property.value;}}
return cfg;},getProperty:function(key){var property=this.config[key.toLowerCase()];if(property&&property.event){return property.value;}else{return undefined;}},resetProperty:function(key){key=key.toLowerCase();var property=this.config[key];if(property&&property.event){if(this.initialConfig[key]&&!YAHOO.lang.isUndefined(this.initialConfig[key])){this.setProperty(key,this.initialConfig[key]);}
return true;}else{return false;}},setProperty:function(key,value,silent){key=key.toLowerCase();if(this.queueInProgress&&!silent){this.queueProperty(key,value);return true;}else{var property=this.config[key];if(property&&property.event){if(property.validator&&!property.validator(value)){return false;}else{property.value=value;if(!silent){this.fireEvent(key,value);this.configChangedEvent.fire([key,value]);}
return true;}}else{return false;}}},queueProperty:function(key,value){key=key.toLowerCase();var property=this.config[key];if(property&&property.event){if(!YAHOO.lang.isUndefined(value)&&property.validator&&!property.validator(value)){return false;}else{if(!YAHOO.lang.isUndefined(value)){property.value=value;}else{value=property.value;}
var foundDuplicate=false;var iLen=this.eventQueue.length;for(var i=0;i<iLen;i++){var queueItem=this.eventQueue[i];if(queueItem){var queueItemKey=queueItem[0];var queueItemValue=queueItem[1];if(queueItemKey==key){this.eventQueue[i]=null;this.eventQueue.push([key,(!YAHOO.lang.isUndefined(value)?value:queueItemValue)]);foundDuplicate=true;break;}}}
if(!foundDuplicate&&!YAHOO.lang.isUndefined(value)){this.eventQueue.push([key,value]);}}
if(property.supercedes){var sLen=property.supercedes.length;for(var s=0;s<sLen;s++){var supercedesCheck=property.supercedes[s];var qLen=this.eventQueue.length;for(var q=0;q<qLen;q++){var queueItemCheck=this.eventQueue[q];if(queueItemCheck){var queueItemCheckKey=queueItemCheck[0];var queueItemCheckValue=queueItemCheck[1];if(queueItemCheckKey==supercedesCheck.toLowerCase()){this.eventQueue.push([queueItemCheckKey,queueItemCheckValue]);this.eventQueue[q]=null;break;}}}}}
return true;}else{return false;}},refireEvent:function(key){key=key.toLowerCase();var property=this.config[key];if(property&&property.event&&!YAHOO.lang.isUndefined(property.value)){if(this.queueInProgress){this.queueProperty(key);}else{this.fireEvent(key,property.value);}}},applyConfig:function(userConfig,init){if(init){this.initialConfig=userConfig;}
for(var prop in userConfig){this.queueProperty(prop,userConfig[prop]);}},refresh:function(){for(var prop in this.config){this.refireEvent(prop);}},fireQueue:function(){this.queueInProgress=true;for(var i=0;i<this.eventQueue.length;i++){var queueItem=this.eventQueue[i];if(queueItem){var key=queueItem[0];var value=queueItem[1];var property=this.config[key];property.value=value;this.fireEvent(key,value);}}
this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(key,handler,obj,override){var property=this.config[key.toLowerCase()];if(property&&property.event){if(!YAHOO.util.Config.alreadySubscribed(property.event,handler,obj)){property.event.subscribe(handler,obj,override);}
return true;}else{return false;}},unsubscribeFromConfigEvent:function(key,handler,obj){var property=this.config[key.toLowerCase()];if(property&&property.event){return property.event.unsubscribe(handler,obj);}else{return false;}},toString:function(){var output="Config";if(this.owner){output+=" ["+this.owner.toString()+"]";}
return output;},outputEventQueue:function(){var output="";for(var q=0;q<this.eventQueue.length;q++){var queueItem=this.eventQueue[q];if(queueItem){output+=queueItem[0]+"="+queueItem[1]+", ";}}
return output;}};YAHOO.util.Config.prototype.init=function(owner){this.owner=owner;this.configChangedEvent=new YAHOO.util.CustomEvent(YAHOO.util.CONFIG_CHANGED_EVENT,this);this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];};YAHOO.util.Config.alreadySubscribed=function(evt,fn,obj){for(var e=0;e<evt.subscribers.length;e++){var subsc=evt.subscribers[e];if(subsc&&subsc.obj==obj&&subsc.fn==fn){return true;}}
return false;};YAHOO.widget.Module=function(el,userConfig){if(el){this.init(el,userConfig);}else{}};YAHOO.widget.Module.IMG_ROOT=null;YAHOO.widget.Module.IMG_ROOT_SSL=null;YAHOO.widget.Module.CSS_MODULE="yui-module";YAHOO.widget.Module.CSS_HEADER="hd";YAHOO.widget.Module.CSS_BODY="bd";YAHOO.widget.Module.CSS_FOOTER="ft";YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL="javascript:false;";YAHOO.widget.Module.textResizeEvent=new YAHOO.util.CustomEvent("textResize");YAHOO.widget.Module._EVENT_TYPES={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTORY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"};YAHOO.widget.Module._DEFAULT_CONFIG={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true}};YAHOO.widget.Module.prototype={constructor:YAHOO.widget.Module,element:null,header:null,body:null,footer:null,id:null,imageRoot:YAHOO.widget.Module.IMG_ROOT,initEvents:function(){var EVENT_TYPES=YAHOO.widget.Module._EVENT_TYPES;this.beforeInitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_INIT,this);this.initEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.INIT,this);this.appendEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.APPEND,this);this.beforeRenderEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_RENDER,this);this.renderEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.RENDER,this);this.changeHeaderEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_HEADER,this);this.changeBodyEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_BODY,this);this.changeFooterEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_FOOTER,this);this.changeContentEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_CONTENT,this);this.destroyEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.DESTORY,this);this.beforeShowEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_SHOW,this);this.showEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.SHOW,this);this.beforeHideEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_HIDE,this);this.hideEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.HIDE,this);},platform:function(){var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1){return"windows";}else if(ua.indexOf("macintosh")!=-1){return"mac";}else{return false;}}(),browser:function(){var ua=navigator.userAgent.toLowerCase();if(ua.indexOf('opera')!=-1){return'opera';}else if(ua.indexOf('msie 7')!=-1){return'ie7';}else if(ua.indexOf('msie')!=-1){return'ie';}else if(ua.indexOf('safari')!=-1){return'safari';}else if(ua.indexOf('gecko')!=-1){return'gecko';}else{return false;}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){var DEFAULT_CONFIG=YAHOO.widget.Module._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.VISIBLE.key,{handler:this.configVisible,value:DEFAULT_CONFIG.VISIBLE.value,validator:DEFAULT_CONFIG.VISIBLE.validator});this.cfg.addProperty(DEFAULT_CONFIG.EFFECT.key,{suppressEvent:DEFAULT_CONFIG.EFFECT.suppressEvent,supercedes:DEFAULT_CONFIG.EFFECT.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:DEFAULT_CONFIG.MONITOR_RESIZE.value});},init:function(el,userConfig){this.initEvents();this.beforeInitEvent.fire(YAHOO.widget.Module);this.cfg=new YAHOO.util.Config(this);if(this.isSecure){this.imageRoot=YAHOO.widget.Module.IMG_ROOT_SSL;}
if(typeof el=="string"){var elId=el;el=document.getElementById(el);if(!el){el=document.createElement("div");el.id=elId;}}
this.element=el;if(el.id){this.id=el.id;}
var childNodes=this.element.childNodes;if(childNodes){for(var i=0;i<childNodes.length;i++){var child=childNodes[i];switch(child.className){case YAHOO.widget.Module.CSS_HEADER:this.header=child;break;case YAHOO.widget.Module.CSS_BODY:this.body=child;break;case YAHOO.widget.Module.CSS_FOOTER:this.footer=child;break;}}}
this.initDefaultConfig();YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Module.CSS_MODULE);if(userConfig){this.cfg.applyConfig(userConfig,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}
this.initEvent.fire(YAHOO.widget.Module);},initResizeMonitor:function(){if(this.browser!="opera"){var resizeMonitor=document.getElementById("_yuiResizeMonitor");if(!resizeMonitor){resizeMonitor=document.createElement("iframe");var bIE=(this.browser.indexOf("ie")===0);if(this.isSecure&&YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL&&bIE){resizeMonitor.src=YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL;}
resizeMonitor.id="_yuiResizeMonitor";resizeMonitor.style.visibility="hidden";document.body.appendChild(resizeMonitor);resizeMonitor.style.width="10em";resizeMonitor.style.height="10em";resizeMonitor.style.position="absolute";var nLeft=-1*resizeMonitor.offsetWidth;var nTop=-1*resizeMonitor.offsetHeight;resizeMonitor.style.top=nTop+"px";resizeMonitor.style.left=nLeft+"px";resizeMonitor.style.borderStyle="none";resizeMonitor.style.borderWidth="0";YAHOO.util.Dom.setStyle(resizeMonitor,"opacity","0");resizeMonitor.style.visibility="visible";if(!bIE){var doc=resizeMonitor.contentWindow.document;doc.open();doc.close();}}
var fireTextResize=function(){YAHOO.widget.Module.textResizeEvent.fire();};if(resizeMonitor&&resizeMonitor.contentWindow){this.resizeMonitor=resizeMonitor;YAHOO.widget.Module.textResizeEvent.subscribe(this.onDomResize,this,true);if(!YAHOO.widget.Module.textResizeInitialized){if(!YAHOO.util.Event.addListener(this.resizeMonitor.contentWindow,"resize",fireTextResize)){YAHOO.util.Event.addListener(this.resizeMonitor,"resize",fireTextResize);}
YAHOO.widget.Module.textResizeInitialized=true;}}}},onDomResize:function(e,obj){var nLeft=-1*this.resizeMonitor.offsetWidth,nTop=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=nTop+"px";this.resizeMonitor.style.left=nLeft+"px";},setHeader:function(headerContent){if(!this.header){this.header=document.createElement("div");this.header.className=YAHOO.widget.Module.CSS_HEADER;}
if(typeof headerContent=="string"){this.header.innerHTML=headerContent;}else{this.header.innerHTML="";this.header.appendChild(headerContent);}
this.changeHeaderEvent.fire(headerContent);this.changeContentEvent.fire();},appendToHeader:function(element){if(!this.header){this.header=document.createElement("div");this.header.className=YAHOO.widget.Module.CSS_HEADER;}
this.header.appendChild(element);this.changeHeaderEvent.fire(element);this.changeContentEvent.fire();},setBody:function(bodyContent){if(!this.body){this.body=document.createElement("div");this.body.className=YAHOO.widget.Module.CSS_BODY;}
if(typeof bodyContent=="string")
{this.body.innerHTML=bodyContent;}else{this.body.innerHTML="";this.body.appendChild(bodyContent);}
this.changeBodyEvent.fire(bodyContent);this.changeContentEvent.fire();},appendToBody:function(element){if(!this.body){this.body=document.createElement("div");this.body.className=YAHOO.widget.Module.CSS_BODY;}
this.body.appendChild(element);this.changeBodyEvent.fire(element);this.changeContentEvent.fire();},setFooter:function(footerContent){if(!this.footer){this.footer=document.createElement("div");this.footer.className=YAHOO.widget.Module.CSS_FOOTER;}
if(typeof footerContent=="string"){this.footer.innerHTML=footerContent;}else{this.footer.innerHTML="";this.footer.appendChild(footerContent);}
this.changeFooterEvent.fire(footerContent);this.changeContentEvent.fire();},appendToFooter:function(element){if(!this.footer){this.footer=document.createElement("div");this.footer.className=YAHOO.widget.Module.CSS_FOOTER;}
this.footer.appendChild(element);this.changeFooterEvent.fire(element);this.changeContentEvent.fire();},render:function(appendToNode,moduleElement){this.beforeRenderEvent.fire();if(!moduleElement){moduleElement=this.element;}
var me=this;var appendTo=function(element){if(typeof element=="string"){element=document.getElementById(element);}
if(element){element.appendChild(me.element);me.appendEvent.fire();}};if(appendToNode){appendTo(appendToNode);}else{if(!YAHOO.util.Dom.inDocument(this.element)){return false;}}
if(this.header&&!YAHOO.util.Dom.inDocument(this.header)){var firstChild=moduleElement.firstChild;if(firstChild){moduleElement.insertBefore(this.header,firstChild);}else{moduleElement.appendChild(this.header);}}
if(this.body&&!YAHOO.util.Dom.inDocument(this.body)){if(this.footer&&YAHOO.util.Dom.isAncestor(this.moduleElement,this.footer)){moduleElement.insertBefore(this.body,this.footer);}else{moduleElement.appendChild(this.body);}}
if(this.footer&&!YAHOO.util.Dom.inDocument(this.footer)){moduleElement.appendChild(this.footer);}
this.renderEvent.fire();return true;},destroy:function(){var parent;if(this.element){YAHOO.util.Event.purgeElement(this.element,true);parent=this.element.parentNode;}
if(parent){parent.removeChild(this.element);}
this.element=null;this.header=null;this.body=null;this.footer=null;for(var e in this){if(e instanceof YAHOO.util.CustomEvent){e.unsubscribeAll();}}
YAHOO.widget.Module.textResizeEvent.unsubscribe(this.onDomResize,this);this.destroyEvent.fire();},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(type,args,obj){var visible=args[0];if(visible){this.beforeShowEvent.fire();YAHOO.util.Dom.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();YAHOO.util.Dom.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(type,args,obj){var monitor=args[0];if(monitor){this.initResizeMonitor();}else{YAHOO.widget.Module.textResizeEvent.unsubscribe(this.onDomResize,this,true);this.resizeMonitor=null;}}};YAHOO.widget.Module.prototype.toString=function(){return"Module "+this.id;};YAHOO.widget.Overlay=function(el,userConfig){YAHOO.widget.Overlay.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.Overlay,YAHOO.widget.Module);YAHOO.widget.Overlay._EVENT_TYPES={"BEFORE_MOVE":"beforeMove","MOVE":"move"};YAHOO.widget.Overlay._DEFAULT_CONFIG={"X":{key:"x",validator:YAHOO.lang.isNumber,suppressEvent:true,supercedes:["iframe"]},"Y":{key:"y",validator:YAHOO.lang.isNumber,suppressEvent:true,supercedes:["iframe"]},"XY":{key:"xy",suppressEvent:true,supercedes:["iframe"]},"CONTEXT":{key:"context",suppressEvent:true,supercedes:["iframe"]},"FIXED_CENTER":{key:"fixedcenter",value:false,validator:YAHOO.lang.isBoolean,supercedes:["iframe","visible"]},"WIDTH":{key:"width",suppressEvent:true,supercedes:["iframe"]},"HEIGHT":{key:"height",suppressEvent:true,supercedes:["iframe"]},"ZINDEX":{key:"zindex",value:null},"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:false,validator:YAHOO.lang.isBoolean,supercedes:["iframe","x","y","xy"]},"IFRAME":{key:"iframe",value:(YAHOO.widget.Module.prototype.browser=="ie"?true:false),validator:YAHOO.lang.isBoolean,supercedes:["zIndex"]}};YAHOO.widget.Overlay.IFRAME_SRC="javascript:false;";YAHOO.widget.Overlay.TOP_LEFT="tl";YAHOO.widget.Overlay.TOP_RIGHT="tr";YAHOO.widget.Overlay.BOTTOM_LEFT="bl";YAHOO.widget.Overlay.BOTTOM_RIGHT="br";YAHOO.widget.Overlay.CSS_OVERLAY="yui-overlay";YAHOO.widget.Overlay.prototype.init=function(el,userConfig){YAHOO.widget.Overlay.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.Overlay);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Overlay.CSS_OVERLAY);if(userConfig){this.cfg.applyConfig(userConfig,true);}
if(this.platform=="mac"&&this.browser=="gecko"){if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}
this.initEvent.fire(YAHOO.widget.Overlay);};YAHOO.widget.Overlay.prototype.initEvents=function(){YAHOO.widget.Overlay.superclass.initEvents.call(this);var EVENT_TYPES=YAHOO.widget.Overlay._EVENT_TYPES;this.beforeMoveEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_MOVE,this);this.moveEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.MOVE,this);};YAHOO.widget.Overlay.prototype.initDefaultConfig=function(){YAHOO.widget.Overlay.superclass.initDefaultConfig.call(this);var DEFAULT_CONFIG=YAHOO.widget.Overlay._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.X.key,{handler:this.configX,validator:DEFAULT_CONFIG.X.validator,suppressEvent:DEFAULT_CONFIG.X.suppressEvent,supercedes:DEFAULT_CONFIG.X.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.Y.key,{handler:this.configY,validator:DEFAULT_CONFIG.Y.validator,suppressEvent:DEFAULT_CONFIG.Y.suppressEvent,supercedes:DEFAULT_CONFIG.Y.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.XY.key,{handler:this.configXY,suppressEvent:DEFAULT_CONFIG.XY.suppressEvent,supercedes:DEFAULT_CONFIG.XY.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.CONTEXT.key,{handler:this.configContext,suppressEvent:DEFAULT_CONFIG.CONTEXT.suppressEvent,supercedes:DEFAULT_CONFIG.CONTEXT.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.FIXED_CENTER.key,{handler:this.configFixedCenter,value:DEFAULT_CONFIG.FIXED_CENTER.value,validator:DEFAULT_CONFIG.FIXED_CENTER.validator,supercedes:DEFAULT_CONFIG.FIXED_CENTER.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.WIDTH.key,{handler:this.configWidth,suppressEvent:DEFAULT_CONFIG.WIDTH.suppressEvent,supercedes:DEFAULT_CONFIG.WIDTH.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.HEIGHT.key,{handler:this.configHeight,suppressEvent:DEFAULT_CONFIG.HEIGHT.suppressEvent,supercedes:DEFAULT_CONFIG.HEIGHT.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.ZINDEX.key,{handler:this.configzIndex,value:DEFAULT_CONFIG.ZINDEX.value});this.cfg.addProperty(DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value,validator:DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator,supercedes:DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.IFRAME.key,{handler:this.configIframe,value:DEFAULT_CONFIG.IFRAME.value,validator:DEFAULT_CONFIG.IFRAME.validator,supercedes:DEFAULT_CONFIG.IFRAME.supercedes});};YAHOO.widget.Overlay.prototype.moveTo=function(x,y){this.cfg.setProperty("xy",[x,y]);};YAHOO.widget.Overlay.prototype.hideMacGeckoScrollbars=function(){YAHOO.util.Dom.removeClass(this.element,"show-scrollbars");YAHOO.util.Dom.addClass(this.element,"hide-scrollbars");};YAHOO.widget.Overlay.prototype.showMacGeckoScrollbars=function(){YAHOO.util.Dom.removeClass(this.element,"hide-scrollbars");YAHOO.util.Dom.addClass(this.element,"show-scrollbars");};YAHOO.widget.Overlay.prototype.configVisible=function(type,args,obj){var visible=args[0];var currentVis=YAHOO.util.Dom.getStyle(this.element,"visibility");if(currentVis=="inherit"){var e=this.element.parentNode;while(e.nodeType!=9&&e.nodeType!=11){currentVis=YAHOO.util.Dom.getStyle(e,"visibility");if(currentVis!="inherit"){break;}
e=e.parentNode;}
if(currentVis=="inherit"){currentVis="visible";}}
var effect=this.cfg.getProperty("effect");var effectInstances=[];if(effect){if(effect instanceof Array){for(var i=0;i<effect.length;i++){var eff=effect[i];effectInstances[effectInstances.length]=eff.effect(this,eff.duration);}}else{effectInstances[effectInstances.length]=effect.effect(this,effect.duration);}}
var isMacGecko=(this.platform=="mac"&&this.browser=="gecko");if(visible){if(isMacGecko){this.showMacGeckoScrollbars();}
if(effect){if(visible){if(currentVis!="visible"||currentVis===""){this.beforeShowEvent.fire();for(var j=0;j<effectInstances.length;j++){var ei=effectInstances[j];if(j===0&&!YAHOO.util.Config.alreadySubscribed(ei.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){ei.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}
ei.animateIn();}}}}else{if(currentVis!="visible"||currentVis===""){this.beforeShowEvent.fire();YAHOO.util.Dom.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(isMacGecko){this.hideMacGeckoScrollbars();}
if(effect){if(currentVis=="visible"){this.beforeHideEvent.fire();for(var k=0;k<effectInstances.length;k++){var h=effectInstances[k];if(k===0&&!YAHOO.util.Config.alreadySubscribed(h.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)){h.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}
h.animateOut();}}else if(currentVis===""){YAHOO.util.Dom.setStyle(this.element,"visibility","hidden");}}else{if(currentVis=="visible"||currentVis===""){this.beforeHideEvent.fire();YAHOO.util.Dom.setStyle(this.element,"visibility","hidden");this.cfg.refireEvent("iframe");this.hideEvent.fire();}}}};YAHOO.widget.Overlay.prototype.doCenterOnDOMEvent=function(){if(this.cfg.getProperty("visible")){this.center();}};YAHOO.widget.Overlay.prototype.configFixedCenter=function(type,args,obj){var val=args[0];if(val){this.center();if(!YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEvent,this.doCenterOnDOMEvent,this)){YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.doCenterOnDOMEvent,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowScrollEvent,this.doCenterOnDOMEvent,this)){YAHOO.widget.Overlay.windowScrollEvent.subscribe(this.doCenterOnDOMEvent,this,true);}}else{YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);}};YAHOO.widget.Overlay.prototype.configHeight=function(type,args,obj){var height=args[0];var el=this.element;YAHOO.util.Dom.setStyle(el,"height",height);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.configWidth=function(type,args,obj){var width=args[0];var el=this.element;YAHOO.util.Dom.setStyle(el,"width",width);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.configzIndex=function(type,args,obj){var zIndex=args[0];var el=this.element;if(!zIndex){zIndex=YAHOO.util.Dom.getStyle(el,"zIndex");if(!zIndex||isNaN(zIndex)){zIndex=0;}}
if(this.iframe){if(zIndex<=0){zIndex=1;}
YAHOO.util.Dom.setStyle(this.iframe,"zIndex",(zIndex-1));}
YAHOO.util.Dom.setStyle(el,"zIndex",zIndex);this.cfg.setProperty("zIndex",zIndex,true);};YAHOO.widget.Overlay.prototype.configXY=function(type,args,obj){var pos=args[0];var x=pos[0];var y=pos[1];this.cfg.setProperty("x",x);this.cfg.setProperty("y",y);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.configX=function(type,args,obj){var x=args[0];var y=this.cfg.getProperty("y");this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");YAHOO.util.Dom.setX(this.element,x,true);this.cfg.setProperty("xy",[x,y],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.configY=function(type,args,obj){var x=this.cfg.getProperty("x");var y=args[0];this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.beforeMoveEvent.fire([x,y]);x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");YAHOO.util.Dom.setY(this.element,y,true);this.cfg.setProperty("xy",[x,y],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([x,y]);};YAHOO.widget.Overlay.prototype.showIframe=function(){if(this.iframe){this.iframe.style.display="block";}};YAHOO.widget.Overlay.prototype.hideIframe=function(){if(this.iframe){this.iframe.style.display="none";}};YAHOO.widget.Overlay.prototype.configIframe=function(type,args,obj){var val=args[0];if(val){if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showIframe,this)){this.showEvent.subscribe(this.showIframe,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideIframe,this)){this.hideEvent.subscribe(this.hideIframe,this,true);}
var x=this.cfg.getProperty("x");var y=this.cfg.getProperty("y");if(!x||!y){this.syncPosition();x=this.cfg.getProperty("x");y=this.cfg.getProperty("y");}
if(!isNaN(x)&&!isNaN(y)){if(!this.iframe){this.iframe=document.createElement("iframe");if(this.isSecure){this.iframe.src=YAHOO.widget.Overlay.IFRAME_SRC;}
var parent=this.element.parentNode;if(parent){parent.appendChild(this.iframe);}else{document.body.appendChild(this.iframe);}
YAHOO.util.Dom.setStyle(this.iframe,"position","absolute");YAHOO.util.Dom.setStyle(this.iframe,"border","none");YAHOO.util.Dom.setStyle(this.iframe,"margin","0");YAHOO.util.Dom.setStyle(this.iframe,"padding","0");YAHOO.util.Dom.setStyle(this.iframe,"opacity","0");if(this.cfg.getProperty("visible")){this.showIframe();}else{this.hideIframe();}}
var iframeDisplay=YAHOO.util.Dom.getStyle(this.iframe,"display");if(iframeDisplay=="none"){this.iframe.style.display="block";}
YAHOO.util.Dom.setXY(this.iframe,[x,y]);var width=this.element.clientWidth;var height=this.element.clientHeight;YAHOO.util.Dom.setStyle(this.iframe,"width",(width+2)+"px");YAHOO.util.Dom.setStyle(this.iframe,"height",(height+2)+"px");if(iframeDisplay=="none"){this.iframe.style.display="none";}}}else{if(this.iframe){this.iframe.style.display="none";}
this.showEvent.unsubscribe(this.showIframe,this);this.hideEvent.unsubscribe(this.hideIframe,this);}};YAHOO.widget.Overlay.prototype.configConstrainToViewport=function(type,args,obj){var val=args[0];if(val){if(!YAHOO.util.Config.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}}else{this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}};YAHOO.widget.Overlay.prototype.configContext=function(type,args,obj){var contextArgs=args[0];if(contextArgs){var contextEl=contextArgs[0];var elementMagnetCorner=contextArgs[1];var contextMagnetCorner=contextArgs[2];if(contextEl){if(typeof contextEl=="string"){this.cfg.setProperty("context",[document.getElementById(contextEl),elementMagnetCorner,contextMagnetCorner],true);}
if(elementMagnetCorner&&contextMagnetCorner){this.align(elementMagnetCorner,contextMagnetCorner);}}}};YAHOO.widget.Overlay.prototype.align=function(elementAlign,contextAlign){var contextArgs=this.cfg.getProperty("context");if(contextArgs){var context=contextArgs[0];var element=this.element;var me=this;if(!elementAlign){elementAlign=contextArgs[1];}
if(!contextAlign){contextAlign=contextArgs[2];}
if(element&&context){var contextRegion=YAHOO.util.Dom.getRegion(context);var doAlign=function(v,h){switch(elementAlign){case YAHOO.widget.Overlay.TOP_LEFT:me.moveTo(h,v);break;case YAHOO.widget.Overlay.TOP_RIGHT:me.moveTo(h-element.offsetWidth,v);break;case YAHOO.widget.Overlay.BOTTOM_LEFT:me.moveTo(h,v-element.offsetHeight);break;case YAHOO.widget.Overlay.BOTTOM_RIGHT:me.moveTo(h-element.offsetWidth,v-element.offsetHeight);break;}};switch(contextAlign){case YAHOO.widget.Overlay.TOP_LEFT:doAlign(contextRegion.top,contextRegion.left);break;case YAHOO.widget.Overlay.TOP_RIGHT:doAlign(contextRegion.top,contextRegion.right);break;case YAHOO.widget.Overlay.BOTTOM_LEFT:doAlign(contextRegion.bottom,contextRegion.left);break;case YAHOO.widget.Overlay.BOTTOM_RIGHT:doAlign(contextRegion.bottom,contextRegion.right);break;}}}};YAHOO.widget.Overlay.prototype.enforceConstraints=function(type,args,obj){var pos=args[0];var x=pos[0];var y=pos[1];var offsetHeight=this.element.offsetHeight;var offsetWidth=this.element.offsetWidth;var viewPortWidth=YAHOO.util.Dom.getViewportWidth();var viewPortHeight=YAHOO.util.Dom.getViewportHeight();var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;var topConstraint=scrollY+10;var leftConstraint=scrollX+10;var bottomConstraint=scrollY+viewPortHeight-offsetHeight-10;var rightConstraint=scrollX+viewPortWidth-offsetWidth-10;if(x<leftConstraint){x=leftConstraint;}else if(x>rightConstraint){x=rightConstraint;}
if(y<topConstraint){y=topConstraint;}else if(y>bottomConstraint){y=bottomConstraint;}
this.cfg.setProperty("x",x,true);this.cfg.setProperty("y",y,true);this.cfg.setProperty("xy",[x,y],true);};YAHOO.widget.Overlay.prototype.center=function(){var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;var viewPortWidth=YAHOO.util.Dom.getClientWidth();var viewPortHeight=YAHOO.util.Dom.getClientHeight();var elementWidth=this.element.offsetWidth;var elementHeight=this.element.offsetHeight;var x=(viewPortWidth/2)-(elementWidth/2)+scrollX;var y=(viewPortHeight/2)-(elementHeight/2)+scrollY;this.cfg.setProperty("xy",[parseInt(x,10),parseInt(y,10)]);this.cfg.refireEvent("iframe");};YAHOO.widget.Overlay.prototype.syncPosition=function(){var pos=YAHOO.util.Dom.getXY(this.element);this.cfg.setProperty("x",pos[0],true);this.cfg.setProperty("y",pos[1],true);this.cfg.setProperty("xy",pos,true);};YAHOO.widget.Overlay.prototype.onDomResize=function(e,obj){YAHOO.widget.Overlay.superclass.onDomResize.call(this,e,obj);var me=this;setTimeout(function(){me.syncPosition();me.cfg.refireEvent("iframe");me.cfg.refireEvent("context");},0);};YAHOO.widget.Overlay.prototype.destroy=function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}
this.iframe=null;YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);YAHOO.widget.Overlay.superclass.destroy.call(this);};YAHOO.widget.Overlay.prototype.toString=function(){return"Overlay "+this.id;};YAHOO.widget.Overlay.windowScrollEvent=new YAHOO.util.CustomEvent("windowScroll");YAHOO.widget.Overlay.windowResizeEvent=new YAHOO.util.CustomEvent("windowResize");YAHOO.widget.Overlay.windowScrollHandler=function(e){if(YAHOO.widget.Module.prototype.browser=="ie"||YAHOO.widget.Module.prototype.browser=="ie7"){if(!window.scrollEnd){window.scrollEnd=-1;}
clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){YAHOO.widget.Overlay.windowScrollEvent.fire();},1);}else{YAHOO.widget.Overlay.windowScrollEvent.fire();}};YAHOO.widget.Overlay.windowResizeHandler=function(e){if(YAHOO.widget.Module.prototype.browser=="ie"||YAHOO.widget.Module.prototype.browser=="ie7"){if(!window.resizeEnd){window.resizeEnd=-1;}
clearTimeout(window.resizeEnd);window.resizeEnd=setTimeout(function(){YAHOO.widget.Overlay.windowResizeEvent.fire();},100);}else{YAHOO.widget.Overlay.windowResizeEvent.fire();}};YAHOO.widget.Overlay._initialized=null;if(YAHOO.widget.Overlay._initialized===null){YAHOO.util.Event.addListener(window,"scroll",YAHOO.widget.Overlay.windowScrollHandler);YAHOO.util.Event.addListener(window,"resize",YAHOO.widget.Overlay.windowResizeHandler);YAHOO.widget.Overlay._initialized=true;}
YAHOO.widget.OverlayManager=function(userConfig){this.init(userConfig);};YAHOO.widget.OverlayManager.CSS_FOCUSED="focused";YAHOO.widget.OverlayManager.prototype={constructor:YAHOO.widget.OverlayManager,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(userConfig){this.cfg=new YAHOO.util.Config(this);this.initDefaultConfig();if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.cfg.fireQueue();var activeOverlay=null;this.getActive=function(){return activeOverlay;};this.focus=function(overlay){var o=this.find(overlay);if(o){if(activeOverlay!=o){if(activeOverlay){activeOverlay.blur();}
activeOverlay=o;YAHOO.util.Dom.addClass(activeOverlay.element,YAHOO.widget.OverlayManager.CSS_FOCUSED);this.overlays.sort(this.compareZIndexDesc);var topZIndex=YAHOO.util.Dom.getStyle(this.overlays[0].element,"zIndex");if(!isNaN(topZIndex)&&this.overlays[0]!=overlay){activeOverlay.cfg.setProperty("zIndex",(parseInt(topZIndex,10)+2));}
this.overlays.sort(this.compareZIndexDesc);o.focusEvent.fire();}}};this.remove=function(overlay){var o=this.find(overlay);if(o){var originalZ=YAHOO.util.Dom.getStyle(o.element,"zIndex");o.cfg.setProperty("zIndex",-1000,true);this.overlays.sort(this.compareZIndexDesc);this.overlays=this.overlays.slice(0,this.overlays.length-1);o.hideEvent.unsubscribe(o.blur);o.destroyEvent.unsubscribe(this._onOverlayDestroy,o);if(o.element){YAHOO.util.Event.removeListener(o.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus);}
o.cfg.setProperty("zIndex",originalZ,true);o.cfg.setProperty("manager",null);o.focusEvent.unsubscribeAll();o.blurEvent.unsubscribeAll();o.focusEvent=null;o.blurEvent=null;o.focus=null;o.blur=null;}};this.blurAll=function(){for(var o=0;o<this.overlays.length;o++){this.overlays[o].blur();}};this._onOverlayBlur=function(p_sType,p_aArgs){activeOverlay=null;};var overlays=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}
if(overlays){this.register(overlays);this.overlays.sort(this.compareZIndexDesc);}},_onOverlayElementFocus:function(p_oEvent){var oTarget=YAHOO.util.Event.getTarget(p_oEvent),oClose=this.close;if(oClose&&(oTarget==oClose||YAHOO.util.Dom.isAncestor(oClose,oTarget))){this.blur();}
else{this.focus();}},_onOverlayDestroy:function(p_sType,p_aArgs,p_oOverlay){this.remove(p_oOverlay);},register:function(overlay){if(overlay instanceof YAHOO.widget.Overlay){overlay.cfg.addProperty("manager",{value:this});overlay.focusEvent=new YAHOO.util.CustomEvent("focus",overlay);overlay.blurEvent=new YAHOO.util.CustomEvent("blur",overlay);var mgr=this;overlay.focus=function(){mgr.focus(this);};overlay.blur=function(){if(mgr.getActive()==this){YAHOO.util.Dom.removeClass(this.element,YAHOO.widget.OverlayManager.CSS_FOCUSED);this.blurEvent.fire();}};overlay.blurEvent.subscribe(mgr._onOverlayBlur);overlay.hideEvent.subscribe(overlay.blur);overlay.destroyEvent.subscribe(this._onOverlayDestroy,overlay,this);YAHOO.util.Event.addListener(overlay.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus,null,overlay);var zIndex=YAHOO.util.Dom.getStyle(overlay.element,"zIndex");if(!isNaN(zIndex)){overlay.cfg.setProperty("zIndex",parseInt(zIndex,10));}else{overlay.cfg.setProperty("zIndex",0);}
this.overlays.push(overlay);return true;}else if(overlay instanceof Array){var regcount=0;for(var i=0;i<overlay.length;i++){if(this.register(overlay[i])){regcount++;}}
if(regcount>0){return true;}}else{return false;}},find:function(overlay){if(overlay instanceof YAHOO.widget.Overlay){for(var o=0;o<this.overlays.length;o++){if(this.overlays[o]==overlay){return this.overlays[o];}}}else if(typeof overlay=="string"){for(var p=0;p<this.overlays.length;p++){if(this.overlays[p].id==overlay){return this.overlays[p];}}}
return null;},compareZIndexDesc:function(o1,o2){var zIndex1=o1.cfg.getProperty("zIndex");var zIndex2=o2.cfg.getProperty("zIndex");if(zIndex1>zIndex2){return-1;}else if(zIndex1<zIndex2){return 1;}else{return 0;}},showAll:function(){for(var o=0;o<this.overlays.length;o++){this.overlays[o].show();}},hideAll:function(){for(var o=0;o<this.overlays.length;o++){this.overlays[o].hide();}},toString:function(){return"OverlayManager";}};YAHOO.widget.Tooltip=function(el,userConfig){YAHOO.widget.Tooltip.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.Tooltip,YAHOO.widget.Overlay);YAHOO.widget.Tooltip.CSS_TOOLTIP="yui-tt";YAHOO.widget.Tooltip._DEFAULT_CONFIG={"PREVENT_OVERLAP":{key:"preventoverlap",value:true,validator:YAHOO.lang.isBoolean,supercedes:["x","y","xy"]},"SHOW_DELAY":{key:"showdelay",value:200,validator:YAHOO.lang.isNumber},"AUTO_DISMISS_DELAY":{key:"autodismissdelay",value:5000,validator:YAHOO.lang.isNumber},"HIDE_DELAY":{key:"hidedelay",value:250,validator:YAHOO.lang.isNumber},"TEXT":{key:"text",suppressEvent:true},"CONTAINER":{key:"container"}};YAHOO.widget.Tooltip.prototype.init=function(el,userConfig){if(document.readyState&&document.readyState!="complete"){var deferredInit=function(){this.init(el,userConfig);};YAHOO.util.Event.addListener(window,"load",deferredInit,this,true);}else{YAHOO.widget.Tooltip.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.Tooltip);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Tooltip.CSS_TOOLTIP);if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.cfg.queueProperty("visible",false);this.cfg.queueProperty("constraintoviewport",true);this.setBody("");this.render(this.cfg.getProperty("container"));this.initEvent.fire(YAHOO.widget.Tooltip);}};YAHOO.widget.Tooltip.prototype.initDefaultConfig=function(){YAHOO.widget.Tooltip.superclass.initDefaultConfig.call(this);var DEFAULT_CONFIG=YAHOO.widget.Tooltip._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.PREVENT_OVERLAP.key,{value:DEFAULT_CONFIG.PREVENT_OVERLAP.value,validator:DEFAULT_CONFIG.PREVENT_OVERLAP.validator,supercedes:DEFAULT_CONFIG.PREVENT_OVERLAP.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.SHOW_DELAY.key,{handler:this.configShowDelay,value:200,validator:DEFAULT_CONFIG.SHOW_DELAY.validator});this.cfg.addProperty(DEFAULT_CONFIG.AUTO_DISMISS_DELAY.key,{handler:this.configAutoDismissDelay,value:DEFAULT_CONFIG.AUTO_DISMISS_DELAY.value,validator:DEFAULT_CONFIG.AUTO_DISMISS_DELAY.validator});this.cfg.addProperty(DEFAULT_CONFIG.HIDE_DELAY.key,{handler:this.configHideDelay,value:DEFAULT_CONFIG.HIDE_DELAY.value,validator:DEFAULT_CONFIG.HIDE_DELAY.validator});this.cfg.addProperty(DEFAULT_CONFIG.TEXT.key,{handler:this.configText,suppressEvent:DEFAULT_CONFIG.TEXT.suppressEvent});this.cfg.addProperty(DEFAULT_CONFIG.CONTAINER.key,{handler:this.configContainer,value:document.body});};YAHOO.widget.Tooltip.prototype.configText=function(type,args,obj){var text=args[0];if(text){this.setBody(text);}};YAHOO.widget.Tooltip.prototype.configContainer=function(type,args,obj){var container=args[0];if(typeof container=='string'){this.cfg.setProperty("container",document.getElementById(container),true);}};YAHOO.widget.Tooltip.prototype._removeEventListeners=function(){var aElements=this._context;if(aElements){var nElements=aElements.length;if(nElements>0){var i=nElements-1,oElement;do{oElement=aElements[i];YAHOO.util.Event.removeListener(oElement,"mouseover",this.onContextMouseOver);YAHOO.util.Event.removeListener(oElement,"mousemove",this.onContextMouseMove);YAHOO.util.Event.removeListener(oElement,"mouseout",this.onContextMouseOut);}
while(i--);}}};YAHOO.widget.Tooltip.prototype.configContext=function(type,args,obj){var context=args[0];if(context){if(!(context instanceof Array)){if(typeof context=="string"){this.cfg.setProperty("context",[document.getElementById(context)],true);}else{this.cfg.setProperty("context",[context],true);}
context=this.cfg.getProperty("context");}
this._removeEventListeners();this._context=context;var aElements=this._context;if(aElements){var nElements=aElements.length;if(nElements>0){var i=nElements-1,oElement;do{oElement=aElements[i];YAHOO.util.Event.addListener(oElement,"mouseover",this.onContextMouseOver,this);YAHOO.util.Event.addListener(oElement,"mousemove",this.onContextMouseMove,this);YAHOO.util.Event.addListener(oElement,"mouseout",this.onContextMouseOut,this);}
while(i--);}}}};YAHOO.widget.Tooltip.prototype.onContextMouseMove=function(e,obj){obj.pageX=YAHOO.util.Event.getPageX(e);obj.pageY=YAHOO.util.Event.getPageY(e);};YAHOO.widget.Tooltip.prototype.onContextMouseOver=function(e,obj){if(obj.hideProcId){clearTimeout(obj.hideProcId);obj.hideProcId=null;}
var context=this;YAHOO.util.Event.addListener(context,"mousemove",obj.onContextMouseMove,obj);if(context.title){obj._tempTitle=context.title;context.title="";}
obj.showProcId=obj.doShow(e,context);};YAHOO.widget.Tooltip.prototype.onContextMouseOut=function(e,obj){var el=this;if(obj._tempTitle){el.title=obj._tempTitle;obj._tempTitle=null;}
if(obj.showProcId){clearTimeout(obj.showProcId);obj.showProcId=null;}
if(obj.hideProcId){clearTimeout(obj.hideProcId);obj.hideProcId=null;}
obj.hideProcId=setTimeout(function(){obj.hide();},obj.cfg.getProperty("hidedelay"));};YAHOO.widget.Tooltip.prototype.doShow=function(e,context){var yOffset=25;if(this.browser=="opera"&&context.tagName&&context.tagName.toUpperCase()=="A"){yOffset+=12;}
var me=this;return setTimeout(function(){if(me._tempTitle){me.setBody(me._tempTitle);}else{me.cfg.refireEvent("text");}
me.moveTo(me.pageX,me.pageY+yOffset);if(me.cfg.getProperty("preventoverlap")){me.preventOverlap(me.pageX,me.pageY);}
YAHOO.util.Event.removeListener(context,"mousemove",me.onContextMouseMove);me.show();me.hideProcId=me.doHide();},this.cfg.getProperty("showdelay"));};YAHOO.widget.Tooltip.prototype.doHide=function(){var me=this;return setTimeout(function(){me.hide();},this.cfg.getProperty("autodismissdelay"));};YAHOO.widget.Tooltip.prototype.preventOverlap=function(pageX,pageY){var height=this.element.offsetHeight;var elementRegion=YAHOO.util.Dom.getRegion(this.element);elementRegion.top-=5;elementRegion.left-=5;elementRegion.right+=5;elementRegion.bottom+=5;var mousePoint=new YAHOO.util.Point(pageX,pageY);if(elementRegion.contains(mousePoint)){this.cfg.setProperty("y",(pageY-height-5));}};YAHOO.widget.Tooltip.prototype.destroy=function(){this._removeEventListeners();YAHOO.widget.Tooltip.superclass.destroy.call(this);};YAHOO.widget.Tooltip.prototype.toString=function(){return"Tooltip "+this.id;};YAHOO.widget.Panel=function(el,userConfig){YAHOO.widget.Panel.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.Panel,YAHOO.widget.Overlay);YAHOO.widget.Panel.CSS_PANEL="yui-panel";YAHOO.widget.Panel.CSS_PANEL_CONTAINER="yui-panel-container";YAHOO.widget.Panel._EVENT_TYPES={"SHOW_MASK":"showMask","HIDE_MASK":"hideMask","DRAG":"drag"};YAHOO.widget.Panel._DEFAULT_CONFIG={"CLOSE":{key:"close",value:true,validator:YAHOO.lang.isBoolean,supercedes:["visible"]},"DRAGGABLE":{key:"draggable",value:(YAHOO.util.DD?true:false),validator:YAHOO.lang.isBoolean,supercedes:["visible"]},"UNDERLAY":{key:"underlay",value:"shadow",supercedes:["visible"]},"MODAL":{key:"modal",value:false,validator:YAHOO.lang.isBoolean,supercedes:["visible"]},"KEY_LISTENERS":{key:"keylisteners",suppressEvent:true,supercedes:["visible"]}};YAHOO.widget.Panel.prototype.init=function(el,userConfig){YAHOO.widget.Panel.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.Panel);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Panel.CSS_PANEL);this.buildWrapper();if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.beforeRenderEvent.subscribe(function(){var draggable=this.cfg.getProperty("draggable");if(draggable){if(!this.header){this.setHeader("&#160;");}}},this,true);this.renderEvent.subscribe(function(){var sWidth=this.cfg.getProperty("width");if(!sWidth){this.cfg.setProperty("width",(this.element.offsetWidth+"px"));}});var me=this;var doBlur=function(){this.blur();};this.showMaskEvent.subscribe(function(){var checkFocusable=function(el){var sTagName=el.tagName.toUpperCase(),bFocusable=false;switch(sTagName){case"A":case"BUTTON":case"SELECT":case"TEXTAREA":if(!YAHOO.util.Dom.isAncestor(me.element,el)){YAHOO.util.Event.addListener(el,"focus",doBlur,el,true);bFocusable=true;}
break;case"INPUT":if(el.type!="hidden"&&!YAHOO.util.Dom.isAncestor(me.element,el)){YAHOO.util.Event.addListener(el,"focus",doBlur,el,true);bFocusable=true;}
break;}
return bFocusable;};this.focusableElements=YAHOO.util.Dom.getElementsBy(checkFocusable);},this,true);this.hideMaskEvent.subscribe(function(){for(var i=0;i<this.focusableElements.length;i++){var el2=this.focusableElements[i];YAHOO.util.Event.removeListener(el2,"focus",doBlur);}},this,true);this.beforeShowEvent.subscribe(function(){this.cfg.refireEvent("underlay");},this,true);this.initEvent.fire(YAHOO.widget.Panel);};YAHOO.widget.Panel.prototype.initEvents=function(){YAHOO.widget.Panel.superclass.initEvents.call(this);var EVENT_TYPES=YAHOO.widget.Panel._EVENT_TYPES;this.showMaskEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.SHOW_MASK,this);this.hideMaskEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.HIDE_MASK,this);this.dragEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.DRAG,this);};YAHOO.widget.Panel.prototype.initDefaultConfig=function(){YAHOO.widget.Panel.superclass.initDefaultConfig.call(this);var DEFAULT_CONFIG=YAHOO.widget.Panel._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.CLOSE.key,{handler:this.configClose,value:DEFAULT_CONFIG.CLOSE.value,validator:DEFAULT_CONFIG.CLOSE.validator,supercedes:DEFAULT_CONFIG.CLOSE.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.DRAGGABLE.key,{handler:this.configDraggable,value:DEFAULT_CONFIG.DRAGGABLE.value,validator:DEFAULT_CONFIG.DRAGGABLE.validator,supercedes:DEFAULT_CONFIG.DRAGGABLE.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.UNDERLAY.key,{handler:this.configUnderlay,value:DEFAULT_CONFIG.UNDERLAY.value,supercedes:DEFAULT_CONFIG.UNDERLAY.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.MODAL.key,{handler:this.configModal,value:DEFAULT_CONFIG.MODAL.value,validator:DEFAULT_CONFIG.MODAL.validator,supercedes:DEFAULT_CONFIG.MODAL.supercedes});this.cfg.addProperty(DEFAULT_CONFIG.KEY_LISTENERS.key,{handler:this.configKeyListeners,suppressEvent:DEFAULT_CONFIG.KEY_LISTENERS.suppressEvent,supercedes:DEFAULT_CONFIG.KEY_LISTENERS.supercedes});};YAHOO.widget.Panel.prototype.configClose=function(type,args,obj){var val=args[0];var doHide=function(e,obj){obj.hide();};if(val){if(!this.close){this.close=document.createElement("span");YAHOO.util.Dom.addClass(this.close,"container-close");this.close.innerHTML="&#160;";this.innerElement.appendChild(this.close);YAHOO.util.Event.addListener(this.close,"click",doHide,this);}else{this.close.style.display="block";}}else{if(this.close){this.close.style.display="none";}}};YAHOO.widget.Panel.prototype.configDraggable=function(type,args,obj){var val=args[0];if(val){if(!YAHOO.util.DD){this.cfg.setProperty("draggable",false);return;}
if(this.header){YAHOO.util.Dom.setStyle(this.header,"cursor","move");this.registerDragDrop();}}else{if(this.dd){this.dd.unreg();}
if(this.header){YAHOO.util.Dom.setStyle(this.header,"cursor","auto");}}};YAHOO.widget.Panel.prototype.configUnderlay=function(type,args,obj){var val=args[0];switch(val.toLowerCase()){case"shadow":YAHOO.util.Dom.removeClass(this.element,"matte");YAHOO.util.Dom.addClass(this.element,"shadow");if(!this.underlay){this.underlay=document.createElement("div");this.underlay.className="underlay";this.underlay.innerHTML="&#160;";this.element.appendChild(this.underlay);}
this.sizeUnderlay();break;case"matte":YAHOO.util.Dom.removeClass(this.element,"shadow");YAHOO.util.Dom.addClass(this.element,"matte");break;default:YAHOO.util.Dom.removeClass(this.element,"shadow");YAHOO.util.Dom.removeClass(this.element,"matte");break;}};YAHOO.widget.Panel.prototype.configModal=function(type,args,obj){var modal=args[0];if(modal){this.buildMask();if(!YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent,this.showMask,this)){this.beforeShowEvent.subscribe(this.showMask,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMask,this)){this.hideEvent.subscribe(this.hideMask,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEvent,this.sizeMask,this)){YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.sizeMask,this,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.destroyEvent,this.removeMask,this)){this.destroyEvent.subscribe(this.removeMask,this,true);}
this.cfg.refireEvent("zIndex");}else{this.beforeShowEvent.unsubscribe(this.showMask,this);this.hideEvent.unsubscribe(this.hideMask,this);YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask,this);this.destroyEvent.unsubscribe(this.removeMask,this);}};YAHOO.widget.Panel.prototype.removeMask=function(){var oMask=this.mask;if(oMask){this.hideMask();var oParentNode=oMask.parentNode;if(oParentNode){oParentNode.removeChild(oMask);}
this.mask=null;}};YAHOO.widget.Panel.prototype.configKeyListeners=function(type,args,obj){var listeners=args[0];if(listeners){if(listeners instanceof Array){for(var i=0;i<listeners.length;i++){var listener=listeners[i];if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,listener.enable,listener)){this.showEvent.subscribe(listener.enable,listener,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,listener.disable,listener)){this.hideEvent.subscribe(listener.disable,listener,true);this.destroyEvent.subscribe(listener.disable,listener,true);}}}else{if(!YAHOO.util.Config.alreadySubscribed(this.showEvent,listeners.enable,listeners)){this.showEvent.subscribe(listeners.enable,listeners,true);}
if(!YAHOO.util.Config.alreadySubscribed(this.hideEvent,listeners.disable,listeners)){this.hideEvent.subscribe(listeners.disable,listeners,true);this.destroyEvent.subscribe(listeners.disable,listeners,true);}}}};YAHOO.widget.Panel.prototype.configHeight=function(type,args,obj){var height=args[0];var el=this.innerElement;YAHOO.util.Dom.setStyle(el,"height",height);this.cfg.refireEvent("underlay");this.cfg.refireEvent("iframe");};YAHOO.widget.Panel.prototype.configWidth=function(type,args,obj){var width=args[0];var el=this.innerElement;YAHOO.util.Dom.setStyle(el,"width",width);this.cfg.refireEvent("underlay");this.cfg.refireEvent("iframe");};YAHOO.widget.Panel.prototype.configzIndex=function(type,args,obj){YAHOO.widget.Panel.superclass.configzIndex.call(this,type,args,obj);var maskZ=0;var currentZ=YAHOO.util.Dom.getStyle(this.element,"zIndex");if(this.mask){if(!currentZ||isNaN(currentZ)){currentZ=0;}
if(currentZ===0){this.cfg.setProperty("zIndex",1);}else{maskZ=currentZ-1;YAHOO.util.Dom.setStyle(this.mask,"zIndex",maskZ);}}};YAHOO.widget.Panel.prototype.buildWrapper=function(){var elementParent=this.element.parentNode;var originalElement=this.element;var wrapper=document.createElement("div");wrapper.className=YAHOO.widget.Panel.CSS_PANEL_CONTAINER;wrapper.id=originalElement.id+"_c";if(elementParent){elementParent.insertBefore(wrapper,originalElement);}
wrapper.appendChild(originalElement);this.element=wrapper;this.innerElement=originalElement;YAHOO.util.Dom.setStyle(this.innerElement,"visibility","inherit");};YAHOO.widget.Panel.prototype.sizeUnderlay=function(){if(this.underlay&&this.browser!="gecko"&&this.browser!="safari"){this.underlay.style.width=this.innerElement.offsetWidth+"px";this.underlay.style.height=this.innerElement.offsetHeight+"px";}};YAHOO.widget.Panel.prototype.onDomResize=function(e,obj){YAHOO.widget.Panel.superclass.onDomResize.call(this,e,obj);var me=this;setTimeout(function(){me.sizeUnderlay();},0);};YAHOO.widget.Panel.prototype.registerDragDrop=function(){if(this.header){if(!YAHOO.util.DD){return;}
this.dd=new YAHOO.util.DD(this.element.id,this.id);if(!this.header.id){this.header.id=this.id+"_h";}
var me=this;this.dd.startDrag=function(){if(me.browser=="ie"){YAHOO.util.Dom.addClass(me.element,"drag");}
if(me.cfg.getProperty("constraintoviewport")){var offsetHeight=me.element.offsetHeight;var offsetWidth=me.element.offsetWidth;var viewPortWidth=YAHOO.util.Dom.getViewportWidth();var viewPortHeight=YAHOO.util.Dom.getViewportHeight();var scrollX=window.scrollX||document.documentElement.scrollLeft;var scrollY=window.scrollY||document.documentElement.scrollTop;var topConstraint=scrollY+10;var leftConstraint=scrollX+10;var bottomConstraint=scrollY+viewPortHeight-offsetHeight-10;var rightConstraint=scrollX+viewPortWidth-offsetWidth-10;this.minX=leftConstraint;this.maxX=rightConstraint;this.constrainX=true;this.minY=topConstraint;this.maxY=bottomConstraint;this.constrainY=true;}else{this.constrainX=false;this.constrainY=false;}
me.dragEvent.fire("startDrag",arguments);};this.dd.onDrag=function(){me.syncPosition();me.cfg.refireEvent("iframe");if(this.platform=="mac"&&this.browser=="gecko"){this.showMacGeckoScrollbars();}
me.dragEvent.fire("onDrag",arguments);};this.dd.endDrag=function(){if(me.browser=="ie"){YAHOO.util.Dom.removeClass(me.element,"drag");}
me.dragEvent.fire("endDrag",arguments);};this.dd.setHandleElId(this.header.id);this.dd.addInvalidHandleType("INPUT");this.dd.addInvalidHandleType("SELECT");this.dd.addInvalidHandleType("TEXTAREA");}};YAHOO.widget.Panel.prototype.buildMask=function(){if(!this.mask){this.mask=document.createElement("div");this.mask.id=this.id+"_mask";this.mask.className="mask";this.mask.innerHTML="&#160;";var maskClick=function(e,obj){YAHOO.util.Event.stopEvent(e);};var firstChild=document.body.firstChild;if(firstChild){document.body.insertBefore(this.mask,document.body.firstChild);}else{document.body.appendChild(this.mask);}}};YAHOO.widget.Panel.prototype.hideMask=function(){if(this.cfg.getProperty("modal")&&this.mask){this.mask.style.display="none";this.hideMaskEvent.fire();YAHOO.util.Dom.removeClass(document.body,"masked");}};YAHOO.widget.Panel.prototype.showMask=function(){if(this.cfg.getProperty("modal")&&this.mask){YAHOO.util.Dom.addClass(document.body,"masked");this.sizeMask();this.mask.style.display="block";this.showMaskEvent.fire();}};YAHOO.widget.Panel.prototype.sizeMask=function(){if(this.mask){this.mask.style.height=YAHOO.util.Dom.getDocumentHeight()+"px";this.mask.style.width=YAHOO.util.Dom.getDocumentWidth()+"px";}};YAHOO.widget.Panel.prototype.render=function(appendToNode){return YAHOO.widget.Panel.superclass.render.call(this,appendToNode,this.innerElement);};YAHOO.widget.Panel.prototype.destroy=function(){YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask,this);if(this.close){YAHOO.util.Event.purgeElement(this.close);}
YAHOO.widget.Panel.superclass.destroy.call(this);};YAHOO.widget.Panel.prototype.toString=function(){return"Panel "+this.id;};YAHOO.widget.Dialog=function(el,userConfig){YAHOO.widget.Dialog.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.Dialog,YAHOO.widget.Panel);YAHOO.widget.Dialog.CSS_DIALOG="yui-dialog";YAHOO.widget.Dialog._EVENT_TYPES={"BEFORE_SUBMIT":"beforeSubmit","SUBMIT":"submit","MANUAL_SUBMIT":"manualSubmit","ASYNC_SUBMIT":"asyncSubmit","FORM_SUBMIT":"formSubmit","CANCEL":"cancel"};YAHOO.widget.Dialog._DEFAULT_CONFIG={"POST_METHOD":{key:"postmethod",value:"async"},"BUTTONS":{key:"buttons",value:"none"}};YAHOO.widget.Dialog.prototype.initDefaultConfig=function(){YAHOO.widget.Dialog.superclass.initDefaultConfig.call(this);this.callback={success:null,failure:null,argument:null};var DEFAULT_CONFIG=YAHOO.widget.Dialog._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.POST_METHOD.key,{handler:this.configPostMethod,value:DEFAULT_CONFIG.POST_METHOD.value,validator:function(val){if(val!="form"&&val!="async"&&val!="none"&&val!="manual"){return false;}else{return true;}}});this.cfg.addProperty(DEFAULT_CONFIG.BUTTONS.key,{handler:this.configButtons,value:DEFAULT_CONFIG.BUTTONS.value});};YAHOO.widget.Dialog.prototype.initEvents=function(){YAHOO.widget.Dialog.superclass.initEvents.call(this);var EVENT_TYPES=YAHOO.widget.Dialog._EVENT_TYPES;this.beforeSubmitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_SUBMIT,this);this.submitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.SUBMIT,this);this.manualSubmitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.MANUAL_SUBMIT,this);this.asyncSubmitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.ASYNC_SUBMIT,this);this.formSubmitEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.FORM_SUBMIT,this);this.cancelEvent=new YAHOO.util.CustomEvent(EVENT_TYPES.CANCEL,this);};YAHOO.widget.Dialog.prototype.init=function(el,userConfig){YAHOO.widget.Dialog.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.Dialog);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.Dialog.CSS_DIALOG);this.cfg.setProperty("visible",false);if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.showEvent.subscribe(this.focusFirst,this,true);this.beforeHideEvent.subscribe(this.blurButtons,this,true);this.beforeRenderEvent.subscribe(function(){var buttonCfg=this.cfg.getProperty("buttons");if(buttonCfg&&buttonCfg!="none"){if(!this.footer){this.setFooter("");}}},this,true);this.initEvent.fire(YAHOO.widget.Dialog);};YAHOO.widget.Dialog.prototype.doSubmit=function(){var pm=this.cfg.getProperty("postmethod");switch(pm){case"async":var method=this.form.getAttribute("method")||'POST';method=method.toUpperCase();YAHOO.util.Connect.setForm(this.form);var cObj=YAHOO.util.Connect.asyncRequest(method,this.form.getAttribute("action"),this.callback);this.asyncSubmitEvent.fire();break;case"form":this.form.submit();this.formSubmitEvent.fire();break;case"none":case"manual":this.manualSubmitEvent.fire();break;}};YAHOO.widget.Dialog.prototype._onFormKeyDown=function(p_oEvent){var oTarget=YAHOO.util.Event.getTarget(p_oEvent),nCharCode=YAHOO.util.Event.getCharCode(p_oEvent);if(nCharCode==13&&oTarget.tagName&&oTarget.tagName.toUpperCase()=="INPUT"){var sType=oTarget.type;if(sType=="text"||sType=="password"||sType=="checkbox"||sType=="radio"||sType=="file"){this.defaultHtmlButton.click();}}};YAHOO.widget.Dialog.prototype.registerForm=function(){var form=this.element.getElementsByTagName("form")[0];if(!form){var formHTML="<form name=\"frm_"+this.id+"\" action=\"\"></form>";this.body.innerHTML+=formHTML;form=this.element.getElementsByTagName("form")[0];}
this.firstFormElement=function(){for(var f=0;f<form.elements.length;f++){var el=form.elements[f];if(el.focus&&!el.disabled){if(el.type&&el.type!="hidden"){return el;}}}
return null;}();this.lastFormElement=function(){for(var f=form.elements.length-1;f>=0;f--){var el=form.elements[f];if(el.focus&&!el.disabled){if(el.type&&el.type!="hidden"){return el;}}}
return null;}();this.form=form;if(this.form&&(this.browser=="ie"||this.browser=="ie7"||this.browser=="gecko")){YAHOO.util.Event.addListener(this.form,"keydown",this._onFormKeyDown,null,this);}
if(this.cfg.getProperty("modal")&&this.form){var me=this;var firstElement=this.firstFormElement||this.firstButton;if(firstElement){this.preventBackTab=new YAHOO.util.KeyListener(firstElement,{shift:true,keys:9},{fn:me.focusLast,scope:me,correctScope:true});this.showEvent.subscribe(this.preventBackTab.enable,this.preventBackTab,true);this.hideEvent.subscribe(this.preventBackTab.disable,this.preventBackTab,true);}
var lastElement=this.lastButton||this.lastFormElement;if(lastElement){this.preventTabOut=new YAHOO.util.KeyListener(lastElement,{shift:false,keys:9},{fn:me.focusFirst,scope:me,correctScope:true});this.showEvent.subscribe(this.preventTabOut.enable,this.preventTabOut,true);this.hideEvent.subscribe(this.preventTabOut.disable,this.preventTabOut,true);}}};YAHOO.widget.Dialog.prototype.configClose=function(type,args,obj){var val=args[0];var doCancel=function(e,obj){obj.cancel();};if(val){if(!this.close){this.close=document.createElement("div");YAHOO.util.Dom.addClass(this.close,"container-close");this.close.innerHTML="&#160;";this.innerElement.appendChild(this.close);YAHOO.util.Event.addListener(this.close,"click",doCancel,this);}else{this.close.style.display="block";}}else{if(this.close){this.close.style.display="none";}}};YAHOO.widget.Dialog.prototype.configButtons=function(type,args,obj){var buttons=args[0];if(buttons!="none"){this.buttonSpan=null;this.buttonSpan=document.createElement("span");this.buttonSpan.className="button-group";for(var b=0;b<buttons.length;b++){var button=buttons[b];var htmlButton=document.createElement("button");htmlButton.setAttribute("type","button");if(button.isDefault){htmlButton.className="default";this.defaultHtmlButton=htmlButton;}
htmlButton.appendChild(document.createTextNode(button.text));YAHOO.util.Event.addListener(htmlButton,"click",button.handler,this,true);this.buttonSpan.appendChild(htmlButton);button.htmlButton=htmlButton;if(b===0){this.firstButton=button.htmlButton;}
if(b==(buttons.length-1)){this.lastButton=button.htmlButton;}}
this.setFooter(this.buttonSpan);this.cfg.refireEvent("iframe");this.cfg.refireEvent("underlay");}else{if(this.buttonSpan){if(this.buttonSpan.parentNode){this.buttonSpan.parentNode.removeChild(this.buttonSpan);}
this.buttonSpan=null;this.firstButton=null;this.lastButton=null;this.defaultHtmlButton=null;}}};YAHOO.widget.Dialog.prototype.focusFirst=function(type,args,obj){if(args){var e=args[1];if(e){YAHOO.util.Event.stopEvent(e);}}
if(this.firstFormElement){this.firstFormElement.focus();}else{this.focusDefaultButton();}};YAHOO.widget.Dialog.prototype.focusLast=function(type,args,obj){if(args){var e=args[1];if(e){YAHOO.util.Event.stopEvent(e);}}
var buttons=this.cfg.getProperty("buttons");if(buttons&&buttons instanceof Array){this.focusLastButton();}else{if(this.lastFormElement){this.lastFormElement.focus();}}};YAHOO.widget.Dialog.prototype.focusDefaultButton=function(){if(this.defaultHtmlButton){this.defaultHtmlButton.focus();}};YAHOO.widget.Dialog.prototype.blurButtons=function(){var buttons=this.cfg.getProperty("buttons");if(buttons&&buttons instanceof Array){var html=buttons[0].htmlButton;if(html){html.blur();}}};YAHOO.widget.Dialog.prototype.focusFirstButton=function(){var buttons=this.cfg.getProperty("buttons");if(buttons&&buttons instanceof Array){var html=buttons[0].htmlButton;if(html){html.focus();}}};YAHOO.widget.Dialog.prototype.focusLastButton=function(){var buttons=this.cfg.getProperty("buttons");if(buttons&&buttons instanceof Array){var html=buttons[buttons.length-1].htmlButton;if(html){html.focus();}}};YAHOO.widget.Dialog.prototype.configPostMethod=function(type,args,obj){var postmethod=args[0];this.registerForm();YAHOO.util.Event.addListener(this.form,"submit",function(e){YAHOO.util.Event.stopEvent(e);this.submit();this.form.blur();},this,true);};YAHOO.widget.Dialog.prototype.validate=function(){return true;};YAHOO.widget.Dialog.prototype.submit=function(){if(this.validate()){this.beforeSubmitEvent.fire();this.doSubmit();this.submitEvent.fire();this.hide();return true;}else{return false;}};YAHOO.widget.Dialog.prototype.cancel=function(){this.cancelEvent.fire();this.hide();};YAHOO.widget.Dialog.prototype.getData=function(){var oForm=this.form;if(oForm){var aElements=oForm.elements,nTotalElements=aElements.length,oData={},sName,oElement,nElements;for(var i=0;i<nTotalElements;i++){sName=aElements[i].name;function isFormElement(p_oElement){var sTagName=p_oElement.tagName.toUpperCase();return((sTagName=="INPUT"||sTagName=="TEXTAREA"||sTagName=="SELECT")&&p_oElement.name==sName);}
oElement=YAHOO.util.Dom.getElementsBy(isFormElement,"*",oForm);nElements=oElement.length;if(nElements>0){if(nElements==1){oElement=oElement[0];var sType=oElement.type,sTagName=oElement.tagName.toUpperCase();switch(sTagName){case"INPUT":if(sType=="checkbox"){oData[sName]=oElement.checked;}
else if(sType!="radio"){oData[sName]=oElement.value;}
break;case"TEXTAREA":oData[sName]=oElement.value;break;case"SELECT":var aOptions=oElement.options,nOptions=aOptions.length,aValues=[],oOption,sValue;for(var n=0;n<nOptions;n++){oOption=aOptions[n];if(oOption.selected){sValue=oOption.value;if(!sValue||sValue===""){sValue=oOption.text;}
aValues[aValues.length]=sValue;}}
oData[sName]=aValues;break;}}
else{var sType=oElement[0].type;switch(sType){case"radio":var oRadio;for(var n=0;n<nElements;n++){oRadio=oElement[n];if(oRadio.checked){oData[sName]=oRadio.value;break;}}
break;case"checkbox":var aValues=[],oCheckbox;for(var n=0;n<nElements;n++){oCheckbox=oElement[n];if(oCheckbox.checked){aValues[aValues.length]=oCheckbox.value;}}
oData[sName]=aValues;break;}}}}}
return oData;};YAHOO.widget.Dialog.prototype.destroy=function(){var Event=YAHOO.util.Event,oForm=this.form,oFooter=this.footer;if(oFooter){var aButtons=oFooter.getElementsByTagName("button");if(aButtons&&aButtons.length>0){var i=aButtons.length-1;do{Event.purgeElement(aButtons[i],false,"click");}
while(i--);}}
if(oForm){Event.purgeElement(oForm);this.body.removeChild(oForm);this.form=null;}
YAHOO.widget.Dialog.superclass.destroy.call(this);};YAHOO.widget.Dialog.prototype.toString=function(){return"Dialog "+this.id;};YAHOO.widget.SimpleDialog=function(el,userConfig){YAHOO.widget.SimpleDialog.superclass.constructor.call(this,el,userConfig);};YAHOO.extend(YAHOO.widget.SimpleDialog,YAHOO.widget.Dialog);YAHOO.widget.SimpleDialog.ICON_BLOCK="blckicon";YAHOO.widget.SimpleDialog.ICON_ALARM="alrticon";YAHOO.widget.SimpleDialog.ICON_HELP="hlpicon";YAHOO.widget.SimpleDialog.ICON_INFO="infoicon";YAHOO.widget.SimpleDialog.ICON_WARN="warnicon";YAHOO.widget.SimpleDialog.ICON_TIP="tipicon";YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG="yui-simple-dialog";YAHOO.widget.SimpleDialog._DEFAULT_CONFIG={"ICON":{key:"icon",value:"none",suppressEvent:true},"TEXT":{key:"text",value:"",suppressEvent:true,supercedes:["icon"]}};YAHOO.widget.SimpleDialog.prototype.initDefaultConfig=function(){YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);var DEFAULT_CONFIG=YAHOO.widget.SimpleDialog._DEFAULT_CONFIG;this.cfg.addProperty(DEFAULT_CONFIG.ICON.key,{handler:this.configIcon,value:DEFAULT_CONFIG.ICON.value,suppressEvent:DEFAULT_CONFIG.ICON.suppressEvent});this.cfg.addProperty(DEFAULT_CONFIG.TEXT.key,{handler:this.configText,value:DEFAULT_CONFIG.TEXT.value,suppressEvent:DEFAULT_CONFIG.TEXT.suppressEvent,supercedes:DEFAULT_CONFIG.TEXT.supercedes});};YAHOO.widget.SimpleDialog.prototype.init=function(el,userConfig){YAHOO.widget.SimpleDialog.superclass.init.call(this,el);this.beforeInitEvent.fire(YAHOO.widget.SimpleDialog);YAHOO.util.Dom.addClass(this.element,YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG);this.cfg.queueProperty("postmethod","manual");if(userConfig){this.cfg.applyConfig(userConfig,true);}
this.beforeRenderEvent.subscribe(function(){if(!this.body){this.setBody("");}},this,true);this.initEvent.fire(YAHOO.widget.SimpleDialog);};YAHOO.widget.SimpleDialog.prototype.registerForm=function(){YAHOO.widget.SimpleDialog.superclass.registerForm.call(this);this.form.innerHTML+="<input type=\"hidden\" name=\""+this.id+"\" value=\"\"/>";};YAHOO.widget.SimpleDialog.prototype.configIcon=function(type,args,obj){var icon=args[0];if(icon&&icon!="none"){var iconHTML="";if(icon.indexOf(".")==-1){iconHTML="<span class=\"yui-icon "+icon+"\" >&#160;</span>";}else{iconHTML="<img src=\""+this.imageRoot+icon+"\" class=\"yui-icon\" />";}
this.body.innerHTML=iconHTML+this.body.innerHTML;}};YAHOO.widget.SimpleDialog.prototype.configText=function(type,args,obj){var text=args[0];if(text){this.setBody(text);this.cfg.refireEvent("icon");}};YAHOO.widget.SimpleDialog.prototype.toString=function(){return"SimpleDialog "+this.id;};YAHOO.widget.ContainerEffect=function(overlay,attrIn,attrOut,targetElement,animClass){if(!animClass){animClass=YAHOO.util.Anim;}
this.overlay=overlay;this.attrIn=attrIn;this.attrOut=attrOut;this.targetElement=targetElement||overlay.element;this.animClass=animClass;};YAHOO.widget.ContainerEffect.prototype.init=function(){this.beforeAnimateInEvent=new YAHOO.util.CustomEvent("beforeAnimateIn",this);this.beforeAnimateOutEvent=new YAHOO.util.CustomEvent("beforeAnimateOut",this);this.animateInCompleteEvent=new YAHOO.util.CustomEvent("animateInComplete",this);this.animateOutCompleteEvent=new YAHOO.util.CustomEvent("animateOutComplete",this);this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStartAnimateOut,this);this.animOut.onTween.subscribe(this.handleTweenAnimateOut,this);this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut,this);};YAHOO.widget.ContainerEffect.prototype.animateIn=function(){this.beforeAnimateInEvent.fire();this.animIn.animate();};YAHOO.widget.ContainerEffect.prototype.animateOut=function(){this.beforeAnimateOutEvent.fire();this.animOut.animate();};YAHOO.widget.ContainerEffect.prototype.handleStartAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateIn=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleStartAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateOut=function(type,args,obj){};YAHOO.widget.ContainerEffect.prototype.toString=function(){var output="ContainerEffect";if(this.overlay){output+=" ["+this.overlay.toString()+"]";}
return output;};YAHOO.widget.ContainerEffect.FADE=function(overlay,dur){var fade=new YAHOO.widget.ContainerEffect(overlay,{attributes:{opacity:{from:0,to:1}},duration:dur,method:YAHOO.util.Easing.easeIn},{attributes:{opacity:{to:0}},duration:dur,method:YAHOO.util.Easing.easeOut},overlay.element);fade.handleStartAnimateIn=function(type,args,obj){YAHOO.util.Dom.addClass(obj.overlay.element,"hide-select");if(!obj.overlay.underlay){obj.overlay.cfg.refireEvent("underlay");}
if(obj.overlay.underlay){obj.initialUnderlayOpacity=YAHOO.util.Dom.getStyle(obj.overlay.underlay,"opacity");obj.overlay.underlay.style.filter=null;}
YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","visible");YAHOO.util.Dom.setStyle(obj.overlay.element,"opacity",0);};fade.handleCompleteAnimateIn=function(type,args,obj){YAHOO.util.Dom.removeClass(obj.overlay.element,"hide-select");if(obj.overlay.element.style.filter){obj.overlay.element.style.filter=null;}
if(obj.overlay.underlay){YAHOO.util.Dom.setStyle(obj.overlay.underlay,"opacity",obj.initialUnderlayOpacity);}
obj.overlay.cfg.refireEvent("iframe");obj.animateInCompleteEvent.fire();};fade.handleStartAnimateOut=function(type,args,obj){YAHOO.util.Dom.addClass(obj.overlay.element,"hide-select");if(obj.overlay.underlay){obj.overlay.underlay.style.filter=null;}};fade.handleCompleteAnimateOut=function(type,args,obj){YAHOO.util.Dom.removeClass(obj.overlay.element,"hide-select");if(obj.overlay.element.style.filter){obj.overlay.element.style.filter=null;}
YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","hidden");YAHOO.util.Dom.setStyle(obj.overlay.element,"opacity",1);obj.overlay.cfg.refireEvent("iframe");obj.animateOutCompleteEvent.fire();};fade.init();return fade;};YAHOO.widget.ContainerEffect.SLIDE=function(overlay,dur){var x=overlay.cfg.getProperty("x")||YAHOO.util.Dom.getX(overlay.element);var y=overlay.cfg.getProperty("y")||YAHOO.util.Dom.getY(overlay.element);var clientWidth=YAHOO.util.Dom.getClientWidth();var offsetWidth=overlay.element.offsetWidth;var slide=new YAHOO.widget.ContainerEffect(overlay,{attributes:{points:{to:[x,y]}},duration:dur,method:YAHOO.util.Easing.easeIn},{attributes:{points:{to:[(clientWidth+25),y]}},duration:dur,method:YAHOO.util.Easing.easeOut},overlay.element,YAHOO.util.Motion);slide.handleStartAnimateIn=function(type,args,obj){obj.overlay.element.style.left=(-25-offsetWidth)+"px";obj.overlay.element.style.top=y+"px";};slide.handleTweenAnimateIn=function(type,args,obj){var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var currentX=pos[0];var currentY=pos[1];if(YAHOO.util.Dom.getStyle(obj.overlay.element,"visibility")=="hidden"&&currentX<x){YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","visible");}
obj.overlay.cfg.setProperty("xy",[currentX,currentY],true);obj.overlay.cfg.refireEvent("iframe");};slide.handleCompleteAnimateIn=function(type,args,obj){obj.overlay.cfg.setProperty("xy",[x,y],true);obj.startX=x;obj.startY=y;obj.overlay.cfg.refireEvent("iframe");obj.animateInCompleteEvent.fire();};slide.handleStartAnimateOut=function(type,args,obj){var vw=YAHOO.util.Dom.getViewportWidth();var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var yso=pos[1];var currentTo=obj.animOut.attributes.points.to;obj.animOut.attributes.points.to=[(vw+25),yso];};slide.handleTweenAnimateOut=function(type,args,obj){var pos=YAHOO.util.Dom.getXY(obj.overlay.element);var xto=pos[0];var yto=pos[1];obj.overlay.cfg.setProperty("xy",[xto,yto],true);obj.overlay.cfg.refireEvent("iframe");};slide.handleCompleteAnimateOut=function(type,args,obj){YAHOO.util.Dom.setStyle(obj.overlay.element,"visibility","hidden");obj.overlay.cfg.setProperty("xy",[x,y]);obj.animateOutCompleteEvent.fire();};slide.init();return slide;};YAHOO.register("container",YAHOO.widget.Module,{version:"2.2.2",build:"204"});;
/*
 * yui-ext 0.33
 * Copyright(c) 2006, Jack Slocum.
 */

YAHOO.namespace('ext', 'ext.util', 'ext.grid');
YAHOO.ext.Strict = (document.compatMode == 'CSS1Compat');
YAHOO.ext.SSL_SECURE_URL = 'javascript:false';

window.undefined = undefined;

 
 
Function.prototype.createCallback = function(){
    
    var args = arguments;
    var method = this;
    return function() {
        return method.apply(window, args);
    };
};


Function.prototype.createDelegate = function(obj, args, appendArgs){
    var method = this;
    return function() {
        var callArgs = args || arguments;
        if(appendArgs === true){
            callArgs = Array.prototype.slice.call(arguments, 0);
            callArgs = callArgs.concat(args);
        }else if(typeof appendArgs == 'number'){
            callArgs = Array.prototype.slice.call(arguments, 0); 
            var applyArgs = [appendArgs, 0].concat(args); 
            Array.prototype.splice.apply(callArgs, applyArgs); 
        }
        return method.apply(obj || window, callArgs);
    };
};


Function.prototype.defer = function(millis, obj, args, appendArgs){
    return setTimeout(this.createDelegate(obj, args, appendArgs), millis);
};

Function.prototype.createSequence = function(fcn, scope){
    if(typeof fcn != 'function'){
        return this;
    }
    var method = this;
    return function() {
        var retval = method.apply(this || window, arguments);
        fcn.apply(scope || this || window, arguments);
        return retval;
    };
};


YAHOO.util.Event.on(window, 'unload', function(){
    delete Function.prototype.createSequence;
    delete Function.prototype.defer;
    delete Function.prototype.createDelegate;
    delete Function.prototype.createCallback;
    delete Function.prototype.createInterceptor;
});


Function.prototype.createInterceptor = function(fcn, scope){
    if(typeof fcn != 'function'){
        return this;
    }
    var method = this;
    return function() {
        fcn.target = this;
        fcn.method = method;
        if(fcn.apply(scope || this || window, arguments) === false){
            return;
        }
        return method.apply(this || window, arguments);;
    };
};


YAHOO.ext.util.Browser = new function(){
	var ua = navigator.userAgent.toLowerCase();
	
	this.isOpera = (ua.indexOf('opera') > -1);
   	
	this.isSafari = (ua.indexOf('webkit') > -1);
   	
	this.isIE = (window.ActiveXObject);
   	
	this.isIE7 = (ua.indexOf('msie 7') > -1);
   	
	this.isGecko = !this.isSafari && (ua.indexOf('gecko') > -1);
	
	if(ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1){
	    
	    this.isWindows = true;
	}else if(ua.indexOf("macintosh") != -1){
		
	    this.isMac = true;
	}
	if(this.isIE && !this.isIE7){
        try{
            document.execCommand("BackgroundImageCache", false, true);
        }catch(e){}
    }
}();

YAHOO.print = function(arg1, arg2, etc){
    if(!YAHOO.ext._console){
        var cs = YAHOO.ext.DomHelper.insertBefore(document.body.firstChild,
        {tag: 'div',style:'width:250px;height:350px;overflow:auto;border:3px solid #c3daf9;' +
                'background:white;position:absolute;right:5px;top:5px;' +
                'font:normal 8pt arial,verdana,helvetica;z-index:50000;padding:5px;'}, true);
        new YAHOO.ext.Resizable(cs, {
            transparent:true,
            handles: 'all',
            pinned:true, 
            adjustments: [0,0], 
            wrap:true, 
            draggable:(YAHOO.util.DD ? true : false)
        });
        cs.on('dblclick', cs.hide);
        YAHOO.ext._console = cs;
    }
    var msg = '';
    for(var i = 0, len = arguments.length; i < len; i++) {
    	msg += arguments[i] + '<hr noshade style="color:#eeeeee;" size="1">';
    }
    YAHOO.ext._console.dom.innerHTML = msg + YAHOO.ext._console.dom.innerHTML;
    YAHOO.ext._console.dom.scrollTop = 0;
    YAHOO.ext._console.show();
};

YAHOO.printf = function(format, arg1, arg2, etc){
    var args = Array.prototype.slice.call(arguments, 1);
    YAHOO.print(format.replace(
      /\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
      function(m, a1, a2, a3) {
        if (m.chatAt == '{') {
          return m.slice(1, -1);
        }
        var rpl = args[a1];
        if (a3) {
          var f = eval(a3);
          rpl = f(rpl);
        }
        return rpl ? rpl : '';
      }));
};

 
YAHOO.util.CustomEvent.prototype.fireDirect = function(){
    var len=this.subscribers.length;
    for (var i=0; i<len; ++i) {
        var s = this.subscribers[i];
        if(s){
            var scope = (s.override) ? s.obj : this.scope;
            if(s.fn.apply(scope, arguments) === false){
                return false;
            }
        }
    }
    return true;
};

YAHOO.extendX = function(subclass, superclass, overrides){
    YAHOO.extend(subclass, superclass);
    subclass.override = function(o){
        YAHOO.override(subclass, o);
    };
    if(!subclass.prototype.override){
        subclass.prototype.override = function(o){
            for(var method in o){
                this[method] = o[method];
            }  
        };
    }
    if(overrides){
        subclass.override(overrides);
    }
};

YAHOO.override = function(origclass, overrides){
    if(overrides){
        var p = origclass.prototype;
        for(var method in overrides){
            p[method] = overrides[method];
        }
    }
};


YAHOO.ext.util.DelayedTask = function(fn, scope, args){
    var timeoutId = null;
    
    
    this.delay = function(delay, newFn, newScope, newArgs){
        if(timeoutId){
            clearTimeout(timeoutId);
        }
        fn = newFn || fn;
        scope = newScope || scope;
        args = newArgs || args;
        timeoutId = setTimeout(fn.createDelegate(scope, args), delay);
    };
    
    
    this.cancel = function(){
        if(timeoutId){
            clearTimeout(timeoutId);
            timeoutId = null;
        }
    };
};


YAHOO.ext.KeyMap = function(el, config, eventName){
    this.el  = getEl(el);
    this.eventName = eventName || 'keydown';
    this.bindings = [];
    if(config instanceof Array){
	    for(var i = 0, len = config.length; i < len; i++){
	        this.addBinding(config[i]);
	    }
    }else{
        this.addBinding(config);
    }
    this.keyDownDelegate = YAHOO.ext.EventManager.wrap(this.handleKeyDown, this, true);
    this.enable();
};

YAHOO.ext.KeyMap.prototype = {
    
	addBinding : function(config){
        var keyCode = config.key, 
            shift = config.shift, 
            ctrl = config.ctrl, 
            alt = config.alt,
            fn = config.fn,
            scope = config.scope;
        if(typeof keyCode == 'string'){
            var ks = [];
            var keyString = keyCode.toUpperCase();
            for(var j = 0, len = keyString.length; j < len; j++){
                ks.push(keyString.charCodeAt(j));
            }
            keyCode = ks;
        }        
        var keyArray = keyCode instanceof Array;
        var handler = function(e){
            if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) &&  (!alt || e.altKey)){
                var k = e.getKey();
                if(keyArray){
                    for(var i = 0, len = keyCode.length; i < len; i++){
                        if(keyCode[i] == k){
                          fn.call(scope || window, k, e);
                          return;
                        }
                    }
                }else{
                    if(k == keyCode){
                        fn.call(scope || window, k, e);
                    }
                }
            }
        };
        this.bindings.push(handler);  
	},
	
	handleKeyDown : function(e){
	    if(this.enabled){ 
    	    var b = this.bindings;
    	    for(var i = 0, len = b.length; i < len; i++){
    	        b[i](e);
    	    }
	    }
	},
	
	
	isEnabled : function(){
	    return this.enabled;  
	},
	
	
	enable: function(){
		if (!this.enabled){
	        this.el.on(this.eventName, this.keyDownDelegate);
		    this.enabled = true;
		}
	},

	
	disable: function(){
		if (this.enabled){
			this.el.removeListener(this.eventName, this.keyDownDelegate);
		    this.enabled = false;
		}
	}
};


YAHOO.ext.util.Observable = function(){};
YAHOO.ext.util.Observable.prototype = {
    
    fireEvent : function(){
        var ce = this.events[arguments[0].toLowerCase()];
        if(typeof ce == 'object'){
            return ce.fireDirect.apply(ce, Array.prototype.slice.call(arguments, 1));
        }else{
            return true;
        }
    },
    
    addListener : function(eventName, fn, scope, override){
        eventName = eventName.toLowerCase();
        var ce = this.events[eventName];
        if(!ce){
            
            throw 'You are trying to listen for an event that does not exist: "' + eventName + '".';
        }
        if(typeof ce == 'boolean'){
            ce = new YAHOO.util.CustomEvent(eventName);
            this.events[eventName] = ce;
        }
        ce.subscribe(fn, scope, override);
    },
    
    delayedListener : function(eventName, fn, scope, delay){
        var newFn = function(){
            setTimeout(fn.createDelegate(scope, arguments), delay || 1);
        };
        this.addListener(eventName, newFn);
        return newFn;
    },
    
    
    bufferedListener : function(eventName, fn, scope, millis){
        var task = new YAHOO.ext.util.DelayedTask();
        var newFn = function(){
            task.delay(millis || 250, fn, scope, Array.prototype.slice.call(arguments, 0));
        };
        this.addListener(eventName, newFn);
        return newFn;
    },
    
    
    removeListener : function(eventName, fn, scope){
        var ce = this.events[eventName.toLowerCase()];
        if(typeof ce == 'object'){
            ce.unsubscribe(fn, scope);
        }
    },
    
    
    purgeListeners : function(){
        for(var evt in this.events){
            if(typeof this.events[evt] == 'object'){
                 this.events[evt].unsubscribeAll();
            }
        }
    }
};

YAHOO.ext.util.Observable.prototype.on = YAHOO.ext.util.Observable.prototype.addListener;


YAHOO.ext.util.Config = {
    
    apply : function(obj, config, defaults){
        if(defaults){
            this.apply(obj, defaults);
        }
        if(config){
            for(var prop in config){
                obj[prop] = config[prop];
            }
        }
        return obj;
    }
};

if(!String.escape){
    String.escape = function(string) {
        return string.replace(/('|\\)/g, "\\$1");
    };
};

String.leftPad = function (val, size, ch) {
    var result = new String(val);
    if (ch == null) {
        ch = " ";
    }
    while (result.length < size) {
        result = ch + result;
    }
    return result;
};


if(YAHOO.util.Connect){
    YAHOO.util.Connect.setHeader = function(o){
		for(var prop in this._http_header){
		    
			if(typeof this._http_header[prop] != 'function'){
				o.conn.setRequestHeader(prop, this._http_header[prop]);
			}
		}
		delete this._http_header;
		this._http_header = {};
		this._has_http_headers = false;
	};   
}

if(YAHOO.util.DragDrop){
    
    YAHOO.util.DragDrop.prototype.defaultPadding = {left:0, right:0, top:0, bottom:0};
    
    
    YAHOO.util.DragDrop.prototype.constrainTo = function(constrainTo, pad, inContent){
        if(typeof pad == 'number'){
            pad = {left: pad, right:pad, top:pad, bottom:pad};
        }
        pad = pad || this.defaultPadding;
        var b = getEl(this.getEl()).getBox();
        var ce = getEl(constrainTo);
        var c = ce.dom == document.body ? { x: 0, y: 0,
                width: YAHOO.util.Dom.getViewportWidth(),
                height: YAHOO.util.Dom.getViewportHeight()} : ce.getBox(inContent || false);
        var topSpace = b.y - c.y;
        var leftSpace = b.x - c.x;

        this.resetConstraints();
        this.setXConstraint(leftSpace - (pad.left||0), 
                c.width - leftSpace - b.width - (pad.right||0) 
        );
        this.setYConstraint(topSpace - (pad.top||0), 
                c.height - topSpace - b.height - (pad.bottom||0) 
        );
    } 
}

YAHOO.ext.util.MixedCollection = function(allowFunctions){
    this.items = [];
    this.keys = [];
    this.events = {
        
        'clear' : new YAHOO.util.CustomEvent('clear'),
        
        'add' : new YAHOO.util.CustomEvent('add'),
        
        'replace' : new YAHOO.util.CustomEvent('replace'),
        
        'remove' : new YAHOO.util.CustomEvent('remove')
    };
    this.allowFunctions = allowFunctions === true;
};

YAHOO.extendX(YAHOO.ext.util.MixedCollection, YAHOO.ext.util.Observable, {
    allowFunctions : false,
   

    add : function(key, o){
        if(arguments.length == 1){
            o = arguments[0];
            key = this.getKey(o);
        }
        this.items.push(o);
        if(typeof key != 'undefined' && key != null){
            this.items[key] = o;
            this.keys.push(key);
        }
        this.fireEvent('add', this.items.length-1, o, key);
        return o;
    },
   

    getKey : function(o){
         return null; 
    },
   

    replace : function(key, o){
        if(arguments.length == 1){
            o = arguments[0];
            key = this.getKey(o);
        }
        if(typeof this.items[key] == 'undefined'){
            return this.add(key, o);
        }
        var old = this.items[key];
        if(typeof key == 'number'){ 
            this.items[key] = o;
        }else{
            var index = this.indexOfKey(key);
            this.items[index] = o;
            this.items[key] = o;
        }
        this.fireEvent('replace', key, old, o);
        return o;
    },
   

    addAll : function(objs){
        if(arguments.length > 1 || objs instanceof Array){
            var args = arguments.length > 1 ? arguments : objs;
            for(var i = 0, len = args.length; i < len; i++){
                this.add(args[i]);
            }
        }else{
            for(var key in objs){
                if(this.allowFunctions || typeof objs[key] != 'function'){
                    this.add(objs[key], key);
                }
            }
        }
    },
   

    each : function(fn, scope){
        for(var i = 0, len = this.items.length; i < len; i++){
            fn.call(scope || window, this.items[i]);
        }
    },
   

    eachKey : function(fn, scope){
        for(var i = 0, len = this.keys.length; i < len; i++){
            fn.call(scope || window, this.keys[i], this.items[i]);
        }
    },
   

    find : function(fn, scope){
        for(var i = 0, len = this.items.length; i < len; i++){
            if(fn.call(scope || window, this.items[i])){
                return this.items[i];
            }
        }
        return null;
    },
   

    insert : function(index, key, o){
        if(arguments.length == 2){
            o = arguments[1];
            key = this.getKey(o);
        }
        if(index >= this.items.length){
            return this.add(o, key);
        }
        this.items.splice(index, 0, o);
        if(typeof key != 'undefined' && key != null){
            this.items[key] = o;
            this.keys.splice(index, 0, key);
        }
        this.fireEvent('add', index, o, key);
        return o;
    },
   

    remove : function(o){
        var index = this.indexOf(o);
        this.items.splice(index, 1);
        if(typeof this.keys[index] != 'undefined'){
            var key = this.keys[index];
            this.keys.splice(index, 1);
            delete this.items[key];
        }
        this.fireEvent('remove', o);
        return o;
    },
   

    removeAt : function(index){
        this.items.splice(index, 1);
        var key = this.keys[index];
        if(typeof key != 'undefined'){
             this.keys.splice(index, 1);
             delete this.items[key];
        }
        this.fireEvent('remove', o, key);
    },
   

    removeKey : function(key){
        var o = this.items[key];
        var index = this.indexOf(o);
        this.items.splice(index, 1);
        this.keys.splice(index, 1);
        delete this.items[key];
        this.fireEvent('remove', o, key);
    },
   

    getCount : function(){
        return this.items.length; 
    },
   

    indexOf : function(o){
        if(!this.items.indexOf){
            for(var i = 0, len = this.items.length; i < len; i++){
                if(this.items[i] == o) return i;
            }
            return -1;
        }else{
            return this.items.indexOf(o);
        }
    },
   

    indexOfKey : function(key){
        if(!this.keys.indexOf){
            for(var i = 0, len = this.keys.length; i < len; i++){
                if(this.keys[i] == key) return i;
            }
            return -1;
        }else{
            return this.keys.indexOf(key);
        }
    },
   

    item : function(key){
        return this.items[key];
    },
   

    contains : function(o){
        return this.indexOf(o) != -1;
    },
   

    containsKey : function(key){
        return typeof this.items[key] != 'undefined';
    },
   

    clear : function(o){
        this.items = [];
        this.keys = [];
        this.fireEvent('clear');
    },
   

    first : function(){
        return this.items[0]; 
    },
   

    last : function(){
        return this.items[this.items.length];   
    }
});

YAHOO.ext.util.MixedCollection.prototype.get = YAHOO.ext.util.MixedCollection.prototype.item;

YAHOO.ext.util.JSON = new function(){
    var useHasOwn = {}.hasOwnProperty ? true : false;
    
    
    
    
    var pad = function(n) {
        return n < 10 ? '0' + n : n;
    };
    
    var m = {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"' : '\\"',
        '\\': '\\\\'
    };

    var encodeString = function(s){
        if (/["\\\x00-\x1f]/.test(s)) {
            return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                var c = m[b];
                if(c){
                    return c;
                }
                c = b.charCodeAt();
                return '\\u00' +
                    Math.floor(c / 16).toString(16) +
                    (c % 16).toString(16);
            }) + '"';
        }
        return '"' + s + '"';
    };
    
    var encodeArray = function(o){
        var a = ['['], b, i, l = o.length, v;
            for (i = 0; i < l; i += 1) {
                v = o[i];
                switch (typeof v) {
                    case 'undefined':
                    case 'function':
                    case 'unknown':
                        break;
                    default:
                        if (b) {
                            a.push(',');
                        }
                        a.push(v === null ? "null" : YAHOO.ext.util.JSON.encode(v));
                        b = true;
                }
            }
            a.push(']');
            return a.join('');
    };
    
    var encodeDate = function(o){
        return '"' + o.getFullYear() + '-' +
                pad(o.getMonth() + 1) + '-' +
                pad(o.getDate()) + 'T' +
                pad(o.getHours()) + ':' +
                pad(o.getMinutes()) + ':' +
                pad(o.getSeconds()) + '"';
    };
    
    
    this.encode = function(o){
        if(typeof o == 'undefined' || o === null){
            return 'null';
        }else if(o instanceof Array){
            return encodeArray(o);
        }else if(o instanceof Date){
            return encodeDate(o);
        }else if(typeof o == 'string'){
            return encodeString(o);
        }else if(typeof o == 'number'){
            return isFinite(o) ? String(o) : "null";
        }else if(typeof o == 'boolean'){
            return String(o);
        }else {
            var a = ['{'], b, i, v;
            for (var i in o) {
                if(!useHasOwn || o.hasOwnProperty(i)) {
                    v = o[i];
                    switch (typeof v) {
                    case 'undefined':
                    case 'function':
                    case 'unknown':
                        break;
                    default:
                        if(b){
                            a.push(',');
                        }
                        a.push(this.encode(i), ':',
                                v === null ? "null" : this.encode(v));
                        b = true;
                    }
                }
            }
            a.push('}');
            return a.join('');
        }
    };
    
    
    this.decode = function(json){
        
        
            
                return eval('(' + json + ')');
           
       
       
       
    };
}();

YAHOO.ext.util.CSS = new function(){
	var rules = null;
   	
   	var toCamel = function(property) {
      var convert = function(prop) {
         var test = /(-[a-z])/i.exec(prop);
         return prop.replace(RegExp.$1, RegExp.$1.substr(1).toUpperCase());
      };
      while(property.indexOf('-') > -1) {
         property = convert(property);
      }
      return property;
   };
   
   
   this.getRules = function(refreshCache){
   		if(rules == null || refreshCache){
   			rules = {};
   			var ds = document.styleSheets;
   			for(var i =0, len = ds.length; i < len; i++){
   			    try{
    		        var ss = ds[i];
    		        var ssRules = ss.cssRules || ss.rules;
    		        for(var j = ssRules.length-1; j >= 0; --j){
    		        	rules[ssRules[j].selectorText] = ssRules[j];
    		        }
   			    }catch(e){} 
	        }
   		}
   		return rules;
   	};
   	
   	
   this.getRule = function(selector, refreshCache){
   		var rs = this.getRules(refreshCache);
   		if(!(selector instanceof Array)){
   		    return rs[selector];
   		}
   		for(var i = 0; i < selector.length; i++){
			if(rs[selector[i]]){
				return rs[selector[i]];
			}
		}
		return null;
   	};
   	
   	
   	
   this.updateRule = function(selector, property, value){
   		if(!(selector instanceof Array)){
   			var rule = this.getRule(selector);
   			if(rule){
   				rule.style[toCamel(property)] = value;
   				return true;
   			}
   		}else{
   			for(var i = 0; i < selector.length; i++){
   				if(this.updateRule(selector[i], property, value)){
   					return true;
   				}
   			}
   		}
   		return false;
   	};
   	
   	
   this.apply = function(el, selector){
   		if(!(selector instanceof Array)){
   			var rule = this.getRule(selector);
   			if(rule){
   			    var s = rule.style;
   				for(var key in s){
   				    if(typeof s[key] != 'function'){
       					if(s[key] && String(s[key]).indexOf(':') < 0 && s[key] != 'false'){
       						try{el.style[key] = s[key];}catch(e){}
       					}
   				    }
   				}
   				return true;
   			}
   		}else{
   			for(var i = 0; i < selector.length; i++){
   				if(this.apply(el, selector[i])){
   					return true;
   				}
   			}
   		}
   		return false;
   	};
   	
   	this.applyFirst = function(el, id, selector){
   		var selectors = [
   			'#' + id + ' ' + selector,
   			selector
   		];
   		return this.apply(el, selectors);
   	};
   	
   	this.revert = function(el, selector){
   		if(!(selector instanceof Array)){
   			var rule = this.getRule(selector);
   			if(rule){
   				for(key in rule.style){
   					if(rule.style[key] && String(rule.style[key]).indexOf(':') < 0 && rule.style[key] != 'false'){
   						try{el.style[key] = '';}catch(e){}
   					}
   				}
   				return true;
   			}
   		}else{
   			for(var i = 0; i < selector.length; i++){
   				if(this.revert(el, selector[i])){
   					return true;
   				}
   			}
   		}
   		return false;
   	};
   	
   	this.revertFirst = function(el, id, selector){
   		var selectors = [
   			'#' + id + ' ' + selector,
   			selector
   		];
   		return this.revert(el, selectors);
   	};
}();
YAHOO.ext.util.Bench = function(){
   this.timers = {};
   this.lastKey = null;
};
YAHOO.ext.util.Bench.prototype = {
   start : function(key){
       this.lastKey = key;
       this.timers[key] = {};
       this.timers[key].startTime = new Date().getTime(); 
   },
   
   stop : function(key){
       key = key || this.lastKey;
       this.timers[key].endTime = new Date().getTime(); 
   },
   
   getElapsed : function(key){
       key = key || this.lastKey;
       return this.timers[key].endTime - this.timers[key].startTime;
   },
   
   toString : function(html){
       var results = "";
       for(var key in this.timers){
           if(typeof this.timers[key] != 'function'){
               results += key + ":\t" + (this.getElapsed(key) / 1000) + " seconds\n";
           }
       }
       if(html){
           results = results.replace("\n", '<br>');
       }
       return results;
   },
   
   show : function(){
       alert(this.toString());
   }
};

YAHOO.ext.DomHelper = new function(){
    
    var d = document;
    var tempTableEl = null;
    
    this.useDom = false;
    var emptyTags = /^(?:base|basefont|br|frame|hr|img|input|isindex|link|meta|nextid|range|spacer|wbr|audioscope|area|param|keygen|col|limittext|spot|tab|over|right|left|choose|atop|of)$/i;
    
    this.applyStyles = function(el, styles){
        if(styles){
           var D = YAHOO.util.Dom;
           if (typeof styles == "string"){
               var re = /\s?([a-z\-]*)\:([^;]*);?/gi;
               var matches;
               while ((matches = re.exec(styles)) != null){
                   D.setStyle(el, matches[1], matches[2]);
               }
           }else if (typeof styles == "object"){
               for (var style in styles){
                  D.setStyle(el, style, styles[style]);
               }
           }else if (typeof styles == "function"){
                YAHOO.ext.DomHelper.applyStyles(el, styles.call());
           }
        }
    }; 
    
    
    
    var createHtml = function(o){
        var b = '';
        b += '<' + o.tag;
        for(var attr in o){
            if(attr == 'tag' || attr == 'children' || attr == 'html' || typeof o[attr] == 'function') continue;
            if(attr == 'style'){
                var s = o['style'];
                if(typeof s == 'function'){
                    s = s.call();
                }
                if(typeof s == 'string'){
                    b += ' style="' + s + '"';
                }else if(typeof s == 'object'){
                    b += ' style="';
                    for(var key in s){
                        if(typeof s[key] != 'function'){
                            b += key + ':' + s[key] + ';';
                        }
                    }
                    b += '"';
                }
            }else{
                if(attr == 'cls'){
                    b += ' class="' + o['cls'] + '"';
                }else if(attr == 'htmlFor'){
                    b += ' for="' + o['htmlFor'] + '"';
                }else{
                    b += ' ' + attr + '="' + o[attr] + '"';
                }
            }
        }
        if(emptyTags.test(o.tag)){
            b += ' />';
        }else{
            b += '>';
            if(o.children){
                for(var i = 0, len = o.children.length; i < len; i++) {
                    b += createHtml(o.children[i], b);
                }
            }
            if(o.html){
                b += o.html;
            }
            b += '</' + o.tag + '>';
        }
        return b;
    };
    
    
    
    var createDom = function(o, parentNode){
        var el = d.createElement(o.tag);
        var useSet = el.setAttribute ? true : false; 
        for(var attr in o){
            if(attr == 'tag' || attr == 'children' || attr == 'html' || attr == 'style' || typeof o[attr] == 'function') continue;
            if(attr=='cls'){
                el.className = o['cls'];
            }else{
                if(useSet) el.setAttribute(attr, o[attr]);
                else el[attr] = o[attr];
            }
        }
        YAHOO.ext.DomHelper.applyStyles(el, o.style);
        if(o.children){
            for(var i = 0, len = o.children.length; i < len; i++) {
             	createDom(o.children[i], el);
            }
        }
        if(o.html){
            el.innerHTML = o.html;
        }
        if(parentNode){
           parentNode.appendChild(el);
        }
        return el;
    };
    
    
    var insertIntoTable = function(tag, where, el, html){
        if(!tempTableEl){
            tempTableEl = document.createElement('div');
        }
        var node;
        if(tag == 'table' || tag == 'tbody'){
           tempTableEl.innerHTML = '<table><tbody>'+html+'</tbody></table>';
           node = tempTableEl.firstChild.firstChild.firstChild;
        }else{
           tempTableEl.innerHTML = '<table><tbody><tr>'+html+'</tr></tbody></table>';
           node = tempTableEl.firstChild.firstChild.firstChild.firstChild;
        }
        if(where == 'beforebegin'){
            el.parentNode.insertBefore(node, el);
            return node;
        }else if(where == 'afterbegin'){
            el.insertBefore(node, el.firstChild);
            return node;
        }else if(where == 'beforeend'){
            el.appendChild(node);
            return node;
        }else if(where == 'afterend'){
            el.parentNode.insertBefore(node, el.nextSibling);
            return node;
        }
    } ;
    
    
    this.insertHtml = function(where, el, html){
        where = where.toLowerCase();
        if(el.insertAdjacentHTML){
            var tag = el.tagName.toLowerCase();
            if(tag == 'table' || tag == 'tbody' || tag == 'tr'){
               return insertIntoTable(tag, where, el, html);
            }
            switch(where){
                case 'beforebegin':
                    el.insertAdjacentHTML(where, html);
                    return el.previousSibling;
                case 'afterbegin':
                    el.insertAdjacentHTML(where, html);
                    return el.firstChild;
                case 'beforeend':
                    el.insertAdjacentHTML(where, html);
                    return el.lastChild;
                case 'afterend':
                    el.insertAdjacentHTML(where, html);
                    return el.nextSibling;
            }
            throw 'Illegal insertion point -> "' + where + '"';
        }
        var range = el.ownerDocument.createRange();
        var frag;
        switch(where){
             case 'beforebegin':
                range.setStartBefore(el);
                frag = range.createContextualFragment(html);
                el.parentNode.insertBefore(frag, el);
                return el.previousSibling;
             case 'afterbegin':
                if(el.firstChild){ 
                    range.setStartBefore(el.firstChild);
                }else{
                    range.selectNodeContents(el);
                    range.collapse(true);
                }
                frag = range.createContextualFragment(html);
                el.insertBefore(frag, el.firstChild);
                return el.firstChild;
            case 'beforeend':
                if(el.lastChild){
                    range.setStartAfter(el.lastChild); 
                }else{
                    range.selectNodeContents(el);
                    range.collapse(false);
                }
                frag = range.createContextualFragment(html);
                el.appendChild(frag);
                return el.lastChild;
            case 'afterend':
                range.setStartAfter(el);
                frag = range.createContextualFragment(html);
                el.parentNode.insertBefore(frag, el.nextSibling);
                return el.nextSibling;
            }
            throw 'Illegal insertion point -> "' + where + '"';
    };
    
    
    this.insertBefore = function(el, o, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode;
        if(this.useDom){
            newNode = createDom(o, null);
            el.parentNode.insertBefore(newNode, el);
        }else{
            var html = createHtml(o);
            newNode = this.insertHtml('beforeBegin', el, html);
        }
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    };
    
    
    this.insertAfter = function(el, o, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode;
        if(this.useDom){
            newNode = createDom(o, null);
            el.parentNode.insertBefore(newNode, el.nextSibling);
        }else{
            var html = createHtml(o);
            newNode = this.insertHtml('afterEnd', el, html);
        }
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    };
    
    
    this.append = function(el, o, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode;
        if(this.useDom){
            newNode = createDom(o, null);
            el.appendChild(newNode);
        }else{
            var html = createHtml(o);
            newNode = this.insertHtml('beforeEnd', el, html);
        }
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    };
    
    
    this.overwrite = function(el, o, returnElement){
        el = YAHOO.util.Dom.get(el);
        el.innerHTML = createHtml(o);
        return returnElement ? YAHOO.ext.Element.get(el.firstChild, true) : el.firstChild;
    };
    
    
    this.createTemplate = function(o){
        var html = createHtml(o);
        return new YAHOO.ext.DomHelper.Template(html);
    };
}();


YAHOO.ext.DomHelper.Template = function(html){
    
    this.html = html;
};
YAHOO.ext.DomHelper.Template.prototype = {
    
    applyTemplate : function(values){
        if(this.compiled){
            return this.compiled(values);
        }
        var empty = '';
        var fn = function(match, index){
            if(typeof values[index] != 'undefined'){
                return values[index];
            }else{
                return empty;
            }
        };
        return this.html.replace(this.re, fn);
    },
    
    
    re : /\{(\w+)\}/g,
    
    
    compile : function(){
        var html = this.html;
        var re = this.re;
        var body = [];
        body.push("this.compiled = function(values){ return [");
        var result;
        var lastMatchEnd = 0;
        while ((result = re.exec(html)) != null){
            body.push("'", html.substring(lastMatchEnd, result.index), "', ");
            body.push("values['", html.substring(result.index+1,re.lastIndex-1), "'], ");
            lastMatchEnd = re.lastIndex;
        }
        body.push("'", html.substr(lastMatchEnd), "'].join('');};");
        eval(body.join(''));
    },
   
    
    insertBefore: function(el, values, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode = YAHOO.ext.DomHelper.insertHtml('beforeBegin', el, this.applyTemplate(values));
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    },
    
    
    insertAfter : function(el, values, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode = YAHOO.ext.DomHelper.insertHtml('afterEnd', el, this.applyTemplate(values));
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    },
    
    
    append : function(el, values, returnElement){
        el = YAHOO.util.Dom.get(el);
        var newNode = YAHOO.ext.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(values));
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    },
    
    
    overwrite : function(el, values, returnElement){
        el = YAHOO.util.Dom.get(el);
        el.innerHTML = '';
        var newNode = YAHOO.ext.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(values));
        return returnElement ? YAHOO.ext.Element.get(newNode, true) : newNode;
    }
};

YAHOO.ext.Template = YAHOO.ext.DomHelper.Template;

YAHOO.ext.Element = function(element, forceNew){
    var dom = YAHOO.util.Dom.get(element);
    if(!dom){ 
        return null;
    }
    if(!forceNew && YAHOO.ext.Element.cache[dom.id]){ 
        return YAHOO.ext.Element.cache[dom.id];
    }
    
    this.dom = dom;
    
    
    this.id = this.dom.id;
    
    this.visibilityMode = YAHOO.ext.Element.VISIBILITY;
    
    
    
    this.originalDisplay = YAHOO.util.Dom.getStyle(this.dom, 'display') || '';
    if(this.autoDisplayMode){
        if(this.originalDisplay == 'none'){
            this.setVisibilityMode(YAHOO.ext.Element.DISPLAY);
        }
    }
    if(this.originalDisplay == 'none'){
        this.originalDisplay = '';
    }
    
    
    this.defaultUnit = 'px';
};

YAHOO.ext.Element.prototype = {    
    
    setVisibilityMode : function(visMode){
        this.visibilityMode = visMode;
        return this;
    },
    
    
    enableDisplayMode : function(display){
        this.setVisibilityMode(YAHOO.ext.Element.DISPLAY);
        if(typeof display != 'undefined') this.originalDisplay = display;
        return this;
    },
    
    
    animate : function(args, duration, onComplete, easing, animType){
        this.anim(args, duration, onComplete, easing, animType);
        return this;
    },
    
    
    anim : function(args, duration, onComplete, easing, animType){
        animType = animType || YAHOO.util.Anim;
        var anim = new animType(this.dom, args, duration || .35, 
                easing || YAHOO.util.Easing.easeBoth);
        if(onComplete){
            if(!(onComplete instanceof Array)){
                anim.onComplete.subscribe(onComplete, this, true);
            }else{
                for(var i = 0; i < onComplete.length; i++){
                    var fn = onComplete[i];
                    if(fn) anim.onComplete.subscribe(fn, this, true);
                }
            }
        }
        anim.animate();
    },
    
    
    scrollIntoView : function(container){
        var c = getEl(container || document.body, true);
        var cp = c.getStyle('position');
        var restorePos = false;
        if(cp != 'relative' && cp != 'absolute'){
            c.setStyle('position', 'relative');
            restorePos = true;
        }
        var el = this.dom;
        var childTop = parseInt(el.offsetTop, 10);
        var childBottom = childTop + el.offsetHeight;
        var containerTop = parseInt(c.scrollTop, 10); 
        var containerBottom = containerTop + c.clientHeight;
        if(childTop < containerTop){
        	c.scrollTop = childTop;
        }else if(childBottom > containerBottom){
            c.scrollTop = childBottom-c.clientHeight;
        }
        if(restorePos){
            c.setStyle('position', cp);
        }
        return this;
    },
        
    
    autoHeight : function(animate, duration, onComplete, easing){
        var oldHeight = this.getHeight();
        this.clip();
        this.setHeight(1); 
        setTimeout(function(){
            var height = parseInt(this.dom.scrollHeight, 10); 
            if(!animate){
                this.setHeight(height);
                this.unclip();
                if(typeof onComplete == 'function'){
                    onComplete();
                }
            }else{
                this.setHeight(oldHeight); 
                this.setHeight(height, animate, duration, function(){
                    this.unclip();
                    if(typeof onComplete == 'function') onComplete();
                }.createDelegate(this), easing);
            }
        }.createDelegate(this), 0);
        return this;
    },
    
    
    isVisible : function(deep) {
        var vis = YAHOO.util.Dom.getStyle(this.dom, 'visibility') != 'hidden' 
               && YAHOO.util.Dom.getStyle(this.dom, 'display') != 'none';
        if(!deep || !vis){
            return vis;
        }
        var p = this.dom.parentNode;
        while(p && p.tagName.toLowerCase() != 'body'){
            if(YAHOO.util.Dom.getStyle(p, 'visibility') == 'hidden' || YAHOO.util.Dom.getStyle(p, 'display') == 'none'){
                return false;
            }
            p = p.parentNode;
        }
        return true;
    },
    
    
    select : function(selector, unique){
        return YAHOO.ext.Element.select('#' + this.dom.id + ' ' + selector, unique);  
    },
    
    
    initDD : function(group, config, overrides){
        var dd = new YAHOO.util.DD(YAHOO.util.Dom.generateId(this.dom), group, config);
        return YAHOO.ext.util.Config.apply(dd, overrides);
    },
   
    
    initDDProxy : function(group, config, overrides){
        var dd = new YAHOO.util.DDProxy(YAHOO.util.Dom.generateId(this.dom), group, config);
        return YAHOO.ext.util.Config.apply(dd, overrides);
    },
   
    
    initDDTarget : function(group, config, overrides){
        var dd = new YAHOO.util.DDTarget(YAHOO.util.Dom.generateId(this.dom), group, config);
        return YAHOO.ext.util.Config.apply(dd, overrides);
    },
   
    
     setVisible : function(visible, animate, duration, onComplete, easing){
        
        if(!animate || !YAHOO.util.Anim){
            if(this.visibilityMode == YAHOO.ext.Element.DISPLAY){
                this.setDisplayed(visible);
            }else{
                YAHOO.util.Dom.setStyle(this.dom, 'visibility', visible ? 'visible' : 'hidden');
            }
        }else{
            
            this.setOpacity(visible?0:1);
            YAHOO.util.Dom.setStyle(this.dom, 'visibility', 'visible');
            if(this.visibilityMode == YAHOO.ext.Element.DISPLAY){
                this.setDisplayed(true);
            }
            var args = {opacity: { from: (visible?0:1), to: (visible?1:0) }};
            var anim = new YAHOO.util.Anim(this.dom, args, duration || .35, 
                easing || (visible ? YAHOO.util.Easing.easeIn : YAHOO.util.Easing.easeOut));
            anim.onComplete.subscribe((function(){
                if(this.visibilityMode == YAHOO.ext.Element.DISPLAY){
                    this.setDisplayed(visible);
                }else{
                    YAHOO.util.Dom.setStyle(this.dom, 'visibility', visible ? 'visible' : 'hidden');
                }
            }).createDelegate(this));
            if(onComplete){
                anim.onComplete.subscribe(onComplete);
            }
            anim.animate();
        }
        return this;
    },
    
    
    isDisplayed : function() {
        return YAHOO.util.Dom.getStyle(this.dom, 'display') != 'none';
    },
    
    
    toggle : function(animate, duration, onComplete, easing){
        this.setVisible(!this.isVisible(), animate, duration, onComplete, easing);
        return this;
    },
    
    
    setDisplayed : function(value) {
        if(typeof value == 'boolean'){
           value = value ? this.originalDisplay : 'none';
        }
        YAHOO.util.Dom.setStyle(this.dom, 'display', value);
        return this;
    },
    
    
    focus : function() {
        try{
            this.dom.focus();
        }catch(e){}
        return this;
    },
    
    
    blur : function() {
        try{
            this.dom.blur();
        }catch(e){}
        return this;
    },
    
    
    addClass : function(className){
        if(className instanceof Array){
            for(var i = 0, len = className.length; i < len; i++) {
            	this.addClass(className[i]);
            }
        }else{
            if(!this.hasClass(className)){
                this.dom.className = this.dom.className + ' ' + className;
            }
        }
        return this;
    },
    
    
    radioClass : function(className){
        var siblings = this.dom.parentNode.childNodes;
        for(var i = 0; i < siblings.length; i++) {
        	var s = siblings[i];
        	if(s.nodeType == 1){
        	    YAHOO.util.Dom.removeClass(s, className);
        	}
        }
        this.addClass(className);
        return this;
    },
    
    removeClass : function(className){
        if(className instanceof Array){
            for(var i = 0, len = className.length; i < len; i++) {
            	this.removeClass(className[i]);
            }
        }else{
            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
            var c = this.dom.className;
            if(re.test(c)){
                this.dom.className = c.replace(re, ' ');
            }
        }
        return this;
    },
    
    
    toggleClass : function(className){
        if(this.hasClass(className)){
            this.removeClass(className);
        }else{
            this.addClass(className);
        }
        return this;
    },
    
    
    hasClass : function(className){
        var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
        return re.test(this.dom.className);
    },
    
    
    replaceClass : function(oldClassName, newClassName){
        this.removeClass(oldClassName);
        this.addClass(newClassName);
        return this;
    },
    
    
    getStyle : function(name){
        return YAHOO.util.Dom.getStyle(this.dom, name);
    },
    
    
    setStyle : function(name, value){
        if(typeof name == 'string'){
            YAHOO.util.Dom.setStyle(this.dom, name, value);
        }else{
            var D = YAHOO.util.Dom;
            for(var style in name){
                if(typeof name[style] != 'function'){
                   D.setStyle(this.dom, style, name[style]);
                }
            }
        }
        return this;
    },
    
    
    applyStyles : function(style){
       YAHOO.ext.DomHelper.applyStyles(this.dom, style);
    },
    
    
    getX : function(){
        return YAHOO.util.Dom.getX(this.dom);
    },
    
    
    getY : function(){
        return YAHOO.util.Dom.getY(this.dom);
    },
    
    
    getXY : function(){
        return YAHOO.util.Dom.getXY(this.dom);
    },
    
    
    setX : function(x, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setX(this.dom, x);
        }else{
            this.setXY([x, this.getY()], animate, duration, onComplete, easing);
        }
        return this;
    },
    
    
    setY : function(y, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setY(this.dom, y);
        }else{
            this.setXY([this.getX(), y], animate, duration, onComplete, easing);
        }
        return this;
    },
    
    
    setLeft : function(left){
        YAHOO.util.Dom.setStyle(this.dom, 'left', this.addUnits(left));
        return this;
    },
    
    
    setTop : function(top){
        YAHOO.util.Dom.setStyle(this.dom, 'top', this.addUnits(top));
        return this;
    },
    
    
    setRight : function(right){
        YAHOO.util.Dom.setStyle(this.dom, 'right', this.addUnits(right));
        return this;
    },
    
    
    setBottom : function(bottom){
        YAHOO.util.Dom.setStyle(this.dom, 'bottom', this.addUnits(bottom));
        return this;
    },
    
    
    setXY : function(pos, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setXY(this.dom, pos);
        }else{
            this.anim({points: {to: pos}}, duration, onComplete, easing, YAHOO.util.Motion);
        }
        return this;
    },
    
    
    setLocation : function(x, y, animate, duration, onComplete, easing){
        this.setXY([x, y], animate, duration, onComplete, easing);
        return this;
    },
    
    
    moveTo : function(x, y, animate, duration, onComplete, easing){
        
        
        this.setXY([x, y], animate, duration, onComplete, easing);
        return this;
    },
    
    
    getRegion : function(){
        return YAHOO.util.Dom.getRegion(this.dom);
    },
    
    
    getHeight : function(contentHeight){
        var h = this.dom.offsetHeight;
        return contentHeight !== true ? h : h-this.getBorderWidth('tb')-this.getPadding('tb');
    },
    
    
    getWidth : function(contentWidth){
        var w = this.dom.offsetWidth;
        return contentWidth !== true ? w : w-this.getBorderWidth('lr')-this.getPadding('lr');
    },
    
    
    getSize : function(contentSize){
        return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
    },
    
    
    adjustWidth : function(width){
        if(typeof width == 'number'){
            if(this.autoBoxAdjust && !this.isBorderBox()){
               width -= (this.getBorderWidth('lr') + this.getPadding('lr'));
            }
            if(width < 0){
                width = 0;
            }
        }
        return width;
    },
    
    
    adjustHeight : function(height){
        if(typeof height == 'number'){
           if(this.autoBoxAdjust && !this.isBorderBox()){
               height -= (this.getBorderWidth('tb') + this.getPadding('tb'));
           }
           if(height < 0){
               height = 0;
           }
        }
        return height;
    },
    
    
    setWidth : function(width, animate, duration, onComplete, easing){
        width = this.adjustWidth(width);
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setStyle(this.dom, 'width', this.addUnits(width));
        }else{
            this.anim({width: {to: width}}, duration, onComplete, 
                easing || (width > this.getWidth() ? YAHOO.util.Easing.easeOut : YAHOO.util.Easing.easeIn));
        }
        return this;
    },
    
    
     setHeight : function(height, animate, duration, onComplete, easing){
        height = this.adjustHeight(height);
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setStyle(this.dom, 'height', this.addUnits(height));
        }else{
            this.anim({height: {to: height}}, duration, onComplete,  
                   easing || (height > this.getHeight() ? YAHOO.util.Easing.easeOut : YAHOO.util.Easing.easeIn));
        }
        return this;
    },
    
    
     setSize : function(width, height, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            this.setWidth(width);
            this.setHeight(height);
        }else{
            width = this.adjustWidth(width); height = this.adjustHeight(height);
            this.anim({width: {to: width}, height: {to: height}}, duration, onComplete, easing);
        }
        return this;
    },
    
    
    setBounds : function(x, y, width, height, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            this.setWidth(width);
            this.setHeight(height);
            this.setLocation(x, y);
        }else{
            width = this.adjustWidth(width); height = this.adjustHeight(height);
            this.anim({points: {to: [x, y]}, width: {to: width}, height: {to: height}}, duration, onComplete, easing, YAHOO.util.Motion);
        }
        return this;
    },
    
    
    setRegion : function(region, animate, duration, onComplete, easing){
        this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, animate, duration, onComplete, easing);
        return this;
    },
    
    
    addListener : function(eventName, handler, scope, override){
        YAHOO.util.Event.addListener(this.dom, eventName, handler, scope || this, true);
        return this;
    },
    
    bufferedListener : function(eventName, fn, scope, millis){
        var task = new YAHOO.ext.util.DelayedTask();
        scope = scope || this;
        var newFn = function(){
            task.delay(millis || 250, fn, scope, Array.prototype.slice.call(arguments, 0));
        };
        this.addListener(eventName, newFn);
        return newFn;
    },
    
    
    
    addHandler : function(eventName, stopPropagation, handler, scope, override){
        var fn = YAHOO.ext.Element.createStopHandler(stopPropagation, handler, scope || this, true);
        YAHOO.util.Event.addListener(this.dom, eventName, fn);
        return this;
    },
    
    
    on : function(eventName, handler, scope, override){
        YAHOO.util.Event.addListener(this.dom, eventName, handler, scope || this, true);
        return this;
    },
    
    
    addManagedListener : function(eventName, fn, scope, override){
        return YAHOO.ext.EventManager.on(this.dom, eventName, fn, scope || this, true);
    },
    
    
    mon : function(eventName, fn, scope, override){
        return YAHOO.ext.EventManager.on(this.dom, eventName, fn, scope || this, true);
    },
    
    removeListener : function(eventName, handler, scope){
        YAHOO.util.Event.removeListener(this.dom, eventName, handler);
        return this;
    },
    
    
    removeAllListeners : function(){
        YAHOO.util.Event.purgeElement(this.dom);
        return this;
    },
    
    
    
     setOpacity : function(opacity, animate, duration, onComplete, easing){
        if(!animate || !YAHOO.util.Anim){
            YAHOO.util.Dom.setStyle(this.dom, 'opacity', opacity);
        }else{
            this.anim({opacity: {to: opacity}}, duration, onComplete, easing);
        }
        return this;
    },
    
    
    getLeft : function(local){
        if(!local){
            return this.getX();
        }else{
            return parseInt(this.getStyle('left'), 10) || 0;
        }
    },
    
    
    getRight : function(local){
        if(!local){
            return this.getX() + this.getWidth();
        }else{
            return (this.getLeft(true) + this.getWidth()) || 0;
        }
    },
    
    
    getTop : function(local) {
        if(!local){
            return this.getY();
        }else{
            return parseInt(this.getStyle('top'), 10) || 0;
        }
    },
    
    
    getBottom : function(local){
        if(!local){
            return this.getY() + this.getHeight();
        }else{
            return (this.getTop(true) + this.getHeight()) || 0;
        }
    },
    
    
    setAbsolutePositioned : function(zIndex){
        this.setStyle('position', 'absolute');
        if(zIndex){
            this.setStyle('z-index', zIndex);
        }
        return this;
    },
    
    
    setRelativePositioned : function(zIndex){
        this.setStyle('position', 'relative');
        if(zIndex){
            this.setStyle('z-index', zIndex);
        }
        return this;
    },
    
    
    clearPositioning : function(){
        this.setStyle('position', '');
        this.setStyle('left', '');
        this.setStyle('right', '');
        this.setStyle('top', '');
        this.setStyle('bottom', '');
        return this;
    },
    
    
    getPositioning : function(){
        return {
            'position' : this.getStyle('position'),
            'left' : this.getStyle('left'),
            'right' : this.getStyle('right'),
            'top' : this.getStyle('top'),
            'bottom' : this.getStyle('bottom')
        };
    },
    
    
    getBorderWidth : function(side){
        return this.addStyles(side, YAHOO.ext.Element.borders);
    },
    
    
    getPadding : function(side){
        return this.addStyles(side, YAHOO.ext.Element.paddings);
    },
    
    
    setPositioning : function(positionCfg){
        if(positionCfg.position)this.setStyle('position', positionCfg.position);
        if(positionCfg.left)this.setLeft(positionCfg.left);
        if(positionCfg.right)this.setRight(positionCfg.right);
        if(positionCfg.top)this.setTop(positionCfg.top);
        if(positionCfg.bottom)this.setBottom(positionCfg.bottom);
        return this;
    },
    
    
    
     setLeftTop : function(left, top){
        this.dom.style.left = this.addUnits(left);
        this.dom.style.top = this.addUnits(top);
        return this;
    },
    
    
     move : function(direction, distance, animate, duration, onComplete, easing){
        var xy = this.getXY();
        direction = direction.toLowerCase();
        switch(direction){
            case 'l':
            case 'left':
                this.moveTo(xy[0]-distance, xy[1], animate, duration, onComplete, easing);
                break;
           case 'r':
           case 'right':
                this.moveTo(xy[0]+distance, xy[1], animate, duration, onComplete, easing);
                break;
           case 't':
           case 'top':
           case 'up':
                this.moveTo(xy[0], xy[1]-distance, animate, duration, onComplete, easing);
                break;
           case 'b':
           case 'bottom':
           case 'down':
                this.moveTo(xy[0], xy[1]+distance, animate, duration, onComplete, easing);
                break;
        }
        return this;
    },
    
    
    clip : function(){
        if(!this.isClipped){
           this.isClipped = true;
           this.originalClip = {
               'o': this.getStyle('overflow'), 
               'x': this.getStyle('overflow-x'),
               'y': this.getStyle('overflow-y')
           };
           this.setStyle('overflow', 'hidden');
           this.setStyle('overflow-x', 'hidden');
           this.setStyle('overflow-y', 'hidden');
        }
        return this;
    },
    
    
    unclip : function(){
        if(this.isClipped){
            this.isClipped = false;
            var o = this.originalClip;
            if(o.o){this.setStyle('overflow', o.o);}
            if(o.x){this.setStyle('overflow-x', o.x);}
            if(o.y){this.setStyle('overflow-y', o.y);}
        }
        return this;
    },
    
    
     alignTo : function(element, position, offsets, animate, duration, onComplete, easing){
        var otherEl = getEl(element);
        if(!otherEl){
            return this; 
        }
        offsets = offsets || [0, 0];
        var r = otherEl.getRegion();
        position = position.toLowerCase();
        switch(position){
           case 'bl':
                this.moveTo(r.left + offsets[0], r.bottom + offsets[1], 
                            animate, duration, onComplete, easing);
                break;
           case 'br':
                this.moveTo(r.right + offsets[0], r.bottom + offsets[1], 
                            animate, duration, onComplete, easing);
                break;
           case 'tl':
                this.moveTo(r.left + offsets[0], r.top + offsets[1], 
                            animate, duration, onComplete, easing);
                break;
           case 'tr':
                this.moveTo(r.right + offsets[0], r.top + offsets[1], 
                            animate, duration, onComplete, easing);
                break;
        }
        return this;
    },
    
    
    clearOpacity : function(){
        if (window.ActiveXObject) {
            this.dom.style.filter = '';
        } else {
            this.dom.style.opacity = '';
            this.dom.style['-moz-opacity'] = '';
            this.dom.style['-khtml-opacity'] = '';
        }
        return this;
    },
    
    
    hide : function(animate, duration, onComplete, easing){
        this.setVisible(false, animate, duration, onComplete, easing);
        return this;
    },
    
    
    show : function(animate, duration, onComplete, easing){
        this.setVisible(true, animate, duration, onComplete, easing);
        return this;
    },
    
    
    addUnits : function(size){
        if(size === '' || size == 'auto' || typeof size == 'undefined'){
            return size;
        }
        if(typeof size == 'number' || !YAHOO.ext.Element.unitPattern.test(size)){
            return size + this.defaultUnit;
        }
        return size;
    },
    
    
    beginMeasure : function(){
        var el = this.dom;
        if(el.offsetWidth || el.offsetHeight){
            return this; 
        }
        var changed = [];
        var p = this.dom; 
        while((!el.offsetWidth && !el.offsetHeight) && p && p.tagName && p.tagName.toLowerCase() != 'body'){
            if(YAHOO.util.Dom.getStyle(p, 'display') == 'none'){
                changed.push({el: p, visibility: YAHOO.util.Dom.getStyle(p, 'visibility')});
                p.style.visibility = 'hidden';
                p.style.display = 'block';
            }
            p = p.parentNode;
        }
        this._measureChanged = changed;
        return this;
               
    },
    
    
    endMeasure : function(){
        var changed = this._measureChanged;
        if(changed){
            for(var i = 0, len = changed.length; i < len; i++) {
            	var r = changed[i];
            	r.el.style.visibility = r.visibility;
                r.el.style.display = 'none';
            }
            this._measureChanged = null;
        }
        return this;
    },
    
    
    update : function(html, loadScripts, callback){
        if(typeof html == 'undefined'){
            html = '';
        }
        if(loadScripts !== true){
            this.dom.innerHTML = html;
            if(typeof callback == 'function'){
                callback();
            }
            return this;
        }
        var id = YAHOO.util.Dom.generateId();
        var dom = this.dom;
        
        html += '<span id="' + id + '"></span>';
        
        YAHOO.util.Event.onAvailable(id, function(){
            var hd = document.getElementsByTagName("head")[0];
            var re = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/img; 
            var srcRe = /\ssrc=([\'\"])(.*?)\1/i;
            var match;
            while(match = re.exec(html)){
                var srcMatch = match[0].match(srcRe);
                if(srcMatch && srcMatch[2]){
                   var s = document.createElement("script");
                   s.src = srcMatch[2];
                   hd.appendChild(s);
                }else if(match[1] && match[1].length > 0){
                   eval(match[1]);
                }                     
            }
            var el = document.getElementById(id);
            if(el){el.parentNode.removeChild(el);}
            if(typeof callback == 'function'){
                callback();
            }
        });
        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/img, '');
        return this;
    },
    
    
    load : function(){
        var um = this.getUpdateManager();
        um.update.apply(um, arguments);
        return this;
    },
    
    
    getUpdateManager : function(){
        if(!this.updateManager){
            this.updateManager = new YAHOO.ext.UpdateManager(this);
        }
        return this.updateManager;
    },
    
    
    unselectable : function(){
        this.dom.unselectable = 'on';
        this.swallowEvent('selectstart', true);
        this.applyStyles('-moz-user-select:none;-khtml-user-select:none;');
        return this;
    },
    
    
    getCenterXY : function(offsetScroll){
        var centerX = Math.round((YAHOO.util.Dom.getViewportWidth()-this.getWidth())/2);
        var centerY = Math.round((YAHOO.util.Dom.getViewportHeight()-this.getHeight())/2);
        if(!offsetScroll){
            return [centerX, centerY];
        }else{
            var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft || 0;
            var scrollY = document.documentElement.scrollTop || document.body.scrollTop || 0;
            return[centerX + scrollX, centerY + scrollY];
        }
    },
    
    
    center : function(centerIn) {
        if(!centerIn){
            this.setXY(this.getCenterXY(true));
        }else{
            var box = YAHOO.ext.Element.get(centerIn).getBox();
            this.setXY([box.x + (box.width / 2) - (this.getWidth() / 2),
                   box.y + (box.height / 2) - (this.getHeight() / 2)]);
        }
        return this;
    },

    
    getChildrenByTagName : function(tagName){
        var children = this.dom.getElementsByTagName(tagName);
        var len = children.length;
        var ce = new Array(len);
        for(var i = 0; i < len; ++i){
            ce[i] = YAHOO.ext.Element.get(children[i], true);
        }
        return ce;
    },
    
    
    getChildrenByClassName : function(className, tagName){
        var children = YAHOO.util.Dom.getElementsByClassName(className, tagName, this.dom);
        var len = children.length;
        var ce = new Array(len);
        for(var i = 0; i < len; ++i){
            ce[i] = YAHOO.ext.Element.get(children[i], true);
        }
        return ce;
    },
    
    
    isBorderBox : function(){
        if(typeof this.bbox == 'undefined'){
            var el = this.dom;
            var b = YAHOO.ext.util.Browser;
            var strict = YAHOO.ext.Strict;
            this.bbox = ((b.isIE && !strict && el.style.boxSizing != 'content-box') || 
               (b.isGecko && YAHOO.util.Dom.getStyle(el, "-moz-box-sizing") == 'border-box') || 
               (!b.isSafari && YAHOO.util.Dom.getStyle(el, "box-sizing") == 'border-box'));
        }
        return this.bbox; 
    },
    
    
    getBox : function(contentBox, local){
        var xy;
        if(!local){
            xy = this.getXY();
        }else{
            var left = parseInt(YAHOO.util.Dom.getStyle('left'), 10) || 0;
            var top = parseInt(YAHOO.util.Dom.getStyle('top'), 10) || 0;
            xy = [left, top];
        }
        var el = this.dom;
        var w = el.offsetWidth;
        var h = el.offsetHeight;
        if(!contentBox){
            return {x: xy[0], y: xy[1], width: w, height: h};
        }else{
            var l = this.getBorderWidth('l')+this.getPadding('l');
            var r = this.getBorderWidth('r')+this.getPadding('r');
            var t = this.getBorderWidth('t')+this.getPadding('t');
            var b = this.getBorderWidth('b')+this.getPadding('b');
            return {x: xy[0]+l, y: xy[1]+t, width: w-(l+r), height: h-(t+b)};
        }
    },
    
    
    setBox : function(box, adjust, animate, duration, onComplete, easing){
        var w = box.width, h = box.height;
        if((adjust && !this.autoBoxAdjust) && !this.isBorderBox()){
           w -= (this.getBorderWidth('lr') + this.getPadding('lr'));
           h -= (this.getBorderWidth('tb') + this.getPadding('tb'));
        }
        this.setBounds(box.x, box.y, w, h, animate, duration, onComplete, easing);
        return this;
    },
    
    
     repaint : function(){
        var dom = this.dom;
        YAHOO.util.Dom.addClass(dom, 'yui-ext-repaint');
        setTimeout(function(){
            YAHOO.util.Dom.removeClass(dom, 'yui-ext-repaint');
        }, 1);
        return this;
    },
    
    
    getMargins : function(side){
        if(!side){
            return {
                top: parseInt(this.getStyle('margin-top'), 10) || 0,
                left: parseInt(this.getStyle('margin-left'), 10) || 0,
                bottom: parseInt(this.getStyle('margin-bottom'), 10) || 0,
                right: parseInt(this.getStyle('margin-right'), 10) || 0
            };
        }else{
            return this.addStyles(side, YAHOO.ext.Element.margins);
         }
    },
    
    addStyles : function(sides, styles){
        var val = 0;
        for(var i = 0, len = sides.length; i < len; i++){
             var w = parseInt(this.getStyle(styles[sides.charAt(i)]), 10);
             if(!isNaN(w)) val += w;
        }
        return val;
    },
    
    
    createProxy : function(config, renderTo, matchBox){
        if(renderTo){
            renderTo = YAHOO.util.Dom.get(renderTo);
        }else{
            renderTo = document.body;
        }
        config = typeof config == 'object' ? 
            config : {tag : 'div', cls: config};
        var proxy = YAHOO.ext.DomHelper.append(renderTo, config, true);
        if(matchBox){
           proxy.setBox(this.getBox());
        }
        return proxy;
    },
    
    
    createShim : function(){
        var config = {
            tag : 'iframe', 
            frameBorder:'no', 
            cls: 'yiframe-shim', 
            style: 'position:absolute;visibility:hidden;left:0;top:0;overflow:hidden;', 
            src: YAHOO.ext.SSL_SECURE_URL
        };
        var shim = YAHOO.ext.DomHelper.append(this.dom.parentNode, config, true);
        shim.setBox(this.getBox());
        return shim;
    },
    
    
    remove : function(){
        this.dom.parentNode.removeChild(this.dom);
        delete YAHOO.ext.Element.cache[this.dom.id];
    },
    
    
    addClassOnOver : function(className){
        this.on('mouseover', function(){
            this.addClass(className);
        }, this, true);
        this.on('mouseout', function(){
            this.removeClass(className);
        }, this, true);
        return this;
    },
    
    
    swallowEvent : function(eventName, preventDefault){
        var fn = function(e){
            e.stopPropagation();
            if(preventDefault){
                e.preventDefault();
            }
        };
        this.mon(eventName, fn);
        return this;
    },
    
    
    fitToParent : function(monitorResize){
        var p = getEl(this.dom.parentNode, true);
        p.beginMeasure(); 
        var box = p.getBox(true, true);
        p.endMeasure();
        this.setSize(box.width, box.height);
        if(monitorResize === true){
            YAHOO.ext.EventManager.onWindowResize(this.fitToParent, this, true);
        }
        return this;
    },
    
    
    getNextSibling : function(){
        var n = this.dom.nextSibling;
        while(n && n.nodeType != 1){
            n = n.nextSibling;
        }
        return n;
    },
    
    
    getPrevSibling : function(){
        var n = this.dom.previousSibling;
        while(n && n.nodeType != 1){
            n = n.previousSibling;
        }
        return n;
    },
    
    
    
    appendChild: function(el){
        el = getEl(el);
        el.appendTo(this);
        return this;
    },
    
    
    createChild: function(config, insertBefore){
        var c;
        if(insertBefore){
            c = YAHOO.ext.DomHelper.insertBefore(insertBefore, config, true);
        }else{
            c = YAHOO.ext.DomHelper.append(this.dom, config, true);
        }
        return c;
    },
    
    
    appendTo: function(el){
        var node = getEl(el).dom;
        node.appendChild(this.dom);
        return this;
    },
    
    
    insertBefore: function(el){
        var node = getEl(el).dom;
        node.parentNode.insertBefore(this.dom, node);
        return this;
    },
    
    
    insertAfter: function(el){
        var node = getEl(el).dom;
        node.parentNode.insertBefore(this.dom, node.nextSibling);
        return this;
    },
    
    
    wrap: function(config){
        if(!config){
            config = {tag: 'div'};
        }
        var newEl = YAHOO.ext.DomHelper.insertBefore(this.dom, config, true);
        newEl.dom.appendChild(this.dom);
        return newEl;
    },
    
    
    replace: function(el){
        el = getEl(el);
        this.insertBefore(el);
        el.remove();
        return this;
    },
    
    
    insertHtml : function(where, html){
        YAHOO.ext.DomHelper.insertHtml(where, this.dom, html);
        return this;
    },
    
    
    set : function(o){
        var el = this.dom;
        var useSet = el.setAttribute ? true : false;
        for(var attr in o){
            if(attr == 'style' || typeof o[attr] == 'function') continue;
            if(attr=='cls'){
                el.className = o['cls'];
            }else{
                if(useSet) el.setAttribute(attr, o[attr]);
                else el[attr] = o[attr];
            }
        }
        YAHOO.ext.DomHelper.applyStyles(el, o.style);
        return this;
    },
    
    
    addKeyListener : function(key, fn, scope){
        var config;
        if(typeof key != 'object' || key instanceof Array){
            config = {
                key: key,
                fn: fn,
                scope: scope 
            };
        }else{
            config = {
                key : key.key,
                shift : key.shift,
                ctrl : key.ctrl,
                alt : key.alt,
                fn: fn,
                scope: scope
            };
        }
        var map = new YAHOO.ext.KeyMap(this, config);
        return map; 
    },
    
    
    addKeyMap : function(config){
        return new YAHOO.ext.KeyMap(this, config);
    }
};


YAHOO.ext.Element.prototype.autoBoxAdjust = true;

YAHOO.ext.Element.prototype.autoDisplayMode = true;

YAHOO.ext.Element.unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;

YAHOO.ext.Element.VISIBILITY = 1;

YAHOO.ext.Element.DISPLAY = 2;

YAHOO.ext.Element.blockElements = /^(?:address|blockquote|center|dir|div|dl|fieldset|form|h\d|hr|isindex|menu|ol|ul|p|pre|table|dd|dt|li|tbody|tr|td|thead|tfoot|iframe)$/i;
YAHOO.ext.Element.borders = {l: 'border-left-width', r: 'border-right-width', t: 'border-top-width', b: 'border-bottom-width'};
YAHOO.ext.Element.paddings = {l: 'padding-left', r: 'padding-right', t: 'padding-top', b: 'padding-bottom'};
YAHOO.ext.Element.margins = {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'};
        

YAHOO.ext.Element.createStopHandler = function(stopPropagation, handler, scope, override){
    return function(e){
        if(e){
            if(stopPropagation){
                YAHOO.util.Event.stopEvent(e);
            }else {
                YAHOO.util.Event.preventDefault(e);
            }
        }
        handler.call(override && scope ? scope : window, e, scope);
    };
};


YAHOO.ext.Element.cache = {};


YAHOO.ext.Element.get = function(el, autoGenerateId){
    if(!el){ return null; }
    autoGenerateId = true; 
    if(el instanceof YAHOO.ext.Element){
        el.dom = YAHOO.util.Dom.get(el.id); 
        YAHOO.ext.Element.cache[el.id] = el; 
        return el;
    }else if(el.isComposite){
        return el;
    }else if(el instanceof Array){
        return YAHOO.ext.Element.select(el);
    }else if(el === document){
        
        if(!YAHOO.ext.Element.cache['__ydocument']){
            var docEl = function(){};
            docEl.prototype = YAHOO.ext.Element.prototype;
            var o = new docEl();
            o.dom = document;
            YAHOO.ext.Element.cache['__ydocument'] = o;
        }
        return YAHOO.ext.Element.cache['__ydocument'];
    }
    var key = el;
    if(typeof el != 'string'){ 
        if(!el.id && !autoGenerateId){ return null; }
        YAHOO.util.Dom.generateId(el, 'elgen-');
        key = el.id;
    }
    var element = YAHOO.ext.Element.cache[key];
    if(!element){
        element = new YAHOO.ext.Element(key);
        if(!element.dom) return null;
        YAHOO.ext.Element.cache[key] = element;
    }else{
        element.dom = YAHOO.util.Dom.get(key);
    }
    return element;
};


var getEl = YAHOO.ext.Element.get;


YAHOO.util.Event.addListener(window, 'unload', function(){ 
    YAHOO.ext.Element.cache = null;
});



YAHOO.ext.CompositeElement = function(els){
    this.elements = [];
    this.addElements(els);
};
YAHOO.ext.CompositeElement.prototype = {
    isComposite: true,
    addElements : function(els){
        if(!els) return this;
        var yels = this.elements;
        var index = yels.length-1;
        for(var i = 0, len = els.length; i < len; i++) {
        	yels[++index] = getEl(els[i], true);
        }
        return this;
    },
    invoke : function(fn, args){
        var els = this.elements;
        for(var i = 0, len = els.length; i < len; i++) {
        	YAHOO.ext.Element.prototype[fn].apply(els[i], args);
        }
        return this;
    },
    
    add : function(els){
        if(typeof els == 'string'){
            this.addElements(YAHOO.ext.Element.selectorFunction(string));
        }else if(els instanceof Array){
            this.addElements(els);
        }else{
            this.addElements([els]);
        }
        return this;
    },
    
    each : function(fn, scope){
        var els = this.elements;
        for(var i = 0, len = els.length; i < len; i++){
            fn.call(scope || els[i], els[i], this, i);
        }
        return this;
    }
};

YAHOO.ext.CompositeElementLite = function(els){
    YAHOO.ext.CompositeElementLite.superclass.constructor.call(this, els);
    this.el = YAHOO.ext.Element.get(this.elements[0], true);
};
YAHOO.extendX(YAHOO.ext.CompositeElementLite, YAHOO.ext.CompositeElement, {
    addElements : function(els){
        if(els){
            this.elements = this.elements.concat(els);
        }
        return this;
    },
    invoke : function(fn, args){
        var els = this.elements;
        var el = this.el;
        for(var i = 0, len = els.length; i < len; i++) {
            el.dom = els[i];
        	YAHOO.ext.Element.prototype[fn].apply(el, args);
        }
        return this;
    }
});
YAHOO.ext.CompositeElement.createCall = function(proto, fnName){
    if(!proto[fnName]){
        proto[fnName] = function(){
            return this.invoke(fnName, arguments);  
        };
    }
};
for(var fnName in YAHOO.ext.Element.prototype){
    if(typeof YAHOO.ext.Element.prototype[fnName] == 'function'){
        YAHOO.ext.CompositeElement.createCall(YAHOO.ext.CompositeElement.prototype, fnName);
    }
}
if(typeof cssQuery == 'function'){
    YAHOO.ext.Element.selectorFunction = cssQuery;
}else if(typeof document.getElementsBySelector == 'function'){ 
    YAHOO.ext.Element.selectorFunction = document.getElementsBySelector.createDelegate(document);
}

YAHOO.ext.Element.select = function(selector, unique){
    var els;
    if(typeof selector == 'string'){
        els = YAHOO.ext.Element.selectorFunction(selector);
    }else if(selector instanceof Array){
        els = selector;
    }else{
        throw 'Invalid selector';
    }
    if(unique === true){
        return new YAHOO.ext.CompositeElement(els);
    }else{
        return new YAHOO.ext.CompositeElementLite(els);
    }
};

var getEls = YAHOO.ext.Element.select;
YAHOO.namespace('ext.state');

YAHOO.ext.state.Provider = function(){
    YAHOO.ext.state.Provider.superclass.constructor.call(this);
    
    this.events = {
        'statechange': new YAHOO.util.CustomEvent('statechange')  
    };
    this.state = {};
};
YAHOO.extendX(YAHOO.ext.state.Provider, YAHOO.ext.util.Observable, {
    
    get : function(name, defaultValue){
        return typeof this.state[name] == 'undefined' ?
            defaultValue : this.state[name];
    },
    
    
    clear : function(name){
        delete this.state[name];
        this.fireEvent('statechange', this, name, null);
    },
    
    
    set : function(name, value){
        this.state[name] = value;
        this.fireEvent('statechange', this, name, value);
    },
    
    
    decodeValue : function(cookie){
        var re = /^(a|n|d|b|s|o)\:(.*)$/;
        var matches = re.exec(unescape(cookie));
        if(!matches || !matches[1]) return; 
        var type = matches[1];
        var v = matches[2];
        switch(type){
            case 'n':
                return parseFloat(v);
            case 'd':
                return new Date(Date.parse(v));
            case 'b':
                return (v == '1');
            case 'a':
                var all = [];
                var values = v.split('^');
                for(var i = 0, len = values.length; i < len; i++){
                    all.push(this.decodeValue(values[i]))
                }
                return all;
           case 'o':
                var all = {};
                var values = v.split('^');
                for(var i = 0, len = values.length; i < len; i++){
                    var kv = values[i].split('=');
                    all[kv[0]] = this.decodeValue(kv[1]);
                }
                return all;
           default:
                return v;
        }
    },
    
    
    encodeValue : function(v){
        var enc;
        if(typeof v == 'number'){
            enc = 'n:' + v;
        }else if(typeof v == 'boolean'){
            enc = 'b:' + (v ? '1' : '0');
        }else if(v instanceof Date){
            enc = 'd:' + v.toGMTString();
        }else if(v instanceof Array){
            var flat = '';
            for(var i = 0, len = v.length; i < len; i++){
                flat += this.encodeValue(v[i]);
                if(i != len-1) flat += '^';
            }
            enc = 'a:' + flat;
        }else if(typeof v == 'object'){
            var flat = '';
            for(var key in v){
                if(typeof v[key] != 'function'){
                    flat += key + '=' + this.encodeValue(v[key]) + '^';
                }
            }
            enc = 'o:' + flat.substring(0, flat.length-1);
        }else{
            enc = 's:' + v;
        }
        return escape(enc);        
    }
});


YAHOO.ext.state.Manager = new function(){
    var provider = new YAHOO.ext.state.Provider();
    
    return {
        
        setProvider : function(stateProvider){
            provider = stateProvider;
        },
        
        
        get : function(key, defaultValue){
            return provider.get(key, defaultValue);
        },
        
        
         set : function(key, value){
            provider.set(key, value);
        },
        
        
        clear : function(key){
            provider.clear(key);
        },
        
        
        getProvider : function(){
            return provider;
        }
    };
}();


YAHOO.ext.state.CookieProvider = function(config){
    YAHOO.ext.state.CookieProvider.superclass.constructor.call(this);
    this.path = '/';
    this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); 
    this.domain = null;
    this.secure = false;
    YAHOO.ext.util.Config.apply(this, config);
    this.state = this.readCookies();
};

YAHOO.extendX(YAHOO.ext.state.CookieProvider, YAHOO.ext.state.Provider, {
    set : function(name, value){
        if(typeof value == 'undefined' || value === null){
            this.clear(name);
            return;
        }
        this.setCookie(name, value);
        YAHOO.ext.state.CookieProvider.superclass.set.call(this, name, value);
    },
        
    clear : function(name){
        this.clearCookie(name);
        YAHOO.ext.state.CookieProvider.superclass.clear.call(this, name);
    },
        
    readCookies : function(){
        var cookies = {};
        var c = document.cookie + ';';
        var re = /\s?(.*?)=(.*?);/g;
    	var matches;
    	while((matches = re.exec(c)) != null){
            var name = matches[1];
            var value = matches[2];
            if(name && name.substring(0,3) == 'ys-'){
                cookies[name.substr(3)] = this.decodeValue(value);
            }
        }
        return cookies;
    },
    
    setCookie : function(name, value){
        document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
           ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
           ((this.path == null) ? "" : ("; path=" + this.path)) +
           ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
           ((this.secure == true) ? "; secure" : "");
    },
    
    clearCookie : function(name){
        document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
           ((this.path == null) ? "" : ("; path=" + this.path)) +
           ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
           ((this.secure == true) ? "; secure" : "");
    }
});



YAHOO.ext.EventManager = new function(){
    var docReadyEvent;
    var docReadyProcId;
    var docReadyState = false;
    this.ieDeferSrc = false;
    var resizeEvent;
    var resizeTask;
    
    var fireDocReady = function(){
        if(!docReadyState){
            docReadyState = true;
            if(docReadyProcId){
                clearInterval(docReadyProcId);
            }
            if(docReadyEvent){
                docReadyEvent.fire();
            }
        }
    };
    
    var initDocReady = function(){
        docReadyEvent = new YAHOO.util.CustomEvent('documentready');
        if(document.addEventListener) {
            YAHOO.util.Event.on(document, "DOMContentLoaded", fireDocReady);
        }else if(YAHOO.ext.util.Browser.isIE){
            
            document.write('<s'+'cript id="ie-deferred-loader" defer="defer" src="' +
                        (YAHOO.ext.EventManager.ieDeferSrc || YAHOO.ext.SSL_SECURE_URL) + '"></s'+'cript>');
            YAHOO.util.Event.on('ie-deferred-loader', 'readystatechange', function(){
                if(this.readyState == 'complete'){
                    fireDocReady();
                }
            });
        }else if(YAHOO.ext.util.Browser.isSafari){ 
            docReadyProcId = setInterval(function(){
                var rs = document.readyState;
                if(rs == 'loaded' || rs == 'complete') {
                    fireDocReady();     
                 }
            }, 10);
        }
        
        YAHOO.util.Event.on(window, 'load', fireDocReady);
    };
    
    this.wrap = function(fn, scope, override){
        var wrappedFn = function(e){
            YAHOO.ext.EventObject.setEvent(e);
            fn.call(override ? scope || window : window, YAHOO.ext.EventObject, scope);
        };
        return wrappedFn;
    };
    
    
    this.addListener = function(element, eventName, fn, scope, override){
        var wrappedFn = this.wrap(fn, scope, override);
        YAHOO.util.Event.addListener(element, eventName, wrappedFn);
        return wrappedFn;
    };
    
    
    this.removeListener = function(element, eventName, wrappedFn){
        return YAHOO.util.Event.removeListener(element, eventName, wrappedFn);
    };
    
    
    this.on = this.addListener;
    
    
    this.onDocumentReady = function(fn, scope, override){
        if(docReadyState){ 
            fn.call(override? scope || window : window, scope);
            return;
        }
        if(!docReadyEvent){
            initDocReady();
        }
        docReadyEvent.subscribe(fn, scope, override);
    };
    
    
    this.onWindowResize = function(fn, scope, override){
        if(!resizeEvent){
            resizeEvent = new YAHOO.util.CustomEvent('windowresize');
            resizeTask = new YAHOO.ext.util.DelayedTask(function(){
                resizeEvent.fireDirect(YAHOO.util.Dom.getViewportWidth(), YAHOO.util.Dom.getViewportHeight());
            });
            YAHOO.util.Event.on(window, 'resize', function(){
                resizeTask.delay(50);
            });
        }
        resizeEvent.subscribe(fn, scope, override);
    };
    
    
    this.removeResizeListener = function(fn, scope){
        if(resizeEvent){
            resizeEvent.unsubscribe(fn, scope);
        }
    };
};


YAHOO.ext.EventObject = new function(){
     
    this.browserEvent = null;
     
    this.button = -1;
     
    this.shiftKey = false;
     
    this.ctrlKey = false;
     
    this.altKey = false;
    
    
    this.BACKSPACE = 8;
    
    this.TAB = 9;
    
    this.RETURN = 13;
    
    this.ESC = 27;
    
    this.SPACE = 32;
    
    this.PAGEUP = 33;
    
    this.PAGEDOWN = 34;
    
    this.END = 35;
    
    this.HOME = 36;
    
    this.LEFT = 37;
    
    this.UP = 38;
    
    this.RIGHT = 39;
    
    this.DOWN = 40;
    
    this.DELETE = 46;
    
    this.F5 = 116;

        
    this.setEvent = function(e){
        if(e == this){ 
            return this;
        }
        this.browserEvent = e;
        if(e){
            this.button = e.button;
            this.shiftKey = e.shiftKey;
            this.ctrlKey = e.ctrlKey;
            this.altKey = e.altKey;
        }else{
            this.button = -1;
            this.shiftKey = false;
            this.ctrlKey = false;
            this.altKey = false;
        }
        return this;
    };
    
     
    this.stopEvent = function(){
        if(this.browserEvent){
            YAHOO.util.Event.stopEvent(this.browserEvent);
        }
    };
    
     
    this.preventDefault = function(){
        if(this.browserEvent){
            YAHOO.util.Event.preventDefault(this.browserEvent);
        }
    };
    
    
    this.isNavKeyPress = function(){
        return (this.browserEvent.keyCode && this.browserEvent.keyCode >= 33 && this.browserEvent.keyCode <= 40);
    };
    
     
    this.stopPropagation = function(){
        if(this.browserEvent){
            YAHOO.util.Event.stopPropagation(this.browserEvent);
        }
    };
    
     
    this.getCharCode = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getCharCode(this.browserEvent);
        }
        return null;
    };
    
    
    this.getKey = function(){
        if(this.browserEvent){
            return this.browserEvent.keyCode || this.browserEvent.charCode;
        }
        return null;
    };
    
     
    this.getPageX = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getPageX(this.browserEvent);
        }
        return null;
    };
    
     
    this.getPageY = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getPageY(this.browserEvent);
        }
        return null;
    };
    
     
    this.getTime = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getTime(this.browserEvent);
        }
        return null;
    };
    
     
    this.getXY = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getXY(this.browserEvent);
        }
        return [];
    };
    
     
    this.getTarget = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getTarget(this.browserEvent);
        }
        return null;
    };
    
     
    this.findTarget = function(className, tagName){
        if(tagName) tagName = tagName.toLowerCase();
        if(this.browserEvent){
            function isMatch(el){
               if(!el){
                   return false;
               }
               if(className && !YAHOO.util.Dom.hasClass(el, className)){
                   return false;
               }
               if(tagName && el.tagName.toLowerCase() != tagName){
                   return false;
               }
               return true;
            };
            
            var t = this.getTarget();
            if(!t || isMatch(t)){
    		    return t;
    	    }
    	    var p = t.parentNode;
    	    var b = document.body;
    	    while(p && p != b){
                if(isMatch(p)){
                	return p;
                }
                p = p.parentNode;
            }
    	}
        return null;
    };
     
    this.getRelatedTarget = function(){
        if(this.browserEvent){
            return YAHOO.util.Event.getRelatedTarget(this.browserEvent);
        }
        return null;
    };
    
    
    this.getWheelDelta = function(){
        var e = this.browserEvent;
        var delta = 0;
        if(e.wheelDelta){ 
            delta = e.wheelDelta/120;
            
            if(window.opera) delta = -delta;
        }else if(e.detail){ 
            delta = -e.detail/3;
        }
        return delta;
    };
    
     
    this.hasModifier = function(){
        return this.ctrlKey || this.altKey || this.shiftKey;
    };
}();
            
    

YAHOO.ext.UpdateManager = function(el, forceNew){
    el = YAHOO.ext.Element.get(el);
    if(!forceNew && el.updateManager){
        return el.updateManager;
    }
    
    this.el = el;
    
    this.defaultUrl = null;
    this.beforeUpdate = new YAHOO.util.CustomEvent('UpdateManager.beforeUpdate');
    this.onUpdate = new YAHOO.util.CustomEvent('UpdateManager.onUpdate');
    this.onFailure = new YAHOO.util.CustomEvent('UpdateManager.onFailure');
    
    this.events = {
        
        'beforeupdate': this.beforeUpdate,
        
        'update': this.onUpdate,
        
        'failure': this.onFailure 
    };
    
    
    this.sslBlankUrl = YAHOO.ext.UpdateManager.defaults.sslBlankUrl;
    
    this.disableCaching = YAHOO.ext.UpdateManager.defaults.disableCaching;
    
    this.indicatorText = YAHOO.ext.UpdateManager.defaults.indicatorText;
    
    this.showLoadIndicator = YAHOO.ext.UpdateManager.defaults.showLoadIndicator;
    
    this.timeout = YAHOO.ext.UpdateManager.defaults.timeout;
    
    
    this.loadScripts = YAHOO.ext.UpdateManager.defaults.loadScripts;
    
    
    this.transaction = null;
    
    
    this.autoRefreshProcId = null;
    
    this.refreshDelegate = this.refresh.createDelegate(this);
    
    this.updateDelegate = this.update.createDelegate(this);
    
    this.formUpdateDelegate = this.formUpdate.createDelegate(this);
    
    this.successDelegate = this.processSuccess.createDelegate(this);
    
     this.failureDelegate = this.processFailure.createDelegate(this);
     
     
      this.renderer = new YAHOO.ext.UpdateManager.BasicRenderer();
};

YAHOO.ext.UpdateManager.prototype = {
    fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
    bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener,
    
    getEl : function(){
        return this.el;
    },
    
    
    update : function(url, params, callback, discardUrl){
        if(this.beforeUpdate.fireDirect(this.el, url, params) !== false){
            if(typeof url == 'object'){ 
                var cfg = url;
                url = cfg.url;
                params = params || cfg.params;
                callback = callback || cfg.callback;
                discardUrl = discardUrl || cfg.discardUrl;
                if(callback && cfg.scope){
                    callback = callback.createDelegate(cfg.scope);
                }
                if(typeof cfg.nocache != 'undefined'){this.disableCaching = cfg.nocache};
                if(typeof cfg.text != 'undefined'){this.indicatorText = '<div class="loading-indicator">'+cfg.text+'</div>'};
                if(typeof cfg.scripts != 'undefined'){this.loadScripts = cfg.scripts};
                if(typeof cfg.timeout != 'undefined'){this.timeout = cfg.timeout};
            }
            this.showLoading();
            if(!discardUrl){
                this.defaultUrl = url;
            }
            if(typeof url == 'function'){
                url = url();
            }
            if(typeof params == 'function'){
                params = params();
            }
            if(params && typeof params != 'string'){ 
                var buf = [];
                for(var key in params){
                    if(typeof params[key] != 'function'){
                        buf.push(encodeURIComponent(key), '=', encodeURIComponent(params[key]), '&');
                    }
                }
                delete buf[buf.length-1];
                params = buf.join('');
            }
            var callback = {
                success: this.successDelegate,
                failure: this.failureDelegate,
                timeout: (this.timeout*1000),
                argument: {'url': url, 'form': null, 'callback': callback, 'params': params}
            };
            var method = params ? 'POST' : 'GET';
            if(method == 'GET'){
                url = this.prepareUrl(url);
            }
            this.transaction = YAHOO.util.Connect.asyncRequest(method, url, callback, params);
        }
    },
    
    
    formUpdate : function(form, url, reset, callback){
        if(this.beforeUpdate.fireDirect(this.el, form, url) !== false){
            this.showLoading();
            formEl = YAHOO.util.Dom.get(form);
            if(typeof url == 'function'){
                url = url();
            }
            if(typeof params == 'function'){
                params = params();
            }
            url = url || formEl.action;
            var callback = {
                success: this.successDelegate,
                failure: this.failureDelegate,
                timeout: (this.timeout*1000),
                argument: {'url': url, 'form': form, 'callback': callback, 'reset': reset}
            };
            var isUpload = false;
            var enctype = formEl.getAttribute('enctype');
            if(enctype && enctype.toLowerCase() == 'multipart/form-data'){
                isUpload = true;
            }
            YAHOO.util.Connect.setForm(form, isUpload, this.sslBlankUrl);
            this.transaction = YAHOO.util.Connect.asyncRequest('POST', url, callback);
        }
    },
    
    
    refresh : function(callback){
        if(this.defaultUrl == null){
            return;
        }
        this.update(this.defaultUrl, null, callback, true);
    },
    
    
    startAutoRefresh : function(interval, url, params, callback, refreshNow){
        if(refreshNow){
            this.update(url || this.defaultUrl, params, callback, true);
        }
        if(this.autoRefreshProcId){
            clearInterval(this.autoRefreshProcId);
        }
        this.autoRefreshProcId = setInterval(this.update.createDelegate(this, [url || this.defaultUrl, params, callback, true]), interval*1000);
    },
    
    
     stopAutoRefresh : function(){
        if(this.autoRefreshProcId){
            clearInterval(this.autoRefreshProcId);
        }
    },
    
    
    showLoading : function(){
        if(this.showLoadIndicator){
            this.el.update(this.indicatorText);
        }
    },
    
    
    prepareUrl : function(url){
        if(this.disableCaching){
            var append = '_dc=' + (new Date().getTime());
            if(url.indexOf('?') !== -1){
                url += '&' + append;
            }else{
                url += '?' + append;
            }
        }
        return url;
    },
    
    
    processSuccess : function(response){
        this.transaction = null;
        if(response.argument.form && response.argument.reset){
            try{ 
                response.argument.form.reset();
            }catch(e){}
        }
        if(this.loadScripts){
            this.renderer.render(this.el, response, this, 
                this.updateComplete.createDelegate(this, [response]));
        }else{
            this.renderer.render(this.el, response, this);
            this.updateComplete(response);
        }
    },
    
    updateComplete : function(response){
        this.fireEvent('update', this.el, response);
        if(typeof response.argument.callback == 'function'){
            response.argument.callback(this.el, true);
        }
    },
    
    
    processFailure : function(response){
        this.transaction = null;
        this.onFailure.fireDirect(this.el, response);
        if(typeof response.argument.callback == 'function'){
            response.argument.callback(this.el, false);
        }
    },
    
    
    setRenderer : function(renderer){
        this.renderer = renderer;
    },
    
    getRenderer : function(){
       return this.renderer;  
    },
    
    
    setDefaultUrl : function(defaultUrl){
        this.defaultUrl = defaultUrl;
    },
    
    
    abort : function(){
        if(this.transaction){
            YAHOO.util.Connect.abort(this.transaction);
        }
    },
    
    
    isUpdating : function(){
        if(this.transaction){
            return YAHOO.util.Connect.isCallInProgress(this.transaction);
        }
        return false;
    }
};


   YAHOO.ext.UpdateManager.defaults = {
       
         timeout : 30,
         
         
        loadScripts : false,
         
        
        sslBlankUrl : (YAHOO.ext.SSL_SECURE_URL || 'javascript:false'),
        
        disableCaching : false,
        
        showLoadIndicator : true,
        
        indicatorText : '<div class="loading-indicator">Loading...</div>'
   };


YAHOO.ext.UpdateManager.updateElement = function(el, url, params, options){
    var um = getEl(el, true).getUpdateManager();
    YAHOO.ext.util.Config.apply(um, options);
    um.update(url, params, options.callback);
};

YAHOO.ext.UpdateManager.update = YAHOO.ext.UpdateManager.updateElement;
 
YAHOO.ext.UpdateManager.BasicRenderer = function(){};

YAHOO.ext.UpdateManager.BasicRenderer.prototype = {
    
     render : function(el, response, updateManager, callback){
        el.update(response.responseText, updateManager.loadScripts, callback);
    }
};



Date.parseFunctions = {count:0};

Date.parseRegexes = [];

Date.formatFunctions = {count:0};


Date.prototype.dateFormat = function(format) {
    if (Date.formatFunctions[format] == null) {
        Date.createNewFormat(format);
    }
    var func = Date.formatFunctions[format];
    return this[func]();
};


Date.prototype.format = Date.prototype.dateFormat;


Date.createNewFormat = function(format) {
    var funcName = "format" + Date.formatFunctions.count++;
    Date.formatFunctions[format] = funcName;
    var code = "Date.prototype." + funcName + " = function(){return ";
    var special = false;
    var ch = '';
    for (var i = 0; i < format.length; ++i) {
        ch = format.charAt(i);
        if (!special && ch == "\\") {
            special = true;
        }
        else if (special) {
            special = false;
            code += "'" + String.escape(ch) + "' + ";
        }
        else {
            code += Date.getFormatCode(ch);
        }
    }
    eval(code.substring(0, code.length - 3) + ";}");
};


Date.getFormatCode = function(character) {
    switch (character) {
    case "d":
        return "String.leftPad(this.getDate(), 2, '0') + ";
    case "D":
        return "Date.dayNames[this.getDay()].substring(0, 3) + ";
    case "j":
        return "this.getDate() + ";
    case "l":
        return "Date.dayNames[this.getDay()] + ";
    case "S":
        return "this.getSuffix() + ";
    case "w":
        return "this.getDay() + ";
    case "z":
        return "this.getDayOfYear() + ";
    case "W":
        return "this.getWeekOfYear() + ";
    case "F":
        return "Date.monthNames[this.getMonth()] + ";
    case "m":
        return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
    case "M":
        return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
    case "n":
        return "(this.getMonth() + 1) + ";
    case "t":
        return "this.getDaysInMonth() + ";
    case "L":
        return "(this.isLeapYear() ? 1 : 0) + ";
    case "Y":
        return "this.getFullYear() + ";
    case "y":
        return "('' + this.getFullYear()).substring(2, 4) + ";
    case "a":
        return "(this.getHours() < 12 ? 'am' : 'pm') + ";
    case "A":
        return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
    case "g":
        return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
    case "G":
        return "this.getHours() + ";
    case "h":
        return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
    case "H":
        return "String.leftPad(this.getHours(), 2, '0') + ";
    case "i":
        return "String.leftPad(this.getMinutes(), 2, '0') + ";
    case "s":
        return "String.leftPad(this.getSeconds(), 2, '0') + ";
    case "O":
        return "this.getGMTOffset() + ";
    case "T":
        return "this.getTimezone() + ";
    case "Z":
        return "(this.getTimezoneOffset() * -60) + ";
    default:
        return "'" + String.escape(character) + "' + ";
    };
};


Date.parseDate = function(input, format) {
    if (Date.parseFunctions[format] == null) {
        Date.createParser(format);
    }
    var func = Date.parseFunctions[format];
    return Date[func](input);
};


Date.createParser = function(format) {
    var funcName = "parse" + Date.parseFunctions.count++;
    var regexNum = Date.parseRegexes.length;
    var currentGroup = 1;
    Date.parseFunctions[format] = funcName;

    var code = "Date." + funcName + " = function(input){\n"
        + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"
        + "var d = new Date();\n"
        + "y = d.getFullYear();\n"
        + "m = d.getMonth();\n"
        + "d = d.getDate();\n"
        + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
        + "if (results && results.length > 0) {"
    var regex = "";

    var special = false;
    var ch = '';
    for (var i = 0; i < format.length; ++i) {
        ch = format.charAt(i);
        if (!special && ch == "\\") {
            special = true;
        }
        else if (special) {
            special = false;
            regex += String.escape(ch);
        }
        else {
            obj = Date.formatCodeToRegex(ch, currentGroup);
            currentGroup += obj.g;
            regex += obj.s;
            if (obj.g && obj.c) {
                code += obj.c;
            }
        }
    }

    code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
        + "{return new Date(y, m, d, h, i, s);}\n"
        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
        + "{return new Date(y, m, d, h, i);}\n"
        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
        + "{return new Date(y, m, d, h);}\n"
        + "else if (y > 0 && m >= 0 && d > 0)\n"
        + "{return new Date(y, m, d);}\n"
        + "else if (y > 0 && m >= 0)\n"
        + "{return new Date(y, m);}\n"
        + "else if (y > 0)\n"
        + "{return new Date(y);}\n"
        + "}return null;}";

    Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
    eval(code);
};


Date.formatCodeToRegex = function(character, currentGroup) {
    switch (character) {
    case "D":
        return {g:0,
        c:null,
        s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
    case "j":
    case "d":
        return {g:1,
            c:"d = parseInt(results[" + currentGroup + "], 10);\n",
            s:"(\\d{1,2})"};
    case "l":
        return {g:0,
            c:null,
            s:"(?:" + Date.dayNames.join("|") + ")"};
    case "S":
        return {g:0,
            c:null,
            s:"(?:st|nd|rd|th)"};
    case "w":
        return {g:0,
            c:null,
            s:"\\d"};
    case "z":
        return {g:0,
            c:null,
            s:"(?:\\d{1,3})"};
    case "W":
        return {g:0,
            c:null,
            s:"(?:\\d{2})"};
    case "F":
        return {g:1,
            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
            s:"(" + Date.monthNames.join("|") + ")"};
    case "M":
        return {g:1,
            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
            s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
    case "n":
    case "m":
        return {g:1,
            c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
            s:"(\\d{1,2})"};
    case "t":
        return {g:0,
            c:null,
            s:"\\d{1,2}"};
    case "L":
        return {g:0,
            c:null,
            s:"(?:1|0)"};
    case "Y":
        return {g:1,
            c:"y = parseInt(results[" + currentGroup + "], 10);\n",
            s:"(\\d{4})"};
    case "y":
        return {g:1,
            c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
            s:"(\\d{1,2})"};
    case "a":
        return {g:1,
            c:"if (results[" + currentGroup + "] == 'am') {\n"
                + "if (h == 12) { h = 0; }\n"
                + "} else { if (h < 12) { h += 12; }}",
            s:"(am|pm)"};
    case "A":
        return {g:1,
            c:"if (results[" + currentGroup + "] == 'AM') {\n"
                + "if (h == 12) { h = 0; }\n"
                + "} else { if (h < 12) { h += 12; }}",
            s:"(AM|PM)"};
    case "g":
    case "G":
    case "h":
    case "H":
        return {g:1,
            c:"h = parseInt(results[" + currentGroup + "], 10);\n",
            s:"(\\d{1,2})"};
    case "i":
        return {g:1,
            c:"i = parseInt(results[" + currentGroup + "], 10);\n",
            s:"(\\d{2})"};
    case "s":
        return {g:1,
            c:"s = parseInt(results[" + currentGroup + "], 10);\n",
            s:"(\\d{2})"};
    case "O":
        return {g:0,
            c:null,
            s:"[+-]\\d{4}"};
    case "T":
        return {g:0,
            c:null,
            s:"[A-Z]{3}"};
    case "Z":
        return {g:0,
            c:null,
            s:"[+-]\\d{1,5}"};
    default:
        return {g:0,
            c:null,
            s:String.escape(character)};
    }
};

Date.prototype.getTimezone = function() {
    return this.toString().replace(
        /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
        /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
};

Date.prototype.getGMTOffset = function() {
    return (this.getTimezoneOffset() > 0 ? "-" : "+")
        + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
        + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
};

Date.prototype.getDayOfYear = function() {
    var num = 0;
    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    for (var i = 0; i < this.getMonth(); ++i) {
        num += Date.daysInMonth[i];
    }
    return num + this.getDate() - 1;
};

Date.prototype.getWeekOfYear = function() {
    
    var now = this.getDayOfYear() + (4 - this.getDay());
    
    var jan1 = new Date(this.getFullYear(), 0, 1);
    var then = (7 - jan1.getDay() + 4);
    return String.leftPad(((now - then) / 7) + 1, 2, "0");
};

Date.prototype.isLeapYear = function() {
    var year = this.getFullYear();
    return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
};

Date.prototype.getFirstDayOfMonth = function() {
    var day = (this.getDay() - (this.getDate() - 1)) % 7;
    return (day < 0) ? (day + 7) : day;
};

Date.prototype.getLastDayOfMonth = function() {
    var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
    return (day < 0) ? (day + 7) : day;
};

Date.prototype.getDaysInMonth = function() {
    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    return Date.daysInMonth[this.getMonth()];
};


Date.prototype.getSuffix = function() {
    switch (this.getDate()) {
        case 1:
        case 21:
        case 31:
            return "st";
        case 2:
        case 22:
            return "nd";
        case 3:
        case 23:
            return "rd";
        default:
            return "th";
    }
};


Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];


Date.monthNames =
   ["January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"];
    

Date.dayNames =
   ["Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"];


Date.y2kYear = 50;


Date.monthNumbers = {
    Jan:0,
    Feb:1,
    Mar:2,
    Apr:3,
    May:4,
    Jun:5,
    Jul:6,
    Aug:7,
    Sep:8,
    Oct:9,
    Nov:10,
    Dec:11};

YAHOO.ext.TabPanel = function(container, config){
    
    this.el = getEl(container, true);
    
    this.tabPosition = 'top';
    this.currentTabWidth = 0;
    
    this.minTabWidth = 40;
    
    this.maxTabWidth = 250;
    
    this.preferredTabWidth = 175;
    
    this.resizeTabs = false;
    
    this.monitorResize = true;
    
    if(config){
        if(typeof config == 'boolean'){
            this.tabPosition = config ? 'bottom' : 'top';
        }else{
            YAHOO.ext.util.Config.apply(this, config);
        }
    }
    if(this.tabPosition == 'bottom'){
        this.bodyEl = getEl(this.createBody(this.el.dom));
        this.el.addClass('ytabs-bottom');
    }
    this.stripWrap = getEl(this.createStrip(this.el.dom), true);
    this.stripEl = getEl(this.createStripList(this.stripWrap.dom), true);
    this.stripBody = getEl(this.stripWrap.dom.firstChild.firstChild, true);
    if(YAHOO.ext.util.Browser.isIE){
        YAHOO.util.Dom.setStyle(this.stripWrap.dom.firstChild, 'overflow-x', 'hidden');
    }
    if(this.tabPosition != 'bottom'){
    
      this.bodyEl = getEl(this.createBody(this.el.dom));
      this.el.addClass('ytabs-top');
    }
    this.items = [];
    
    this.bodyEl.setStyle('position', 'relative');
    
    
    if(!this.items.indexOf){
        this.items.indexOf = function(o){
            for(var i = 0, len = this.length; i < len; i++){
                if(this[i] == o) return i;
            }
            return -1;
        };
    }
    this.active = null;
    this.onTabChange = new YAHOO.util.CustomEvent('TabItem.onTabChange');
    this.activateDelegate = this.activate.createDelegate(this);
    
    this.events = {
        
        'tabchange': this.onTabChange,
        
        'beforetabchange' : new YAHOO.util.CustomEvent('beforechange')
    };
    
    YAHOO.ext.EventManager.onWindowResize(this.onResize, this, true);
    this.cpad = this.el.getPadding('lr');
    this.hiddenCount = 0;
}

YAHOO.ext.TabPanel.prototype = {
    fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
    
    addTab : function(id, text, content, closable){
        var item = new YAHOO.ext.TabPanelItem(this, id, text, closable);
        this.addTabItem(item);
        if(content){
            item.setContent(content);
        }
        return item;
    },
    
    
    getTab : function(id){
        return this.items[id];
    },
    
    
    hideTab : function(id){
        var t = this.items[id];
        if(!t.isHidden()){
           t.setHidden(true);
           this.hiddenCount++;
           this.autoSizeTabs();
        }
    },
    
    
    unhideTab : function(id){
        var t = this.items[id];
        if(t.isHidden()){
           t.setHidden(false);
           this.hiddenCount--;
           this.autoSizeTabs();
        }
    },
    
    
    addTabItem : function(item){
        this.items[item.id] = item;
        this.items.push(item);
        if(this.resizeTabs){
           item.setWidth(this.currentTabWidth || this.preferredTabWidth)
           this.autoSizeTabs();
        }else{
            item.autoSize();
        }
    },
        
    
    removeTab : function(id){
        var items = this.items;
        var tab = items[id];
        if(!tab) return;
        var index = items.indexOf(tab);
        if(this.active == tab && items.length > 1){
            var newTab = this.getNextAvailable(index);
            if(newTab)newTab.activate();
        }
        this.stripEl.dom.removeChild(tab.pnode.dom);
        if(tab.bodyEl.dom.parentNode == this.bodyEl.dom){ 
            this.bodyEl.dom.removeChild(tab.bodyEl.dom);
        }
        items.splice(index, 1);
        delete this.items[tab.id];
        tab.fireEvent('close', tab);
        tab.purgeListeners();
        this.autoSizeTabs();
    },
    
    getNextAvailable : function(start){
        var items = this.items;
        var index = start;
        
        
        while(index < items.length){
            var item = items[++index];
            if(item && !item.isHidden()){
                return item;
            }
        }
        
        var index = start;
        while(index >= 0){
            var item = items[--index];
            if(item && !item.isHidden()){
                return item;
            }
        }
        return null;
    },
    
    
    disableTab : function(id){
        var tab = this.items[id];
        if(tab && this.active != tab){
            tab.disable();
        }
    },
    
    
    enableTab : function(id){
        var tab = this.items[id];
        tab.enable();
    },
    
    
    activate : function(id){
        var tab = this.items[id];
        if(tab == this.active){
            return tab;
        } 
        var e = {};
        this.fireEvent('beforetabchange', this, e, tab);
        if(e.cancel !== true && !tab.disabled){
            if(this.active){
                this.active.hide();
            }
            this.active = this.items[id];
            this.active.show();
            this.onTabChange.fireDirect(this, this.active);
        }
        return tab;
    },
    
    
    getActiveTab : function(){
        return this.active;
    },
    
    
    syncHeight : function(targetHeight){
        var height = (targetHeight || this.el.getHeight())-this.el.getBorderWidth('tb')-this.el.getPadding('tb');
        var bm = this.bodyEl.getMargins();
        var newHeight = height-(this.stripWrap.getHeight()||0)-(bm.top+bm.bottom);
        this.bodyEl.setHeight(newHeight);
        return newHeight; 
    },
    
    onResize : function(){
        if(this.monitorResize){
            this.autoSizeTabs();
        }
    },

    
    beginUpdate : function(){
        this.updating = true;    
    },
    
    
    endUpdate : function(){
        this.updating = false;
        this.autoSizeTabs();  
    },
    
    
    autoSizeTabs : function(){
        var count = this.items.length;
        var vcount = count - this.hiddenCount;
        if(!this.resizeTabs || count < 1 || vcount < 1 || this.updating) return;
        var w = Math.max(this.el.getWidth() - this.cpad, 10);
        var availWidth = Math.floor(w / vcount);
        var b = this.stripBody;
        if(b.getWidth() > w){
            var tabs = this.items;
            this.setTabWidth(Math.max(availWidth, this.minTabWidth));
            if(availWidth < this.minTabWidth){
                
            }
        }else{
            if(this.currentTabWidth < this.preferredTabWidth){
                this.setTabWidth(Math.min(availWidth, this.preferredTabWidth));
            }
        }
    },
    
    
     getCount : function(){
         return this.items.length;  
     },
    
    
    setTabWidth : function(width){
        this.currentTabWidth = width;
        for(var i = 0, len = this.items.length; i < len; i++) {
        	if(!this.items[i].isHidden())this.items[i].setWidth(width);
        }
    },
    
    
    destroy : function(removeEl){
        YAHOO.ext.EventManager.removeResizeListener(this.onResize, this);
        for(var i = 0, len = this.items.length; i < len; i++){
            this.items[i].purgeListeners();
        }
        if(removeEl === true){
            this.el.update('');
            this.el.remove();
        }
    }
};

 
YAHOO.ext.TabPanelItem = function(tabPanel, id, text, closable){
    
    this.tabPanel = tabPanel;
    
    this.id = id;
    
    this.disabled = false;
    
    this.text = text;
    
    this.loaded = false;
    this.closable = closable;
    
    
    this.bodyEl = getEl(tabPanel.createItemBody(tabPanel.bodyEl.dom, id));
    this.bodyEl.setVisibilityMode(YAHOO.ext.Element.VISIBILITY);
    this.bodyEl.setStyle('display', 'block');
    this.bodyEl.setStyle('zoom', '1');
    this.hideAction();
    
    var els = tabPanel.createStripElements(tabPanel.stripEl.dom, text, closable);
    
    this.el = getEl(els.el, true);
    this.inner = getEl(els.inner, true);
    this.textEl = getEl(this.el.dom.firstChild.firstChild.firstChild, true);
    this.pnode = getEl(els.el.parentNode, true);
    this.el.mon('click', this.onTabClick, this, true);
    
    if(closable){
        var c = getEl(els.close, true);
        c.dom.title = this.closeText;
        c.addClassOnOver('close-over');
        c.mon('click', this.closeClick, this, true);
     }
    
    
    this.onActivate = new YAHOO.util.CustomEvent('TabItem.onActivate');
    this.onDeactivate = new YAHOO.util.CustomEvent('TabItem.onDeactivate');
    
    this.events = {
         
        'activate': this.onActivate,
        
        'beforeclose': new YAHOO.util.CustomEvent('beforeclose'),
        
         'close': new YAHOO.util.CustomEvent('close'),
        
         'deactivate' : this.onDeactivate  
    };
    this.hidden = false;
};

YAHOO.ext.TabPanelItem.prototype = {
    fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : function(){
       YAHOO.ext.util.Observable.prototype.purgeListeners.call(this);
       this.el.removeAllListeners(); 
    },
    
    show : function(){
        this.pnode.addClass('on');
        this.showAction();
        if(YAHOO.ext.util.Browser.isOpera){
            this.tabPanel.stripWrap.repaint();
        }
        this.onActivate.fireDirect(this.tabPanel, this); 
    },
    
    
    isActive : function(){
        return this.tabPanel.getActiveTab() == this;  
    },
    
    
    hide : function(){
        this.pnode.removeClass('on');
        this.hideAction();
        this.onDeactivate.fireDirect(this.tabPanel, this); 
    },
    
    hideAction : function(){
        this.bodyEl.setStyle('position', 'absolute');
        this.bodyEl.setLeft('-20000px');
        this.bodyEl.setTop('-20000px');
        this.bodyEl.hide();
    },
    
    showAction : function(){
        this.bodyEl.setStyle('position', 'relative');
        this.bodyEl.setTop('');
        this.bodyEl.setLeft('');
        this.bodyEl.show();
        this.tabPanel.el.repaint.defer(1);
    },
    
    
    setTooltip : function(text){
        this.textEl.dom.title = text;
    },
    
    onTabClick : function(e){
        e.preventDefault();
        this.tabPanel.activate(this.id);
    },
    
    getWidth : function(){
        return this.inner.getWidth();  
    },
    
    setWidth : function(width){
        var iwidth = width - this.pnode.getPadding("lr");
        this.inner.setWidth(iwidth);
        this.textEl.setWidth(iwidth-this.inner.getPadding('lr'));
        this.pnode.setWidth(width);
    },
    
    setHidden : function(hidden){
        this.hidden = hidden;
        this.pnode.setStyle('display', hidden ? 'none' : '');  
    },
    
    
    isHidden : function(){
        return this.hidden;  
    },
    
    
    getText : function(){
        return this.text;
    },
    
    autoSize : function(){
        this.el.beginMeasure();
        this.textEl.setWidth(1);
        this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding('lr'));
        this.el.endMeasure();
    },
    
    
    setText : function(text){
        this.text = text;
        this.textEl.update(text);
        this.textEl.dom.title = text;
        if(!this.tabPanel.resizeTabs){
            this.autoSize();
        }
    },
    
    activate : function(){
        this.tabPanel.activate(this.id);
    },
    
    
    disable : function(){
        if(this.tabPanel.active != this){
            this.disabled = true;
            this.pnode.addClass('disabled');
        }
    },
    
    
    enable : function(){
        this.disabled = false;
        this.pnode.removeClass('disabled');
    },
    
    
    setContent : function(content, loadScripts){
        this.bodyEl.update(content, loadScripts);
    },
    
    
    getUpdateManager : function(){
        return this.bodyEl.getUpdateManager();
    },
    
    
    setUrl : function(url, params, loadOnce){
        if(this.refreshDelegate){
            this.onActivate.unsubscribe(this.refreshDelegate);
        }
        this.refreshDelegate = this._handleRefresh.createDelegate(this, [url, params, loadOnce]);
        this.onActivate.subscribe(this.refreshDelegate);
        return this.bodyEl.getUpdateManager();
    },
    
    
    _handleRefresh : function(url, params, loadOnce){
        if(!loadOnce || !this.loaded){
            var updater = this.bodyEl.getUpdateManager();
            updater.update(url, params, this._setLoaded.createDelegate(this));
        }
    },
    
    
    refresh : function(){
        if(this.refreshDelegate){
           this.loaded = false;
           this.refreshDelegate();
        }
    }, 
    
    
    _setLoaded : function(){
        this.loaded = true;
    },
    
    
    closeClick : function(e){
        var e = {};
        this.fireEvent('beforeclose', this, e);
        if(e.cancel !== true){
            this.tabPanel.removeTab(this.id);
        }
    },
    
    closeText : 'Close this tab'
};


YAHOO.ext.TabPanel.prototype.createStrip = function(container){
    var strip = document.createElement('div');
    strip.className = 'ytab-wrap';
    container.appendChild(strip);
    return strip;
};

YAHOO.ext.TabPanel.prototype.createStripList = function(strip){
    
    strip.innerHTML = '<div class="ytab-strip-wrap"><table class="ytab-strip" cellspacing="0" cellpadding="0" border="0"><tbody><tr></tr></tbody></table></div>';
    return strip.firstChild.firstChild.firstChild.firstChild;
};

YAHOO.ext.TabPanel.prototype.createBody = function(container){
    var body = document.createElement('div');
    YAHOO.util.Dom.generateId(body, 'tab-body');
    YAHOO.util.Dom.addClass(body, 'yui-ext-tabbody');
    container.appendChild(body);
    return body;
};

YAHOO.ext.TabPanel.prototype.createItemBody = function(bodyEl, id){
    var body = YAHOO.util.Dom.get(id);
    if(!body){
        body = document.createElement('div');
        body.id = id;
    }
    YAHOO.util.Dom.addClass(body, 'yui-ext-tabitembody');
    bodyEl.insertBefore(body, bodyEl.firstChild);
    return body;
};

YAHOO.ext.TabPanel.prototype.createStripElements = function(stripEl, text, closable){
    var td = document.createElement('td');
    stripEl.appendChild(td);
    if(closable){
        td.className = "ytab-closable";
        if(!this.closeTpl){
            this.closeTpl = new YAHOO.ext.Template(
               '<a href="#" class="ytab-right"><span class="ytab-left"><em class="ytab-inner">' +
               '<span unselectable="on" title="{text}" class="ytab-text">{text}</span>' +
               '<div unselectable="on" class="close-icon">&#160;</div></em></span></a>'
            );
        }
        var el = this.closeTpl.overwrite(td, {'text': text});
        var close = el.getElementsByTagName('div')[0];
        var inner = el.getElementsByTagName('em')[0];
        return {'el': el, 'close': close, 'inner': inner};
    } else {
        if(!this.tabTpl){
            this.tabTpl = new YAHOO.ext.Template(
               '<a href="#" class="ytab-right"><span class="ytab-left"><em class="ytab-inner">' +
               '<span unselectable="on" title="{text}" class="ytab-text">{text}</span></em></span></a>'
            );
        }
        var el = this.tabTpl.overwrite(td, {'text': text});
        var inner = el.getElementsByTagName('em')[0];
        return {'el': el, 'inner': inner};
    }
};


YAHOO.ext.Actor = function(element, animator, selfCapture){
    this.el = YAHOO.ext.Element.get(element, true); 
    YAHOO.ext.Actor.superclass.constructor.call(this, element, true);
    this.onCapture = new YAHOO.util.CustomEvent('Actor.onCapture');
    if(animator){
        
        animator.addActor(this);
    }
    
    this.capturing = selfCapture;
    this.playlist = selfCapture ? new YAHOO.ext.Animator.AnimSequence() : null;
};

YAHOO.extendX(YAHOO.ext.Actor, YAHOO.ext.Element);


YAHOO.ext.Actor.prototype.capture = function(action){
    if(this.playlist != null){
        this.playlist.add(action);
    }
    this.onCapture.fireDirect(this, action);
    return action;
};


YAHOO.ext.Actor.overrideAnimation = function(method, animParam, onParam){
    return function(){
        if(!this.capturing){
            return method.apply(this, arguments);
        }
        var args = Array.prototype.slice.call(arguments, 0);
        if(args[animParam] === true){
            return this.capture(new YAHOO.ext.Actor.AsyncAction(this, method, args, onParam));
        }else{
            return this.capture(new YAHOO.ext.Actor.Action(this, method, args));
        }
    };
};


YAHOO.ext.Actor.overrideBasic = function(method){
    return function(){
        if(!this.capturing){
            return method.apply(this, arguments);
        }
        var args = Array.prototype.slice.call(arguments, 0);
        return this.capture(new YAHOO.ext.Actor.Action(this, method, args));
    };
};



YAHOO.ext.Actor.prototype.setVisibilityMode = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setVisibilityMode);

YAHOO.ext.Actor.prototype.enableDisplayMode = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.enableDisplayMode);

YAHOO.ext.Actor.prototype.focus = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.focus);

YAHOO.ext.Actor.prototype.addClass = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.addClass);

YAHOO.ext.Actor.prototype.removeClass = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.removeClass);

YAHOO.ext.Actor.prototype.replaceClass = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.replaceClass);

YAHOO.ext.Actor.prototype.setStyle = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setStyle);

YAHOO.ext.Actor.prototype.setLeft = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setLeft);

YAHOO.ext.Actor.prototype.setTop = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setTop);

YAHOO.ext.Actor.prototype.setAbsolutePositioned = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setAbsolutePositioned);

YAHOO.ext.Actor.prototype.setRelativePositioned = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setRelativePositioned);

YAHOO.ext.Actor.prototype.clearPositioning = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.clearPositioning);

YAHOO.ext.Actor.prototype.setPositioning = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.setPositioning);

YAHOO.ext.Actor.prototype.clip = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.clip);

YAHOO.ext.Actor.prototype.unclip = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.unclip);

YAHOO.ext.Actor.prototype.clearOpacity = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.clearOpacity);

YAHOO.ext.Actor.prototype.update = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.update);

YAHOO.ext.Actor.prototype.remove = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.remove);
YAHOO.ext.Actor.prototype.fitToParent = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.fitToParent);
YAHOO.ext.Actor.prototype.appendChild = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.appendChild);
YAHOO.ext.Actor.prototype.createChild = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.createChild);
YAHOO.ext.Actor.prototype.appendTo = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.appendTo);
YAHOO.ext.Actor.prototype.insertBefore = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.insertBefore);
YAHOO.ext.Actor.prototype.insertAfter = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.insertAfter);
YAHOO.ext.Actor.prototype.wrap = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.wrap);
YAHOO.ext.Actor.prototype.replace = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.replace);
YAHOO.ext.Actor.prototype.insertHtml = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.insertHtml);
YAHOO.ext.Actor.prototype.set = YAHOO.ext.Actor.overrideBasic(YAHOO.ext.Actor.superclass.set);


YAHOO.ext.Actor.prototype.load = function(){
   if(!this.capturing){
        return YAHOO.ext.Actor.superclass.load.apply(this, arguments);
   }
   var args = Array.prototype.slice.call(arguments, 0);
   return this.capture(new YAHOO.ext.Actor.AsyncAction(this, YAHOO.ext.Actor.superclass.load, 
        args, 2));
};


YAHOO.ext.Actor.prototype.animate = function(args, duration, onComplete, easing, animType){
    if(!this.capturing){
        return YAHOO.ext.Actor.superclass.animate.apply(this, arguments);
    }
    return this.capture(new YAHOO.ext.Actor.AsyncAction(this, YAHOO.ext.Actor.superclass.animate, 
        [args, duration, onComplete, easing, animType], 2));
};


YAHOO.ext.Actor.prototype.setVisible = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setVisible, 1, 3);

YAHOO.ext.Actor.prototype.toggle = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.toggle, 0, 2);

YAHOO.ext.Actor.prototype.setXY = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setXY, 1, 3);

YAHOO.ext.Actor.prototype.setLocation = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setLocation, 2, 4);

YAHOO.ext.Actor.prototype.setWidth = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setWidth, 1, 3);

YAHOO.ext.Actor.prototype.setHeight = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setHeight, 1, 3);

YAHOO.ext.Actor.prototype.setSize = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setSize, 2, 4);

YAHOO.ext.Actor.prototype.setBounds = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setBounds, 4, 6);

YAHOO.ext.Actor.prototype.setOpacity = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setOpacity, 1, 3);

YAHOO.ext.Actor.prototype.moveTo = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.moveTo, 2, 4);

YAHOO.ext.Actor.prototype.move = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.move, 2, 4);

YAHOO.ext.Actor.prototype.alignTo = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.alignTo, 3, 5);

YAHOO.ext.Actor.prototype.hide = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.hide, 0, 2);

YAHOO.ext.Actor.prototype.show = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.show, 0, 2);


YAHOO.ext.Actor.prototype.setBox = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setBox, 2, 4);


YAHOO.ext.Actor.prototype.autoHeight = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.autoHeight, 0, 2);

YAHOO.ext.Actor.prototype.setX = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setX, 1, 3);

YAHOO.ext.Actor.prototype.setY = YAHOO.ext.Actor.overrideAnimation(YAHOO.ext.Actor.superclass.setY, 1, 3);


YAHOO.ext.Actor.prototype.startCapture = function(){
    this.capturing = true;
    this.playlist = new YAHOO.ext.Animator.AnimSequence();
 };
 
 
 YAHOO.ext.Actor.prototype.stopCapture = function(){
     this.capturing = false;
 };


YAHOO.ext.Actor.prototype.clear = function(){
    this.playlist = new YAHOO.ext.Animator.AnimSequence();
};


YAHOO.ext.Actor.prototype.play = function(oncomplete){
    this.capturing = false;
    if(this.playlist){
        this.playlist.play(oncomplete);
    }
 };


YAHOO.ext.Actor.prototype.addCall = function(fcn, args, scope){
    if(!this.capturing){
        fcn.apply(scope || this, args || []);
    }else{
        this.capture(new YAHOO.ext.Actor.Action(scope, fcn, args || []));
    }
};


YAHOO.ext.Actor.prototype.addAsyncCall = function(fcn, callbackIndex, args, scope){
    if(!this.capturing){
        fcn.apply(scope || this, args || []);
    }else{
       this.capture(new YAHOO.ext.Actor.AsyncAction(scope, fcn, args || [], callbackIndex));
    }
};
 

YAHOO.ext.Actor.prototype.pause = function(seconds){
    this.capture(new YAHOO.ext.Actor.PauseAction(seconds));
};
 

YAHOO.ext.Actor.prototype.shake = function(){
    this.move('left', 20, true, .05);
    this.move('right', 40, true, .05);
    this.move('left', 40, true, .05);
    this.move('right', 20, true, .05);
};


YAHOO.ext.Actor.prototype.bounce = function(){
    this.move('up', 20, true, .05);
    this.move('down', 40, true, .05);
    this.move('up', 40, true, .05);
    this.move('down', 20, true, .05);
};


YAHOO.ext.Actor.prototype.blindShow = function(anchor, newSize, duration, easing){
    var size = newSize || this.getSize();
    this.clip();
    this.setVisible(true);
    anchor = anchor.toLowerCase();
    switch(anchor){
        case 't':
        case 'top':
            this.setHeight(1);
            this.setHeight(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
        case 'l':
        case 'left':
            this.setWidth(1);
            this.setWidth(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
    }
    this.unclip();
    return size;
};


YAHOO.ext.Actor.prototype.blindHide = function(anchor, duration, easing){
    var size = this.getSize();
    this.clip();
    anchor = anchor.toLowerCase();
    switch(anchor){
        case 't':
        case 'top':
            this.setSize(size.width, 1, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
        case 'l':
        case 'left':
            this.setSize(1, size.height, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
        case 'r':
        case 'right':
            this.animate({width: {to: 1}, points: {by: [this.getWidth(), 0]}}, 
            duration || .5, null, YAHOO.util.Easing.easeIn, YAHOO.util.Motion);
            this.setVisible(false);
        break;
        case 'b':
        case 'bottom':
            this.animate({height: {to: 1}, points: {by: [0, this.getHeight()]}}, 
            duration || .5, null, YAHOO.util.Easing.easeIn, YAHOO.util.Motion);
            this.setVisible(false);
        break;
    }
    return size;
};


YAHOO.ext.Actor.prototype.slideShow = function(anchor, newSize, duration, easing, clearPositioning){
    var size = newSize || this.getSize();
    this.clip();
    var firstChild = this.dom.firstChild;
    if(!firstChild || (firstChild.nodeName && "#TEXT" == firstChild.nodeName.toUpperCase())) { 
        this.blindShow(anchor, newSize, duration, easing);
        return;
    }
    var child = YAHOO.ext.Element.get(firstChild, true);
    var pos = child.getPositioning();
    this.addCall(child.setAbsolutePositioned, null, child);
    this.setVisible(true);
    anchor = anchor.toLowerCase();
    switch(anchor){
        case 't':
        case 'top':
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['top', ''], child);
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['bottom', '0px'], child);
            this.setHeight(1);
            this.setHeight(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
        case 'l':
        case 'left':
            this.addCall(child.setStyle, ['left', ''], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.addCall(child.setStyle, ['right', '0px'], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.setWidth(1);
            this.setWidth(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
        case 'r':
        case 'right':
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.setWidth(1);
            this.setWidth(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
        case 'b':
        case 'bottom':
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.setHeight(1);
            this.setHeight(newSize, true, duration || .5, null, easing || YAHOO.util.Easing.easeOut);
        break;
    }
    if(clearPositioning !== false){
      this.addCall(child.setPositioning, [pos], child);
    }
    this.unclip();
    return size;
};


YAHOO.ext.Actor.prototype.slideHide = function(anchor, duration, easing){
    var size = this.getSize();
    this.clip();
    var firstChild = this.dom.firstChild;
    if(!firstChild || (firstChild.nodeName && "#TEXT" == firstChild.nodeName.toUpperCase())) { 
        this.blindHide(anchor, duration, easing);
        return;
    }
    var child = YAHOO.ext.Element.get(firstChild, true);
    var pos = child.getPositioning();
    this.addCall(child.setAbsolutePositioned, null, child);
    anchor = anchor.toLowerCase();
    switch(anchor){
        case 't':
        case 'top':
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['top', ''], child);
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['bottom', '0px'], child);
            this.setSize(size.width, 1, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
        case 'l':
        case 'left':
            this.addCall(child.setStyle, ['left', ''], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.addCall(child.setStyle, ['right', '0px'], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.setSize(1, size.height, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
        case 'r':
        case 'right':
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.setSize(1, size.height, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
        case 'b':
        case 'bottom':
            this.addCall(child.setStyle, ['right', ''], child);
            this.addCall(child.setStyle, ['top', '0px'], child);
            this.addCall(child.setStyle, ['left', '0px'], child);
            this.addCall(child.setStyle, ['bottom', ''], child);
            this.setSize(size.width, 1, true, duration || .5, null, easing || YAHOO.util.Easing.easeIn);
            this.setVisible(false);
        break;
    }
    this.addCall(child.setPositioning, [pos], child);
    return size;
};


YAHOO.ext.Actor.prototype.squish = function(duration){
    var size = this.getSize();
    this.clip();
    this.setSize(1, 1, true, duration || .5);
    this.setVisible(false);
    return size;
};


YAHOO.ext.Actor.prototype.appear = function(duration){
    this.setVisible(true, true, duration);
};


YAHOO.ext.Actor.prototype.fade = function(duration){
    this.setVisible(false, true, duration);
};


YAHOO.ext.Actor.prototype.switchOff = function(duration){
    this.clip();
    this.setVisible(false, true, .1);
    this.clearOpacity();
    this.setVisible(true);
    this.animate({height: {to: 1}, points: {by: [0, this.getHeight()/2]}}, 
            duration || .5, null, YAHOO.util.Easing.easeOut, YAHOO.util.Motion);
    this.setVisible(false);
};


YAHOO.ext.Actor.prototype.highlight = function(color, fromColor, duration, attribute){
    attribute = attribute || 'background-color';
    var original = this.getStyle(attribute);
    fromColor = fromColor || ((original && original != '' && original != 'transparent') ? original : '#FFFFFF');
    var cfg = {};
    cfg[attribute] = {to: color, from: fromColor};
    this.setVisible(true);
    this.animate(cfg, duration || .5, null, YAHOO.util.Easing.bounceOut, YAHOO.util.ColorAnim);
    this.setStyle(attribute, original);
};


YAHOO.ext.Actor.prototype.pulsate = function(count, duration){
    count = count || 3;
    for(var i = 0; i < count; i++){
        this.toggle(true, duration || .25);
        this.toggle(true, duration || .25);
    }
};


YAHOO.ext.Actor.prototype.dropOut = function(duration){
    this.animate({opacity: {to: 0}, points: {by: [0, this.getHeight()]}}, 
            duration || .5, null, YAHOO.util.Easing.easeIn, YAHOO.util.Motion);
    this.setVisible(false);
};


YAHOO.ext.Actor.prototype.moveOut = function(anchor, duration, easing){
    var Y = YAHOO.util;
    var vw = Y.Dom.getViewportWidth();
    var vh = Y.Dom.getViewportHeight();
    var cpoints = this.getCenterXY()
    var centerX = cpoints[0];
    var centerY = cpoints[1];
    var anchor = anchor.toLowerCase();
    var p;
    switch(anchor){
        case 't':
        case 'top':
            p = [centerX, -this.getHeight()];
        break;
        case 'l':
        case 'left':
            p = [-this.getWidth(), centerY];
        break;
        case 'r':
        case 'right':
            p = [vw+this.getWidth(), centerY];
        break;
        case 'b':
        case 'bottom':
            p = [centerX, vh+this.getHeight()];
        break;
        case 'tl':
        case 'top-left':
            p = [-this.getWidth(), -this.getHeight()];
        break;
        case 'bl':
        case 'bottom':
            p = [-this.getWidth(), vh+this.getHeight()];
        break;
        case 'br':
        case 'bottom-right':
            p = [vw+this.getWidth(), vh+this.getHeight()];
        break;
        case 'tr':
        case 'top-right':
            p = [vw+this.getWidth(), -this.getHeight()];
        break;
    }
    this.moveTo(p[0], p[1], true, duration || .35, null, easing || Y.Easing.easeIn);
    this.setVisible(false);
};


YAHOO.ext.Actor.prototype.moveIn = function(anchor, to, duration, easing){
    to = to || this.getCenterXY();
    this.moveOut(anchor, .01);
    this.setVisible(true);
    this.setXY(to, true, duration || .35, null, easing || YAHOO.util.Easing.easeOut);
};

YAHOO.ext.Actor.prototype.frame = function(color, count, duration){
    color = color || "red";
    count = count || 3;
    duration = duration || .5;
    var frameFn = function(callback){
        var box = this.getBox();
        var animFn = function(){ 
            var proxy = this.createProxy({
                 tag:"div",
                 style:{
                    visbility:"hidden",
                    position:"absolute",
                    zIndex:this.getStyle("zIndex"),
                    border:"0px solid " + color
                 }
              });
            var scale = proxy.isBorderBox() ? 2 : 1;
            proxy.animate({
                top:{from:box.y, to:box.y - 20},
                left:{from:box.x, to:box.x - 20},
                borderWidth:{from:0, to:10},
                opacity:{from:1, to:0},
                height:{from:box.height, to:(box.height + (20*scale))},
                width:{from:box.width, to:(box.width + (20*scale))}
            }, duration, function(){
                proxy.remove();
            });
            if(--count > 0){
                 animFn.defer((duration/2)*1000, this);
            }else{
                if(typeof callback == 'function'){
                    callback();
                }
            }
       }
       animFn.call(this);
   }
   this.addAsyncCall(frameFn, 0, null, this);
};

YAHOO.ext.Actor.Action = function(actor, method, args){
      this.actor = actor;
      this.method = method;
      this.args = args;
};
  
YAHOO.ext.Actor.Action.prototype = {
    play : function(onComplete){
        this.method.apply(this.actor || window, this.args);
        onComplete();
    }  
};


YAHOO.ext.Actor.AsyncAction = function(actor, method, args, onIndex){
    YAHOO.ext.Actor.AsyncAction.superclass.constructor.call(this, actor, method, args);
    this.onIndex = onIndex;
    this.originalCallback = this.args[onIndex];
};

YAHOO.extendX(YAHOO.ext.Actor.AsyncAction, YAHOO.ext.Actor.Action);

YAHOO.ext.Actor.AsyncAction.prototype.play = function(onComplete){
    var callbackArg = this.originalCallback ? 
                        this.originalCallback.createSequence(onComplete) : onComplete;
    this.args[this.onIndex] = callbackArg;
    this.method.apply(this.actor, this.args);
};


YAHOO.ext.Actor.PauseAction = function(seconds){
    this.seconds = seconds;
};
YAHOO.ext.Actor.PauseAction.prototype = {
    play : function(onComplete){
        setTimeout(onComplete, this.seconds * 1000);
    }
};
 
YAHOO.ext.Animator = function(){
    this.actors = [];
    this.playlist = new YAHOO.ext.Animator.AnimSequence();
    this.captureDelegate = this.capture.createDelegate(this);
    this.playDelegate = this.play.createDelegate(this);
    this.syncing = false;
    this.stopping = false;
    this.playing = false;
    for(var i = 0; i < arguments.length; i++){
        this.addActor(arguments[i]);
    }
};
 
YAHOO.ext.Animator.prototype = {
 
     capture : function(actor, action){
		  if(this.syncing){
			   if(!this.syncMap[actor.id]){
					this.syncMap[actor.id] = new YAHOO.ext.Animator.AnimSequence();
			   }
			   this.syncMap[actor.id].add(action);
		  }else{
			   this.playlist.add(action);
		  }
	 },
    
    
     addActor : function(actor){
		  actor.onCapture.subscribe(this.captureDelegate);
		  this.actors.push(actor);
	 },
    
    
    
     startCapture : function(clearPlaylist){
		  for(var i = 0; i < this.actors.length; i++){
			   var a = this.actors[i];
			   if(!this.isCapturing(a)){
					a.onCapture.subscribe(this.captureDelegate);
			   }
			   a.capturing = true;
		  }
		  if(clearPlaylist){
			   this.playlist = new YAHOO.ext.Animator.AnimSequence();
		  }
     },
     
     
     isCapturing : function(actor){
		  var subscribers = actor.onCapture.subscribers;
		  if(subscribers){
			   for(var i = 0; i < subscribers.length; i++){
					if(subscribers[i] && subscribers[i].contains(this.captureDelegate)){
						 return true;
					}
			   }
		  }
		  return false;
     },
     
     
     stopCapture : function(){
		  for(var i = 0; i < this.actors.length; i++){
			   var a = this.actors[i];
			   a.onCapture.unsubscribe(this.captureDelegate);
			   a.capturing = false;
		  }
     },
     
     
	 beginSync : function(){
		  this.syncing = true;
		  this.syncMap = {};
     },
     
     
	 endSync : function(){
		  this.syncing = false;
		  var composite = new YAHOO.ext.Animator.CompositeSequence();
		  for(key in this.syncMap){
			   if(typeof this.syncMap[key] != 'function'){
					composite.add(this.syncMap[key]);
			   }
		  }
		  this.playlist.add(composite);
		  this.syncMap = null;
     },
     
    
	 play : function(oncomplete){
		  if(this.playing) return; 
		  this.stopCapture();
		  this.playlist.play(oncomplete);
	 },
    
    
	 stop : function(){
		  this.playlist.stop();
	 },
    
    
	 isPlaying : function(){
		  return this.playlist.isPlaying();
	 },
    
	 clear : function(){
		  this.playlist = new YAHOO.ext.Animator.AnimSequence();
     },
     
    
     addCall : function(fcn, args, scope){
		  this.playlist.add(new YAHOO.ext.Actor.Action(scope, fcn, args || []));
     },
     
     
	 addAsyncCall : function(fcn, callbackIndex, args, scope){
		  this.playlist.add(new YAHOO.ext.Actor.AsyncAction(scope, fcn, args || [], callbackIndex));
     },
     
     
	 pause : function(seconds){
		  this.playlist.add(new YAHOO.ext.Actor.PauseAction(seconds));
     }
     
};

YAHOO.ext.Animator.select = function(selector){
	 var els;
	 if(typeof selector == 'string'){
		  els = YAHOO.ext.Element.selectorFunction(selector);
	 }else if(selector instanceof Array){
		  els = selector;
	 }else{
		  throw 'Invalid selector';
	 }
	 return new YAHOO.ext.AnimatorComposite(els);
};
var getActors = YAHOO.ext.Animator.select;


YAHOO.ext.AnimatorComposite = function(els){
	 this.animator = new YAHOO.ext.Animator();
	 this.addElements(els);
	 this.syncAnims = true;
};
YAHOO.ext.AnimatorComposite.prototype = {
	 isComposite: true,
    
	 addElements : function(els){
		  if(!els) return this;
		  var anim = this.animator;
		  for(var i = 0, len = els.length; i < len; i++) {
			   anim.addActor(new YAHOO.ext.Actor(els[i]));
		  }
		  anim.startCapture();
		  return this;
	 },
    
	 sequence : function(){
		  this.syncAnims = false;
		  return this;
	 },
    
	 sync : function(){
		  this.syncAnims = true;
		  return this;
	 },
	 invoke : function(fn, args){
		  var els = this.animator.actors;
		  if(this.syncAnims) this.animator.beginSync();
		  for(var i = 0, len = els.length; i < len; i++) {
			   YAHOO.ext.Actor.prototype[fn].apply(els[i], args);
		  }
		  if(this.syncAnims) this.animator.endSync();
		  return this;
	 },
    
	 play : function(callback){
		  this.animator.play(callback);
		  return this;
	 },
    
	 reset : function(callback){
		  this.animator.startCapture(true);
		  return this;
	 },
    
	 pause : function(seconds){
		  this.animator.pause(seconds);
		  return this;
	 },
    
	 getAnimator : function(){
		  return this.animator;
	 },
    
	 each : function(fn, scope){
		  var els = this.animator.actors;
		  if(this.syncAnims) this.animator.beginSync();
		  for(var i = 0, len = els.length; i < len; i++){
			   fn.call(scope || els[i], els[i], this, i);
		  }
		  if(this.syncAnims) this.animator.endSync();
		  return this;
	 },
    
     addCall : function(fcn, args, scope){
		  this.animator.addCall(fcn, args, scope);
		  return this;
	 },
    
	 addAsyncCall : function(fcn, callbackIndex, args, scope){
		  this.animator.addAsyncCall(fcn, callbackIndex, args, scope);
		  return this;
	 }
};
for(var fnName in YAHOO.ext.Actor.prototype){
	 if(typeof YAHOO.ext.Actor.prototype[fnName] == 'function'){
		  YAHOO.ext.CompositeElement.createCall(YAHOO.ext.AnimatorComposite.prototype, fnName);
	 }
}


YAHOO.ext.Animator.AnimSequence = function(){
	 this.actions = [];
	 this.nextDelegate = this.next.createDelegate(this);
	 this.playDelegate = this.play.createDelegate(this);
	 this.oncomplete = null;
	 this.playing = false;
	 this.stopping = false;
	 this.actionIndex = -1;
};
 
YAHOO.ext.Animator.AnimSequence.prototype = {
 
	 add : function(action){
		  this.actions.push(action);
	 },
    
	 next : function(){
		  if(this.stopping){
			   this.playing = false;
			   if(this.oncomplete){
					this.oncomplete(this, false);
			   }
			   return;
		  }
		  var nextAction = this.actions[++this.actionIndex];
		  if(nextAction){
			   nextAction.play(this.nextDelegate);
		  }else{
			   this.playing = false;
			   if(this.oncomplete){
					this.oncomplete(this, true);
			   }
		  }
	 },
    
	 play : function(oncomplete){
		  if(this.playing) return; 
		  this.oncomplete = oncomplete;
		  this.stopping = false;
		  this.playing = true;
		  this.actionIndex = -1;
		  this.next();
	 },
    
	 stop : function(){
		  this.stopping = true;
	 },
    
	 isPlaying : function(){
		  return this.playing;
	 },
    
	 clear : function(){
		  this.actions = [];
	 },
     
	 addCall : function(fcn, args, scope){
		  this.actions.push(new YAHOO.ext.Actor.Action(scope, fcn, args || []));
     },
     
     addAsyncCall : function(fcn, callbackIndex, args, scope){
		  this.actions.push(new YAHOO.ext.Actor.AsyncAction(scope, fcn, args || [], callbackIndex));
     },
     
     pause : function(seconds){
		  this.actions.push(new YAHOO.ext.Actor.PauseAction(seconds));
     }
     
};

YAHOO.ext.Animator.CompositeSequence = function(){
	 this.sequences = [];
	 this.completed = 0;
	 this.trackDelegate = this.trackCompletion.createDelegate(this);
};

YAHOO.ext.Animator.CompositeSequence.prototype = {
	 add : function(sequence){
		  this.sequences.push(sequence);
	 },
	 
	 play : function(onComplete){
		  this.completed = 0;
		  if(this.sequences.length < 1){
			   if(onComplete)onComplete();
			   return;
		  }
		  this.onComplete = onComplete;
		  for(var i = 0; i < this.sequences.length; i++){
			   this.sequences[i].play(this.trackDelegate);
		  }
	 },
	 
	 trackCompletion : function(){
		  ++this.completed;
		  if(this.completed >= this.sequences.length && this.onComplete){
			   this.onComplete();
		  }
	 },
	 
	 stop : function(){
		  for(var i = 0; i < this.sequences.length; i++){
			   this.sequences[i].stop();
		  }
	 },
	 
	 isPlaying : function(){
		  for(var i = 0; i < this.sequences.length; i++){
			   if(this.sequences[i].isPlaying()){
					return true;
			   }
		  }
		  return false;
	 }
};

YAHOO.ext.Toolbar = function(container, buttons){
	 this.el = getEl(container, true);
	 var div = document.createElement('div');
	 div.className = 'ytoolbar';
	 var tb = document.createElement('table');
	 tb.border = 0;
	 tb.cellPadding = 0; 
	 tb.cellSpacing = 0;
	 div.appendChild(tb);
	 var tbody = document.createElement('tbody');
	 tb.appendChild(tbody);
	 var tr = document.createElement('tr');
	 tbody.appendChild(tr);
	 this.el.dom.appendChild(div);
	 this.tr = tr;
	 if(buttons){
		  this.add.apply(this, buttons);
	 }
};

YAHOO.ext.Toolbar.prototype = {
    
	 add : function(){
		  for(var i = 0; i < arguments.length; i++){
			   var el = arguments[i];
			   var td = document.createElement('td');
			   this.tr.appendChild(td);
			   if(el instanceof YAHOO.ext.ToolbarButton){
					el.init(td);
			   }else if(el instanceof Array){
					this.addButton(el);
			   }else if(typeof el == 'string'){
					var span = document.createElement('span');
					if(el == 'separator'){
						 span.className = 'ytb-sep';
					}else{
						 span.innerHTML = el;
						 span.className = 'ytb-text';
					}
					td.appendChild(span);
			   }else if(typeof el == 'object' && el.nodeType){ 
					td.appendChild(el);
			   }else if(typeof el == 'object'){ 
					this.addButton(el);
			   }
		  }
	 },
    
    
	 getEl : function(){
		  return this.el;  
	 },
    
    
	 addSeparator : function(){
		  var td = document.createElement('td');
		  this.tr.appendChild(td);
		  var span = document.createElement('span');
		  span.className = 'ytb-sep';
		  td.appendChild(span);
	 },
    
    
	 addButton : function(config){
		  if(config instanceof Array){
			   var buttons = [];
			   for(var i = 0, len = config.length; i < len; i++) {
					buttons.push(this.addButton(config[i]));
			   }
			   return buttons;
		  }
		  var b = config;
		  if(!(config instanceof YAHOO.ext.ToolbarButton)){
			   b = new YAHOO.ext.ToolbarButton(config);
		  }
		  this.add(b);
		  return b;
	 },
    
    
	 addText : function(text){
		  var td = document.createElement('td');
		  this.tr.appendChild(td);
		  var span = document.createElement('span');
		  span.className = 'ytb-text';
		  span.innerHTML = text;
		  td.appendChild(span);
		  return span;
	 },
    
    
	 insertButton : function(index, config){
		  if(config instanceof Array){
			   var buttons = [];
			   for(var i = 0, len = config.length; i < len; i++) {
					buttons.push(this.insertButton(index + i, config[i]));
			   }
			   return buttons;
		  }
		  var b = new YAHOO.ext.ToolbarButton(config);
		  var td = document.createElement('td');
		  var nextSibling = this.tr.childNodes[index];
		  if (nextSibling)
			   this.tr.insertBefore(td, nextSibling);
		  else
			   this.tr.appendChild(td);
		  b.init(td);
		  return b;
	 }
};


YAHOO.ext.ToolbarButton = function(config){
	 YAHOO.ext.util.Config.apply(this, config);
};

YAHOO.ext.ToolbarButton.prototype = {
    
	 init : function(appendTo){
		  var element = document.createElement('span');
		  element.className = 'ytb-button';
		  if(this.id){
			   element.id = this.id;
		  }
		  this.setDisabled(this.disabled === true);
		  var inner = document.createElement('span');
		  inner.className = 'ytb-button-inner ' + this.className;
		  inner.unselectable = 'on';
		  if(this.tooltip){
			   element.setAttribute('title', this.tooltip);
		  }
		  if(this.style){
			   YAHOO.ext.DomHelper.applyStyles(inner, this.style);
		  } 
		  element.appendChild(inner);
		  appendTo.appendChild(element);
		  this.el = getEl(element, true);
		  this.el.unselectable();
		  inner.innerHTML = (this.text ? this.text : '&#160;');
		  this.inner = inner;
		  this.el.mon('click', this.onClick, this, true);    
		  this.el.mon('mouseover', this.onMouseOver, this, true);    
		  this.el.mon('mouseout', this.onMouseOut, this, true);
	 },
    
    
	 setHandler : function(click, scope){
		  this.click = click;
		  this.scope = scope;  
	 },
    
    
	 setText : function(text){
		  this.inner.innerHTML = text;    
	 },
    
    
	 setTooltip : function(text){
		  this.el.dom.title = text;    
	 },
    
    
	 show: function(){
		  this.el.dom.parentNode.style.display = '';
	 },
    
    
	 hide: function(){
		  this.el.dom.parentNode.style.display = 'none';  
	 },
    
    
	 disable : function(){
		  this.disabled = true;
		  if(this.el){
			   this.el.addClass('ytb-button-disabled');
		  }
	 },
    
    
	 enable : function(){
		  this.disabled = false;
		  if(this.el){
			   this.el.removeClass('ytb-button-disabled');
		  }
	 },
    
    
	 isDisabled : function(){
		  return this.disabled === true;
	 },
    
	 setDisabled : function(disabled){
		  if(disabled){
			   this.disable();
		  }else{
			   this.enable();
		  }
	 },
    
    
	 onClick : function(){
		  if(!this.disabled && this.click){
			   this.click.call(this.scope || window, this);
		  }
	 },
    
    
	 onMouseOver : function(){
		  if(!this.disabled){
			   this.el.addClass('ytb-button-over');
			   if(this.mouseover){
					this.mouseover.call(this.scope || window, this);
			   }
		  }
	 },
    
    
	 onMouseOut : function(){
		  this.el.removeClass('ytb-button-over');
		  if(!this.disabled){
			   if(this.mouseout){
					this.mouseout.call(this.scope || window, this);
			   }
		  }
	 }
};

YAHOO.ext.Resizable = function(el, config){
	 this.el = getEl(el);
    
	 if(config && config.wrap){
		  config.resizeChild = this.el;
		  this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : null);
		  this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
		  this.el.setStyle('overflow', 'hidden');
		  this.el.setPositioning(config.resizeChild.getPositioning());
		  config.resizeChild.clearPositioning();
		  if(!config.width || !config.height){
			   var csize = config.resizeChild.getSize();
            
            
			   this.el.setSize(csize.width, csize.height);
		  }
		  if(config.pinned && !config.adjustments){
			   config.adjustments = 'auto';
		  }
	 }
    
	 this.proxy = this.el.createProxy({tag: 'div', cls: 'yresizable-proxy', id: this.el.id + '-rzproxy'})
	 this.proxy.unselectable();
    
    
	 this.overlay = this.el.createProxy({tag: 'div', cls: 'yresizable-overlay', html: '&#160;'});
	 this.overlay.unselectable();
	 this.overlay.enableDisplayMode('block');
	 this.overlay.mon('mousemove', this.onMouseMove, this, true);
	 this.overlay.mon('mouseup', this.onMouseUp, this, true);
    
	 YAHOO.ext.util.Config.apply(this, config, {
        
		  resizeChild : false,
        
										   adjustments : [0, 0],
        
										   minWidth : 5,
        
										   minHeight : 5,
        
										   maxWidth : 10000,
        
										   maxHeight : 10000,
        
										   enabled : true,
        
										   animate : false,
        
										   duration : .35,
        
										   dynamic : false,
        
        
										   handles : false,
										   multiDirectional : false,
        
										   disableTrackOver : false,
        
										   easing : YAHOO.util.Easing ? YAHOO.util.Easing.easeOutStrong : null,
        
										   widthIncrement : 0,
        
										   heightIncrement : 0,
        
										   pinned : false,
        
										   width : null,
        
										   height : null,
        
										   preserveRatio : false,
        
										   transparent: false,
        
										   minX: 0,
        
										   minY: 0,
        
										   draggable: false
										   });
    
	 if(this.pinned){
		  this.disableTrackOver = true;
		  this.el.addClass('yresizable-pinned');    
	 }
    
	 var position = this.el.getStyle('position');
	 if(position != 'absolute' && position != 'fixed'){
		  this.el.setStyle('position', 'relative');
	 }
	 if(!this.handles){ 
		  this.handles = 's,e,se';
		  if(this.multiDirectional){
			   this.handles += ',n,w';
		  }
	 }
	 if(this.handles == 'all'){
		  this.handles = 'n s e w ne nw se sw';
	 }
	 var hs = this.handles.split(/\s*?[,;]\s*?| /);
	 var ps = YAHOO.ext.Resizable.positions;
	 for(var i = 0, len = hs.length; i < len; i++){
		  if(hs[i] && ps[hs[i]]){
			   var pos = ps[hs[i]];
			   this[pos] = new YAHOO.ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
		  }
	 }
    
	 this.corner = this.southeast;
    
	 this.activeHandle = null;
    
	 if(this.resizeChild){
		  if(typeof this.resizeChild == 'boolean'){
			   this.resizeChild = YAHOO.ext.Element.get(this.el.dom.firstChild, true);
		  }else{
			   this.resizeChild = YAHOO.ext.Element.get(this.resizeChild, true);
		  }
	 }
    
	 if(this.adjustments == 'auto'){
		  var rc = this.resizeChild;
		  var hw = this.west, he = this.east, hn = this.north, hs = this.south;
		  if(rc && (hw || hn)){
			   rc.setRelativePositioned();
			   rc.setLeft(hw ? hw.el.getWidth() : 0);
			   rc.setTop(hn ? hn.el.getHeight() : 0);
		  }
		  this.adjustments = [
			   (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
			   (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 
			   ];
	 }
    
	 if(this.draggable){
		  this.dd = this.dynamic ? 
		  this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
		  this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
	 }
    
    
	 this.events = {
        
		  'beforeresize' : new YAHOO.util.CustomEvent(),
        
		  'resize' : new YAHOO.util.CustomEvent()
	 };
    
	 if(this.width !== null && this.height !== null){
		  this.resizeTo(this.width, this.height);
	 }else{
		  this.updateChildSize();
	 }
};

YAHOO.extendX(YAHOO.ext.Resizable, YAHOO.ext.util.Observable, {
    
	 resizeTo : function(width, height){
						this.el.setSize(width, height);
						this.updateChildSize();
						this.fireEvent('resize', this, width, height, null);
				   },
    
						startSizing : function(e){
						this.fireEvent('beforeresize', this, e);
						if(this.enabled){ 
							 this.resizing = true;
							 this.startBox = this.el.getBox();
							 this.startPoint = e.getXY();
							 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
											 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
							 this.proxy.setBox(this.startBox);
            
							 this.overlay.setSize(YAHOO.util.Dom.getDocumentWidth(), YAHOO.util.Dom.getDocumentHeight());
							 this.overlay.show();
            
							 if(!this.dynamic){
								  this.proxy.show();
							 }
						}
				   },
    
						onMouseDown : function(handle, e){
						if(this.enabled){
							 e.stopEvent();
							 this.activeHandle = handle;
							 this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
							 this.startSizing(e);
						}          
				   },
    
						onMouseUp : function(e){
						var size = this.resizeElement();
						this.resizing = false;
						this.handleOut();
						this.overlay.hide();
						this.fireEvent('resize', this, size.width, size.height, e);
				   },
    
						updateChildSize : function(){
						if(this.resizeChild){
							 var el = this.el;
							 var child = this.resizeChild;
							 var adj = this.adjustments;
							 if(el.dom.offsetWidth){
								  var b = el.getSize(true);
								  child.setSize(b.width+adj[0], b.height+adj[1]);
							 }
            
            
            
            
							 if(YAHOO.ext.util.Browser.isIE){
								  setTimeout(function(){
												  if(el.dom.offsetWidth){
													   var b = el.getSize(true);
													   child.setSize(b.width+adj[0], b.height+adj[1]);
												  }
											 }, 10);
							 }
						}
				   },
    
						snap : function(value, inc, min){
						if(!inc || !value) return value;
						var newValue = value;
						var m = value % inc;
						if(m > 0){
							 if(m > (inc/2)){
								  newValue = value + (inc-m);
							 }else{
								  newValue = value - m;
							 }
						}
						return Math.max(min, newValue);
				   },
    
						resizeElement : function(){
						var box = this.proxy.getBox();
        
        
        
						this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
        
        
        
						this.updateChildSize();
						this.proxy.hide();
						return box;
				   },
    
						constrain : function(v, diff, m, mx){
						if(v - diff < m){
							 diff = v - m;    
						}else if(v - diff > mx){
							 diff = mx - v; 
						}
						return diff;                
				   },
    
						onMouseMove : function(e){
						if(this.enabled){
							 try{
            
            
								  var curSize = this.curSize || this.startBox;
								  var x = this.startBox.x, y = this.startBox.y;
								  var ox = x, oy = y;
								  var w = curSize.width, h = curSize.height;
								  var ow = w, oh = h;
								  var mw = this.minWidth, mh = this.minHeight;
								  var mxw = this.maxWidth, mxh = this.maxHeight;
								  var wi = this.widthIncrement;
								  var hi = this.heightIncrement;
            
								  var eventXY = e.getXY();
								  var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
								  var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
            
								  var pos = this.activeHandle.position;
            
								  switch(pos){
								  case 'east':
									   w += diffX; 
									   w = Math.min(Math.max(mw, w), mxw);
									   break;
								  case 'south':
									   h += diffY;
									   h = Math.min(Math.max(mh, h), mxh);
									   break;
								  case 'southeast':
									   w += diffX; 
									   h += diffY;
									   w = Math.min(Math.max(mw, w), mxw);
									   h = Math.min(Math.max(mh, h), mxh);
									   break;
								  case 'north':
									   diffY = this.constrain(h, diffY, mh, mxh);
									   y += diffY;
									   h -= diffY;
									   break;
								  case 'west':
									   diffX = this.constrain(w, diffX, mw, mxw);
									   x += diffX;
									   w -= diffX;
									   break;
								  case 'northeast':
									   w += diffX; 
									   w = Math.min(Math.max(mw, w), mxw);
									   diffY = this.constrain(h, diffY, mh, mxh);
									   y += diffY;
									   h -= diffY;
									   break;
								  case 'northwest':
									   diffX = this.constrain(w, diffX, mw, mxw);
									   diffY = this.constrain(h, diffY, mh, mxh);
									   y += diffY;
									   h -= diffY;
									   x += diffX;
									   w -= diffX;
									   break;
								  case 'southwest':
									   diffX = this.constrain(w, diffX, mw, mxw);
									   h += diffY;
									   h = Math.min(Math.max(mh, h), mxh);
									   x += diffX;
									   w -= diffX;
									   break;
								  }
            
								  var sw = this.snap(w, wi, mw);
								  var sh = this.snap(h, hi, mh);
								  if(sw != w || sh != h){
									   switch(pos){
									   case 'northeast':
											y -= sh - h;
											break;
									   case 'north':
											y -= sh - h;
											break;
									   case 'southwest':
											x -= sw - w;
											break;
									   case 'west':
											x -= sw - w;
											break;
									   case 'northwest':
											x -= sw - w;
											y -= sh - h;
											break;
									   }
									   w = sw;
									   h = sh;
								  }
            
								  if(this.preserveRatio){
									   switch(pos){
									   case 'southeast':
									   case 'east':
											h = oh * (w/ow);
											h = Math.min(Math.max(mh, h), mxh);
											w = ow * (h/oh);
											break;
									   case 'south':
											w = ow * (h/oh);
											w = Math.min(Math.max(mw, w), mxw);
											h = oh * (w/ow);
											break;
									   case 'northeast':
											w = ow * (h/oh);
											w = Math.min(Math.max(mw, w), mxw);
											h = oh * (w/ow);
											break;
									   case 'north':
											var tw = w;
											w = ow * (h/oh);
											w = Math.min(Math.max(mw, w), mxw);
											h = oh * (w/ow);
											x += (tw - w) / 2;
											break;
									   case 'southwest':
											h = oh * (w/ow);
											h = Math.min(Math.max(mh, h), mxh);
											var tw = w;
											w = ow * (h/oh);
											x += tw - w;
											break;
									   case 'west':
											var th = h;
											h = oh * (w/ow);
											h = Math.min(Math.max(mh, h), mxh);
											y += (th - h) / 2;
											var tw = w;
											w = ow * (h/oh);
											x += tw - w;
											break;
									   case 'northwest':
											var tw = w;
											var th = h;
											h = oh * (w/ow);
											h = Math.min(Math.max(mh, h), mxh);
											w = ow * (h/oh);
											y += th - h;
											x += tw - w;
											break;
                        
									   }
								  }
								  this.proxy.setBounds(x, y, w, h);
								  if(this.dynamic){
									   this.resizeElement();
								  }
							 }catch(e){}
						}
				   },
    
						handleOver : function(){
						if(this.enabled){
							 this.el.addClass('yresizable-over');
						}
				   },
    
						handleOut : function(){
						if(!this.resizing){
							 this.el.removeClass('yresizable-over');
						}
				   },
    
    
						getEl : function(){
						return this.el;
				   },
    
    
						getResizeChild : function(){
						return this.resizeChild;
				   }
	 });


YAHOO.ext.Resizable.positions = {
	 n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast' 
};


YAHOO.ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
	 if(!this.tpl){
        
		  var tpl = YAHOO.ext.DomHelper.createTemplate(
			   {tag: 'div', cls: 'yresizable-handle yresizable-handle-{0}', html: '&#160;'}
			   );
		  tpl.compile();
		  YAHOO.ext.Resizable.Handle.prototype.tpl = tpl;
	 }
	 this.position = pos;
	 this.rz = rz;
	 this.el = this.tpl.append(rz.el.dom, [this.position], true);
	 this.el.unselectable();
	 if(transparent){
		  this.el.setOpacity(0);
	 }
	 this.el.mon('mousedown', this.onMouseDown, this, true);
	 if(!disableTrackOver){
		  this.el.mon('mouseover', this.onMouseOver, this, true);
		  this.el.mon('mouseout', this.onMouseOut, this, true);
	 }
};

YAHOO.ext.Resizable.Handle.prototype = {
	 afterResize : function(rz){
        
	 },
    
	 onMouseDown : function(e){
		  this.rz.onMouseDown(this, e);
	 },
    
	 onMouseOver : function(e){
		  this.rz.handleOver(this, e);
	 },
    
	 onMouseOut : function(e){
		  this.rz.handleOut(this, e);
	 }  
};




if(YAHOO.util.DragDropMgr){
	 YAHOO.util.DragDropMgr.clickTimeThresh = 350;
};

YAHOO.ext.SplitBar = function(dragElement, resizingElement, orientation, placement){
    
    
	 this.el = YAHOO.ext.Element.get(dragElement, true);
	 this.el.dom.unselectable = 'on';
    
	 this.resizingEl = YAHOO.ext.Element.get(resizingElement, true);
    
    
	 this.orientation = orientation || YAHOO.ext.SplitBar.HORIZONTAL;
    
    
	 this.minSize = 0;
    
    
	 this.maxSize = 2000;
    
	 this.onMoved = new YAHOO.util.CustomEvent("SplitBarMoved", this);
    
    
	 this.animate = false;
    
    
	 this.useShim = false;
    
    
	 this.shim = null;
    
    
	 this.proxy = YAHOO.ext.SplitBar.createProxy(this.orientation);
    
    
	 this.dd = new YAHOO.util.DDProxy(this.el.dom.id, "SplitBars", {dragElId : this.proxy.id});
    
    
	 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
    
    
	 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
    
    
	 this.dragSpecs = {};
    
    
	 this.adapter = new YAHOO.ext.SplitBar.BasicLayoutAdapter();
	 this.adapter.init(this);
    
	 if(this.orientation == YAHOO.ext.SplitBar.HORIZONTAL){
        
		  this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? YAHOO.ext.SplitBar.LEFT : YAHOO.ext.SplitBar.RIGHT);
		  this.el.setStyle('cursor', 'e-resize');
	 }else{
        
		  this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? YAHOO.ext.SplitBar.TOP : YAHOO.ext.SplitBar.BOTTOM);
		  this.el.setStyle('cursor', 'n-resize');
	 }
    
	 this.events = {
        
		  'resize' : this.onMoved,
        
		  'moved' : this.onMoved,
        
		  'beforeresize' : new YAHOO.util.CustomEvent('beforeresize')
	 }
}

YAHOO.extendX(YAHOO.ext.SplitBar, YAHOO.ext.util.Observable, {
	 onStartProxyDrag : function(x, y){
						this.fireEvent('beforeresize', this);
						if(this.useShim){
							 if(!this.shim){
								  this.shim = YAHOO.ext.SplitBar.createShim();
							 }
							 this.shim.setVisible(true);
						}
						YAHOO.util.Dom.setStyle(this.proxy, 'display', 'block');
						var size = this.adapter.getElementSize(this);
						this.activeMinSize = this.getMinimumSize();;
						this.activeMaxSize = this.getMaximumSize();;
						var c1 = size - this.activeMinSize;
						var c2 = Math.max(this.activeMaxSize - size, 0);
						if(this.orientation == YAHOO.ext.SplitBar.HORIZONTAL){
							 this.dd.resetConstraints();
							 this.dd.setXConstraint(
								  this.placement == YAHOO.ext.SplitBar.LEFT ? c1 : c2, 
								  this.placement == YAHOO.ext.SplitBar.LEFT ? c2 : c1
								  );
							 this.dd.setYConstraint(0, 0);
						}else{
							 this.dd.resetConstraints();
							 this.dd.setXConstraint(0, 0);
							 this.dd.setYConstraint(
								  this.placement == YAHOO.ext.SplitBar.TOP ? c1 : c2, 
								  this.placement == YAHOO.ext.SplitBar.TOP ? c2 : c1
								  );
						}
						this.dragSpecs.startSize = size;
						this.dragSpecs.startPoint = [x, y];
        
						YAHOO.util.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
				   },
    
    
						onEndProxyDrag : function(e){
						YAHOO.util.Dom.setStyle(this.proxy, 'display', 'none');
						var endPoint = YAHOO.util.Event.getXY(e);
						if(this.useShim){
							 this.shim.setVisible(false);
						}
						var newSize;
						if(this.orientation == YAHOO.ext.SplitBar.HORIZONTAL){
							 newSize = this.dragSpecs.startSize + 
								  (this.placement == YAHOO.ext.SplitBar.LEFT ?
								   endPoint[0] - this.dragSpecs.startPoint[0] :
								   this.dragSpecs.startPoint[0] - endPoint[0]
									   );
						}else{
							 newSize = this.dragSpecs.startSize + 
								  (this.placement == YAHOO.ext.SplitBar.TOP ?
								   endPoint[1] - this.dragSpecs.startPoint[1] :
								   this.dragSpecs.startPoint[1] - endPoint[1]
									   );
						}
						newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
						if(newSize != this.dragSpecs.startSize){
							 this.adapter.setElementSize(this, newSize);
							 this.onMoved.fireDirect(this, newSize);
						}
				   },
    
    
						getAdapter : function(){
						return this.adapter;
				   },
    
    
						setAdapter : function(adapter){
						this.adapter = adapter;
						this.adapter.init(this);
				   },
    
    
						getMinimumSize : function(){
						return this.minSize;
				   },
    
    
						setMinimumSize : function(minSize){
						this.minSize = minSize;
				   },
    
    
						getMaximumSize : function(){
						return this.maxSize;
				   },
    
    
						setMaximumSize : function(maxSize){
						this.maxSize = maxSize;
				   },
    
    
						setCurrentSize : function(size){
						var oldAnimate = this.animate;
						this.animate = false;
						this.adapter.setElementSize(this, size);
						this.animate = oldAnimate;
				   },
    
    
						destroy : function(removeEl){
						if(this.shim){
							 this.shim.remove();
						}
						this.dd.unreg();
						this.proxy.parentNode.removeChild(this.proxy);
						if(removeEl){
							 this.el.remove();
						}
				   }
	 });


YAHOO.ext.SplitBar.createShim = function(){
	 var shim = document.createElement('div');
	 shim.unselectable = 'on';
	 YAHOO.util.Dom.generateId(shim, 'split-shim');
	 YAHOO.util.Dom.setStyle(shim, 'width', '100%');
	 YAHOO.util.Dom.setStyle(shim, 'height', '100%');
	 YAHOO.util.Dom.setStyle(shim, 'position', 'absolute');
	 YAHOO.util.Dom.setStyle(shim, 'background', 'white');
	 YAHOO.util.Dom.setStyle(shim, 'z-index', 11000);
	 window.document.body.appendChild(shim);
	 var shimEl = YAHOO.ext.Element.get(shim);
	 shimEl.setOpacity(.01);
	 shimEl.setXY([0, 0]);
	 return shimEl;
};


YAHOO.ext.SplitBar.createProxy = function(orientation){
	 var proxy = document.createElement('div');
	 proxy.unselectable = 'on';
	 YAHOO.util.Dom.generateId(proxy, 'split-proxy');
	 YAHOO.util.Dom.setStyle(proxy, 'position', 'absolute');
	 YAHOO.util.Dom.setStyle(proxy, 'visibility', 'hidden');
	 YAHOO.util.Dom.setStyle(proxy, 'z-index', 11001);
	 YAHOO.util.Dom.setStyle(proxy, 'background-color', "#aaa");
	 if(orientation == YAHOO.ext.SplitBar.HORIZONTAL){
		  YAHOO.util.Dom.setStyle(proxy, 'cursor', 'e-resize');
	 }else{
		  YAHOO.util.Dom.setStyle(proxy, 'cursor', 'n-resize');
	 }
    
	 YAHOO.util.Dom.setStyle(proxy, 'line-height', '0px');
	 YAHOO.util.Dom.setStyle(proxy, 'font-size', '0px');
	 window.document.body.appendChild(proxy);
	 return proxy;
};


YAHOO.ext.SplitBar.BasicLayoutAdapter = function(){
};

YAHOO.ext.SplitBar.BasicLayoutAdapter.prototype = {
    
	 init : function(s){
    
	 },
    
     getElementSize : function(s){
		  if(s.orientation == YAHOO.ext.SplitBar.HORIZONTAL){
			   return s.resizingEl.getWidth();
		  }else{
			   return s.resizingEl.getHeight();
		  }
	 },
    
    
	 setElementSize : function(s, newSize, onComplete){
		  if(s.orientation == YAHOO.ext.SplitBar.HORIZONTAL){
			   if(!YAHOO.util.Anim || !s.animate){
					s.resizingEl.setWidth(newSize);
					if(onComplete){
						 onComplete(s, newSize);
					}
			   }else{
					s.resizingEl.setWidth(newSize, true, .1, onComplete, YAHOO.util.Easing.easeOut);
			   }
		  }else{
            
			   if(!YAHOO.util.Anim || !s.animate){
					s.resizingEl.setHeight(newSize);
					if(onComplete){
						 onComplete(s, newSize);
					}
			   }else{
					s.resizingEl.setHeight(newSize, true, .1, onComplete, YAHOO.util.Easing.easeOut);
			   }
		  }
	 }
};


YAHOO.ext.SplitBar.AbsoluteLayoutAdapter = function(container){
	 this.basic = new YAHOO.ext.SplitBar.BasicLayoutAdapter();
	 this.container = getEl(container);
};

YAHOO.ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
	 init : function(s){
		  this.basic.init(s);
		  
	 },
    
	 getElementSize : function(s){
		  return this.basic.getElementSize(s);
	 },
	 
	 setElementSize : function(s, newSize, onComplete){
		  this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
	 },
	 
	 moveSplitter : function(s){
		  var yes = YAHOO.ext.SplitBar;
		  switch(s.placement){
		  case yes.LEFT:
			   s.el.setX(s.resizingEl.getRight());
			   break;
		  case yes.RIGHT:
			   s.el.setStyle('right', (this.container.getWidth() - s.resizingEl.getLeft()) + 'px');
			   break;
		  case yes.TOP:
			   s.el.setY(s.resizingEl.getBottom());
			   break;
		  case yes.BOTTOM:
			   s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
			   break;
		  }
	 }
};


YAHOO.ext.SplitBar.VERTICAL = 1;
YAHOO.ext.SplitBar.HORIZONTAL = 2;
YAHOO.ext.SplitBar.LEFT = 1;
YAHOO.ext.SplitBar.RIGHT = 2;
YAHOO.ext.SplitBar.TOP = 3;
YAHOO.ext.SplitBar.BOTTOM = 4;

YAHOO.ext.grid.Grid = function(container, config, colModel, selectionModel){
	
	 this.container = YAHOO.ext.Element.get(container);
	 this.container.update('');
	 this.container.setStyle('overflow', 'hidden');
	 this.id = this.container.id;
	 this.rows = [];
	 this.rowCount = 0;
	 this.fieldId = null;
	 var dataModel = config; 
	 this.dataModel = dataModel;
	 this.colModel = colModel;
	 this.selModel = selectionModel;
	 this.activeEditor = null;
	 this.editingCell = null;
	
	
	 this.minColumnWidth = 25;
	
	
	 this.autoSizeColumns = false;
	
	
	 this.autoSizeHeaders = false;
	
	
	 this.monitorWindowResize = true;
	
	
	 this.maxRowsToMeasure = 0;
	
	
	 this.trackMouseOver = false;
	
	
	 this.enableDragDrop = false;
	
	
	 this.stripeRows = true;
	
	 this.autoHeight = false;
	
	
	 this.autoWidth = false;
	
	
	 this.view = null;
	
	
	 this.allowTextSelectionPattern = /INPUT|TEXTAREA|SELECT/i;
	
	 if(typeof config == 'object' && !config.getRowCount){
		  YAHOO.ext.util.Config.apply(this, config);
	 }
	
	
	 this.setValueDelegate = this.setCellValue.createDelegate(this);
	
	
	 this.events = {
	    
	    
		  'click' : true,
	    
		  'dblclick' : true,
	    
		  'mousedown' : true,
	    
		  'mouseup' : true,
	    
		  'mouseover' : true,
	    
		  'mouseout' : true,
	    
		  'keypress' : true,
	    
		  'keydown' : true,
	    
	    
	    
	    
		  'cellclick' : true,
	    
		  'celldblclick' : true,
	    
		  'rowclick' : true,
	    
		  'rowdblclick' : true,
	    
		  'headerclick' : true,
	    
		  'rowcontextmenu' : true,
	    
		  'headercontextmenu' : true,
	    
		  'beforeedit' : true,
	    
		  'afteredit' : true,
	    
		  'bodyscroll' : true,
	    
		  'columnresize' : true,
	    
		  'startdrag' : true,
	    
		  'enddrag' : true,
	    
		  'dragdrop' : true,
	    
		  'dragover' : true,
	    
		  'dragenter' : true,
	    
		  'dragout' : true
	 };
};

YAHOO.ext.grid.Grid.prototype = { 
    
	 render : function(){
		  if((!this.container.dom.offsetHeight || this.container.dom.offsetHeight < 20) 
			 || this.container.getStyle('height') == 'auto'){
			   this.autoHeight = true;   
		  }	       
		  if((!this.container.dom.offsetWidth || this.container.dom.offsetWidth < 20)){
			   this.autoWidth = true;   
		  }	       
		  if(!this.view){
			   if(this.dataModel.isPaged()){
					this.view = new YAHOO.ext.grid.PagedGridView();
			   }else{
					this.view = new YAHOO.ext.grid.GridView();
			   }
		  }
		  this.view.init(this);
		  this.el = getEl(this.view.render(), true);
		  var c = this.container;
		  c.mon("click", this.onClick, this, true);
		  c.mon("dblclick", this.onDblClick, this, true);
		  c.mon("contextmenu", this.onContextMenu, this, true);
		  c.mon("selectstart", this.cancelTextSelection, this, true);
		  c.mon("mousedown", this.cancelTextSelection, this, true);
		  c.mon("mousedown", this.onMouseDown, this, true);
		  c.mon("mouseup", this.onMouseUp, this, true);
		  if(this.trackMouseOver){
			   this.el.mon("mouseover", this.onMouseOver, this, true);
			   this.el.mon("mouseout", this.onMouseOut, this, true);
		  }
		  c.mon("keypress", this.onKeyPress, this, true);
		  c.mon("keydown", this.onKeyDown, this, true);
		  this.init();
		  return this;
	 },
    
	 init : function(){
		  this.rows = this.el.dom.rows;
		  if(!this.disableSelection){
			   if(!this.selModel){
					this.selModel = new YAHOO.ext.grid.DefaultSelectionModel(this);
			   }
			   this.selModel.init(this);
			   this.selModel.onSelectionChange.subscribe(this.updateField, this, true);
		  }else{
			   this.selModel = new YAHOO.ext.grid.DisableSelectionModel(this);
			   this.selModel.init(this);
		  }
        
		  if(this.enableDragDrop){
			   this.dd = new YAHOO.ext.grid.GridDD(this, this.container.dom);
		  }
     },   

    
	 reset : function(config){
		  this.destroy(false, true);
		  YAHOO.ext.util.Config.apply(this, config);
		  return this;
	 },
    
    
	 destroy : function(removeEl, keepListeners){
		  var c = this.container;
		  c.removeAllListeners();
		  this.view.destroy();
		  YAHOO.ext.EventManager.removeResizeListener(this.view.onWindowResize, this.view);
		  this.view = null;
		  this.colModel.purgeListeners();
		  if(!keepListeners){
			   this.purgeListeners();
		  }
		  c.update('');
		  if(removeEl === true){
			   c.remove();
		  }
	 },
    
    
	 setDataModel : function(dm, rerender){
		  this.view.unplugDataModel(this.dataModel);
		  this.dataModel = dm;
		  this.view.plugDataModel(dm);
		  if(rerender){
			   dm.fireEvent('datachanged');
		  }
	 },
    
	 onMouseDown : function(e){
		  this.fireEvent('mousedown', e);
	 },
    
	 onMouseUp : function(e){
		  this.fireEvent('mouseup', e);
	 },
    
	 onMouseOver : function(e){
		  this.fireEvent('mouseover', e);
	 },
    
	 onMouseOut : function(e){
		  this.fireEvent('mouseout', e);
	 },
    
	 onKeyPress : function(e){
		  this.fireEvent('keypress', e);
	 },
    
	 onKeyDown : function(e){
		  this.fireEvent('keydown', e);
	 },
    
	 fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
	 on : YAHOO.ext.util.Observable.prototype.on,
	 addListener : YAHOO.ext.util.Observable.prototype.addListener,
	 delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
	 removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
	 purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
	 bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener,
    
	 onClick : function(e){
		  this.fireEvent('click', e);
		  var target = e.getTarget();
		  var row = this.getRowFromChild(target);
		  var cell = this.getCellFromChild(target);
		  var header = this.getHeaderFromChild(target);
		  if(row){
			   this.fireEvent('rowclick', this, row.rowIndex, e);
		  }
		  if(cell){
			   this.fireEvent('cellclick', this, row.rowIndex, cell.columnIndex, e);
		  }
		  if(header){
			   this.fireEvent('headerclick', this, header.columnIndex, e);
		  }
    },

    onContextMenu : function(e){
        var target = e.getTarget();
        var row = this.getRowFromChild(target);
        var header = this.getHeaderFromChild(target);
        if(row){
            this.fireEvent('rowcontextmenu', this, row.rowIndex, e);
        }
        if(header){
            this.fireEvent('headercontextmenu', this, header.columnIndex, e);
        }
        e.preventDefault();
    },

    onDblClick : function(e){
        this.fireEvent('dblclick', e);
        var target = e.getTarget();
        var row = this.getRowFromChild(target);
        var cell = this.getCellFromChild(target);
        if(row){
            this.fireEvent('rowdblclick', this, row.rowIndex, e);
        }
        if(cell){
            this.fireEvent('celldblclick', this, row.rowIndex, cell.columnIndex, e);
        }
    },
    
    
    startEditing : function(rowIndex, colIndex){
        var row = this.rows[rowIndex];
        var cell = row.childNodes[colIndex];
        this.stopEditing();
        setTimeout(this.doEdit.createDelegate(this, [row, cell]), 10);
    },
        
    
    stopEditing : function(){
        if(this.activeEditor){
            this.activeEditor.stopEditing();
        }
    },
        
    
    doEdit : function(row, cell){
        if(!row || !cell) return;
        var cm = this.colModel;
        var dm = this.dataModel;
        var colIndex = cell.columnIndex;
        var rowIndex = row.rowIndex;
        if(cm.isCellEditable(colIndex, rowIndex)){
           var ed = cm.getCellEditor(colIndex, rowIndex);
           if(ed){
               if(this.activeEditor){
                   this.activeEditor.stopEditing();
               }
               this.fireEvent('beforeedit', this, rowIndex, colIndex);
               this.activeEditor = ed;
               this.editingCell = cell;
               this.view.ensureVisible(row, true);
               try{
                   cell.focus();
               }catch(e){}
               ed.init(this, this.el.dom.parentNode, this.setValueDelegate);
               var value = dm.getValueAt(rowIndex, cm.getDataIndex(colIndex));
               
               setTimeout(ed.startEditing.createDelegate(ed, [value, row, cell]), 1);
           }   
        }  
    },
    
    setCellValue : function(value, rowIndex, colIndex){
         this.dataModel.setValueAt(value, rowIndex, this.colModel.getDataIndex(colIndex));
         this.fireEvent('afteredit', this, rowIndex, colIndex);
    },
    
    
    cancelTextSelection : function(e){
        var target = e.getTarget();
        if(target && target != this.el.dom.parentNode && !this.allowTextSelectionPattern.test(target.tagName)){
            e.preventDefault();
        }
    },
    
    
    autoSize : function(){
        this.view.updateWrapHeight();
        this.view.adjustForScroll();
    },
    
    
    scrollTo : function(row){
        if(typeof row == 'number'){
            row = this.rows[row];
        }
        this.view.ensureVisible(row, true);
    },
    
    
    getEditingCell : function(){
        return this.editingCell;    
    },
    
    
    bindToField : function(fieldId){
        this.fieldId = fieldId;
        this.readField();
    },
    
    
    updateField : function(){
        if(this.fieldId){
            var field = YAHOO.util.Dom.get(this.fieldId);
            field.value = this.getSelectedRowIds().join(',');
        }
    },
    
    
    readField : function(){
        if(this.fieldId){
            var field = YAHOO.util.Dom.get(this.fieldId);
            var values = field.value.split(',');
            var rows = this.getRowsById(values);
            this.selModel.selectRows(rows, false);
        }
    },
	
	
    getRow : function(index){
        return this.rows[index];
    },
	
	
    getRowsById : function(id){
        var dm = this.dataModel;
        if(!(id instanceof Array)){
            for(var i = 0; i < this.rows.length; i++){
                if(dm.getRowId(i) == id){
                    return this.rows[i];
                }
            }
            return null;
        }
        var found = [];
        var re = "^(?:";
        for(var i = 0; i < id.length; i++){
            re += id[i];
            if(i != id.length-1) re += "|";
        }
        var regex = new RegExp(re + ")$");
        for(var i = 0; i < this.rows.length; i++){
            if(regex.test(dm.getRowId(i))){
                found.push(this.rows[i]);
            }
        }
        return found;
    },
    
    
    getRowAfter : function(row){
        return this.getSibling('next', row);
    },
    
    
    getRowBefore : function(row){
        return this.getSibling('previous', row);
    },
    
    
    getCellAfter : function(cell, includeHidden){
        var next = this.getSibling('next', cell);
        if(next && !includeHidden && this.colModel.isHidden(next.columnIndex)){
            return this.getCellAfter(next);
        }
        return next;
    },
    
    
    getCellBefore : function(cell, includeHidden){
        var prev = this.getSibling('previous', cell);
        if(prev && !includeHidden && this.colModel.isHidden(prev.columnIndex)){
            return this.getCellBefore(prev);
        }
        return prev;
    },
    
    
    getLastCell : function(row, includeHidden){
        var cell = this.getElement('previous', row.lastChild);
        if(cell && !includeHidden && this.colModel.isHidden(cell.columnIndex)){
            return this.getCellBefore(cell);
        }
        return cell;
    },
    
    
    getFirstCell : function(row, includeHidden){
        var cell = this.getElement('next', row.firstChild);
        if(cell && !includeHidden && this.colModel.isHidden(cell.columnIndex)){
            return this.getCellAfter(cell);
        }
        return cell;
    },
    
    
    getSibling : function(type, node){
        if(!node) return null;
        type += 'Sibling';
        var n = node[type];
        while(n && n.nodeType != 1){
            n = n[type];
        }
        return n;
    },
    
    
    getElement : function(direction, node){
        if(!node || node.nodeType == 1) return node;
        else return this.getSibling(direction, node);
    },
    
    
    getElementFromChild : function(childEl, parentClass){
        if(!childEl || (YAHOO.util.Dom.hasClass(childEl, parentClass))){
		    return childEl;
	    }
	    var p = childEl.parentNode;
	    var b = document.body;
	    while(p && p != b){
            if(YAHOO.util.Dom.hasClass(p, parentClass)){
            	return p;
            }
            p = p.parentNode;
        }
	    return null;
    },
    
    
    getRowFromChild : function(childEl){
        return this.getElementFromChild(childEl, 'ygrid-row');
    },
    
    
    getCellFromChild : function(childEl){
        return this.getElementFromChild(childEl, 'ygrid-col');
    },
    
    
    
     getHeaderFromChild : function(childEl){
        return this.getElementFromChild(childEl, 'ygrid-hd');
    },
    
    
    getSelectedRows : function(){
        return this.selModel.getSelectedRows();
    },
    
    
    getSelectedRow : function(){
        if(this.selModel.hasSelection()){
            return this.selModel.getSelectedRows()[0];
        }
        return null;
    },
    
    
    getSelectedRowIndexes : function(){
        var a = [];
        var rows = this.selModel.getSelectedRows();
        for(var i = 0; i < rows.length; i++) {
        	a[i] = rows[i].rowIndex;
        }
        return a;
    },
    
    
    getSelectedRowIndex : function(){
        if(this.selModel.hasSelection()){
           return this.selModel.getSelectedRows()[0].rowIndex;
        }
        return -1;
    },
    
    
    getSelectedRowId : function(){
        if(this.selModel.hasSelection()){
           return this.selModel.getSelectedRowIds()[0];
        }
        return null;
    },
    
    
    getSelectedRowIds : function(){
        return this.selModel.getSelectedRowIds();
    },
    
    
    clearSelections : function(){
        this.selModel.clearSelections();
    },
    
        
    
    selectAll : function(){
        this.selModel.selectAll();
    },
    
        
    
    getSelectionCount : function(){
        return this.selModel.getCount();
    },
    
    
    hasSelection : function(){
        return this.selModel.hasSelection();
    },
    
    
    getSelectionModel : function(){
        if(!this.selModel){
            this.selModel = new DefaultSelectionModel();
        }
        return this.selModel;
    },
    
    
    getDataModel : function(){
        return this.dataModel;
    },
    
    
    getColumnModel : function(){
        return this.colModel;
    },
    
    
    getView : function(){
        return this.view;
    },
    
    getDragDropText : function(){
        return this.ddText.replace('%0', this.selModel.getCount());
    }
};

YAHOO.ext.grid.Grid.prototype.ddText = "%0 selected row(s)";


if(YAHOO.util.DDProxy)
{

	 YAHOO.ext.grid.GridDD = function(grid, bwrap){
		  this.grid = grid;
		  var ddproxy = document.createElement('div');
		  ddproxy.id = grid.container.id + '-ddproxy';
		  ddproxy.className = 'ygrid-drag-proxy';
		  document.body.insertBefore(ddproxy, document.body.firstChild);
		  YAHOO.util.Dom.setStyle(ddproxy, 'opacity', .80);
		  var ddicon = document.createElement('span');
		  ddicon.className = 'ygrid-drop-icon ygrid-drop-nodrop';
		  ddproxy.appendChild(ddicon);
		  var ddtext = document.createElement('span');
		  ddtext.className = 'ygrid-drag-text';
		  ddtext.innerHTML = "&#160;";
		  ddproxy.appendChild(ddtext);
		  
		  this.ddproxy = ddproxy;
		  this.ddtext = ddtext;
		  this.ddicon = ddicon;
		  YAHOO.util.Event.on(bwrap, 'click', this.handleClick, this, true);
		  YAHOO.ext.grid.GridDD.superclass.constructor.call(this, bwrap.id, 'GridDD', 
															{dragElId : ddproxy.id, resizeFrame: false});
          
		  this.unlockDelegate = grid.selModel.unlock.createDelegate(grid.selModel);
	 };

	 YAHOO.extendX(YAHOO.ext.grid.GridDD, YAHOO.util.DDProxy);

	 YAHOO.ext.grid.GridDD.prototype.handleMouseDown = function(e){
		  var row = this.grid.getRowFromChild(YAHOO.util.Event.getTarget(e));
		  if(!row) return;
		  if(this.grid.selModel.isSelected(row)){
			   YAHOO.ext.grid.GridDD.superclass.handleMouseDown.call(this, e);
		  }else {
			   this.grid.selModel.unlock();
			   YAHOO.ext.EventObject.setEvent(e);
			   this.grid.selModel.rowClick(this.grid, row.rowIndex, YAHOO.ext.EventObject);
			   YAHOO.ext.grid.GridDD.superclass.handleMouseDown.call(this, e);
			   this.grid.selModel.lock();
		  }
	 };

	 YAHOO.ext.grid.GridDD.prototype.handleClick = function(e){
		  if(this.grid.selModel.isLocked()){
			   setTimeout(this.unlockDelegate, 1);
			   YAHOO.util.Event.stopEvent(e);
		  };
	 };

	 YAHOO.ext.grid.GridDD.prototype.setDropStatus = function(dropStatus){
		  if(dropStatus === true){
			   YAHOO.util.Dom.replaceClass(this.ddicon, 'ygrid-drop-nodrop', 'ygrid-drop-ok');
		  }else{
			   YAHOO.util.Dom.replaceClass(this.ddicon, 'ygrid-drop-ok', 'ygrid-drop-nodrop');
		  }
	 };

	 YAHOO.ext.grid.GridDD.prototype.startDrag = function(e){
		  this.ddtext.innerHTML = this.grid.getDragDropText();
		  this.setDropStatus(false);
		  this.grid.selModel.lock();
		  this.grid.fireEvent('startdrag', this.grid, this, e);
	 };
       
	 YAHOO.ext.grid.GridDD.prototype.endDrag = function(e){
		  YAHOO.util.Dom.setStyle(this.ddproxy, 'visibility', 'hidden');
		  this.grid.fireEvent('enddrag', this.grid, this, e);
	 };

	 YAHOO.ext.grid.GridDD.prototype.autoOffset = function(iPageX, iPageY) {
		  this.setDelta(-12, -20);
	 };

	 YAHOO.ext.grid.GridDD.prototype.onDragEnter = function(e, id) {
		  this.setDropStatus(true);
		  this.grid.fireEvent('dragenter', this.grid, this, id, e);
	 };

	 YAHOO.ext.grid.GridDD.prototype.onDragDrop = function(e, id) {
		  this.grid.fireEvent('dragdrop', this.grid, this, id, e);
	 };

	 YAHOO.ext.grid.GridDD.prototype.onDragOver = function(e, id) {
		  this.grid.fireEvent('dragover', this.grid, this, id, e);
	 };

	 YAHOO.ext.grid.GridDD.prototype.onDragOut = function(e, id) {
		  this.setDropStatus(false);
		  this.grid.fireEvent('dragout', this.grid, this, id, e);
	 };
};

YAHOO.ext.grid.GridView = function(){
	this.grid = null;
	this.lastFocusedRow = null;
	this.onScroll = new YAHOO.util.CustomEvent('onscroll');
	this.adjustScrollTask = new YAHOO.ext.util.DelayedTask(this._adjustForScroll, this);
	this.ensureVisibleTask = new YAHOO.ext.util.DelayedTask();
};

YAHOO.ext.grid.GridView.prototype = {
	init: function(grid){
		this.grid = grid;
	},
	
	fireScroll: function(scrollLeft, scrollTop){
		this.onScroll.fireDirect(this.grid, scrollLeft, scrollTop);
	},
	
	
	getColumnRenderers : function(){
    	var renderers = [];
    	var cm = this.grid.colModel;
        var colCount = cm.getColumnCount();
        for(var i = 0; i < colCount; i++){
            renderers.push(cm.getRenderer(i));
        }
        return renderers;
    },
    
    buildIndexMap : function(){
        var colToData = {};
        var dataToCol = {};
        var cm = this.grid.colModel;
        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
            var di = cm.getDataIndex(i);
            colToData[i] = di;
            dataToCol[di] = i;
        }
        return {'colToData': colToData, 'dataToCol': dataToCol};
    },
    
    getDataIndexes : function(){
    	if(!this.indexMap){
            this.indexMap = this.buildIndexMap();
        }
        return this.indexMap.colToData;
    },
    
    getColumnIndexByDataIndex : function(dataIndex){
        if(!this.indexMap){
            this.indexMap = this.buildIndexMap();
        }
    	return this.indexMap.dataToCol[dataIndex];
    },
    
    updateHeaders : function(){
        var colModel = this.grid.colModel;
        var hcells = this.headers;
        var colCount = colModel.getColumnCount();
        for(var i = 0; i < colCount; i++){
            hcells[i].textNode.innerHTML = colModel.getColumnHeader(i);
        }
    },
    
    adjustForScroll : function(disableDelay){
        if(!disableDelay){
            this.adjustScrollTask.delay(50);
        }else{
            this._adjustForScroll();
        }
    },
    
    
     getCellAtPoint : function(x, y){
        var colIndex = null;        
        var rowIndex = null;
        
        
        var xy = YAHOO.util.Dom.getXY(this.wrap);
        x = (x - xy[0]) + this.wrap.scrollLeft;
        y = (y - xy[1]) + this.wrap.scrollTop;
        
        var colModel = this.grid.colModel;
        var pos = 0;
        var colCount = colModel.getColumnCount();
        for(var i = 0; i < colCount; i++){
            if(colModel.isHidden(i)) continue;
            var width = colModel.getColumnWidth(i);
            if(x >= pos && x < pos+width){
                colIndex = i;
                break;
            }
            pos += width;
        }
        if(colIndex != null){
            rowIndex = (y == 0 ? 0 : Math.floor(y / this.getRowHeight()));
            if(rowIndex >= this.grid.dataModel.getRowCount()){
                return null;
            }
            return [colIndex, rowIndex];
        }
        return null;
    },
    
    
    _adjustForScroll : function(){
        this.forceScrollUpdate();
        if(this.scrollbarMode == YAHOO.ext.grid.GridView.SCROLLBARS_OVERLAP){
            var adjustment = 0;
            if(this.wrap.clientWidth && this.wrap.clientWidth !== 0){
                adjustment = this.wrap.offsetWidth - this.wrap.clientWidth;
            }
            this.hwrap.setWidth(this.wrap.offsetWidth-adjustment);
        }else{
            this.hwrap.setWidth(this.wrap.offsetWidth);
        }
        this.bwrap.setWidth(Math.max(this.grid.colModel.getTotalWidth(), this.wrap.clientWidth));
    },

    
     focusRow : function(row){
        if(typeof row == 'number'){
            row = this.getBodyTable().childNodes[row];
        }
        if(!row) return;
    	var left = this.wrap.scrollLeft;
    	try{ 
    	    row.childNodes.item(0).hideFocus = true;
        	row.childNodes.item(0).focus();
        }catch(e){}
        this.ensureVisible(row);
        this.wrap.scrollLeft = left;
        this.handleScroll();
        this.lastFocusedRow = row;
    },

    
     ensureVisible : function(row, disableDelay){
        if(!disableDelay){
            this.ensureVisibleTask.delay(50, this._ensureVisible, this, [row]);
        }else{
            this._ensureVisible(row);
        }
    },

    
    _ensureVisible : function(row){
        if(typeof row == 'number'){
            row = this.getBodyTable().childNodes[row];
        }
        if(!row) return;
    	var left = this.wrap.scrollLeft;
    	var rowTop = parseInt(row.offsetTop, 10); 
        var rowBottom = rowTop + row.offsetHeight;
        var clientTop = parseInt(this.wrap.scrollTop, 10); 
        var clientBottom = clientTop + this.wrap.clientHeight;
        if(rowTop < clientTop){
        	this.wrap.scrollTop = rowTop;
        }else if(rowBottom > clientBottom){
            this.wrap.scrollTop = rowBottom-this.wrap.clientHeight;
        }
        this.wrap.scrollLeft = left;
        this.handleScroll();
    },
    
    updateColumns : function(){
        this.grid.stopEditing();
        var colModel = this.grid.colModel;
        var hcols = this.headers;
        var colCount = colModel.getColumnCount();
        var pos = 0;
        var totalWidth = colModel.getTotalWidth();
        for(var i = 0; i < colCount; i++){
            if(colModel.isHidden(i)) continue;
            var width = colModel.getColumnWidth(i);
            hcols[i].style.width = width + 'px';
            hcols[i].style.left = pos + 'px';
            hcols[i].split.style.left = (pos+width-3) + 'px';
            this.setCSSWidth(i, width, pos);
            pos += width;
        }
        this.lastWidth = totalWidth;
        if(this.grid.autoWidth){
            this.grid.container.setWidth(totalWidth+this.grid.container.getBorderWidth('lr'));
            this.grid.autoSize();
        }
        this.bwrap.setWidth(Math.max(totalWidth, this.wrap.clientWidth));
        if(!YAHOO.ext.util.Browser.isIE){ 
        	this.wrap.scrollLeft = this.hwrap.dom.scrollLeft;
        }
        this.syncScroll();
        this.forceScrollUpdate();
        if(this.grid.autoHeight){
            this.autoHeight();
            this.updateWrapHeight();
        }
    },
    
    setCSSWidth : function(colIndex, width, pos){
        var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];
        YAHOO.ext.util.CSS.updateRule(selector, 'width', width + 'px');
        if(typeof pos == 'number'){
            YAHOO.ext.util.CSS.updateRule(selector, 'left', pos + 'px');
        }
    },
    
    
     setCSSStyle : function(colIndex, name, value){
        var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];
        YAHOO.ext.util.CSS.updateRule(selector, name, value);
    },
    
    handleHiddenChange : function(colModel, colIndex, hidden){
        if(hidden){
            this.hideColumn(colIndex);
        }else{
            this.unhideColumn(colIndex);
        }
        this.updateColumns();
    },
    
    hideColumn : function(colIndex){
        var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];
        YAHOO.ext.util.CSS.updateRule(selector, 'position', 'absolute');
        YAHOO.ext.util.CSS.updateRule(selector, 'visibility', 'hidden');
        
        this.headers[colIndex].style.display = 'none';
        this.headers[colIndex].split.style.display = 'none';
    },
    
    unhideColumn : function(colIndex){
        var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];
        YAHOO.ext.util.CSS.updateRule(selector, 'position', '');
        YAHOO.ext.util.CSS.updateRule(selector, 'visibility', 'visible');
        
        this.headers[colIndex].style.display = '';
        this.headers[colIndex].split.style.display = '';
    },
    
    getBodyTable : function(){
    	return this.bwrap.dom;
    },
    
    updateRowIndexes : function(firstRow, lastRow){
        var stripeRows = this.grid.stripeRows;
        var bt = this.getBodyTable();
        var nodes = bt.childNodes;
        firstRow = firstRow || 0;
        lastRow = lastRow || nodes.length-1;
        var re = /^(?:ygrid-row ygrid-row-alt|ygrid-row)/;
        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
            var node = nodes[rowIndex];
            if(stripeRows && (rowIndex+1) % 2 == 0){
        		node.className = node.className.replace(re, 'ygrid-row ygrid-row-alt');
        	}else{
        		node.className = node.className.replace(re, 'ygrid-row');
        	}
            node.rowIndex = rowIndex;
            nodes[rowIndex].style.top = (rowIndex * this.rowHeight) + 'px';
        }
    },

    insertRows : function(dataModel, firstRow, lastRow){
        this.updateBodyHeight();
        this.adjustForScroll(true);
        var renderers = this.getColumnRenderers();
        var dindexes = this.getDataIndexes();
        var colCount = this.grid.colModel.getColumnCount();
        var beforeRow = null;
        var bt = this.getBodyTable();
        if(firstRow < bt.childNodes.length){
            beforeRow = bt.childNodes[firstRow];
        }
        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
            var row = document.createElement('span');
            row.className = 'ygrid-row';
            row.style.top = (rowIndex * this.rowHeight) + 'px';
            this.renderRow(dataModel, row, rowIndex, colCount, renderers, dindexes);
            if(beforeRow){
            	bt.insertBefore(row, beforeRow);
            }else{
                bt.appendChild(row);
            }
        }
        this.updateRowIndexes(firstRow);
        this.adjustForScroll(true);
    },
    
    renderRow : function(dataModel, row, rowIndex, colCount, renderers, dindexes){
        for(var colIndex = 0; colIndex < colCount; colIndex++){
            var td = document.createElement('span');
            td.className = 'ygrid-col ygrid-col-' + colIndex + (colIndex == colCount-1 ? ' ygrid-col-last' : '');
            td.columnIndex = colIndex;
            td.tabIndex = 0;
            var span = document.createElement('span');
            span.className = 'ygrid-cell-text';
            td.appendChild(span);
            var val = renderers[colIndex](dataModel.getValueAt(rowIndex, dindexes[colIndex]), rowIndex, colIndex, td);
            if(typeof val == 'undefined' || val === '') val = '&#160;';
            span.innerHTML = val;
            row.appendChild(td);
        }
    },
    
    deleteRows : function(dataModel, firstRow, lastRow){
        this.updateBodyHeight();
        
        this.grid.selModel.deselectRange(firstRow, lastRow);
        var bt = this.getBodyTable();
        var rows = []; 
        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
            rows.push(bt.childNodes[rowIndex]);
        }
        for(var i = 0; i < rows.length; i++){
            bt.removeChild(rows[i]);
            rows[i] = null;
        }
        rows = null;
        this.updateRowIndexes(firstRow);
        this.adjustForScroll();
    },
    
    updateRows : function(dataModel, firstRow, lastRow){
        var bt = this.getBodyTable();
        var dindexes = this.getDataIndexes();
        var renderers = this.getColumnRenderers();
        var colCount = this.grid.colModel.getColumnCount();
        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
            var row = bt.rows[rowIndex];
            var cells = row.childNodes;
            for(var colIndex = 0; colIndex < colCount; colIndex++){
                var td = cells[colIndex];
                var val = renderers[colIndex](dataModel.getValueAt(rowIndex, dindexes[colIndex]), rowIndex, colIndex, td);
                if(typeof val == 'undefined' || val === '') val = '&#160;';
                td.firstChild.innerHTML = val;
            }
        }
    },
    
    handleSort : function(dataModel, sortColumnIndex, sortDir, noRefresh){
        this.grid.selModel.syncSelectionsToIds();
        if(!noRefresh){
           this.updateRows(dataModel, 0, dataModel.getRowCount()-1);
        }
        this.updateHeaderSortState();
        if(this.lastFocusedRow){
            this.focusRow(this.lastFocusedRow);
        }
    },
    
    syncScroll : function(){
        this.hwrap.dom.scrollLeft = this.wrap.scrollLeft;
    },
    
    handleScroll : function(){
        this.syncScroll();
        this.fireScroll(this.wrap.scrollLeft, this.wrap.scrollTop);
        this.grid.fireEvent('bodyscroll', this.wrap.scrollLeft, this.wrap.scrollTop);
    },
    
    getRowHeight : function(){
        if(!this.rowHeight){
            var rule = YAHOO.ext.util.CSS.getRule(["#" + this.grid.id + " .ygrid-row", ".ygrid-row"]);
        	if(rule && rule.style.height){
        	    this.rowHeight = parseInt(rule.style.height, 10);
        	}else{
        	    this.rowHeight = 21;
        	}
        }
        return this.rowHeight;
    },
    
    renderRows : function(dataModel){
        this.grid.stopEditing();
        if(this.grid.selModel){
            this.grid.selModel.clearSelections();
        }
    	var bt = this.getBodyTable();
    	bt.innerHTML = '';
    	this.rowHeight = this.getRowHeight();
    	this.insertRows(dataModel, 0, dataModel.getRowCount()-1);
    },
    
    updateCell : function(dataModel, rowIndex, dataIndex){
        var colIndex = this.getColumnIndexByDataIndex(dataIndex);
        if(typeof colIndex == 'undefined'){ 
            return;
        }
        var bt = this.getBodyTable();
        var row = bt.childNodes[rowIndex];
        var cell = row.childNodes[colIndex];
        var renderer = this.grid.colModel.getRenderer(colIndex);
        var val = renderer(dataModel.getValueAt(rowIndex, dataIndex), rowIndex, colIndex, cell);
        if(typeof val == 'undefined' || val === '') val = '&#160;';
        cell.firstChild.innerHTML = val;
    },
    
    calcColumnWidth : function(colIndex, maxRowsToMeasure){
        var maxWidth = 0;
        var bt = this.getBodyTable();
        var rows = bt.childNodes;
        var stopIndex = Math.min(maxRowsToMeasure || rows.length, rows.length);
        if(this.grid.autoSizeHeaders){
            var h = this.headers[colIndex];
            var curWidth = h.style.width;
            h.style.width = this.grid.minColumnWidth+'px';
            maxWidth = Math.max(maxWidth, h.scrollWidth);
            h.style.width = curWidth;
        }
        for(var i = 0; i < stopIndex; i++){
            var cell = rows[i].childNodes[colIndex].firstChild;
            maxWidth = Math.max(maxWidth, cell.scrollWidth);
        }
        return maxWidth +  5;
    },
    
    
     autoSizeColumn : function(colIndex, forceMinSize){
        if(forceMinSize){
           this.setCSSWidth(colIndex, this.grid.minColumnWidth);
        }
        var newWidth = this.calcColumnWidth(colIndex);
        this.grid.colModel.setColumnWidth(colIndex,
            Math.max(this.grid.minColumnWidth, newWidth));
        this.grid.fireEvent('columnresize', colIndex, newWidth);
    },
    
    
     autoSizeColumns : function(){
        var colModel = this.grid.colModel;
        var colCount = colModel.getColumnCount();
        var wrap = this.wrap;
        for(var i = 0; i < colCount; i++){
            this.setCSSWidth(i, this.grid.minColumnWidth);
            colModel.setColumnWidth(i, this.calcColumnWidth(i, this.grid.maxRowsToMeasure), true);
        }
        if(colModel.getTotalWidth() < wrap.clientWidth){
            var diff = Math.floor((wrap.clientWidth - colModel.getTotalWidth()) / colCount);
            for(var i = 0; i < colCount; i++){
                colModel.setColumnWidth(i, colModel.getColumnWidth(i) + diff, true);
            }
        }
        this.updateColumns();  
    },
    
    
    fitColumns : function(){
        var cm = this.grid.colModel;
        var colCount = cm.getColumnCount();
        var cols = [];
        var width = 0;
        var i, w;
        for (i = 0; i < colCount; i++){
            if(!cm.isHidden(i) && !cm.isFixed(i)){
                w = cm.getColumnWidth(i);
                cols.push(i);
                cols.push(w);
                width += w;
            }
        }
        var frac = (this.wrap.clientWidth - cm.getTotalWidth())/width;
        while (cols.length){
            w = cols.pop();
            i = cols.pop();
            cm.setColumnWidth(i, Math.floor(w + w*frac), true);
        }
        this.updateColumns();
    }, 
    
    onWindowResize : function(){
        if(this.grid.monitorWindowResize){
            this.adjustForScroll();
            this.updateWrapHeight();
            this.adjustForScroll();
        }  
    },
    
    updateWrapHeight : function(){
        this.grid.container.beginMeasure();
        this.autoHeight();
        var box = this.grid.container.getSize(true);
        this.wrapEl.setHeight(box.height-this.footerHeight-parseInt(this.wrap.offsetTop, 10));
        this.pwrap.setSize(box.width, box.height);
        this.grid.container.endMeasure();
    },
    
    forceScrollUpdate : function(){
        var wrap = this.wrapEl;
        wrap.setWidth(wrap.getWidth(true));
        setTimeout(function(){ 
            wrap.setWidth('');
        }, 1);
    },
    
    updateHeaderSortState : function(){
        var state = this.grid.dataModel.getSortState();
        if(!state || typeof state.column == 'undefined') return;
        var sortColumn = this.getColumnIndexByDataIndex(state.column);
        var sortDir = state.direction;
        for(var i = 0, len = this.headers.length; i < len; i++){
            var h = this.headers[i];
            if(i != sortColumn){
                h.sortDesc.style.display = 'none';
                h.sortAsc.style.display = 'none';
            }else{
                h.sortDesc.style.display = sortDir == 'DESC' ? 'block' : 'none';
                h.sortAsc.style.display = sortDir == 'ASC' ? 'block' : 'none';
            }
        }
    },

    unplugDataModel : function(dm){
        dm.removeListener('cellupdated', this.updateCell, this);
        dm.removeListener('datachanged', this.renderRows, this);
        dm.removeListener('rowsdeleted', this.deleteRows, this);
        dm.removeListener('rowsinserted', this.insertRows, this);
        dm.removeListener('rowsupdated', this.updateRows, this);
        dm.removeListener('rowssorted', this.handleSort, this);
    },
    
    plugDataModel : function(dm){
        dm.on('cellupdated', this.updateCell, this, true);
        dm.on('datachanged', this.renderRows, this, true);
        dm.on('rowsdeleted', this.deleteRows, this, true);
        dm.on('rowsinserted', this.insertRows, this, true);
        dm.on('rowsupdated', this.updateRows, this, true);
        dm.on('rowssorted', this.handleSort, this, true);
    },
    
    destroy : function(){
        this.unplugDataModel(this.grid.dataModel);
        var sp = this.splitters;
        if(sp){
            for(var i in sp){
                if(sp[i] && typeof sp[i] != 'function'){
                    sp[i].destroy(true);
                }
            }
        }
    },
    
    render : function(){
        var grid = this.grid;
        var container = grid.container.dom;
        var dataModel = grid.dataModel;
        this.plugDataModel(dataModel);
    
        var colModel = grid.colModel;
        colModel.onWidthChange.subscribe(this.updateColumns, this, true);
        colModel.onHeaderChange.subscribe(this.updateHeaders, this, true);
        colModel.onHiddenChange.subscribe(this.handleHiddenChange, this, true);
        
        if(grid.monitorWindowResize === true){
            YAHOO.ext.EventManager.onWindowResize(this.onWindowResize, this, true);
        }
        var autoSizeDelegate = this.autoSizeColumn.createDelegate(this);
        
        var colCount = colModel.getColumnCount();
        
        var dh = YAHOO.ext.DomHelper;
        this.pwrap = dh.append(container, 
            {tag: 'div', cls: 'ygrid-positioner', 
            style: 'position:relative;width:100%;height:100%;left:0;top:0;overflow:hidden;'}, true);
        var pos = this.pwrap.dom;
        
        
        var wrap = dh.append(pos, {tag: 'div', cls: 'ygrid-wrap'});
        this.wrap = wrap;
        this.wrapEl = getEl(wrap, true);
        YAHOO.ext.EventManager.on(wrap, 'scroll', this.handleScroll, this, true);
        
        var hwrap = dh.append(pos, {tag: 'div', cls: 'ygrid-wrap-headers'});
        this.hwrap = getEl(hwrap, true);
        
        var bwrap = dh.append(wrap, {tag: 'div', cls: 'ygrid-wrap-body', id: container.id + '-body'});
        this.bwrap = getEl(bwrap, true);
        this.bwrap.setWidth(colModel.getTotalWidth());
        bwrap.rows = bwrap.childNodes;
        
        this.footerHeight = 0;
        var foot = this.appendFooter(this.pwrap.dom);
        if(foot){
            this.footer = getEl(foot, true);
            this.footerHeight = this.footer.getHeight();
        }
        this.updateWrapHeight();
        
        var hrow = dh.append(hwrap, {tag: 'span', cls: 'ygrid-hrow'});
        this.hrow = hrow;
        
        if(!YAHOO.ext.util.Browser.isGecko){
            
            var iframe = document.createElement('iframe');
            iframe.className = 'ygrid-hrow-frame';
            iframe.frameBorder = 0;
            iframe.src = YAHOO.ext.SSL_SECURE_URL;
            hwrap.appendChild(iframe);
        }
        this.headerCtrl = new YAHOO.ext.grid.HeaderController(this.grid);
        this.headers = [];
        this.cols = [];
        this.splitters = [];
        
        var htemplate = dh.createTemplate({
           tag: 'span', cls: 'ygrid-hd ygrid-header-{0}', children: [{
                tag: 'span',
                cls: 'ygrid-hd-body',
                html: '<table border="0" cellpadding="0" cellspacing="0" title="{2}">' +
                      '<tbody><tr><td><span>{1}</span></td>' +
                      '<td><span class="sort-desc"></span><span class="sort-asc"></span></td>' +
                      '</tr></tbody></table>'
           }]
        });
        htemplate.compile();
        for(var i = 0; i < colCount; i++){
            var hd = htemplate.append(hrow, [i, colModel.getColumnHeader(i), colModel.getColumnTooltip(i) || '']);
            var spans = hd.getElementsByTagName('span');
            hd.textNode = spans[1];
            hd.sortDesc = spans[2];
            hd.sortAsc = spans[3];
    	    hd.columnIndex = i;
            this.headers.push(hd);
            if(colModel.isSortable(i)){
                this.headerCtrl.register(hd);
            }
            var split = dh.append(hrow, {tag: 'span', cls: 'ygrid-hd-split'});
            hd.split = split;
        	
        	if(colModel.isResizable(i) && !colModel.isFixed(i)){
            	YAHOO.util.Event.on(split, 'dblclick', autoSizeDelegate.createCallback(i+0, true));
            	var sb = new YAHOO.ext.SplitBar(split, hd, null, YAHOO.ext.SplitBar.LEFT);
            	sb.columnIndex = i;
            	sb.minSize = grid.minColumnWidth;
            	sb.onMoved.subscribe(this.onColumnSplitterMoved, this, true);
            	YAHOO.util.Dom.addClass(sb.proxy, 'ygrid-column-sizer');
            	YAHOO.util.Dom.setStyle(sb.proxy, 'background-color', '');
            	sb.dd._resizeProxy = function(){
            	    var el = this.getDragEl();
            	    YAHOO.util.Dom.setStyle(el, 'height', (hwrap.clientHeight+wrap.clientHeight-2) +'px');
            	};
            	this.splitters[i] = sb;
        	}else{
        	    split.style.cursor = 'default';
        	}
        }
       if(grid.autoSizeColumns){
            this.renderRows(dataModel);
            this.autoSizeColumns();
        }else{
            this.updateColumns();
            this.renderRows(dataModel);
        }
        
        for(var i = 0; i < colCount; i++){
            if(colModel.isHidden(i)){
                this.hideColumn(i);
            }
        }
        this.updateHeaderSortState();
        return this.bwrap;
    },
    
    onColumnSplitterMoved : function(splitter, newSize){
        this.grid.colModel.setColumnWidth(splitter.columnIndex, newSize);
        this.grid.fireEvent('columnresize', splitter.columnIndex, newSize);
    },
    
    appendFooter : function(parentEl){
        return null;  
    },
    
    autoHeight : function(){
        if(this.grid.autoHeight){
            var h = this.getBodyHeight();
            var c = this.grid.container;
            var total = h + (parseInt(this.wrap.offsetTop, 10)||0) + 
                    this.footerHeight + c.getBorderWidth('tb') + c.getPadding('tb')
                    + (this.wrap.offsetHeight - this.wrap.clientHeight);
            c.setHeight(total);
            
        }
    },
    
    getBodyHeight : function(){
        return this.grid.dataModel.getRowCount() * this.getRowHeight();;
    },
    
    updateBodyHeight : function(){
        this.getBodyTable().style.height = this.getBodyHeight() + 'px';
        if(this.grid.autoHeight){
            this.autoHeight();
            this.updateWrapHeight();
        }
    }
};
YAHOO.ext.grid.GridView.SCROLLBARS_UNDER = 0;
YAHOO.ext.grid.GridView.SCROLLBARS_OVERLAP = 1;
YAHOO.ext.grid.GridView.prototype.scrollbarMode = YAHOO.ext.grid.GridView.SCROLLBARS_UNDER;

YAHOO.ext.grid.GridView.prototype.fitColumnsToContainer = YAHOO.ext.grid.GridView.prototype.fitColumns;

YAHOO.ext.grid.HeaderController = function(grid){
	this.grid = grid;
	this.headers = [];
};

YAHOO.ext.grid.HeaderController.prototype = {
	register : function(header){
		this.headers.push(header);
		YAHOO.ext.EventManager.on(header, 'selectstart', this.cancelTextSelection, this, true);
        YAHOO.ext.EventManager.on(header, 'mousedown', this.cancelTextSelection, this, true);
        YAHOO.ext.EventManager.on(header, 'mouseover', this.headerOver, this, true);
        YAHOO.ext.EventManager.on(header, 'mouseout', this.headerOut, this, true);
        YAHOO.ext.EventManager.on(header, 'click', this.headerClick, this, true);
	},
	
	headerClick : function(e){
	    var grid = this.grid, cm = grid.colModel, dm = grid.dataModel;
	    grid.stopEditing();
        var header = grid.getHeaderFromChild(e.getTarget());
        var state = dm.getSortState();
        var direction = header.sortDir || 'ASC';
        if(typeof state.column != 'undefined' && 
                 grid.getView().getColumnIndexByDataIndex(state.column) == header.columnIndex){
            direction = (state.direction == 'ASC' ? 'DESC' : 'ASC');
        }
        header.sortDir = direction;
        dm.sort(cm, cm.getDataIndex(header.columnIndex), direction);
    },
    
    headerOver : function(e){
        var header = this.grid.getHeaderFromChild(e.getTarget());
        YAHOO.util.Dom.addClass(header, 'ygrid-hd-over');
        
    },
    
    headerOut : function(e){
        var header = this.grid.getHeaderFromChild(e.getTarget());
        YAHOO.util.Dom.removeClass(header, 'ygrid-hd-over');
        
    },
    
    cancelTextSelection : function(e){
    	e.preventDefault();
    }
};

YAHOO.ext.grid.PagedGridView = function(){
    YAHOO.ext.grid.PagedGridView.superclass.constructor.call(this);
    this.cursor = 1;
};

YAHOO.extendX(YAHOO.ext.grid.PagedGridView, YAHOO.ext.grid.GridView, {
    appendFooter : function(parentEl){
        var fwrap = document.createElement('div');
        fwrap.className = 'ygrid-wrap-footer';
        var fbody = document.createElement('span');
        fbody.className = 'ygrid-footer';
        fwrap.appendChild(fbody);
        parentEl.appendChild(fwrap);
        this.createPagingToolbar(fbody);
        return fwrap;
    },

    createPagingToolbar : function(container){
        var tb = new YAHOO.ext.Toolbar(container);
        this.pageToolbar = tb;
        this.first = tb.addButton({
            tooltip: this.firstText, 
            className: 'ygrid-page-first',
            disabled: true,
            click: this.onClick.createDelegate(this, ['first'])
        });
        this.prev = tb.addButton({
            tooltip: this.prevText, 
            className: 'ygrid-page-prev', 
            disabled: true,
            click: this.onClick.createDelegate(this, ['prev'])
        });
        tb.addSeparator();
        tb.add(this.beforePageText);
        var pageBox = document.createElement('input');
        pageBox.type = 'text';
        pageBox.size = 3;
        pageBox.value = '1';
        pageBox.className = 'ygrid-page-number';
        tb.add(pageBox);
        this.field = getEl(pageBox, true);
        this.field.mon('keydown', this.onEnter, this, true);
        this.field.on('focus', function(){pageBox.select();});
        this.afterTextEl = tb.addText(this.afterPageText.replace('%0', '1'));
        this.field.setHeight(18);
        tb.addSeparator();
        this.next = tb.addButton({
            tooltip: this.nextText, 
            className: 'ygrid-page-next', 
            disabled: true,
            click: this.onClick.createDelegate(this, ['next'])
        });
        this.last = tb.addButton({
            tooltip: this.lastText, 
            className: 'ygrid-page-last', 
            disabled: true,
            click: this.onClick.createDelegate(this, ['last'])
        });
        tb.addSeparator();
        this.loading = tb.addButton({
            tooltip: this.refreshText, 
            className: 'ygrid-loading',
            disabled: true,
            click: this.onClick.createDelegate(this, ['refresh'])
        });
        this.onPageLoaded(1, this.grid.dataModel.getTotalPages());
    },
    
    
    getPageToolbar : function(){
        return this.pageToolbar;  
    },
    
    onPageLoaded : function(pageNum, totalPages){
        this.cursor = pageNum;
        this.lastPage = totalPages;
        this.afterTextEl.innerHTML = this.afterPageText.replace('%0', totalPages);
        this.field.dom.value = pageNum;
        this.first.setDisabled(pageNum == 1);
        this.prev.setDisabled(pageNum == 1);
        this.next.setDisabled(pageNum == totalPages);
        this.last.setDisabled(pageNum == totalPages);
        this.loading.enable();
    },
    
    onLoadError : function(){
        this.loading.enable();
    },
    
    onEnter : function(e){
        if(e.browserEvent.keyCode == e.RETURN){
            var v = this.field.dom.value;
            if(!v){
                this.field.dom.value = this.cursor;
                return;
            }
            var pageNum = parseInt(v, 10);
            if(isNaN(pageNum)){
                this.field.dom.value = this.cursor;
                return;
            }
            pageNum = Math.min(Math.max(1, pageNum), this.lastPage);
            this.grid.dataModel.loadPage(pageNum);
            e.stopEvent();
        }
    },
    
    beforeLoad : function(){
        this.grid.stopEditing();
        if(this.loading){
            this.loading.disable();
        }  
    },
    
    onClick : function(which){
        switch(which){
            case 'first':
                this.grid.dataModel.loadPage(1);
            break;
            case 'prev':
                this.grid.dataModel.loadPage(this.cursor -1);
            break;
            case 'next':
                this.grid.dataModel.loadPage(this.cursor + 1);
            break;
            case 'last':
                this.grid.dataModel.loadPage(this.lastPage);
            break;
            case 'refresh':
                this.grid.dataModel.loadPage(this.cursor);
            break;
        }
    },
    
    unplugDataModel : function(dm){
        dm.removeListener('beforeload', this.beforeLoad, this);
        dm.removeListener('load', this.onPageLoaded, this);
        dm.removeListener('loadexception', this.onLoadError, this);
        YAHOO.ext.grid.PagedGridView.superclass.unplugDataModel.call(this, dm);
    },
    
    plugDataModel : function(dm){
        dm.on('beforeload', this.beforeLoad, this, true);
        dm.on('load', this.onPageLoaded, this, true);
        dm.on('loadexception', this.onLoadError, this);
        YAHOO.ext.grid.PagedGridView.superclass.plugDataModel.call(this, dm);
    },
    
    
    beforePageText : "Page",
    
    afterPageText : "of %0",
    
    firstText : "First Page",
    
    prevText : "Previous Page",
    
    nextText : "Next Page",
    
    lastText : "Last Page",
    
    refreshText : "Refresh"
});


YAHOO.ext.grid.EditorGrid = function(container, dataModel, colModel){
	 YAHOO.ext.grid.EditorGrid.superclass.constructor.call(this, container, dataModel, 
														   colModel, new YAHOO.ext.grid.EditorSelectionModel());
	 this.container.addClass('yeditgrid');
};
YAHOO.extendX(YAHOO.ext.grid.EditorGrid, YAHOO.ext.grid.Grid);

YAHOO.ext.grid.AbstractColumnModel = function(){
	
	this.onWidthChange = new YAHOO.util.CustomEvent('widthChanged');
    this.onHeaderChange = new YAHOO.util.CustomEvent('headerChanged');
	this.onHiddenChange = new YAHOO.util.CustomEvent('hiddenChanged');
    
    this.events = {
        
	    'widthchange': this.onWidthChange,
        
	    'headerchange': this.onHeaderChange,
        
	    'hiddenchange': this.onHiddenChange
    };
};

YAHOO.ext.grid.AbstractColumnModel.prototype = {
	fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
    bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener,
    
    fireWidthChange : function(colIndex, newWidth){
		this.onWidthChange.fireDirect(this, colIndex, newWidth);
	},
	
	fireHeaderChange : function(colIndex, newHeader){
		this.onHeaderChange.fireDirect(this, colIndex, newHeader);
	},
	
	fireHiddenChange : function(colIndex, hidden){
		this.onHiddenChange.fireDirect(this, colIndex, hidden);
	},
	
	
    getColumnCount : function(){
        return 0;
    },
    
    
    isSortable : function(col){
        return false;
    },
    
    
    isHidden : function(col){
        return false;
    },
    
    
    getSortType : function(col){
        return YAHOO.ext.grid.DefaultColumnModel.sortTypes.none;
    },
    
    
    getRenderer : function(col){
        return YAHOO.ext.grid.DefaultColumnModel.defaultRenderer;
    },
    
    
    getColumnWidth : function(col){
        return 0;
    },
    
    
    getTotalWidth : function(){
        return 0;
    },
    
    
    getColumnHeader : function(col){
        return '';
    }
};


YAHOO.ext.grid.DefaultColumnModel = function(config){
	YAHOO.ext.grid.DefaultColumnModel.superclass.constructor.call(this);
    
    this.config = config;
    
    
    this.defaultWidth = 100;
    
    this.defaultSortable = false;
};
YAHOO.extendX(YAHOO.ext.grid.DefaultColumnModel, YAHOO.ext.grid.AbstractColumnModel, {
    
    
    getColumnCount : function(){
        return this.config.length;
    },
        
    
    isSortable : function(col){
        if(typeof this.config[col].sortable == 'undefined'){
            return this.defaultSortable;
        }
        return this.config[col].sortable;
    },
        
    
    getSortType : function(col){
        if(!this.dataMap){
            
            var map = [];
            for(var i = 0, len = this.config.length; i < len; i++){
                map[this.getDataIndex(i)] = i;
            }
            this.dataMap = map;
        }
        col = this.dataMap[col];
        if(!this.config[col].sortType){
            return YAHOO.ext.grid.DefaultColumnModel.sortTypes.none;
        }
        return this.config[col].sortType;
    },
        
    
    setSortType : function(col, fn){
        this.config[col].sortType = fn;
    },
        
    
    
    getRenderer : function(col){
        if(!this.config[col].renderer){
            return YAHOO.ext.grid.DefaultColumnModel.defaultRenderer;
        }
        return this.config[col].renderer;
    },
        
    
    setRenderer : function(col, fn){
        this.config[col].renderer = fn;
    },
        
    
    getColumnWidth : function(col){
        return this.config[col].width || this.defaultWidth;
    },
        
    
    setColumnWidth : function(col, width, suppressEvent){
        this.config[col].width = width;
        this.totalWidth = null;
        if(!suppressEvent){
             this.onWidthChange.fireDirect(this, col, width);
        }
    },
        
    
    getTotalWidth : function(includeHidden){
        if(!this.totalWidth){
            this.totalWidth = 0;
            for(var i = 0; i < this.config.length; i++){
                if(includeHidden || !this.isHidden(i)){
                    this.totalWidth += this.getColumnWidth(i);
                }
            }
        }
        return this.totalWidth;
    },
        
    
    getColumnHeader : function(col){
        return this.config[col].header;
    },
         
    
    setColumnHeader : function(col, header){
        this.config[col].header = header;
        this.onHeaderChange.fireDirect(this, col, header);
    },
    
    
    getColumnTooltip : function(col){
            return this.config[col].tooltip;
    },
    
    setColumnTooltip : function(col, header){
            this.config[col].tooltip = tooltip;
    },
        
    
    getDataIndex : function(col){
        if(typeof this.config[col].dataIndex != 'number'){
            return col;
        }
        return this.config[col].dataIndex;
    },
         
    
    setDataIndex : function(col, dataIndex){
        this.config[col].dataIndex = dataIndex;
    },
    
    isCellEditable : function(colIndex, rowIndex){
        return this.config[colIndex].editable || (typeof this.config[colIndex].editable == 'undefined' && this.config[colIndex].editor);
    },
    
    
    getCellEditor : function(colIndex, rowIndex){
        return this.config[colIndex].editor;
    },
       
    
    setEditable : function(col, editable){
        this.config[col].editable = editable;
    },
    
    
    
    isHidden : function(colIndex){
        return this.config[colIndex].hidden;
    },
    
    
    
    isFixed : function(colIndex){
        return this.config[colIndex].fixed;
    },
    
    
    isResizable : function(colIndex){
        return this.config[colIndex].resizable !== false;
    },
    
    setHidden : function(colIndex, hidden){
        this.config[colIndex].hidden = hidden;
        this.totalWidth = null;
        this.fireHiddenChange(colIndex, hidden);
    },
    
    
    setEditor : function(col, editor){
        this.config[col].editor = editor;
    }
});


YAHOO.ext.grid.DefaultColumnModel.sortTypes = {
    none : function(s) {
    	return s;
    },

    asUCString : function(s) {
    	return String(s).toUpperCase();
    },
    
    asDate : function(s) {
        if(s instanceof Date){
            return s.getTime();
        }
    	return Date.parse(String(s));
    },
    
    asFloat : function(s) {
    	var val = parseFloat(String(s).replace(/,/g, ''));
        if(isNaN(val)) val = 0;
    	return val;
    },
    
    asInt : function(s) {
        var val = parseInt(String(s).replace(/,/g, ''));
        if(isNaN(val)) val = 0;
    	return val;
    }
};

YAHOO.ext.grid.DefaultColumnModel.defaultRenderer = function(value){
	if(typeof value == 'string' && value.length < 1){
	    return '&#160;';
	}
	return value;
};

YAHOO.ext.grid.AbstractDataModel = function(){
    
    this.onCellUpdated = new YAHOO.util.CustomEvent('onCellUpdated');
    
    this.onTableDataChanged = new YAHOO.util.CustomEvent('onTableDataChanged');
    
    this.onRowsDeleted = new YAHOO.util.CustomEvent('onRowsDeleted');
    
    this.onRowsInserted = new YAHOO.util.CustomEvent('onRowsInserted');
    
    this.onRowsUpdated = new YAHOO.util.CustomEvent('onRowsUpdated');
    
    this.onRowsSorted = new YAHOO.util.CustomEvent('onRowsSorted');
    
    this.events = {
      
      'cellupdated' : this.onCellUpdated,
      
      'datachanged' : this.onTableDataChanged,
      
      'rowsdeleted' : this.onRowsDeleted,
      
      'rowsinserted' : this.onRowsInserted,
      
      'rowsupdated' : this.onRowsUpdated,
      
      'rowssorted' : this.onRowsSorted
    };
};

YAHOO.ext.grid.AbstractDataModel.prototype = {
    
    fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
    bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener,
    
    
    fireCellUpdated : function(row, col){
        this.onCellUpdated.fireDirect(this, row, col);
    },
    
    
    fireTableDataChanged : function(){
        this.onTableDataChanged.fireDirect(this);
    },
    
    
    fireRowsDeleted : function(firstRow, lastRow){
        this.onRowsDeleted.fireDirect(this, firstRow, lastRow);
    },
    
    
    fireRowsInserted : function(firstRow, lastRow){
        this.onRowsInserted.fireDirect(this, firstRow, lastRow);
    },
    
    
    fireRowsUpdated : function(firstRow, lastRow){
        this.onRowsUpdated.fireDirect(this, firstRow, lastRow);
    },
    
    
    fireRowsSorted : function(sortColumnIndex, sortDir, noRefresh){
        this.onRowsSorted.fireDirect(this, sortColumnIndex, sortDir, noRefresh);
    },
    
    
    sort : function(sortInfo, columnIndex, direction, suppressEvent){
    	
    },
    
    
    getSortState : function(){
    	return {column: this.sortColumn, direction: this.sortDir};
    },
    
    
    getRowCount : function(){
    	
    },
    
    
    getTotalRowCount : function(){
    	return this.getRowCount();
    },
    
    
    
    getRowId : function(rowIndex){
    	
    },
    
    
    getValueAt : function(rowIndex, colIndex){
    	
    },
    
    
    setValueAt : function(value, rowIndex, colIndex){
    	
    },
    
    isPaged : function(){
        return false;
    }
};


YAHOO.ext.grid.DefaultDataModel = function(data){
    YAHOO.ext.grid.DefaultDataModel.superclass.constructor.call(this);
    
    this.data = data;
};
YAHOO.extendX(YAHOO.ext.grid.DefaultDataModel, YAHOO.ext.grid.AbstractDataModel, {
    
    getRowCount : function(){
        return this.data.length;
    },
        
    
    getRowId : function(rowIndex){
        return this.data[rowIndex][0];
    },
    
    
    getRow : function(rowIndex){
        return this.data[rowIndex];
    },
    
    
    getRows : function(indexes){
        var data = this.data;
        var r = [];
        for(var i = 0; i < indexes.length; i++){
           r.push(data[indexes[i]]);
        }
        return r;
    },
    
    
    getValueAt : function(rowIndex, colIndex){
    	return this.data[rowIndex][colIndex];
    },
    
    
    setValueAt: function(value, rowIndex, colIndex){
        this.data[rowIndex][colIndex] = value;
        this.fireCellUpdated(rowIndex, colIndex);
    },
    
    
    removeRows: function(startIndex, endIndex){
        endIndex = endIndex || startIndex;
        this.data.splice(startIndex, endIndex-startIndex+1);
        this.fireRowsDeleted(startIndex, endIndex);
    },
    
    
    removeRow: function(index){
        this.data.splice(index, 1);
        this.fireRowsDeleted(index, index);
    },
    
    
    removeAll: function(){
    	var count = this.getRowCount();
    	if(count > 0){
        	this.removeRows(0, count-1);
    	}
    },
    
    
    query: function(spec, returnUnmatched){
        var d = this.data;
        var r = [];
        for(var i = 0; i < d.length; i++){
            var row = d[i];
            var isMatch = true;
            for(var col in spec){
                
                    if(!isMatch) continue;
                    var filter = spec[col];
                    switch(typeof filter){
                        case 'string':
                        case 'number':
                        case 'boolean':
                          if(row[col] != filter){
                              isMatch = false;
                          }
                        break;
                        case 'function':
                          if(!filter(row[col], row)){
                              isMatch = false;
                          }
                        break;
                        case 'object':
                           if(filter instanceof RegExp){
                               if(String(row[col]).search(filter) === -1){
                                   isMatch = false;
                               }
                           }
                        break;
                    }
                
            }
            if(isMatch && !returnUnmatched){
                r.push(i);
            }else if(!isMatch && returnUnmatched){
                r.push(i);
            }
        }
        return r;
    },
    
    
    filter: function(query){
        var matches = this.query(query, true);
        var data = this.data;
        
        
        for(var i = 0; i < matches.length; i++){ 
            data[matches[i]]._deleted = true;
        }
        for(var i = 0; i < data.length; i++){
            while(data[i] && data[i]._deleted === true){
                this.removeRow(i);
            }
        }
        return matches.length;
    },
    
    
    addRow: function(cellValues){
        this.data.push(cellValues);
        var newIndex = this.data.length-1;
        this.fireRowsInserted(newIndex, newIndex);
        this.applySort();
        return newIndex;
    },
    
    
    addRows: function(rowData){
        this.data = this.data.concat(rowData);
        var firstIndex = this.data.length-rowData.length;
        this.fireRowsInserted(firstIndex, firstIndex+rowData.length-1);
        this.applySort();
    },
    
    
    insertRow: function(index, cellValues){
        this.data.splice(index, 0, cellValues);
        this.fireRowsInserted(index, index);
        this.applySort();
        return index;
    },
    
    
    insertRows: function(index, rowData){
        
        var args = rowData.concat();
        args.splice(0, 0, index, 0);
        this.data.splice.apply(this.data, args);
        this.fireRowsInserted(index, index+rowData.length-1);
        this.applySort();
    },
    
    
    applySort: function(suppressEvent){
    	if(typeof this.sortColumn != 'undefined'){
    		this.sort(this.sortInfo, this.sortColumn, this.sortDir, suppressEvent);
    	}
    },
    
    
    setDefaultSort: function(sortInfo, columnIndex, direction){
        this.sortInfo = sortInfo;
        this.sortColumn = columnIndex;
        this.sortDir = direction;
    },
    
    sort: function(sortInfo, columnIndex, direction, suppressEvent){
        
        this.sortInfo = sortInfo;
        this.sortColumn = columnIndex;
        this.sortDir = direction;
        
        var dsc = (direction && direction.toUpperCase() == 'DESC');
        var sortType = null;
        if(sortInfo != null){
            if(typeof sortInfo == 'function'){
                sortType = sortInfo;
            }else if(typeof sortInfo == 'object'){
                sortType = sortInfo.getSortType(columnIndex);;
            }
        }
        var fn = function(cells, cells2){
            var v1 = sortType ? sortType(cells[columnIndex], cells) : cells[columnIndex];
            var v2 = sortType ? sortType(cells2[columnIndex], cells2) : cells2[columnIndex];
            if(v1 < v2)
    			return dsc ? +1 : -1;
    		if(v1 > v2)
    			return dsc ? -1 : +1;
    	    return 0;
        };
        this.data.sort(fn);
        if(!suppressEvent){
           this.fireRowsSorted(columnIndex, direction);
        }
    },
    
     
    each: function(fn, scope){
        var d = this.data;
        for(var i = 0, len = d.length; i < len; i++){
            if(fn.call(scope || window, d[i], i) === false) break;
        }
    }
});


if(YAHOO.ext.grid.DefaultColumnModel){
    YAHOO.ext.grid.DefaultDataModel.sortTypes = YAHOO.ext.grid.DefaultColumnModel.sortTypes;
}

YAHOO.ext.grid.LoadableDataModel = function(dataType){
    YAHOO.ext.grid.LoadableDataModel.superclass.constructor.call(this, []);
    
    
    this.onLoad = new YAHOO.util.CustomEvent('load');
    
    this.onLoadException = new YAHOO.util.CustomEvent('loadException');
    
    this.events['load'] = this.onLoad;
    
    this.events['beforeload'] = new YAHOO.util.CustomEvent('beforeload');
    
    this.events['loadexception'] = this.onLoadException;
    
    
    this.dataType = dataType;
    
    this.preprocessors = [];
    
    this.postprocessors = [];
    
    
    
    this.loadedPage = 1;
    
    this.remoteSort = false;
    
    this.pageSize = 0;
    
    this.pageUrl = null;
    
    this.baseParams = {};
    
    this.paramMap = {'page':'page', 'pageSize':'pageSize', 'sortColumn':'sortColumn', 'sortDir':'sortDir'};
    
};
YAHOO.extendX(YAHOO.ext.grid.LoadableDataModel, YAHOO.ext.grid.DefaultDataModel, {
    
    
    setLoadedPage: function(pageNum, userCallback){
        this.loadedPage = pageNum;
        if(typeof userCallback == 'function'){
            userCallback();
        }
    },
    
    
    isPaged: function(){
        return this.pageSize > 0;
    },
    
    
    getTotalRowCount: function(){
        return this.totalCount || this.getRowCount();
    },
    
    
    getPageSize: function(){
        return this.pageSize;
    },
    
    
    getTotalPages: function(){
        if(this.getPageSize() == 0 || this.getTotalRowCount() == 0){
            return 1;
        }
        return Math.ceil(this.getTotalRowCount()/this.getPageSize());
    },
    
    
    initPaging: function(url, pageSize, baseParams){
        this.pageUrl = url;
        this.pageSize = pageSize;
        this.remoteSort = true;
        if(baseParams) this.baseParams = baseParams;
    },
    
    
    createParams: function(pageNum, sortColumn, sortDir){
        var params = {}, map = this.paramMap;
        for(var key in this.baseParams){
            if(typeof this.baseParams[key] != 'function'){
                params[key] = this.baseParams[key];
            }
        }
        params[map['page']] = pageNum;
        params[map['pageSize']] = this.getPageSize();
        params[map['sortColumn']] = (typeof sortColumn == 'undefined' ? '' : sortColumn);
        params[map['sortDir']] = sortDir || '';
        return params;
    },
    
    
    loadPage: function(pageNum, callback, keepExisting){
        var sort = this.getSortState();
        var params = this.createParams(pageNum, sort.column, sort.direction);
        this.load(this.pageUrl, params, this.setLoadedPage.createDelegate(this, [pageNum, callback]), 
                   keepExisting ? (pageNum-1) * this.pageSize : null);
    },
    
    
    applySort: function(suppressEvent){
    	if(!this.remoteSort){
            YAHOO.ext.grid.LoadableDataModel.superclass.applySort.apply(this, arguments);
        }else if(!suppressEvent){
            var sort = this.getSortState();
            if(sort.column){
               this.fireRowsSorted(sort.column, sort.direction, true);
            }
        }
    },
    
    
    resetPaging: function(){
    	this.loadedPage = 1;
    },
    
    
    sort: function(sortInfo, columnIndex, direction, suppressEvent){
        if(!this.remoteSort){
            YAHOO.ext.grid.LoadableDataModel.superclass.sort.apply(this, arguments);
        }else{
            this.sortInfo = sortInfo;
            this.sortColumn = columnIndex;
            this.sortDir = direction;
            var params = this.createParams(this.loadedPage, columnIndex, direction);
            this.load(this.pageUrl, params, this.fireRowsSorted.createDelegate(this, [columnIndex, direction, true]));
        }
    },
    
    
    load: function(url, params, callback, insertIndex){
    	this.fireEvent('beforeload', this);
    	if(params && typeof params != 'string'){ 
            var buf = [];
            for(var key in params){
                if(typeof params[key] != 'function'){
                    buf.push(encodeURIComponent(key), '=', encodeURIComponent(params[key]), '&');
                }
            }
            delete buf[buf.length-1];
            params = buf.join('');
        }
        var cb = {
            success: this.processResponse,
            failure: this.processException,
            scope: this,
    		argument: {callback: callback, insertIndex: insertIndex}
        };
        var method = params ? 'POST' : 'GET';
        this.transId = YAHOO.util.Connect.asyncRequest(method, url, cb, params);
    },
    
    
    processResponse: function(response){
        var cb = response.argument.callback;
        var keepExisting = (typeof response.argument.insertIndex == 'number');
        var insertIndex = response.argument.insertIndex;
        switch(this.dataType){
        	case YAHOO.ext.grid.LoadableDataModel.XML:
        		this.loadData(response.responseXML, cb, keepExisting, insertIndex);
        	break;
        	case YAHOO.ext.grid.LoadableDataModel.JSON:
        		var rtext = response.responseText;
        		try { 
    		        
    		        while(rtext.substring(0,1) == " ") {
    		            rtext = rtext.substring(1, rtext.length);
    		        }
    		        
    		        if(rtext.indexOf("{") < 0) {
    		            throw "Invalid JSON response";
    		        }
    		
    		        
    		        if(rtext.indexOf("{}") === 0) {
    		            this.loadData({}, response.argument.callback);
    		            return;
    		        }
    		
    		        
    		        
    		        var jsonObjRaw = eval("(" + rtext + ")");
    		        if(!jsonObjRaw) {
    		            throw "Error evaling JSON response";
    		        }
    				this.loadData(jsonObjRaw, cb, keepExisting, insertIndex);
    		    } catch(e) {
    		        this.fireLoadException(e, response);
    				if(typeof cb == 'function'){
    			    	cb(this, false);
    			    }
    		   	}
        	break;
        	case YAHOO.ext.grid.LoadableDataModel.TEXT:
        		this.loadData(response.responseText, cb, keepExisting, insertIndex);
        	break;
        };
    },
    
    
    processException: function(response){
        this.fireLoadException(null, response);
        if(typeof response.argument.callback == 'function'){
            response.argument.callback(this, false);
        }
    },
    
    fireLoadException: function(e, responseObj){
        this.onLoadException.fireDirect(this, e, responseObj);
    },
    
    fireLoadEvent: function(){
        this.fireEvent('load', this.loadedPage, this.getTotalPages());
    },
    
    
    addPreprocessor: function(columnIndex, fn){
        this.preprocessors[columnIndex] = fn;
    },
    
    
    getPreprocessor: function(columnIndex){
        return this.preprocessors[columnIndex];
    },
    
    
    removePreprocessor: function(columnIndex){
        this.preprocessors[columnIndex] = null;
    },
    
    
    addPostprocessor: function(columnIndex, fn){
        this.postprocessors[columnIndex] = fn;
    },
    
    
    getPostprocessor: function(columnIndex){
        return this.postprocessors[columnIndex];
    },
    
    
    removePostprocessor: function(columnIndex){
        this.postprocessors[columnIndex] = null;
    },
    
    loadData: function(data, callback, keepExisting, insertIndex){
    	
    }
});

YAHOO.ext.grid.LoadableDataModel.XML = 'xml';
YAHOO.ext.grid.LoadableDataModel.JSON = 'json';
YAHOO.ext.grid.LoadableDataModel.TEXT = 'text';







YAHOO.ext.grid.XMLDataModel = function(schema, xml){
    YAHOO.ext.grid.XMLDataModel.superclass.constructor.call(this, YAHOO.ext.grid.LoadableDataModel.XML);
    
    this.schema = schema;
    this.xml = xml;
    if(xml){
        this.loadData(xml);
    }
    this.idSeed = 0;
};
YAHOO.extendX(YAHOO.ext.grid.XMLDataModel, YAHOO.ext.grid.LoadableDataModel, {
    
    getDocument: function(){
       return this.xml;    
    },
    
    
    loadData: function(doc, callback, keepExisting, insertIndex){
    	this.xml = doc;
    	var idField = this.schema.id;
    	var fields = this.schema.fields;
    	if(this.schema.totalTag){
    	    this.totalCount = null;
    	    var totalNode = doc.getElementsByTagName(this.schema.totalTag);
    	    if(totalNode && totalNode.item(0) && totalNode.item(0).firstChild) {
                var v = parseInt(totalNode.item(0).firstChild.nodeValue, 10);
                if(!isNaN(v)){
                    this.totalCount = v;
                }
        	}
    	}
    	var rowData = [];
    	var nodes = doc.getElementsByTagName(this.schema.tagName);
        if(nodes && nodes.length > 0) {
    	    for(var i = 0; i < nodes.length; i++) {
    	        var node = nodes.item(i);
    	        var colData = [];
    	        colData.node = node;
    	        colData.id = this.getNamedValue(node, idField, String(++this.idSeed));
    	        for(var j = 0; j < fields.length; j++) {
    	            var val = this.getNamedValue(node, fields[j], "");
    	            if(this.preprocessors[j]){
    	                val = this.preprocessors[j](val);
    	            }
    	            colData.push(val);
    	        }
    	        rowData.push(colData);
    	    }
        }
        if(keepExisting !== true){
           YAHOO.ext.grid.XMLDataModel.superclass.removeAll.call(this);
    	}
    	if(typeof insertIndex != 'number'){
    	    insertIndex = this.getRowCount();
    	}
        YAHOO.ext.grid.XMLDataModel.superclass.insertRows.call(this, insertIndex, rowData);
        if(typeof callback == 'function'){
        	callback(this, true);
        }
        this.fireLoadEvent();
    },
    
    
    addRow: function(id, cellValues){
        var node = this.createNode(this.xml, id, cellValues);
        cellValues.id = id || ++this.idSeed;
        cellValues.node = node;
        return YAHOO.ext.grid.XMLDataModel.superclass.addRow.call(this, cellValues);
    },
    
    
    insertRow: function(index, id, cellValues){
        var node = this.createNode(this.xml, id, cellValues);
        cellValues.id = id || ++this.idSeed;
        cellValues.node = node;
        return YAHOO.ext.grid.XMLDataModel.superclass.insertRow.call(this, index, cellValues);
    },
    
    
    removeRow: function(index){
        var node = this.data[index].node;
        node.parentNode.removeChild(node);
        YAHOO.ext.grid.XMLDataModel.superclass.removeRow.call(this, index, index);
    },
    
    getNode: function(rowIndex){
        return this.data[rowIndex].node;
    },
    
    
    createNode: function(xmlDoc, id, colData){
        var template = this.data[0].node;
        var newNode = template.cloneNode(true);
        var fields = this.schema.fields;
        for(var i = 0, len = fields.length; i < len; i++){
            var nodeValue = colData[i];
            if(this.postprocessors[i]){
                nodeValue = this.postprocessors[i](nodeValue);
            }
            this.setNamedValue(newNode, fields[i], nodeValue);
        }
        if(id){
            this.setNamedValue(newNode, this.schema.idField, id);
        }
        template.parentNode.appendChild(newNode);
        return newNode;
    },
    
    
    getNamedValue: function(node, name, defaultValue){
    	if(!node || !name){
    		return defaultValue;
    	}
    	var nodeValue = defaultValue;
        var attrNode = node.attributes.getNamedItem(name);
        if(attrNode) {
        	nodeValue = attrNode.value;
        } else {
            var childNode = node.getElementsByTagName(name);
            if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
                nodeValue = childNode.item(0).firstChild.nodeValue;
        	}else{
        	    
        	    var index = name.indexOf(':');
        	    if(index > 0){
        	        return this.getNamedValue(node, name.substr(index+1), defaultValue);
        	    }
        	}
        }
        return nodeValue;
    },
    
    
    setNamedValue: function(node, name, value){
    	if(!node || !name){
    		return;
    	}
    	var attrNode = node.attributes.getNamedItem(name);
        if(attrNode) {
        	attrNode.value = value;
        	return;
        }
        var childNode = node.getElementsByTagName(name);
        if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
            childNode.item(0).firstChild.nodeValue = value;
        }else{
    	    
    	    var index = name.indexOf(':');
    	    if(index > 0){
    	        this.setNamedValue(node, name.substr(index+1), value);
    	    }
    	}
    },
    
    
    setValueAt: function(value, rowIndex, colIndex){
        var node = this.data[rowIndex].node;
        if(node){
            var nodeValue = value;
            if(this.postprocessors[colIndex]){
                nodeValue = this.postprocessors[colIndex](value);
            }
            this.setNamedValue(node, this.schema.fields[colIndex], nodeValue);
        }
        YAHOO.ext.grid.XMLDataModel.superclass.setValueAt.call(this, value, rowIndex, colIndex);
    },
    
    
    getRowId: function(rowIndex){
        return this.data[rowIndex].id;
    },
    
    addRows : function(rowData){   
        for(var j = 0, len = rowData.length; j < len; j++){
           var cellValues = rowData[j];
           var id = ++this.idSeed; 
           var node = this.createNode(this.xml, id, cellValues);       
           cellValues.node=node;
           cellValues.id = cellValues.id || id;
           YAHOO.ext.grid.XMLDataModel.superclass.addRow.call(this,cellValues);
        }
    },   

   insertRows : function(index, rowData){
       
       rowData = rowData.slice(0).reverse();
       for(var j = 0, len = rowData.length; j < len; j++){
          var cellValues = rowData[j];
          var id = ++this.idSeed; 
          var node = this.createNode(this.xml, id, cellValues);
          cellValues.id = cellValues.id || id;
          cellValues.node = node;
          YAHOO.ext.grid.XMLDataModel.superclass.insertRow.call(this, index, cellValues);
       }
   }
});

YAHOO.ext.grid.XMLQueryDataModel = function(){
   YAHOO.ext.grid.XMLQueryDataModel.superclass.constructor.apply(this, arguments);
};
YAHOO.extendX(YAHOO.ext.grid.XMLQueryDataModel, YAHOO.ext.grid.XMLDataModel, {
    getNamedValue: function(node, name, defaultValue){
    	if(!node || !name){
    		return defaultValue;
    	}
    	var nodeValue = defaultValue;
    	var childNode = cssQuery(name, node);
    	if(childNode && childNode[0]) {
            nodeValue = childNode[0].firstChild.nodeValue;
    	}
        return nodeValue;
    }
});


YAHOO.ext.grid.JSONDataModel = function(schema){
    YAHOO.ext.grid.JSONDataModel.superclass.constructor.call(this, YAHOO.ext.grid.LoadableDataModel.JSON);
    
    this.schema = schema;
};
YAHOO.extendX(YAHOO.ext.grid.JSONDataModel, YAHOO.ext.grid.LoadableDataModel, {
    
    loadData : function(data, callback, keepExisting){
    	var idField = this.schema.id;
    	var fields = this.schema.fields;
    	try{
        	if(this.schema.totalProperty){
                var v = parseInt(eval('data.' + this.schema.totalProperty), 10);
                if(!isNaN(v)){
                    this.totalCount = v;
                }
            }
        	var rowData = [];
    	    var root = eval('data.' + this.schema.root);
    	    for(var i = 0; i < root.length; i++){
    			var node = root[i];
    			var colData = [];
    			colData.node = node;
    			colData.id = (typeof node[idField] != 'undefined' && node[idField] !== '' ? node[idField] : String(i));
    			for(var j = 0; j < fields.length; j++) {
    			    var val = node[fields[j]];
    			    if(typeof val == 'undefined'){
    			        val = '';
    			    }
    	            if(this.preprocessors[j]){
    	                val = this.preprocessors[j](val);
    	            }
    	            colData.push(val);
    	        }
    	        rowData.push(colData);
    		}
    		if(keepExisting !== true){
    		  this.removeAll();
    		}
            this.addRows(rowData);
        	if(typeof callback == 'function'){
    	    	callback(this, true);
    	    }
          	this.fireLoadEvent();
    	}catch(e){
    		this.fireLoadException(e, null);
    		if(typeof callback == 'function'){
    	    	callback(this, false);
    	    }
    	}
    },
    
    
    getRowId : function(rowIndex){
        return this.data[rowIndex].id;
    }
});

YAHOO.ext.grid.DefaultSelectionModel = function(){
    this.selectedRows = [];
    this.selectedRowIds = [];
    this.lastSelectedRow = null;
    
    this.onRowSelect = new YAHOO.util.CustomEvent('SelectionTable.rowSelected');
    this.onSelectionChange = new YAHOO.util.CustomEvent('SelectionTable.selectionChanged');
    
    this.events = {
        
	    'selectionchange' : this.onSelectionChange,
        
	    'rowselect' : this.onRowSelect
    };
    
    this.locked = false;
};

YAHOO.ext.grid.DefaultSelectionModel.prototype = {
    
    init : function(grid){
        this.grid = grid;
        this.initEvents();
    },
    
    
    lock : function(){
        this.locked = true;
    },
    
    
    unlock : function(){
        this.locked = false;  
    },
    
    
    isLocked : function(){
        return this.locked;    
    },
    
    
    initEvents : function(){
        if(this.grid.trackMouseOver){
        	this.grid.addListener("mouseover", this.handleOver, this, true);
        	this.grid.addListener("mouseout", this.handleOut, this, true);
        }
        this.grid.addListener("rowclick", this.rowClick, this, true);
        this.grid.addListener("keydown", this.keyDown, this, true);
    },
    
    fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent,
    on : YAHOO.ext.util.Observable.prototype.on,
    addListener : YAHOO.ext.util.Observable.prototype.addListener,
    delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener,
    removeListener : YAHOO.ext.util.Observable.prototype.removeListener,
    purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners,
    bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener,
    
    
    syncSelectionsToIds : function(){
        if(this.getCount() > 0){
            var ids = this.selectedRowIds.concat();
            this.clearSelections();
            this.selectRowsById(ids, true);
        }
    },
    
    
    selectRowsById : function(id, keepExisting){
        var rows = this.grid.getRowsById(id);
        if (!(rows instanceof Array)){
            this.selectRow(rows, keepExisting);
            return;
        }
        this.selectRows(rows, keepExisting);
    },
    
    
    getCount : function(){
        return this.selectedRows.length;
    },
    
    
    selectFirstRow : function(){
        for(var j = 0; j < this.grid.rows.length; j++){
            if(this.isSelectable(this.grid.rows[j])){
            	this.focusRow(this.grid.rows[j]);
                this.setRowState(this.grid.rows[j], true);
                return;
            }
        }
    },
    
    
    selectNext : function(keepExisting){
        if(this.lastSelectedRow){
            for(var j = (this.lastSelectedRow.rowIndex+1); j < this.grid.rows.length; j++){
                var row = this.grid.rows[j];
                if(this.isSelectable(row)){
                    this.focusRow(row);
                    this.setRowState(row, true, keepExisting);
                    return;
                }
            }
        }
    },
    
    
    selectPrevious : function(keepExisting){
        if(this.lastSelectedRow){
            for(var j = (this.lastSelectedRow.rowIndex-1); j >= 0; j--){
                var row = this.grid.rows[j];
                if(this.isSelectable(row)){
                    this.focusRow(row);
                    this.setRowState(row, true, keepExisting);
                    return;
                }
            }
        }
    },
    
    
    getSelectedRows : function(){
        return this.selectedRows;
    },
    
    
    getSelectedRowIds : function(){
        return this.selectedRowIds;
    },
    
    
    clearSelections : function(){
        if(this.isLocked()) return;
        var oldSelections = this.selectedRows.concat();
        for(var j = 0; j < oldSelections.length; j++){
            this.setRowState(oldSelections[j], false);
        }
        this.selectedRows = [];
        this.selectedRowIds = [];
    },
    
        
    
    selectAll : function(){
        if(this.isLocked()) return;
        this.selectedRows = [];
        this.selectedRowIds = [];
        for(var j = 0, len = this.grid.rows.length; j < len; j++){
            this.setRowState(this.grid.rows[j], true, true);
        }
    },
    
    
    hasSelection : function(){
        return this.selectedRows.length > 0;
    },
    
    
    isSelected : function(row){
        return row && (row.selected === true || row.getAttribute('selected') == 'true');
    },
    
    
    isSelectable : function(row){
        return row && row.getAttribute('selectable') != 'false';
    },
    
    
    rowClick : function(grid, rowIndex, e){
        if(this.isLocked()) return;
        var row = grid.getRow(rowIndex);
        if(this.isSelectable(row)){
            if(e.shiftKey && this.lastSelectedRow){
                var lastIndex = this.lastSelectedRow.rowIndex;
                this.selectRange(this.lastSelectedRow, row, e.ctrlKey);
                this.lastSelectedRow = this.grid.el.dom.rows[lastIndex];
            }else{
                this.focusRow(row);
                var rowState = e.ctrlKey ? !this.isSelected(row) : true;
                this.setRowState(row, rowState, e.hasModifier());
            }
        }
    },
    
    
    focusRow : function(row){
    	this.grid.view.focusRow(row);
    },

    
    selectRow : function(row, keepExisting){
        this.setRowState(this.getRow(row), true, keepExisting);
    },
    
    
    selectRows : function(rows, keepExisting){
        if(!keepExisting){
            this.clearSelections();
        }
        for(var i = 0; i < rows.length; i++){
            this.selectRow(rows[i], true);
        }
    },
    
    
    deselectRow : function(row){
        this.setRowState(this.getRow(row), false);
    },
    
    
    getRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.rows[row];
        }
        return row;
    },
    
    
    selectRange : function(startRow, endRow, keepExisting){
        startRow = this.getRow(startRow);
        endRow = this.getRow(endRow);
        this.setRangeState(startRow, endRow, true, keepExisting);
    },
    
    
    deselectRange : function(startRow, endRow){
        startRow = this.getRow(startRow);
        endRow = this.getRow(endRow);
        this.setRangeState(startRow, endRow, false, true);
    },
    
    
    setRowStateFromChild : function(childEl, selected, keepExisting){
        var row = this.grid.getRowFromChild(childEl);
        this.setRowState(row, selected, keepExisting);
    },
    
    
    setRangeState : function(startRow, endRow, selected, keepExisting){
        if(this.isLocked()) return;
        if(!keepExisting){
            this.clearSelections();
        }
        var curRow = startRow;
        while(curRow.rowIndex != endRow.rowIndex){
            this.setRowState(curRow, selected, true);
            curRow = (startRow.rowIndex < endRow.rowIndex ? 
                        this.grid.getRowAfter(curRow) : this.grid.getRowBefore(curRow))
        }
        this.setRowState(endRow, selected, true);
    },
    
    
    setRowState : function(row, selected, keepExisting){
        if(this.isLocked()) return;
        if(this.isSelectable(row)){
            if(selected){
                if(!keepExisting){
                    this.clearSelections();
                }
                this.setRowClass(row, 'selected');
                row.selected = true;
                this.selectedRows.push(row);
                this.selectedRowIds.push(this.grid.dataModel.getRowId(row.rowIndex));
                this.lastSelectedRow = row;
            }else{
                this.setRowClass(row, '');
                row.selected = false;
                this._removeSelected(row);
            }
            this.fireEvent('rowselect', this, row, selected);
            this.fireEvent('selectionchange', this, this.selectedRows, this.selectedRowIds);
        }
    },

    
    handleOver : function(e){
        var row = this.grid.getRowFromChild(e.getTarget());
        if(this.isSelectable(row) && !this.isSelected(row)){
            this.setRowClass(row, 'over');
        }
    },
    
    
    handleOut : function(e){
        var row = this.grid.getRowFromChild(e.getTarget());
        if(this.isSelectable(row) && !this.isSelected(row)){
            this.setRowClass(row, '');
        }
    },
    
    
    keyDown : function(e){
        if(e.browserEvent.keyCode == e.DOWN){
            this.selectNext(e.shiftKey);
            e.preventDefault();
        }else if(e.browserEvent.keyCode == e.UP){
            this.selectPrevious(e.shiftKey);
            e.preventDefault();
        }
    },

    
    setRowClass : function(row, cssClass){
        if(this.isSelectable(row)){
            if(cssClass == 'selected'){
                YAHOO.util.Dom.removeClass(row, 'ygrid-row-over');
                YAHOO.util.Dom.addClass(row, 'ygrid-row-selected');
            }else if(cssClass == 'over'){
                YAHOO.util.Dom.removeClass(row, 'ygrid-row-selected');
                YAHOO.util.Dom.addClass(row, 'ygrid-row-over');
            }else if(cssClass == ''){
                YAHOO.util.Dom.removeClass(row, 'ygrid-row-selected');
                YAHOO.util.Dom.removeClass(row, 'ygrid-row-over');
            }
        }
    },
    
    
    _removeSelected : function(row){
        var sr = this.selectedRows;
        for (var i = 0; i < sr.length; i++) {
          if (sr[i] === row){
              this.selectedRows.splice(i, 1);
              this.selectedRowIds.splice(i, 1);
              return;
          }
        }
    }
};


YAHOO.ext.grid.SingleSelectionModel = function(){
    YAHOO.ext.grid.SingleSelectionModel.superclass.constructor.call(this);
};

YAHOO.extendX(YAHOO.ext.grid.SingleSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);


YAHOO.ext.grid.SingleSelectionModel.prototype.setRowState = function(row, selected){
    YAHOO.ext.grid.SingleSelectionModel.superclass.setRowState.call(this, row, selected, false);
};

YAHOO.ext.grid.DisableSelectionModel = function(){
    YAHOO.ext.grid.DisableSelectionModel.superclass.constructor.call(this);
};

YAHOO.extendX(YAHOO.ext.grid.DisableSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);

YAHOO.ext.grid.DisableSelectionModel.prototype.initEvents = function(){
};


YAHOO.ext.grid.EditorSelectionModel = function(){
    YAHOO.ext.grid.EditorSelectionModel.superclass.constructor.call(this);
    
    this.clicksToActivateCell = 1;
    this.events['cellactivate'] = new YAHOO.util.CustomEvent('cellactivate');
};

YAHOO.extendX(YAHOO.ext.grid.EditorSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);

YAHOO.ext.grid.EditorSelectionModel.prototype.disableArrowNavigation = false;
YAHOO.ext.grid.EditorSelectionModel.prototype.controlForArrowNavigation = false;


YAHOO.ext.grid.EditorSelectionModel.prototype.initEvents = function(){
    this.grid.addListener("cellclick", this.onCellClick, this, true);
    this.grid.addListener("celldblclick", this.onCellDblClick, this, true);
    this.grid.addListener("keydown", this.keyDown, this, true);
};

YAHOO.ext.grid.EditorSelectionModel.prototype.onCellClick = function(grid, rowIndex, colIndex){
    if(this.clicksToActivateCell == 1){
        var row = this.grid.getRow(rowIndex);
        var cell = row.childNodes[colIndex];
        if(cell){
            this.activate(row, cell);
        }
    }
};

YAHOO.ext.grid.EditorSelectionModel.prototype.activate = function(row, cell){
    this.fireEvent('cellactivate', this, row, cell);
    this.grid.doEdit(row, cell);
};

YAHOO.ext.grid.EditorSelectionModel.prototype.onCellDblClick = function(grid, rowIndex, colIndex){
    if(this.clicksToActivateCell == 2){
        var row = this.grid.getRow(rowIndex);
        var cell = row.childNodes[colIndex];
        if(cell){
            this.activate(row, cell);
        }
    }
};


YAHOO.ext.grid.EditorSelectionModel.prototype.setRowState = function(row, selected){
    YAHOO.ext.grid.EditorSelectionModel.superclass.setRowState.call(this, row, false, false);
};

YAHOO.ext.grid.EditorSelectionModel.prototype.focusRow = function(row, selected){
};

YAHOO.ext.grid.EditorSelectionModel.prototype.getEditorCellAfter = function(cell, spanRows){
    var g = this.grid;
    var next = g.getCellAfter(cell);
    while(next && !g.colModel.isCellEditable(next.columnIndex)){
        next = g.getCellAfter(next);
    }
    if(!next && spanRows){
        var row = g.getRowAfter(g.getRowFromChild(cell));
        if(row){
            next = g.getFirstCell(row);
            if(!g.colModel.isCellEditable(next.columnIndex)){
                next = this.getEditorCellAfter(next);
            }
        }
    }
    return next;
};

YAHOO.ext.grid.EditorSelectionModel.prototype.getEditorCellBefore = function(cell, spanRows){
    var g = this.grid;
    var prev = g.getCellBefore(cell);
    while(prev && !g.colModel.isCellEditable(prev.columnIndex)){
        prev = g.getCellBefore(prev);
    }
    if(!prev && spanRows){
        var row = g.getRowBefore(g.getRowFromChild(cell));
        if(row){
            prev = g.getLastCell(row);
            if(!g.colModel.isCellEditable(prev.columnIndex)){
               prev = this.getEditorCellBefore(prev);
            }
        }
    }
    return prev;
};

YAHOO.ext.grid.EditorSelectionModel.prototype.allowArrowNav = function(e){
    return (!this.disableArrowNavigation && (!this.controlForArrowNavigation || e.ctrlKey));
};

YAHOO.ext.grid.EditorSelectionModel.prototype.keyDown = function(e){
    var g = this.grid, cm = g.colModel, cell = g.getEditingCell();
    if(!cell) return;
    var newCell;
    switch(e.browserEvent.keyCode){
         case e.TAB:
             if(e.shiftKey){
                 newCell = this.getEditorCellBefore(cell, true);
             }else{
                 newCell = this.getEditorCellAfter(cell, true);
             }
             e.preventDefault();
         break;
         case e.DOWN:
             if(this.allowArrowNav(e)){
                 var next = g.getRowAfter(g.getRowFromChild(cell));
                 if(next){
                     newCell = next.childNodes[cell.columnIndex];
                 }
             }
         break;
         case e.UP:
             if(this.allowArrowNav(e)){
                 var prev = g.getRowBefore(g.getRowFromChild(cell));
                 if(prev){
                     newCell = prev.childNodes[cell.columnIndex];
                 }
             }
         break;
         case e.RETURN:
             if(e.shiftKey){
                 var prev = g.getRowBefore(g.getRowFromChild(cell));
                 if(prev){
                     newCell = prev.childNodes[cell.columnIndex];
                 }
             }else{
                 var next = g.getRowAfter(g.getRowFromChild(cell));
                 if(next){
                     newCell = next.childNodes[cell.columnIndex];
                 }
             }
         break;
         case e.RIGHT:
             if(this.allowArrowNav(e)){
                 newCell = this.getEditorCellAfter(cell);
             }
         break;
         case e.LEFT:
             if(this.allowArrowNav(e)){
                 newCell = this.getEditorCellBefore(cell);
             }
         break;
    };
    if(newCell){
        this.activate(g.getRowFromChild(newCell), newCell);
        e.stopEvent();
    }
};


YAHOO.ext.grid.EditorAndSelectionModel = function(){
    YAHOO.ext.grid.EditorAndSelectionModel.superclass.constructor.call(this);
    this.events['cellactivate'] = new YAHOO.util.CustomEvent('cellactivate');
};

YAHOO.extendX(YAHOO.ext.grid.EditorAndSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);

YAHOO.ext.grid.EditorAndSelectionModel.prototype.initEvents = function(){
    YAHOO.ext.grid.EditorAndSelectionModel.superclass.initEvents.call(this);
    this.grid.addListener("celldblclick", this.onCellDblClick, this, true);
};

YAHOO.ext.grid.EditorAndSelectionModel.prototype.onCellDblClick = function(grid, rowIndex, colIndex){
    var row = this.grid.getRow(rowIndex);
    var cell = row.childNodes[colIndex];
    if(cell){
        this.fireEvent('cellactivate', this, row, cell);
        this.grid.doEdit(row, cell);
    }
}; 

YAHOO.ext.grid.CellEditor = function(element){
    this.colIndex = null;
    this.rowIndex = null;
    this.grid = null;
    this.editing = false;
    this.originalValue = null;
    this.element = getEl(element, true);
    this.element.addClass('ygrid-editor');
    this.element.dom.tabIndex = 1;
    this.initialized = false;
    this.callback = null;
};

YAHOO.ext.grid.CellEditor.prototype = {
    init : function(grid, bodyElement, callback){
        
        
        
        if(this.initialized) return;
        this.initialized = true;
        this.callback = callback;
        this.grid = grid;
        bodyElement.appendChild(this.element.dom);
        this.initEvents();
    },
    
    initEvents : function(){
        var stopOnEnter = function(e){
            if(e.browserEvent.keyCode == e.RETURN){
                this.stopEditing(true);
            }else if(e.browserEvent.keyCode == e.ESC){
                this.setValue(this.originalValue);
                this.stopEditing(true);
            }
        };
        this.element.mon('keydown', stopOnEnter, this, true);
        this.element.on('blur', this.stopEditing, this, true);
    },

    startEditing : function(value, row, cell){
        this.originalValue = value;
        this.rowIndex = row.rowIndex;
        this.colIndex = cell.columnIndex;
        this.cell = cell;
        this.setValue(value);
        var cellbox = getEl(cell, true).getBox();
        this.fitToCell(cellbox);
        this.editing = true;
        this.show();
    },
     
    stopEditing : function(focusCell){
         if(this.editing){
             this.editing = false;
             var newValue = this.getValue();
             this.hide();
             
             if(this.originalValue != newValue){
                this.callback(newValue, this.rowIndex, this.colIndex);
             }
         }
     },
     
    setValue : function(value){
        this.element.dom.value = value;
    },
    
    getValue : function(){
        return this.element.dom.value;
    },
    
    fitToCell : function(box){
        this.element.setBox(box, true);
    },
    
    show : function(){
        this.element.show();
        this.element.focus();
    },
    
    hide : function(){
        try{
            this.element.dom.blur();
        }catch(e){}
        this.element.hide();
    }
};

YAHOO.ext.grid.CheckboxEditor = function(){
    var div = document.createElement('span');
    div.className = 'ygrid-editor ygrid-checkbox-editor';
    var cb = document.createElement('input');
    cb.type = 'checkbox';
    cb.setAttribute('autocomplete', 'off');
    div.appendChild(cb);
    document.body.appendChild(div);
    YAHOO.ext.grid.CheckboxEditor.superclass.constructor.call(this, div);
    div.tabIndex = '';
    cb.tabIndex = 1;
    this.cb = getEl(cb, true);
};

YAHOO.extendX(YAHOO.ext.grid.CheckboxEditor, YAHOO.ext.grid.CellEditor);

YAHOO.ext.grid.CheckboxEditor.prototype.fitToCell = function(box){
    this.element.setBox(box, true);
};

YAHOO.ext.grid.CheckboxEditor.prototype.setValue = function(value){
     this.cb.dom.checked = (value === true || value === 'true' || value === 1 || value === '1');
};

YAHOO.ext.grid.CheckboxEditor.prototype.getValue = function(){
     return this.cb.dom.checked;
};

YAHOO.ext.grid.CheckboxEditor.prototype.show = function(){
    this.element.show();
    this.cb.focus();
};

YAHOO.ext.grid.CheckboxEditor.prototype.initEvents = function(){
    var stopOnEnter = function(e) {
        if(e.browserEvent.keyCode == e.RETURN){
            this.stopEditing(true);
        }else if(e.browserEvent.keyCode == e.ESC){
            this.setValue(this.originalValue);
            this.stopEditing(true);
        }
    };
    this.cb.mon('keydown', stopOnEnter, this, true);
    this.cb.on('blur', this.stopEditing, this, true);
};

YAHOO.ext.grid.CheckboxEditor.prototype.hide = function(){
    try{
        this.cb.dom.blur();
    }catch(e){}
    this.element.hide();
};

YAHOO.ext.grid.DateEditor = function(config){
    var div = document.createElement('span');
    div.className = 'ygrid-editor ygrid-editor-container';
    
    var element = document.createElement('input');
    element.type = 'text';
    element.tabIndex = 1;
    element.setAttribute('autocomplete', 'off');
    div.appendChild(element);
    
    var pick = document.createElement('span');
    pick.className = 'pick-button';
    div.appendChild(pick);
    
    document.body.appendChild(div);
    
    this.div = getEl(div, true);
    this.element = getEl(element, true);
    this.pick = getEl(pick, true);
    
    this.colIndex = null;
    this.rowIndex = null;
    this.grid = null;
    this.editing = false;
    this.originalValue = null;
    this.initialized = false;
    this.callback = null;
    
    this.cal = null;
    this.mouseDownHandler = YAHOO.ext.EventManager.wrap(this.handleMouseDown, this, true);
    
    YAHOO.ext.util.Config.apply(this, config);
    if(typeof this.minValue == 'string') this.minValue = this.parseDate(this.minValue);
    if(typeof this.maxValue == 'string') this.maxValue = this.parseDate(this.maxValue);
    this.ddMatch = /ddnone/;
    if(this.disabledDates){
        var dd = this.disabledDates;
        var re = "(?:";
        for(var i = 0; i < dd.length; i++){
            re += dd[i];
            if(i != dd.length-1) re += "|";
        }
        this.ddMatch = new RegExp(re + ")");
    }
};

YAHOO.ext.grid.DateEditor.prototype = {
    init : function(grid, bodyElement, callback){
        if(this.initialized) return;
        
        this.initialized = true;
        this.callback = callback;
        this.grid = grid;
        bodyElement.appendChild(this.div.dom);
        this.initEvents();
    },
    
    initEvents : function(){
         var stopOnEnter = function(e){
            if(e.browserEvent.keyCode == e.RETURN){
                this.stopEditing(true);
            }else if(e.browserEvent.keyCode == e.ESC){
                this.setValue(this.originalValue);
                this.stopEditing(true);
            }
		 };
        this.element.mon('keydown', stopOnEnter, this, true);
        var vtask = new YAHOO.ext.util.DelayedTask(this.validate, this);
        this.element.mon('keyup', vtask.delay.createDelegate(vtask, [this.validationDelay]));
        this.pick.on('click', this.showCalendar, this, true);
    },
    
    startEditing : function(value, row, cell){
        this.originalValue = value;
        this.rowIndex = row.rowIndex;
        this.colIndex = cell.columnIndex;
        this.cell = cell;
        this.setValue(value);
        this.validate();
        var cellbox = getEl(cell, true).getBox();
        this.div.setBox(cellbox, true);
        this.element.setWidth(cellbox.width-this.pick.getWidth());
        this.editing = true;
        YAHOO.util.Event.on(document, "mousedown", this.mouseDownHandler);
        this.show();
    },
     
     stopEditing : function(focusCell){
         if(this.editing){
             YAHOO.util.Event.removeListener(document, "mousedown", this.mouseDownHandler);
             this.editing = false;
             var newValue = this.getValue();
             this.hide();
             
             if(this.originalValue != newValue){
                this.callback(newValue, this.rowIndex, this.colIndex);
             }
         }
     },
    
    setValue : function(value){
        this.element.dom.value = this.formatDate(value);
        this.validate();
    },
    
    getValue : function(){
        if(!this.validate()){
           return this.originalValue;
       }else{
           var value = this.element.dom.value;
           if(value.length < 1){
               return value;
           } else{
               return this.parseDate(value);
           }
       }   
    },
    
    show : function() {
        this.div.show();
        this.element.focus();
        this.validate();
    },
    
    hide : function(){
        try{
            this.element.dom.blur();
        }catch(e){}
        this.div.hide();
    },
    
    validate : function(){
        var dom = this.element.dom;
        var value = dom.value;
        if(value.length < 1){ 
             if(this.allowBlank){
                 dom.title = '';
                 this.element.removeClass('ygrid-editor-invalid');
                 return true;
             }else{
                 dom.title = this.blankText;
                 this.element.addClass('ygrid-editor-invalid');
                 return false;
             }
        }
        value = this.parseDate(value);
        if(!value){
            dom.title = this.invalidText.replace('%0', dom.value).replace('%1', this.format);
            this.element.addClass('ygrid-editor-invalid');
            return false;
        }
        var time = value.getTime();
        if(this.minValue && time < this.minValue.getTime()){
            dom.title = this.minText.replace('%0', this.formatDate(this.minValue));
            this.element.addClass('ygrid-editor-invalid');
            return false;
        }
        if(this.maxValue && time > this.maxValue.getTime()){
            dom.title = this.maxText.replace('%0', this.formatDate(this.maxValue));
            this.element.addClass('ygrid-editor-invalid');
            return false;
        }
        if(this.disabledDays){
            var day = value.getDay();
            for(var i = 0; i < this.disabledDays.length; i++) {
            	if(day === this.disabledDays[i]){
            	    dom.title = this.disabledDaysText;
                    this.element.addClass('ygrid-editor-invalid');
                    return false;
            	}
            }
        }
        var fvalue = this.formatDate(value);
        if(this.ddMatch.test(fvalue)){
            dom.title = this.disabledDatesText.replace('%0', fvalue);
            this.element.addClass('ygrid-editor-invalid');
            return false;
        }
        var msg = this.validator(value);
        if(msg !== true){
            dom.title = msg;
            this.element.addClass('ygrid-editor-invalid');
            return false;
        }
        dom.title = '';
        this.element.removeClass('ygrid-editor-invalid');
        return true;
    },
    
    handleMouseDown : function(e){
        var t = e.getTarget();
        var dom = this.div.dom;
        if(t != dom && !YAHOO.util.Dom.isAncestor(dom, t)){
            this.stopEditing();
        }
    },
    
    showCalendar : function(value){
        if(this.cal == null){
            this.cal = new YAHOO.ext.DatePicker(this.div.dom.parentNode.parentNode);
        }
        this.cal.minDate = this.minValue;
        this.cal.maxDate = this.maxValue;
        this.cal.disabledDatesRE = this.ddMatch;
        this.cal.disabledDatesText = this.disabledDatesText;
        this.cal.disabledDays = this.disabledDays;
        this.cal.disabledDaysText = this.disabledDaysText;
        this.cal.format = this.format;
        if(this.minValue){
            this.cal.minText = this.minText.replace('%0', this.formatDate(this.minValue));
        }
        if(this.maxValue){
            this.cal.maxText = this.maxText.replace('%0', this.formatDate(this.maxValue));
        }
        var r = this.div.getRegion();
        this.cal.show(r.left, r.bottom, this.getValue(), this.setValue.createDelegate(this));
    },
    
    parseDate : function(value){
        if(!value || value instanceof Date) return value;
        return Date.parseDate(value, this.format);
    },
    
    formatDate : function(date){
        if(!date || !(date instanceof Date)) return date;
        return date.format(this.format);
    }
};

YAHOO.ext.grid.DateEditor.prototype.format = 'm/d/y';
YAHOO.ext.grid.DateEditor.prototype.disabledDays = null;
YAHOO.ext.grid.DateEditor.prototype.disabledDaysText = '';
YAHOO.ext.grid.DateEditor.prototype.disabledDates = null;
YAHOO.ext.grid.DateEditor.prototype.disabledDatesText = '';
YAHOO.ext.grid.DateEditor.prototype.allowBlank = true;
YAHOO.ext.grid.DateEditor.prototype.minValue = null;
YAHOO.ext.grid.DateEditor.prototype.maxValue = null;
YAHOO.ext.grid.DateEditor.prototype.minText = 'The date in this field must be after %0';
YAHOO.ext.grid.DateEditor.prototype.maxText = 'The date in this field must be before %0';
YAHOO.ext.grid.DateEditor.prototype.blankText = 'This field cannot be blank';
YAHOO.ext.grid.DateEditor.prototype.invalidText = '%0 is not a valid date - it must be in the format %1';
YAHOO.ext.grid.DateEditor.prototype.validationDelay = 200;
YAHOO.ext.grid.DateEditor.prototype.validator = function(){return true;};

YAHOO.ext.grid.NumberEditor = function(config){
    var element = document.createElement('input');
    element.type = 'text';
    element.className = 'ygrid-editor ygrid-num-editor';
    element.setAttribute('autocomplete', 'off');
    document.body.appendChild(element);
    YAHOO.ext.grid.NumberEditor.superclass.constructor.call(this, element);
    YAHOO.ext.util.Config.apply(this, config);
};
YAHOO.extendX(YAHOO.ext.grid.NumberEditor, YAHOO.ext.grid.CellEditor);

YAHOO.ext.grid.NumberEditor.prototype.initEvents = function(){
    var stopOnEnter = function(e){
        if(e.browserEvent.keyCode == e.RETURN){
            this.stopEditing(true);
        }else if(e.browserEvent.keyCode == e.ESC){
            this.setValue(this.originalValue);
            this.stopEditing(true);
        }
    };
    
    var allowed = "0123456789";
    if(this.allowDecimals){
        allowed += this.decimalSeparator;
    }
    if(this.allowNegative){
        allowed += '-';
    }
    var keyPress = function(e){
        var c = e.getCharCode();
        if(c != e.BACKSPACE && allowed.indexOf(String.fromCharCode(c)) === -1){
            e.stopEvent();
        }
    };
    this.element.mon('keydown', stopOnEnter, this, true);
    var vtask = new YAHOO.ext.util.DelayedTask(this.validate, this);
    this.element.mon('keyup', vtask.delay.createDelegate(vtask, [this.validationDelay]));
    this.element.mon('keypress', keyPress, this, true);
    this.element.on('blur', this.stopEditing, this, true);
};

YAHOO.ext.grid.NumberEditor.prototype.validate = function(){
    var dom = this.element.dom;
    var value = dom.value;
    if(value.length < 1){ 
         if(this.allowBlank){
             dom.title = '';
             this.element.removeClass('ygrid-editor-invalid');
             return true;
         }else{
             dom.title = this.blankText;
             this.element.addClass('ygrid-editor-invalid');
             return false;
         }
    }
    if(value.search(/\d+/) === -1){
        dom.title = this.nanText.replace('%0', value);
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    var num = this.parseValue(value);
    if(num < this.minValue){
        dom.title = this.minText.replace('%0', this.minValue);
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    if(num > this.maxValue){
        dom.title = this.maxText.replace('%0', this.maxValue);
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    var msg = this.validator(value);
    if(msg !== true){
        dom.title = msg;
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    dom.title = '';
    this.element.removeClass('ygrid-editor-invalid');
    return true;
};

YAHOO.ext.grid.NumberEditor.prototype.show = function(){
    this.element.dom.title = '';
    YAHOO.ext.grid.NumberEditor.superclass.show.call(this);
    if(this.selectOnFocus){
        try{
            this.element.dom.select();
        }catch(e){}
    }
    this.validate(this.element.dom.value);
};

YAHOO.ext.grid.NumberEditor.prototype.getValue = function(){
   if(!this.validate()){
       return this.originalValue;
   }else{
       var value = this.element.dom.value;
       if(value.length < 1){
           return value;
       } else{
           return this.fixPrecision(this.parseValue(value));
       }
   }   
};
YAHOO.ext.grid.NumberEditor.prototype.parseValue = function(value){
    return parseFloat(new String(value).replace(this.decimalSeparator, '.'));
};

YAHOO.ext.grid.NumberEditor.prototype.fixPrecision = function(value){
   if(!this.allowDecimals || this.decimalPrecision == -1 || isNaN(value) || value == 0 || !value){
       return value;
   }
   var scale = Math.pow(10, this.decimalPrecision+1);
   var fixed = this.decimalPrecisionFcn(value * scale);
   fixed = this.decimalPrecisionFcn(fixed/10);
   return fixed / (scale/10);
};

YAHOO.ext.grid.NumberEditor.prototype.allowBlank = true;
YAHOO.ext.grid.NumberEditor.prototype.allowDecimals = true;
YAHOO.ext.grid.NumberEditor.prototype.decimalSeparator = '.';
YAHOO.ext.grid.NumberEditor.prototype.decimalPrecision = 2;
YAHOO.ext.grid.NumberEditor.prototype.decimalPrecisionFcn = Math.floor;
YAHOO.ext.grid.NumberEditor.prototype.allowNegative = true;
YAHOO.ext.grid.NumberEditor.prototype.selectOnFocus = true;
YAHOO.ext.grid.NumberEditor.prototype.minValue = Number.NEGATIVE_INFINITY;
YAHOO.ext.grid.NumberEditor.prototype.maxValue = Number.MAX_VALUE;
YAHOO.ext.grid.NumberEditor.prototype.minText = 'The minimum value for this field is %0';
YAHOO.ext.grid.NumberEditor.prototype.maxText = 'The maximum value for this field is %0';
YAHOO.ext.grid.NumberEditor.prototype.blankText = 'This field cannot be blank';
YAHOO.ext.grid.NumberEditor.prototype.nanText = '%0 is not a valid number';
YAHOO.ext.grid.NumberEditor.prototype.validationDelay = 100;
YAHOO.ext.grid.NumberEditor.prototype.validator = function(){return true;};
YAHOO.ext.DatePicker = function(id, parentElement){
    this.id = id;
    this.selectedDate = new Date();
    this.visibleDate = new Date();
    this.element = null;
    this.shadow = null;
    this.callback = null;
    this.buildControl(parentElement || document.body);
    this.mouseDownHandler = YAHOO.ext.EventManager.wrap(this.handleMouseDown, this, true);
    this.keyDownHandler = YAHOO.ext.EventManager.wrap(this.handleKeyDown, this, true);
    this.wheelHandler = YAHOO.ext.EventManager.wrap(this.handleMouseWheel, this, true);
};

YAHOO.ext.DatePicker.prototype = {
    show : function(x, y, value, callback){
        this.hide();
        this.selectedDate = value;
        this.visibleDate = value;
        this.callback = callback;
        this.refresh();
        this.element.show();
        this.element.setXY(this.constrainToViewport ? this.constrainXY(x, y) : [x, y]);
        this.shadow.show();
        this.shadow.setRegion(this.element.getRegion());
        this.element.dom.tabIndex = 1;
        this.element.focus();
        YAHOO.util.Event.on(document, "mousedown", this.mouseDownHandler);
        YAHOO.util.Event.on(document, "keydown", this.keyDownHandler);
        YAHOO.util.Event.on(document, "mousewheel", this.wheelHandler);
        YAHOO.util.Event.on(document, "DOMMouseScroll", this.wheelHandler);
    },
    
    constrainXY : function(x, y){
        var w = YAHOO.util.Dom.getViewportWidth();
        var h = YAHOO.util.Dom.getViewportHeight();
        var size = this.element.getSize();
        return [
            Math.min(w-size.width, x),
            Math.min(h-size.height, y)
        ];
    },
    
    hide : function(){
        this.shadow.hide();
        this.element.hide();
        YAHOO.util.Event.removeListener(document, "mousedown", this.mouseDownHandler);
        YAHOO.util.Event.removeListener(document, "keydown", this.keyDownHandler);
        YAHOO.util.Event.removeListener(document, "mousewheel", this.wheelHandler);
        YAHOO.util.Event.removeListener(document, "DOMMouseScroll", this.wheelHandler);
    },
    
    setSelectedDate : function(date){
        this.selectedDate = date;
    },
    
    getSelectedDate : function(){
        return this.selectedDate;
    },
    
    showPrevMonth : function(){
        this.visibleDate = this.getPrevMonth(this.visibleDate);
        this.refresh();
    },
    
    showNextMonth : function(){
        this.visibleDate = this.getNextMonth(this.visibleDate);
        this.refresh();
    },
    
    showPrevYear : function(){
        var d = this.visibleDate;
        this.visibleDate = new Date(d.getFullYear()-1, d.getMonth(), d.getDate());
        this.refresh();
    },
    
    showNextYear : function(){
        var d = this.visibleDate;
        this.visibleDate = new Date(d.getFullYear()+1, d.getMonth(), d.getDate());
        this.refresh();
    },
    
    handleMouseDown : function(e){
        var target = e.getTarget();
        if(target != this.element.dom && !YAHOO.util.Dom.isAncestor(this.element.dom, target)){
            this.hide();
        }
    },
    
    handleKeyDown : function(e){
        switch(e.browserEvent.keyCode){
            case e.LEFT:
                this.showPrevMonth();
                e.stopEvent();
            break;
            case e.RIGHT:
                this.showNextMonth();
                e.stopEvent();
            break;
            case e.DOWN:
                this.showPrevYear();
                e.stopEvent();
            break;
            case e.UP:
                this.showNextYear();
                e.stopEvent();
            break;
        }
    },
    
    handleMouseWheel : function(e){
        var delta = e.getWheelDelta();
        if(delta > 0){
            this.showPrevMonth();
            e.stopEvent();
        } else if(delta < 0){
            this.showNextMonth();
            e.stopEvent();
        }
    },
    
    handleClick : function(e){
        var d = this.visibleDate;
        var t = e.getTarget();
        if(t && t.className){
            switch(t.className){
                case 'active':
                    this.handleSelection(new Date(d.getFullYear(), d.getMonth(), parseInt(t.innerHTML)));
                break;
                case 'prevday':
                    var p = this.getPrevMonth(d);
                    this.handleSelection(new Date(p.getFullYear(), p.getMonth(), parseInt(t.innerHTML)));
                break;
                case 'nextday':
                    var n = this.getNextMonth(d);
                    this.handleSelection(new Date(n.getFullYear(), n.getMonth(), parseInt(t.innerHTML)));
                break;
                case 'ypopcal-today':
                    this.handleSelection(new Date());
                break;
                case 'next-month':
                    this.showNextMonth();
                break;
                case 'prev-month':
                    this.showPrevMonth();
                break;
            }   
        }
        e.stopEvent();
    },
    
    selectToday : function(){
        this.handleSelection(new Date());
    },
    
    handleSelection: function(date){
        this.selectedDate = date;
        this.callback(date);
        this.hide();    
    },
    
    getPrevMonth : function(d){
        var m = d.getMonth();var y = d.getFullYear();
        return (m == 0 ? new Date(--y, 11, 1) : new Date(y, --m, 1));
    },
    
    getNextMonth : function(d){
        var m = d.getMonth();var y = d.getFullYear();
        return (m == 11 ? new Date(++y, 0, 1) : new Date(y, ++m, 1));
    },
    
    getDaysInMonth : function(m, y){
        return (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) ? 31 : (m == 4 || m == 6 || m == 9 || m == 11) ? 30 : this.isLeapYear(y) ? 29 : 28;
    },
    
    isLeapYear : function(y){
        return (((y % 4) == 0) && ((y % 100) != 0) || ((y % 400) == 0));
    },
    
    clearTime : function(date){
        if(date){
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            date.setMilliseconds(0);
        }
        return date;
    },
    
    refresh : function(){
        var d = this.visibleDate;
        this.buildInnerCal(d);
        this.calHead.update(this.monthNames[d.getMonth()] + ' ' + d.getFullYear());
        if(this.element.isVisible()){
            this.shadow.setRegion(this.element.getRegion());
        }
    }
};

 
YAHOO.ext.DatePicker.prototype.buildControl = function(parentElement){
    var c = document.createElement('div');
    c.style.position = 'absolute';
    c.style.visibility = 'hidden';
    document.body.appendChild(c);
    var html = '<iframe id="'+this.id+'_shdw" frameborder="0" style="position:absolute; z-index:2000; display:none; top:0px; left:0px;" class="ypopcal-shadow"></iframe>' +
    '<div hidefocus="true" class="ypopcal" id="'+this.id+'" style="-moz-outline:none; position:absolute; z-index:2001; display:none; top:0px; left:0px;">' +
    '<table class="ypopcal-head" border=0 cellpadding=0 cellspacing=0><tbody><tr><td class="ypopcal-arrow"><div class="prev-month">&#160;</div></td><td class="ypopcal-month">&#160;</td><td class="ypopcal-arrow"><div class="next-month">&#160;</div></td></tr></tbody></table>' +
    '<center><div class="ypopcal-inner">';
    html += "<table border=0 cellpadding=2 cellspacing=0 class=\"ypopcal-table\"><thead><tr class=\"ypopcal-daynames\">";
    var names = this.dayNames;
    for(var i = 0; i < names.length; i++){
        html += '<td>' + names[i].substr(0, 1) + '</td>';
    }
    html+= "</tr></thead><tbody><tr>";
    for(var i = 0; i < 42; i++) {
        if(i % 7 == 0 && i != 0){
            html += '</tr><tr>';
        }
        html += "<td>&nbsp;</td>";
    }
    html += "</tr></tbody></table>";
    html += '</div><button class="ypopcal-today" style="margin-top:2px;">'+this.todayText+'</button></center></div>';
    c.innerHTML = html;
    this.shadow = getEl(c.childNodes[0], true);
    this.shadow.enableDisplayMode();
    this.element = getEl(c.childNodes[1], true);
    this.element.enableDisplayMode();
    document.body.appendChild(this.shadow.dom);
    document.body.appendChild(this.element.dom);
    document.body.removeChild(c);
    this.element.on("selectstart", function(){return false;});
    var tbody = this.element.dom.getElementsByTagName('tbody')[1];
    this.cells = tbody.getElementsByTagName('td');
    this.calHead = this.element.getChildrenByClassName('ypopcal-month', 'td')[0];
    this.element.mon('mousedown', this.handleClick, this, true);
};

YAHOO.ext.DatePicker.prototype.buildInnerCal = function(dateVal){
    var days = this.getDaysInMonth(dateVal.getMonth() + 1, dateVal.getFullYear());
    var firstOfMonth = new Date(dateVal.getFullYear(), dateVal.getMonth(), 1);
    var startingPos = firstOfMonth.getDay();
    if(startingPos == 0) startingPos = 7;
    var pm = this.getPrevMonth(dateVal);
    var prevStart = this.getDaysInMonth(pm.getMonth()+1, pm.getFullYear())-startingPos;
    var cells = this.cells;
    days += startingPos;
    
    
    var day = 86400000;
    var date = this.clearTime(new Date(pm.getFullYear(), pm.getMonth(), prevStart));
    var today = this.clearTime(new Date()).getTime();
    var sel = this.selectedDate ? this.clearTime(this.selectedDate).getTime() : today + 1; 
    var min = this.minDate ? this.clearTime(this.minDate).getTime() : Number.NEGATIVE_INFINITY;
    var max = this.maxDate ? this.clearTime(this.maxDate).getTime() : Number.POSITIVE_INFINITY;
    var ddMatch = this.disabledDatesRE;
    var ddText = this.disabledDatesText;
    var ddays = this.disabledDays;
    var ddaysText = this.disabledDaysText;
    var format = this.format;
    
    var setCellClass = function(cal, cell, d){
        cell.title = '';
        var t = d.getTime();
        if(t == today){
            cell.className += ' today';
            cell.title = cal.todayText;
        }
        if(t == sel){
            cell.className += ' selected';
        }
        
        if(t < min) {
            cell.className = ' ypopcal-disabled';
            cell.title = cal.minText;
            return;
        }
        if(t > max) {
            cell.className = ' ypopcal-disabled';
            cell.title = cal.maxText;
            return;
        }
        if(ddays){
            var day = d.getDay();
            for(var i = 0; i < ddays.length; i++) {
            	if(day === ddays[i]){
            	    cell.title = ddaysText;
                    cell.className = ' ypopcal-disabled';
                    return;
                }
            }
        }
        if(ddMatch && format){
            var fvalue = d.format(format);
            if(ddMatch.test(fvalue)){
                cell.title = ddText.replace('%0', fvalue);
                cell.className = ' ypopcal-disabled';
                return;
            }
        }
    };
    
    var i = 0;
    for(; i < startingPos; i++) {
        cells[i].innerHTML = (++prevStart);
        date.setDate(date.getDate()+1);
        cells[i].className = 'prevday';
        setCellClass(this, cells[i], date);
    }
    for(; i < days; i++){
        intDay = i - startingPos + 1;
        cells[i].innerHTML = (intDay);
        date.setDate(date.getDate()+1);
        cells[i].className = 'active';
        setCellClass(this, cells[i], date);
    }
    var extraDays = 0;
    for(; i < 42; i++) {
         cells[i].innerHTML = (++extraDays);
         date.setDate(date.getDate()+1);
         cells[i].className = 'nextday';
         setCellClass(this, cells[i], date);
    }
};

YAHOO.ext.DatePicker.prototype.todayText = "Today";
YAHOO.ext.DatePicker.prototype.minDate = null;
YAHOO.ext.DatePicker.prototype.maxDate = null;
YAHOO.ext.DatePicker.prototype.minText = "This date is before the minimum date";
YAHOO.ext.DatePicker.prototype.maxText = "This date is after the maximum date";
YAHOO.ext.DatePicker.prototype.format = 'm/d/y';
YAHOO.ext.DatePicker.prototype.disabledDays = null;
YAHOO.ext.DatePicker.prototype.disabledDaysText = '';
YAHOO.ext.DatePicker.prototype.disabledDatesRE = null;
YAHOO.ext.DatePicker.prototype.disabledDatesText = '';
YAHOO.ext.DatePicker.prototype.constrainToViewport = true;


YAHOO.ext.DatePicker.prototype.monthNames = Date.monthNames;

YAHOO.ext.DatePicker.prototype.dayNames = Date.dayNames;

YAHOO.ext.grid.SelectEditor = function(element){
    element.hideFocus = true;
    YAHOO.ext.grid.SelectEditor.superclass.constructor.call(this, element);
    this.element.swallowEvent('click');
};
YAHOO.extendX(YAHOO.ext.grid.SelectEditor, YAHOO.ext.grid.CellEditor);

YAHOO.ext.grid.SelectEditor.prototype.fitToCell = function(box){
    if(YAHOO.ext.util.Browser.isGecko){
        box.height -= 3;
    }
    this.element.setBox(box, true);
};

YAHOO.ext.grid.TextEditor = function(config){
    var element = document.createElement('input');
    element.type = 'text';
    element.className = 'ygrid-editor ygrid-text-editor';
    element.setAttribute('autocomplete', 'off');
    document.body.appendChild(element);
    YAHOO.ext.grid.TextEditor.superclass.constructor.call(this, element);
    YAHOO.ext.util.Config.apply(this, config);
};
YAHOO.extendX(YAHOO.ext.grid.TextEditor, YAHOO.ext.grid.CellEditor);

YAHOO.ext.grid.TextEditor.prototype.validate = function(){
    var dom = this.element.dom;
    var value = dom.value;
    if(value.length < 1){ 
         if(this.allowBlank){
             dom.title = '';
             this.element.removeClass('ygrid-editor-invalid');
             return true;
         }else{
             dom.title = this.blankText;
             this.element.addClass('ygrid-editor-invalid');
             return false;
         }
    }
    if(value.length < this.minLength){
        dom.title = this.minText.replace('%0', this.minLength);
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    if(value.length > this.maxLength){
        dom.title = this.maxText.replace('%0', this.maxLength);
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    var msg = this.validator(value);
    if(msg !== true){
        dom.title = msg;
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    if(this.regex && !this.regex.test(value)){
        dom.title = this.regexText;
        this.element.addClass('ygrid-editor-invalid');
        return false;
    }
    dom.title = '';
    this.element.removeClass('ygrid-editor-invalid');
    return true;
};

YAHOO.ext.grid.TextEditor.prototype.initEvents = function(){
    YAHOO.ext.grid.TextEditor.superclass.initEvents.call(this);
    var vtask = new YAHOO.ext.util.DelayedTask(this.validate, this);
    this.element.mon('keyup', vtask.delay.createDelegate(vtask, [this.validationDelay]));
};

YAHOO.ext.grid.TextEditor.prototype.show = function(){
    this.element.dom.title = '';
    YAHOO.ext.grid.TextEditor.superclass.show.call(this);
    this.element.focus();
    if(this.selectOnFocus){
        try{
            this.element.dom.select();
        }catch(e){}
    }
    this.validate(this.element.dom.value);
};

YAHOO.ext.grid.TextEditor.prototype.getValue = function(){
   if(!this.validate()){
       return this.originalValue;
   }else{
       return this.element.dom.value;
   }   
};

YAHOO.ext.grid.TextEditor.prototype.allowBlank = true;
YAHOO.ext.grid.TextEditor.prototype.minLength = 0;
YAHOO.ext.grid.TextEditor.prototype.maxLength = Number.MAX_VALUE;
YAHOO.ext.grid.TextEditor.prototype.minText = 'The minimum length for this field is %0';
YAHOO.ext.grid.TextEditor.prototype.maxText = 'The maximum length for this field is %0';
YAHOO.ext.grid.TextEditor.prototype.selectOnFocus = true;
YAHOO.ext.grid.TextEditor.prototype.blankText = 'This field cannot be blank';
YAHOO.ext.grid.TextEditor.prototype.validator = function(){return true;};
YAHOO.ext.grid.TextEditor.prototype.validationDelay = 200;
YAHOO.ext.grid.TextEditor.prototype.regex = null;
YAHOO.ext.grid.TextEditor.prototype.regexText = '';

YAHOO.ext.LayoutManager = function(container){
    YAHOO.ext.LayoutManager.superclass.constructor.call(this);
    this.el = getEl(container, true);
    this.id = this.el.id;
    this.el.addClass('ylayout-container');
    
    this.monitorWindowResize = true;
    this.regions = {};
    this.events = {
        
        'layout' : new YAHOO.util.CustomEvent(),
        
        'regionresized' : new YAHOO.util.CustomEvent(),
        
        'regioncollapsed' : new YAHOO.util.CustomEvent(),
        
        'regionexpanded' : new YAHOO.util.CustomEvent()
    };
    this.updating = false;
    YAHOO.ext.EventManager.onWindowResize(this.onWindowResize, this, true);
};

YAHOO.extendX(YAHOO.ext.LayoutManager, YAHOO.ext.util.Observable, {
    
    isUpdating : function(){
        return this.updating; 
    },
    
    
    beginUpdate : function(){
        this.updating = true;    
    },
    
    
    endUpdate : function(noLayout){
        this.updating = false;
        if(!noLayout){
            this.layout();
        }    
    },
    
    layout: function(){
        
    },
    
    onRegionResized : function(region, newSize){
        this.fireEvent('regionresized', region, newSize);
        this.layout();
    },
    
    onRegionCollapsed : function(region){
        this.fireEvent('regioncollapsed', region);
    },
    
    onRegionExpanded : function(region){
        this.fireEvent('regionexpanded', region);
    },
        
    
    getViewSize : function(){
        var size;
        if(this.el.dom != document.body){
            this.el.beginMeasure();
            size = this.el.getSize();
            this.el.endMeasure();
        }else{
            size = {width: YAHOO.util.Dom.getViewportWidth(), height: YAHOO.util.Dom.getViewportHeight()};
        }
        size.width -= this.el.getBorderWidth('lr')-this.el.getPadding('lr');
        size.height -= this.el.getBorderWidth('tb')-this.el.getPadding('tb');
        return size;
    },
    
    
    getEl : function(){
        return this.el;
    },
    
    
    getRegion : function(target){
        return this.regions[target.toLowerCase()];
    },
    
    onWindowResize : function(){
        if(this.monitorWindowResize){
            this.layout();
        }
    }
});

YAHOO.ext.LayoutRegion = function(mgr, config, pos){
    this.mgr = mgr;
    this.position  = pos;
    var dh = YAHOO.ext.DomHelper;
    
    this.el = dh.append(mgr.el.dom, {tag: 'div', cls: 'ylayout-panel ylayout-panel-' + this.position}, true);
    
    this.titleEl = dh.append(this.el.dom, {tag: 'div', unselectable: 'on', cls: 'yunselectable ylayout-panel-hd ylayout-title-'+this.position, children:[
        {tag: 'span', cls: 'yunselectable ylayout-panel-hd-text', unselectable: 'on', html: '&#160;'},
        {tag: 'div', cls: 'yunselectable ylayout-panel-hd-tools', unselectable: 'on'}
    ]}, true);
    this.titleEl.enableDisplayMode();
    
    this.titleTextEl = this.titleEl.dom.firstChild;
    this.tools = getEl(this.titleEl.dom.childNodes[1], true);
    this.closeBtn = this.createTool(this.tools.dom, 'ylayout-close');
    this.closeBtn.enableDisplayMode();
    this.closeBtn.on('click', this.closeClicked, this, true);
    this.closeBtn.hide();
    
    this.bodyEl = dh.append(this.el.dom, {tag: 'div', cls: 'ylayout-panel-body'}, true);
    this.events = {
        
        'beforeremove' : new YAHOO.util.CustomEvent('beforeremove'),
        
        'invalidated' : new YAHOO.util.CustomEvent('invalidated'),
        
        'visibilitychange' : new YAHOO.util.CustomEvent('visibilitychange'),
        
        'paneladded' : new YAHOO.util.CustomEvent('paneladded'),
        
        'panelremoved' : new YAHOO.util.CustomEvent('panelremoved'),
        
        'collapsed' : new YAHOO.util.CustomEvent('collapsed'),
        
        'expanded' : new YAHOO.util.CustomEvent('expanded'),
        
        'panelactivated' : new YAHOO.util.CustomEvent('panelactivated'),
        
        'resized' : new YAHOO.util.CustomEvent('resized')
    };
    
    this.panels = new YAHOO.ext.util.MixedCollection();
    this.panels.getKey = this.getPanelId.createDelegate(this);
    this.box = null;
    this.visible = false;
    this.collapsed = false;
    this.hide();
    this.on('paneladded', this.validateVisibility, this, true);
    this.on('panelremoved', this.validateVisibility, this, true);
    this.activePanel = null;
    
    this.applyConfig(config);
    
    
};

YAHOO.extendX(YAHOO.ext.LayoutRegion, YAHOO.ext.util.Observable, {
    getPanelId : function(p){
        return p.getId();
    },
    
    applyConfig : function(config){
        if(config.collapsible && this.position != 'center' && !this.collapsedEl){
            var dh = YAHOO.ext.DomHelper;
            this.collapseBtn = this.createTool(this.tools.dom, 'ylayout-collapse-'+this.position);
            this.collapseBtn.mon('click', this.collapse, this, true);
            
            this.collapsedEl = dh.append(this.mgr.el.dom, {tag: 'div', cls: 'ylayout-collapsed ylayout-collapsed-'+this.position, children:[
                {tag: 'div', cls: 'ylayout-collapsed-tools'}
            ]}, true);
            if(config.floatable !== false){
               this.collapsedEl.addClassOnOver('ylayout-collapsed-over');
               this.collapsedEl.mon('click', this.collapseClick, this, true);
            }
            this.expandBtn = this.createTool(this.collapsedEl.dom.firstChild, 'ylayout-expand-'+this.position);
            this.expandBtn.mon('click', this.expand, this, true);
        }
        if(this.collapseBtn){
            this.collapseBtn.setVisible(config.collapsible == true);
        }
        this.cmargins = config.cmargins || this.cmargins || 
                         (this.position == 'west' || this.position == 'east' ? 
                             {top: 0, left: 2, right:2, bottom: 0} : 
                             {top: 2, left: 0, right:0, bottom: 2});
        this.margins = config.margins || this.margins || {top: 0, left: 0, right:0, bottom: 0};
        this.bottomTabs = config.tabPosition != 'top';
        this.autoScroll = config.autoScroll || false;
        if(this.autoScroll){
            this.bodyEl.setStyle('overflow', 'auto');
        }else{
            this.bodyEl.setStyle('overflow', 'hidden');
        }
        if((!config.titlebar && !config.title) || config.titlebar === false){
            this.titleEl.hide();
        }else{
            this.titleEl.show();
            if(config.title){
                this.titleTextEl.innerHTML = config.title;
            }
        }
        this.duration = config.duration || .30;
        this.slideDuration = config.slideDuration || .45;
        this.config = config;
        if(config.collapsed){
            this.collapse(true);
        }
    },
    
    
    resizeTo : function(newSize){
        switch(this.position){
            case 'east':
            case 'west':
                this.el.setWidth(newSize);
                this.fireEvent('resized', this, newSize);
            break;
            case 'north':
            case 'south':
                this.el.setHeight(newSize);
                this.fireEvent('resized', this, newSize);
            break;                
        }
    },
    
    getBox : function(){
        var b;
        if(!this.collapsed){
            b = this.el.getBox(false, true);
        }else{
            b = this.collapsedEl.getBox(false, true);
        }
        return b;
    },
    
    getMargins : function(){
        return this.collapsed ? this.cmargins : this.margins;
    },
    
    highlight : function(){
        this.el.addClass('ylayout-panel-dragover'); 
    },
    
    unhighlight : function(){
        this.el.removeClass('ylayout-panel-dragover'); 
    },
    
    updateBox : function(box){
        this.box = box;
        if(!this.collapsed){
            this.el.dom.style.left = box.x + 'px';
            this.el.dom.style.top = box.y + 'px';
            this.el.setSize(box.width, box.height);
            var bodyHeight = this.titleEl.isVisible() ? box.height - (this.titleEl.getHeight()||0) : box.height;
            bodyHeight -= this.el.getBorderWidth('tb');
            bodyWidth = box.width - this.el.getBorderWidth('rl');
            this.bodyEl.setHeight(bodyHeight);
            this.bodyEl.setWidth(bodyWidth);
            var tabHeight = bodyHeight;
            if(this.tabs){
                tabHeight = this.tabs.syncHeight(bodyHeight);
                if(YAHOO.ext.util.Browser.isIE) this.tabs.el.repaint();
            }
            this.panelSize = {width: bodyWidth, height: tabHeight};
            if(this.activePanel){
                this.activePanel.setSize(bodyWidth, tabHeight);
            }
        }else{
            this.collapsedEl.dom.style.left = box.x + 'px';
            this.collapsedEl.dom.style.top = box.y + 'px';
            this.collapsedEl.setSize(box.width, box.height);
        }
        if(this.tabs){
            this.tabs.autoSizeTabs();
        }
    },
    
    
    getEl : function(){
        return this.el;
    },
    
    
    hide : function(){
        if(!this.collapsed){
            this.el.dom.style.left = '-2000px';
            this.el.hide();
        }else{
            this.collapsedEl.dom.style.left = '-2000px';
            this.collapsedEl.hide();
        }
        this.visible = false;
        this.fireEvent('visibilitychange', this, false);
    },
    
    
    show : function(){
        if(!this.collapsed){
            this.el.show();
        }else{
            this.collapsedEl.show();
        }
        this.visible = true;
        this.fireEvent('visibilitychange', this, true);
    },
    
    
    isVisible : function(){
        return this.visible;
    },
    
    closeClicked : function(){
        if(this.activePanel){
            this.remove(this.activePanel);
        }
    },
    
    collapseClick : function(e){
       if(this.isSlid){
           e.stopPropagation();
           this.slideIn();
       }else{
           e.stopPropagation();
           this.slideOut();
       }   
    },
    
    
    collapse : function(skipAnim){
        if(this.collapsed) return;
        this.collapsed = true;
        if(this.split){
            this.split.el.hide();
        }
        if(this.config.animate && skipAnim !== true){
            this.fireEvent('invalidated', this);    
            this.animateCollapse();
        }else{
            this.el.setLocation(-20000,-20000);
            this.el.hide();
            this.collapsedEl.show();
            this.fireEvent('collapsed', this);
            this.fireEvent('invalidated', this); 
        }
    },
    
    animateCollapse : function(){
        
    },
    
    
    expand : function(e, skipAnim){
        if(e) e.stopPropagation();
        if(!this.collapsed) return;
        if(this.isSlid){
            this.slideIn(this.expand.createDelegate(this));
            return;
        }
        this.collapsed = false;
        this.el.show();
        if(this.config.animate && skipAnim !== true){
            this.animateExpand();
        }else{
            if(this.split){
                this.split.el.show();
            }
            this.collapsedEl.setLocation(-2000,-2000);
            this.collapsedEl.hide();
            this.fireEvent('invalidated', this);
            this.fireEvent('expanded', this);
        }
    },
    
    animateExpand : function(){
        
    },
    
    initTabs : function(){
        this.bodyEl.setStyle('overflow', 'hidden');
        var ts = new YAHOO.ext.TabPanel(this.bodyEl.dom, this.bottomTabs);
        this.tabs = ts;
        ts.resizeTabs = this.config.resizeTabs === true;
        ts.minTabWidth = this.config.minTabWidth || 40;
        ts.maxTabWidth = this.config.maxTabWidth || 250;
        ts.preferredTabWidth = this.config.preferredTabWidth || 150;
        ts.monitorResize = false;
        ts.bodyEl.setStyle('overflow', this.config.autoScroll ? 'auto' : 'hidden');
        this.panels.each(this.initPanelAsTab, this);
    },
    
    initPanelAsTab : function(panel){
        var ti = this.tabs.addTab(panel.getEl().id, panel.getTitle(), null, 
                    this.config.closeOnTab && panel.isClosable());
        ti.on('activate', function(){ 
              this.setActivePanel(panel); 
        }, this, true);
        if(this.config.closeOnTab){
            ti.on('beforeclose', function(t, e){
                e.cancel = true;
                this.remove(panel);
            }, this, true);
        }
        return ti;
    },
    
    updatePanelTitle : function(panel, title){
        if(this.activePanel == panel){
            this.updateTitle(title);
        }
        if(this.tabs){
            this.tabs.getTab(panel.getEl().id).setText(title);
        }
    },
    
    updateTitle : function(title){
        if(this.titleTextEl && !this.config.title){
            this.titleTextEl.innerHTML = (typeof title != 'undefined' && title.length > 0 ? title : "&#160;");
        }
    },
    
    setActivePanel : function(panel){
        panel = this.getPanel(panel);
        if(this.activePanel && this.activePanel != panel){
            this.activePanel.setActiveState(false);
        }
        this.activePanel = panel;
        panel.setActiveState(true);
        if(this.panelSize){
            panel.setSize(this.panelSize.width, this.panelSize.height);
        }
        this.closeBtn.setVisible(!this.config.closeOnTab && !this.isSlid && panel.isClosable());
        this.updateTitle(panel.getTitle());
        this.fireEvent('panelactivated', this, panel);
        
    },
    
    
    showPanel : function(panel){
        if(panel = this.getPanel(panel)){
            if(this.tabs){
                this.tabs.activate(panel.getEl().id);
            }else{
                this.setActivePanel(panel);
            }
        }
        return panel;
    },
    
    
    getActivePanel : function(){
        return this.activePanel;
    },
    
    validateVisibility : function(){
        if(this.panels.getCount() < 1){
            this.updateTitle('&#160;');
            this.closeBtn.hide();
            this.hide();
        }else{
            if(!this.isVisible()){
                this.show();
            }
        }
    },
    
    
    add : function(panel){
        if(arguments.length > 1){
            for(var i = 0, len = arguments.length; i < len; i++) {
            	this.add(arguments[i]);
            }
            return null;
        }
        if(this.hasPanel(panel)){
            this.showPanel(panel);
            return panel;
        }
        panel.setRegion(this);
        this.panels.add(panel);
        if(this.panels.getCount() == 1 && !this.config.alwaysShowTabs){
            this.bodyEl.dom.appendChild(panel.getEl().dom);
            this.setActivePanel(panel);
            this.fireEvent('paneladded', this, panel);
            return panel;
        }
        if(!this.tabs){
            this.initTabs();
        }else{
            this.initPanelAsTab(panel);
        }
        this.tabs.activate(panel.getEl().id);
        this.fireEvent('paneladded', this, panel);
        return panel;
    },
    
    
    hasPanel : function(panel){
        if(typeof panel == 'object'){ 
            panel = panel.getId();
        }
        return this.getPanel(panel) ? true : false;
    },
    
    
    hidePanel : function(panel){
        if(this.tabs && (panel = this.getPanel(panel))){
            this.tabs.hideTab(panel.getEl().id);
        }
    },
    
    
    unhidePanel : function(panel){
        if(this.tabs && (panel = this.getPanel(panel))){
            this.tabs.unhideTab(panel.getEl().id);
        }
    },
    
    clearPanels : function(){
        while(this.panels.getCount() > 0){
             this.remove(this.panels.first());
        }
    },
    
    
    remove : function(panel, preservePanel){
        panel = this.getPanel(panel);
        if(!panel){
            return null;
        }
        var e = {};
        this.fireEvent('beforeremove', this, panel, e);
        if(e.cancel === true){
            return null;
        }
        preservePanel = (typeof preservePanel != 'undefined' ? preservePanel : (this.config.preservePanels === true || panel.preserve === true));
        var panelId = panel.getId();
        this.panels.removeKey(panelId);
        if(preservePanel){
            document.body.appendChild(panel.getEl().dom);
        }
        if(this.tabs){
            this.tabs.removeTab(panel.getEl().id);
        }else if (!preservePanel){
            this.bodyEl.dom.removeChild(panel.getEl().dom);
        }
        if(this.panels.getCount() == 1 && this.tabs && !this.config.alwaysShowTabs){
            var p = this.panels.first();
            var tempEl = document.createElement('span'); 
            tempEl.appendChild(p.getEl().dom);
            this.bodyEl.update('');
            this.bodyEl.dom.appendChild(p.getEl().dom);
            tempEl = null;
            this.updateTitle(p.getTitle());
            this.tabs = null;
            this.bodyEl.setStyle('overflow', this.config.autoScroll ? 'auto' : 'hidden');
            this.setActivePanel(p);
        }
        panel.setRegion(null);
        if(this.activePanel == panel){
            this.activePanel = null;
        }
        if(this.config.autoDestroy !== false && preservePanel !== true){
            try{panel.destroy();}catch(e){}
        }
        this.fireEvent('panelremoved', this, panel);
        return panel;
    },
    
    
    getTabs : function(){
        return this.tabs;    
    },
    
    
    getPanel : function(id){
        if(typeof id == 'object'){ 
            return id;
        }
        return this.panels.get(id);
    },
    
    
    getPosition: function(){
        return this.position;    
    },
    
    createTool : function(parentEl, className){
        var btn = YAHOO.ext.DomHelper.append(parentEl, {tag: 'div', cls: 'ylayout-tools-button', 
            children: [{tag: 'div', cls: 'ylayout-tools-button-inner ' + className, html: '&#160;'}]}, true);
        btn.addClassOnOver('ylayout-tools-button-over');
        return btn;
    }
});

YAHOO.ext.SplitLayoutRegion = function(mgr, config, pos, cursor){
    this.cursor = cursor;
    YAHOO.ext.SplitLayoutRegion.superclass.constructor.call(this, mgr, config, pos);
    if(config.split){
        this.hide();
    }
};

YAHOO.extendX(YAHOO.ext.SplitLayoutRegion, YAHOO.ext.LayoutRegion, {
    applyConfig : function(config){
        YAHOO.ext.SplitLayoutRegion.superclass.applyConfig.call(this, config);
        if(config.split){
            if(!this.split){
                var splitEl = YAHOO.ext.DomHelper.append(this.mgr.el.dom, 
                        {tag: 'div', id: this.el.id + '-split', cls: 'ylayout-split ylayout-split-'+this.position, html: '&#160;'});
                
                this.split = new YAHOO.ext.SplitBar(splitEl, this.el);
                this.split.onMoved.subscribe(this.onSplitMove, this, true);
                this.split.useShim = config.useShim === true;
                YAHOO.util.Dom.setStyle([this.split.el.dom, this.split.proxy], 'cursor', this.cursor);
                this.split.getMaximumSize = this.getMaxSize.createDelegate(this);
            }
            if(typeof config.minSize != 'undefined'){
                this.split.minSize = config.minSize;
            }
            if(typeof config.maxSize != 'undefined'){
                this.split.maxSize = config.maxSize;
            }
        }
    },
    
    getMaxSize : function(){
         var cmax = this.config.maxSize || 10000;
         var center = this.mgr.getRegion('center');
         return Math.min(cmax, (this.el.getWidth()+center.getEl().getWidth())-center.getMinWidth());
    },
    
    onSplitMove : function(split, newSize){
        this.fireEvent('resized', this, newSize);
    },
    
    
    getSplitBar : function(){
        return this.split;
    },
    
    hide : function(){
        if(this.split){
            this.split.el.setLocation(-2000,-2000);
            this.split.el.hide();
        }
        YAHOO.ext.SplitLayoutRegion.superclass.hide.call(this);
    },
    
    show : function(){
        if(this.split){
            this.split.el.show();
        }
        YAHOO.ext.SplitLayoutRegion.superclass.show.call(this);
    },
    
    beforeSlide: function(){
        if(YAHOO.ext.util.Browser.isGecko){
            this.bodyEl.clip();
            if(this.tabs) this.tabs.bodyEl.clip();
            if(this.activePanel){
                this.activePanel.getEl().clip();
                
                if(this.activePanel.beforeSlide){
                    this.activePanel.beforeSlide();
                }
            }
        }
    },
    
    afterSlide : function(){
        if(YAHOO.ext.util.Browser.isGecko){
            this.bodyEl.unclip();
            if(this.tabs) this.tabs.bodyEl.unclip();
            if(this.activePanel){
                this.activePanel.getEl().unclip();
                if(this.activePanel.afterSlide){
                    this.activePanel.afterSlide();
                }
            }
        }
    },
    
    slideOut : function(){
        if(!this.slideEl){
            this.slideEl = new YAHOO.ext.Actor(
                YAHOO.ext.DomHelper.append(this.mgr.el.dom, {tag: 'div', cls:'ylayout-slider'}));
            if(this.config.autoHide !== false){
                var slideInTask = new YAHOO.ext.util.DelayedTask(this.slideIn, this);
                this.slideEl.mon('mouseout', function(e){
                    var to = e.getRelatedTarget();
                    if(to && to != this.slideEl.dom && !YAHOO.util.Dom.isAncestor(this.slideEl.dom, to)){
                        slideInTask.delay(500);
                    }
                }, this, true);
                this.slideEl.mon('mouseover', function(e){
                    slideInTask.cancel();
                }, this, true);
            }
        }
        var sl = this.slideEl, c = this.collapsedEl, cm = this.cmargins;
        this.isSlid = true;
        this.snapshot = {
            'left': this.el.getLeft(true),
            'top': this.el.getTop(true),
            'colbtn': this.collapseBtn.isVisible(),
            'closebtn': this.closeBtn.isVisible()
        };
        this.collapseBtn.hide();
        this.closeBtn.hide();
        this.el.show();
        this.el.setLeftTop(0,0);
        sl.startCapture(true);
        var size;
        switch(this.position){
            case 'west':
                sl.setLeft(c.getRight(true));
                sl.setTop(c.getTop(true));
                size = this.el.getWidth();
            break;
            case 'east':
                sl.setRight(this.mgr.getViewSize().width-c.getLeft(true));
                sl.setTop(c.getTop(true));
                size = this.el.getWidth();
            break;
            case 'north':
                sl.setLeft(c.getLeft(true));
                sl.setTop(c.getBottom(true));
                size = this.el.getHeight();
            break;
            case 'south':
                sl.setLeft(c.getLeft(true));
                sl.setBottom(this.mgr.getViewSize().height-c.getTop(true));
                size = this.el.getHeight();
            break;
        }
        sl.dom.appendChild(this.el.dom);
        YAHOO.util.Event.on(document.body, 'click', this.slideInIf, this, true);
        sl.setSize(this.el.getWidth(), this.el.getHeight());
        this.beforeSlide();
        if(this.activePanel){
            this.activePanel.setSize(this.bodyEl.getWidth(), this.bodyEl.getHeight());
        }
        sl.slideShow(this.getAnchor(), size, this.slideDuration, null, false);
        sl.play(function(){
            this.afterSlide();
        }.createDelegate(this));
    },
    
    slideInIf : function(e){
        var t = YAHOO.util.Event.getTarget(e);
        if(!YAHOO.util.Dom.isAncestor(this.el.dom, t)){
            this.slideIn();
        }
    },
    
    slideIn : function(callback){
        if(this.isSlid && !this.slideEl.playlist.isPlaying()){
            YAHOO.util.Event.removeListener(document.body, 'click', this.slideInIf, this, true);
            this.slideEl.startCapture(true);
            this.slideEl.slideHide(this.getAnchor(), this.slideDuration, null);
            this.beforeSlide();
            this.slideEl.play(function(){
                this.isSlid = false;
                this.el.setPositioning(this.snapshot);
                this.collapseBtn.setVisible(this.snapshot.colbtn);
                this.closeBtn.setVisible(this.snapshot.closebtn);
                this.afterSlide();
                this.mgr.el.dom.appendChild(this.el.dom);
                if(typeof callback == 'function'){
                    callback();
                }
            }.createDelegate(this));
        }
    },
    
    animateExpand : function(){
        var em = this.margins, cm = this.cmargins;
        var c = this.collapsedEl, el = this.el;
        var direction, distance;
        switch(this.position){
            case 'west':
                direction = 'right';
                el.setLeft(-(el.getWidth() + (em.right+em.left)));
                el.setTop(c.getTop(true)-cm.top+em.top);
                distance = el.getWidth() + (em.right+em.left);
            break;
            case 'east':
                direction = 'left';
                el.setLeft(this.mgr.getViewSize().width + em.left);
                el.setTop(c.getTop(true)-cm.top+em.top);
                distance = el.getWidth() + (em.right+em.left);
            break;
            case 'north':
                direction = 'down';
                el.setLeft(em.left);
                el.setTop(-(el.getHeight() + (em.top+em.bottom)));
                distance = el.getHeight() + (em.top+em.bottom);
            break;
            case 'south':
                direction = 'up';
                el.setLeft(em.left);
                el.setTop(this.mgr.getViewSize().height + em.top);
                distance = el.getHeight() + (em.top+em.bottom);
            break;
        }
        this.beforeSlide();
        el.setStyle('z-index', '100');
        el.show();
        c.setLocation(-2000,-2000);
        c.hide();
        el.move(direction, distance, true, this.duration, function(){
            this.afterSlide();
            el.setStyle('z-index', '');
            if(this.split){
                this.split.el.show();
            }
            this.fireEvent('invalidated', this);
            this.fireEvent('expanded', this);
        }.createDelegate(this), this.config.easing || YAHOO.util.Easing.easeOut);
    },
    
    animateCollapse : function(){
        var em = this.margins, cm = this.cmargins;
        var c = this.collapsedEl, el = this.el;
        var direction, distance;
        switch(this.position){
            case 'west':
                direction = 'left';
                distance = el.getWidth() + (em.right+em.left);
            break;
            case 'east':
                direction = 'right';
                distance = el.getWidth() + (em.right+em.left);
            break;
            case 'north':
                direction = 'up';
                distance = el.getHeight() + (em.top+em.bottom);
            break;
            case 'south':
                direction = 'down';
                distance = el.getHeight() + (em.top+em.bottom);
            break;
        }
        this.el.setStyle('z-index', '100');
        this.beforeSlide();
        this.el.move(direction, distance, true, this.duration, function(){
            this.afterSlide();
            this.el.setStyle('z-index', '');
            this.el.setLocation(-20000,-20000);
            this.el.hide();
            this.collapsedEl.show();
            this.fireEvent('collapsed', this); 
        }.createDelegate(this), YAHOO.util.Easing.easeIn);
    },
    
    getAnchor : function(){
        switch(this.position){
            case 'west':
                return 'left';
            case 'east':
                return 'right';
            case 'north':
                return 'top';
            case 'south':
                return 'bottom';
        }
    }
});

YAHOO.ext.BorderLayout = function(container, config){
    YAHOO.ext.BorderLayout.superclass.constructor.call(this, container);
    this.factory = config.factory || YAHOO.ext.BorderLayout.RegionFactory;
    
    this.hideOnLayout = config.hideOnLayout || false;
    for(var i = 0, len = this.factory.validRegions.length; i < len; i++) {
    	var target = this.factory.validRegions[i];
    	if(config[target]){
    	    this.addRegion(target, config[target]);
    	}
    }
    
};

YAHOO.extendX(YAHOO.ext.BorderLayout, YAHOO.ext.LayoutManager, {
    
    addRegion : function(target, config){
        if(!this.regions[target]){
            var r = this.factory.create(target, this, config);
    	    this.regions[target] = r;
    	    r.on('visibilitychange', this.layout, this, true);
            r.on('paneladded', this.layout, this, true);
            r.on('panelremoved', this.layout, this, true);
            r.on('invalidated', this.layout, this, true);
            r.on('resized', this.onRegionResized, this, true);
            r.on('collapsed', this.onRegionCollapsed, this, true);
            r.on('expanded', this.onRegionExpanded, this, true);
        }
        return this.regions[target];
    },
    
    
    layout : function(){
        if(this.updating) return;
        
	    
        var size = this.getViewSize();
        var w = size.width, h = size.height;
        var centerW = w, centerH = h, centerY = 0, centerX = 0;
        var x = 0, y = 0;
        
        var rs = this.regions;
        var n = rs['north'], s = rs['south'], west = rs['west'], e = rs['east'], c = rs['center'];
        if(this.hideOnLayout){
            c.el.setStyle('display', 'none');
        }
        if(n && n.isVisible()){
            var b = n.getBox();
            var m = n.getMargins();
            b.width = w - (m.left+m.right);
            b.x = m.left;
            b.y = m.top;
            centerY = b.height + b.y + m.bottom;
            centerH -= centerY;
            n.updateBox(this.safeBox(b));
        }
        if(s && s.isVisible()){
            var b = s.getBox();
            var m = s.getMargins();
            b.width = w - (m.left+m.right);
            b.x = m.left;
            var totalHeight = (b.height + m.top + m.bottom);
            b.y = h - totalHeight + m.top;
            centerH -= totalHeight;
            s.updateBox(this.safeBox(b));
        }
        if(west && west.isVisible()){
            var b = west.getBox();
            var m = west.getMargins();
            b.height = centerH - (m.top+m.bottom);
            b.x = m.left;
            b.y = centerY + m.top;
            var totalWidth = (b.width + m.left + m.right);
            centerX += totalWidth;
            centerW -= totalWidth;
            west.updateBox(this.safeBox(b));
        }
        if(e && e.isVisible()){
            var b = e.getBox();
            var m = e.getMargins();
            b.height = centerH - (m.top+m.bottom);
            var totalWidth = (b.width + m.left + m.right);
            b.x = w - totalWidth + m.left;
            b.y = centerY + m.top;
            centerW -= totalWidth;
            e.updateBox(this.safeBox(b));
        }
        if(c){
            var m = c.getMargins();
            var centerBox = {
                x: centerX + m.left,
                y: centerY + m.top,
                width: centerW - (m.left+m.right),
                height: centerH - (m.top+m.bottom)
            };
            if(this.hideOnLayout){
                c.el.setStyle('display', 'block');
            }
            c.updateBox(this.safeBox(centerBox));
        }
        this.el.repaint();
        this.fireEvent('layout', this);
        
	    
    },
    
    safeBox : function(box){
        box.width = Math.max(0, box.width);
        box.height = Math.max(0, box.height);
        return box;
    },
    
    
    add : function(target, panel){
        target = target.toLowerCase();
        return this.regions[target].add(panel);
    },
    
    
    remove : function(target, panel){
        target = target.toLowerCase();
        return this.regions[target].remove(panel);
    },
    
    
    findPanel : function(panelId){
        var rs = this.regions;
        for(var target in rs){
            if(typeof rs[target] != 'function'){
                var p = rs[target].getPanel(panelId);
                if(p){
                    return p;
                }
            }
        }
        return null;
    },
    
    
    showPanel : function(panelId) {
      var rs = this.regions;
      for(var target in rs){
         var r = rs[target];
         if(typeof r != 'function'){
            if(r.hasPanel(panelId)){
               return r.showPanel(panelId);
            }
         }
      }
      return null;
   },
   
   
    restoreState : function(provider){
        if(!provider){
            provider = YAHOO.ext.state.Manager;
        }
        var sm = new YAHOO.ext.LayoutStateManager();
        sm.init(this, provider);
    }
});

YAHOO.ext.BorderLayout.RegionFactory = {};
YAHOO.ext.BorderLayout.RegionFactory.validRegions = ['north','south','east','west','center'];
YAHOO.ext.BorderLayout.RegionFactory.create = function(target, mgr, config){
    if(config.lightweight){
        return new YAHOO.ext.LayoutRegionLite(mgr, config);
    }
    target = target.toLowerCase();
    switch(target){
        case 'north':
            return new YAHOO.ext.NorthLayoutRegion(mgr, config);
        case 'south':
            return new YAHOO.ext.SouthLayoutRegion(mgr, config);
        case 'east':
            return new YAHOO.ext.EastLayoutRegion(mgr, config);
        case 'west':
            return new YAHOO.ext.WestLayoutRegion(mgr, config);
        case 'center':
            return new YAHOO.ext.CenterLayoutRegion(mgr, config);
    }
    throw 'Layout region "'+target+'" not supported.';
};

YAHOO.ext.CenterLayoutRegion = function(mgr, config){
    YAHOO.ext.CenterLayoutRegion.superclass.constructor.call(this, mgr, config, 'center');
    this.visible = true;
    this.minWidth = config.minWidth || 20;
    this.minHeight = config.minHeight || 20;
};

YAHOO.extendX(YAHOO.ext.CenterLayoutRegion, YAHOO.ext.LayoutRegion, {
    hide : function(){
        
    },
    
    show : function(){
        
    },
    
    getMinWidth: function(){
        return this.minWidth;
    },
    
    getMinHeight: function(){
        return this.minHeight;
    }
});


YAHOO.ext.NorthLayoutRegion = function(mgr, config){
    YAHOO.ext.NorthLayoutRegion.superclass.constructor.call(this, mgr, config, 'north', 'n-resize');
    if(this.split){
        this.split.placement = YAHOO.ext.SplitBar.TOP;
        this.split.orientation = YAHOO.ext.SplitBar.VERTICAL;
        this.split.el.addClass('ylayout-split-v');
    }
    if(typeof config.initialSize != 'undefined'){
        this.el.setHeight(config.initialSize);
    }
};
YAHOO.extendX(YAHOO.ext.NorthLayoutRegion, YAHOO.ext.SplitLayoutRegion, {
    getBox : function(){
        if(this.collapsed){
            return this.collapsedEl.getBox();
        }
        var box = this.el.getBox();
        if(this.split){
            box.height += this.split.el.getHeight();
        }
        return box;
    },
    
    updateBox : function(box){
        if(this.split && !this.collapsed){
            box.height -= this.split.el.getHeight();
            this.split.el.setLeft(box.x);
            this.split.el.setTop(box.y+box.height);
            this.split.el.setWidth(box.width);
        }
        if(this.collapsed){
            this.el.setWidth(box.width);
            var bodyWidth = box.width - this.el.getBorderWidth('rl');
            this.bodyEl.setWidth(bodyWidth);
            if(this.activePanel && this.panelSize){
                this.activePanel.setSize(bodyWidth, this.panelSize.height);
            }
        }
        YAHOO.ext.NorthLayoutRegion.superclass.updateBox.call(this, box);
    }
});

YAHOO.ext.SouthLayoutRegion = function(mgr, config){
    YAHOO.ext.SouthLayoutRegion.superclass.constructor.call(this, mgr, config, 'south', 's-resize');
    if(this.split){
        this.split.placement = YAHOO.ext.SplitBar.BOTTOM;
        this.split.orientation = YAHOO.ext.SplitBar.VERTICAL;
        this.split.el.addClass('ylayout-split-v');
    }
    if(typeof config.initialSize != 'undefined'){
        this.el.setHeight(config.initialSize);
    }
};
YAHOO.extendX(YAHOO.ext.SouthLayoutRegion, YAHOO.ext.SplitLayoutRegion, {
    getBox : function(){
        if(this.collapsed){
            return this.collapsedEl.getBox();
        }
        var box = this.el.getBox();
        if(this.split){
            var sh = this.split.el.getHeight();
            box.height += sh;
            box.y -= sh;
        }
        return box;
    },
    
    updateBox : function(box){
        if(this.split && !this.collapsed){
            var sh = this.split.el.getHeight();
            box.height -= sh;
            box.y += sh;
            this.split.el.setLeft(box.x);
            this.split.el.setTop(box.y-sh);
            this.split.el.setWidth(box.width);
        }
        if(this.collapsed){
            this.el.setWidth(box.width);
            var bodyWidth = box.width - this.el.getBorderWidth('rl');
            this.bodyEl.setWidth(bodyWidth);
            if(this.activePanel && this.panelSize){
                this.activePanel.setSize(bodyWidth, this.panelSize.height);
            }
        }
        YAHOO.ext.SouthLayoutRegion.superclass.updateBox.call(this, box);
    }
});

YAHOO.ext.EastLayoutRegion = function(mgr, config){
    YAHOO.ext.EastLayoutRegion.superclass.constructor.call(this, mgr, config, 'east', 'e-resize');
    if(this.split){
        this.split.placement = YAHOO.ext.SplitBar.RIGHT;
        this.split.orientation = YAHOO.ext.SplitBar.HORIZONTAL;
        this.split.el.addClass('ylayout-split-h');
    }
    if(typeof config.initialSize != 'undefined'){
        this.el.setWidth(config.initialSize);
    }
};
YAHOO.extendX(YAHOO.ext.EastLayoutRegion, YAHOO.ext.SplitLayoutRegion, {
    getBox : function(){
        if(this.collapsed){
            return this.collapsedEl.getBox();
        }
        var box = this.el.getBox();
        if(this.split){
            var sw = this.split.el.getWidth();
            box.width += sw;
            box.x -= sw;
        }
        return box;
    },
    
    updateBox : function(box){
        if(this.split && !this.collapsed){
            var sw = this.split.el.getWidth();
            box.width -= sw;
            this.split.el.setLeft(box.x);
            this.split.el.setTop(box.y);
            this.split.el.setHeight(box.height);
            box.x += sw;
        }
        if(this.collapsed){
            this.el.setHeight(box.height);
            var bodyHeight = this.config.titlebar ? box.height - (this.titleEl.getHeight()||0) : box.height;
            bodyHeight -= this.el.getBorderWidth('tb');
            this.bodyEl.setHeight(bodyHeight);
            if(this.activePanel && this.panelSize){
                this.activePanel.setSize(this.panelSize.width, bodyHeight);
            }
        }
        YAHOO.ext.EastLayoutRegion.superclass.updateBox.call(this, box);
    }
});

YAHOO.ext.WestLayoutRegion = function(mgr, config){
    YAHOO.ext.WestLayoutRegion.superclass.constructor.call(this, mgr, config, 'west', 'w-resize');
    if(this.split){
        this.split.placement = YAHOO.ext.SplitBar.LEFT;
        this.split.orientation = YAHOO.ext.SplitBar.HORIZONTAL;
        this.split.el.addClass('ylayout-split-h');
    }
    if(typeof config.initialSize != 'undefined'){
        this.el.setWidth(config.initialSize);
    }
};
YAHOO.extendX(YAHOO.ext.WestLayoutRegion, YAHOO.ext.SplitLayoutRegion, {
    getBox : function(){
        if(this.collapsed){
            return this.collapsedEl.getBox();
        }
        var box = this.el.getBox();
        if(this.split){
            box.width += this.split.el.getWidth();
        }
        return box;
    },
    
    updateBox : function(box){
        if(this.split && !this.collapsed){
            var sw = this.split.el.getWidth();
            box.width -= sw;
            this.split.el.setLeft(box.x+box.width);
            this.split.el.setTop(box.y);
            this.split.el.setHeight(box.height);
        }
        if(this.collapsed){
            this.el.setHeight(box.height);
            var bodyHeight = this.config.titlebar ? box.height - (this.titleEl.getHeight()||0) : box.height;
            bodyHeight -= this.el.getBorderWidth('tb');
            this.bodyEl.setHeight(bodyHeight);
            if(this.activePanel && this.panelSize){
                this.activePanel.setSize(this.panelSize.width, bodyHeight);
            }
        }
        YAHOO.ext.WestLayoutRegion.superclass.updateBox.call(this, box);
    }
});


YAHOO.ext.ContentPanel = function(el, config, content){
    YAHOO.ext.ContentPanel.superclass.constructor.call(this);
    this.el = getEl(el, true);
    if(!this.el && config && config.autoCreate){
        if(typeof config.autoCreate == 'object'){
            if(!config.autoCreate.id){
                config.autoCreate.id = el;
            }
            this.el = YAHOO.ext.DomHelper.append(document.body,
                        config.autoCreate, true);
        }else{
            this.el = YAHOO.ext.DomHelper.append(document.body,
                        {tag: 'div', cls: 'ylayout-inactive-content', id: el}, true);
        }
    }
    this.closable = false;
    this.loaded = false;
    this.active = false;
    if(typeof config == 'string'){
        this.title = config;
    }else{
        YAHOO.ext.util.Config.apply(this, config);
    }
    if(this.resizeEl){
        this.resizeEl = getEl(this.resizeEl, true);
    }else{
        this.resizeEl = this.el;
    }
    this.events = {
        
        'activate' : new YAHOO.util.CustomEvent('activate'),
        
        'deactivate' : new YAHOO.util.CustomEvent('deactivate') 
    };
    if(this.autoScroll){
        this.el.setStyle('overflow', 'auto');
    }
    if(content){
        this.setContent(content);
    }
};

YAHOO.extendX(YAHOO.ext.ContentPanel, YAHOO.ext.util.Observable, {
    setRegion : function(region){
        this.region = region;
        if(region){
           this.el.replaceClass('ylayout-inactive-content', 'ylayout-active-content'); 
        }else{
           this.el.replaceClass('ylayout-active-content', 'ylayout-inactive-content'); 
        } 
    },
    
    
    getToolbar : function(){
        return this.toolbar;
    },
    
    setActiveState : function(active){
        this.active = active;
        if(!active){
            this.fireEvent('deactivate', this);
        }else{
            this.fireEvent('activate', this);
        }
    },
    
    setContent : function(content, loadScripts){
        this.el.update(content, loadScripts);
    },
    
    
    getUpdateManager : function(){
        return this.el.getUpdateManager();
    },
    
    
    setUrl : function(url, params, loadOnce){
        if(this.refreshDelegate){
            this.removeListener('activate', this.refreshDelegate);
        }
        this.refreshDelegate = this._handleRefresh.createDelegate(this, [url, params, loadOnce]);
        this.on('activate', this._handleRefresh.createDelegate(this, [url, params, loadOnce]));
        return this.el.getUpdateManager();
    },
    
    _handleRefresh : function(url, params, loadOnce){
        if(!loadOnce || !this.loaded){
            var updater = this.el.getUpdateManager();
            updater.update(url, params, this._setLoaded.createDelegate(this));
        }
    },
    
    _setLoaded : function(){
        this.loaded = true;
    }, 
    
    
    getId : function(){
        return this.el.id;
    },
    
    
    getEl : function(){
        return this.el;
    },
    
    adjustForComponents : function(width, height){
        if(this.toolbar){
            var te = this.toolbar.getEl();
            height -= te.getHeight();
            te.setWidth(width);
        }
        if(this.adjustments){
            width += this.adjustments[0];
            height += this.adjustments[1];
        }
        return {'width': width, 'height': height};
    },
    
    setSize : function(width, height){
        if(this.fitToFrame){
            var size = this.adjustForComponents(width, height);
            this.resizeEl.setSize(this.autoWidth ? 'auto' : size.width, size.height);
        }
    },
    
    
    getTitle : function(){
        return this.title;
    },
    
    
    setTitle : function(title){
        this.title = title;
        if(this.region){
            this.region.updatePanelTitle(this, title);
        }
    },
    
    
    isClosable : function(){
        return this.closable;
    },
    
    beforeSlide : function(){
        this.el.clip();
        this.resizeEl.clip();
    },
    
    afterSlide : function(){
        this.el.unclip();
        this.resizeEl.unclip();
    },
    
    
    refresh : function(){
        if(this.refreshDelegate){
           this.loaded = false;
           this.refreshDelegate();
        }
    },
    
    
    destroy : function(){
        this.el.removeAllListeners();
        var tempEl = document.createElement('span');
        tempEl.appendChild(this.el.dom);
        tempEl.innerHTML = '';
        this.el = null;
    }
});


YAHOO.ext.GridPanel = function(grid, config){
    this.wrapper = YAHOO.ext.DomHelper.append(document.body, 
        {tag: 'div', cls: 'ylayout-grid-wrapper ylayout-inactive-content'}, true);
    this.wrapper.dom.appendChild(grid.container.dom);
    YAHOO.ext.GridPanel.superclass.constructor.call(this, this.wrapper, config);
    if(this.toolbar){
        this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);
    }
    grid.monitorWindowResize = false; 
    grid.autoHeight = false;
    grid.autoWidth = false;
    this.grid = grid;
    this.grid.container.replaceClass('ylayout-inactive-content', 'ylayout-component-panel');
};

YAHOO.extendX(YAHOO.ext.GridPanel, YAHOO.ext.ContentPanel, {
    getId : function(){
        return this.grid.id;
    },
    
    
    getGrid : function(){
        return this.grid;    
    },
    
    setSize : function(width, height){
        var grid = this.grid;
        var size = this.adjustForComponents(width, height);
        grid.container.setSize(size.width, size.height);
        grid.autoSize();
    },
    
    beforeSlide : function(){
        this.grid.getView().wrapEl.clip();
    },
    
    afterSlide : function(){
        this.grid.getView().wrapEl.unclip();
    },
    
    destroy : function(){
        this.grid.getView().unplugDataModel(this.grid.getDataModel());
        this.grid.container.removeAllListeners();
        YAHOO.ext.GridPanel.superclass.destroy.call(this);
    }
});



YAHOO.ext.NestedLayoutPanel = function(layout, config){
    YAHOO.ext.NestedLayoutPanel.superclass.constructor.call(this, layout.getEl(), config);
    layout.monitorWindowResize = false; 
    this.layout = layout;
    this.layout.getEl().addClass('ylayout-nested-layout');
};

YAHOO.extendX(YAHOO.ext.NestedLayoutPanel, YAHOO.ext.ContentPanel, {
    setSize : function(width, height){
        var size = this.adjustForComponents(width, height);
        this.layout.getEl().setSize(size.width, size.height);
        this.layout.layout();
    },
    
    
    getLayout : function(){
        return this.layout;
    }
});

YAHOO.ext.LayoutStateManager = function(layout){
     
     this.state = {
        north: {},
        south: {},
        east: {},
        west: {}       
    };
};

YAHOO.ext.LayoutStateManager.prototype = {
    init : function(layout, provider){
        this.provider = provider;
        var state = provider.get(layout.id+'-layout-state');
        if(state){
            var wasUpdating = layout.isUpdating();
            if(!wasUpdating){
                layout.beginUpdate();
            }
            for(var key in state){
                if(typeof state[key] != 'function'){
                    var rstate = state[key];
                    var r = layout.getRegion(key);
                    if(r && rstate){
                        if(rstate.size){
                            r.resizeTo(rstate.size);
                        }
                        if(rstate.collapsed == true){
                            r.collapse(true);
                        }else{
                            r.expand(null, true);
                        }
                    }
                }
            }
            if(!wasUpdating){
                layout.endUpdate();
            }
            this.state = state; 
        }
        this.layout = layout;
        layout.on('regionresized', this.onRegionResized, this, true);
        layout.on('regioncollapsed', this.onRegionCollapsed, this, true);
        layout.on('regionexpanded', this.onRegionExpanded, this, true);
    },
    
    storeState : function(){
        this.provider.set(this.layout.id+'-layout-state', this.state);
    },
    
    onRegionResized : function(region, newSize){
        this.state[region.getPosition()].size = newSize;
        this.storeState();
    },
    
    onRegionCollapsed : function(region){
        this.state[region.getPosition()].collapsed = true;
        this.storeState();
    },
    
    onRegionExpanded : function(region){
        this.state[region.getPosition()].collapsed = false;
        this.storeState();
    }
};

YAHOO.ext.BasicDialog = function(el, config){
    this.el = getEl(el);
    var dh = YAHOO.ext.DomHelper;
    if(!this.el && config && config.autoCreate){
        if(typeof config.autoCreate == 'object'){
            if(!config.autoCreate.id){
                config.autoCreate.id = el;
            }
            this.el = dh.append(document.body,
                        config.autoCreate, true);
        }else{
            this.el = dh.append(document.body,
                        {tag: 'div', id: el}, true);
        }
    }
    el = this.el;
    el.setDisplayed(true);
    el.hide = this.hideAction;
    this.id = el.id;
    el.addClass('ydlg');
    this.shadowOffset = 3;
    this.minHeight = 80;
    this.minWidth = 200;
    this.minButtonWidth = 75;
    this.defaultButton = null;
    
    YAHOO.ext.util.Config.apply(this, config);
    
    this.proxy = el.createProxy('ydlg-proxy');
    this.proxy.hide = this.hideAction;
    this.proxy.setOpacity(.5);
    this.proxy.hide();
    
    if(config.width){
        el.setWidth(config.width);
    }
    if(config.height){
        el.setHeight(config.height);
    }
    this.size = el.getSize();
    if(typeof config.x != 'undefined' && typeof config.y != 'undefined'){
        this.xy = [config.x,config.y];
    }else{
        this.xy = el.getCenterXY(true);
    }
    
    var cn = el.dom.childNodes;
    for(var i = 0, len = cn.length; i < len; i++) {
    	var node = cn[i];
    	if(node && node.nodeType == 1){
    	    if(YAHOO.util.Dom.hasClass(node, 'ydlg-hd')){
    	        this.header = getEl(node, true);
    	    }else if(YAHOO.util.Dom.hasClass(node, 'ydlg-bd')){
    	        this.body = getEl(node, true);
    	    }else if(YAHOO.util.Dom.hasClass(node, 'ydlg-ft')){
    	        
                this.footer = getEl(node, true);
    	    }
    	}
    }
    
    if(!this.header){
        
        this.header = dh.append(el.dom, {tag: 'div', cls:'ydlg-hd'}, true);
    }
    if(this.title){
        this.header.update(this.title);
    }
    if(!this.body){
        
        this.body = dh.append(el.dom, {tag: 'div', cls:'ydlg-bd'}, true);
    }
    
    var hl = dh.insertBefore(this.header.dom, {tag: 'div', cls:'ydlg-hd-left'});
    var hr = dh.append(hl, {tag: 'div', cls:'ydlg-hd-right'});
    hr.appendChild(this.header.dom);
    
    
    this.bwrap = dh.insertBefore(this.body.dom, {tag: 'div', cls:'ydlg-dlg-body'}, true);
    this.bwrap.dom.appendChild(this.body.dom);
    if(this.footer) this.bwrap.dom.appendChild(this.footer.dom);
    
    if(this.autoScroll !== false && !this.autoTabs){
        this.body.setStyle('overflow', 'auto');
    }
    if(this.closable !== false){
        this.el.addClass('ydlg-closable');
        this.close = dh.append(el.dom, {tag: 'div', cls:'ydlg-close'}, true);
        this.close.mon('click', function(){
            this.hide();
        }, this, true);
    }
    if(this.resizable !== false){
        this.el.addClass('ydlg-resizable');
        this.resizer = new YAHOO.ext.Resizable(el, {
            minWidth: this.minWidth || 80, 
            minHeight:this.minHeight || 80, 
            handles: 'all',
            pinned: true
        });
        this.resizer.on('beforeresize', this.beforeResize, this, true);
        this.resizer.on('resize', this.onResize, this, true);
    }
    if(this.draggable !== false){
        el.addClass('ydlg-draggable');
        if (!this.proxyDrag) {
            var dd = new YAHOO.util.DD(el.dom.id, 'WindowDrag');
        }
        else {
            var dd = new YAHOO.util.DDProxy(el.dom.id, 'WindowDrag', {dragElId: this.proxy.id});
        }
        dd.setHandleElId(this.header.id);
        dd.endDrag = this.endMove.createDelegate(this);
        dd.startDrag = this.startMove.createDelegate(this);
        dd.onDrag = this.onDrag.createDelegate(this);
        this.dd = dd;
    }
    if(this.modal){
        this.mask = dh.append(document.body, {tag: 'div', cls:'ydlg-mask'}, true);
        this.mask.enableDisplayMode('block');
        this.mask.hide();
    }
    if(this.shadow){
        this.shadow = el.createProxy({tag: 'div', cls:'ydlg-shadow'});
        this.shadow.setOpacity(.3);
        this.shadow.setVisibilityMode(YAHOO.ext.Element.VISIBILITY);
        this.shadow.setDisplayed('block');
        this.shadow.hide = this.hideAction;
        this.shadow.hide();
    }else{
        this.shadowOffset = 0;
    }
    if(this.shim){
        this.shim = this.el.createShim();
        this.shim.hide = this.hideAction;
        this.shim.hide();
    }
    if(this.autoTabs){
        var tabEls = YAHOO.util.Dom.getElementsByClassName('ydlg-tab', this.tabTag || 'div', el.dom);
        if(tabEls.length > 0){
            this.body.addClass(this.tabPosition == 'bottom' ? 'ytabs-bottom' : 'ytabs-top');
            this.tabs = new YAHOO.ext.TabPanel(this.body.dom, this.tabPosition == 'bottom');
            for(var i = 0, len = tabEls.length; i < len; i++) {
            	var tabEl = tabEls[i];
            	this.tabs.addTab(YAHOO.util.Dom.generateId(tabEl), tabEl.title);
            	tabEl.title = '';
            }
            this.tabs.activate(tabEls[0].id);
        }
    }
    this.syncBodyHeight();
    this.events = {
        
        'keydown' : true,
        
        'move' : true,
        
        'resize' : true,
        
        'beforehide' : true,
        
        'hide' : true,
        
        'beforeshow' : true,
        
        'show' : true
    };
    el.mon('keydown', this.onKeyDown, this, true);
    el.mon("mousedown", this.toFront, this, true);

    YAHOO.ext.EventManager.onWindowResize(this.adjustViewport, this, true);
    this.el.hide();
    YAHOO.ext.DialogManager.register(this);
};

YAHOO.extendX(YAHOO.ext.BasicDialog, YAHOO.ext.util.Observable, {
    
    setTitle : function(text){
        this.header.update(text);
        return this; 
    },
    
    beforeResize : function(){
        this.resizer.minHeight = Math.max(this.minHeight, this.getHeaderFooterHeight(true)+40);
    },
    
    onResize : function(){
        this.refreshSize();
        this.syncBodyHeight();
        this.adjustAssets();
        this.fireEvent('resize', this, this.size.width, this.size.height);
    },
    
    onKeyDown : function(e){
        this.fireEvent('keydown', this, e);
    },
    
    
    resizeTo : function(width, height){
        this.el.setSize(width, height);
        this.size = {width: width, height: height};
        this.syncBodyHeight();
        if(this.fixedcenter){
            this.center();
        }
        if(this.isVisible()){
            this.constrainXY();
            this.adjustAssets();
        }
        this.fireEvent('resize', this, width, height);
        return this;
    },
    
    
    addKeyListener : function(key, fn, scope){
        var keyCode, shift, ctrl, alt;
        if(typeof key == 'object' && !(key instanceof Array)){
            keyCode = key['key'];
            shift = key['shift'];
            ctrl = key['ctrl'];
            alt = key['alt'];
        }else{
            keyCode = key;
        }
        var handler = function(dlg, e){
            if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) &&  (!alt || e.altKey)){
                var k = e.getKey();
                if(keyCode instanceof Array){
                    for(var i = 0, len = keyCode.length; i < len; i++){
                        if(keyCode[i] == k){
                          fn.call(scope || window, dlg, k, e);
                          return;
                        }
                    }
                }else{
                    if(k == keyCode){
                        fn.call(scope || window, dlg, k, e);
                    }
                }
            }
        };
        this.on('keydown', handler);
        return this; 
    },
    
    
    getTabs : function(){
        if(!this.tabs){
            this.body.addClass(this.tabPosition == 'bottom' ? 'ytabs-bottom' : 'ytabs-top');
            this.tabs = new YAHOO.ext.TabPanel(this.body.dom, this.tabPosition == 'bottom');
        }
        return this.tabs;    
    },
    
    
    addButton : function(config, handler, scope){
        var dh = YAHOO.ext.DomHelper;
        if(!this.footer){
            this.footer = dh.append(this.bwrap.dom, {tag: 'div', cls:'ydlg-ft'}, true);
        }
        var bconfig = {
            handler: handler,
            scope: scope,
            minWidth: this.minButtonWidth
        };
        if(typeof config == 'string'){
            bconfig.text = config;
        }else{
            bconfig.dhconfig = config;
        }
        var btn = new YAHOO.ext.Button(this.footer, bconfig);
        this.syncBodyHeight();
        if(!this.buttons){
            this.buttons = [];
        }
        this.buttons.push(btn);
        return btn;
    },
    
    
    setDefaultButton : function(btn){
        this.defaultButton = btn;  
        return this;
    },
    
    getHeaderFooterHeight : function(safe){
        var height = 0;
        if(this.header){
           height += this.header.getHeight();
        }
        if(this.footer){
            var fm = this.footer.getMargins();
            height += (this.footer.getHeight()+fm.top+fm.bottom);
        }
        height += this.bwrap.getPadding('tb')+this.bwrap.getBorderWidth('tb');
        return height;
    },
    
    syncBodyHeight : function(){
        var height = this.size.height - this.getHeaderFooterHeight(false);
        var bm = this.body.getMargins();
        this.body.setHeight(height-(bm.top+bm.bottom));
        if(this.tabs){
            this.tabs.syncHeight();
        }
        this.bwrap.setHeight(this.size.height-this.header.getHeight());
        
        this.body.setWidth(this.el.getWidth(true)-this.bwrap.getBorderWidth('lr')-this.bwrap.getPadding('lr'));
    },
    
    
    restoreState : function(){
        var box = YAHOO.ext.state.Manager.get(this.el.id + '-state');
        if(box && box.width){
            this.xy = [box.x, box.y];
            this.resizeTo(box.width, box.height);
        }
        return this; 
    },
    
    beforeShow : function(){
        if(this.fixedcenter) {
            this.xy = this.el.getCenterXY(true);
        }
        if(this.modal){
            YAHOO.util.Dom.addClass(document.body, 'masked');
            this.mask.setSize(YAHOO.util.Dom.getDocumentWidth(), YAHOO.util.Dom.getDocumentHeight());
            this.mask.show();
        }
        this.constrainXY();
    },
    
    animShow : function(){
        var b = getEl(this.animateTarget, true).getBox();
        this.proxy.setSize(b.width, b.height);
        this.proxy.setLocation(b.x, b.y);
        this.proxy.show();
        this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height, 
                    true, .35, this.showEl.createDelegate(this));
    },
    
    
    show : function(animateTarget){
        if (this.fireEvent('beforeshow', this) === false){
            return;
        }
        if(this.syncHeightBeforeShow){
            this.syncBodyHeight();
        }
        this.animateTarget = animateTarget || this.animateTarget;
        if(!this.el.isVisible()){
            this.beforeShow();
            if(this.animateTarget){
                this.animShow();
            }else{
                this.showEl();
            }
        }
        return this; 
    },
    
    showEl : function(){
        this.proxy.hide();
        this.el.setXY(this.xy);
        this.el.show();
        this.adjustAssets(true);
        this.toFront();
        if(this.defaultButton){
            this.defaultButton.focus();
        }
        this.fireEvent('show', this);
    },
    
    constrainXY : function(){
        if(this.constraintoviewport !== false){
            if(!this.viewSize){
                this.viewSize = [YAHOO.util.Dom.getViewportWidth(), YAHOO.util.Dom.getViewportHeight()];
            }
            var x = this.xy[0], y = this.xy[1];
            var w = this.size.width, h = this.size.height;
            var vw = this.viewSize[0], vh = this.viewSize[1];
            
            var moved = false;
            
            if(x + w > vw){
                x = vw - w;
                moved = true;
            }
            if(y + h > vh){
                y = vh - h;
                moved = true;
            }
            
            if(x < 0){
                x = 0;
                moved = true;
            }
            if(y < 0){
                y = 0;
                moved = true;
            }
            if(moved){
                
                this.xy = [x, y];
                if(this.isVisible()){
                    this.el.setLocation(x, y);
                    this.adjustAssets();
                }
            }
        }
    },
    
    onDrag : function(){
        if(!this.proxyDrag){
            this.xy = this.el.getXY();
            this.adjustAssets();
        }   
    },
    
    adjustAssets : function(doShow){
        var x = this.xy[0], y = this.xy[1];
        var w = this.size.width, h = this.size.height;
        if(doShow === true){
            if(this.shadow){
                this.shadow.show();
            }
            if(this.shim){
                this.shim.show();
            }
        }
        if(this.shadow && this.shadow.isVisible()){
            this.shadow.setBounds(x + this.shadowOffset, y + this.shadowOffset, w, h);
        }
        if(this.shim && this.shim.isVisible()){
            this.shim.setBounds(x, y, w, h);
        }
    },
    
    
    adjustViewport : function(w, h){
        if(!w || !h){
            w = YAHOO.util.Dom.getViewportWidth();
            h = YAHOO.util.Dom.getViewportHeight();
        }
        
        this.viewSize = [w, h];
        if(this.modal && this.mask.isVisible()){
            this.mask.setSize(w, h); 
            this.mask.setSize(YAHOO.util.Dom.getDocumentWidth(), YAHOO.util.Dom.getDocumentHeight());
        }
        if(this.isVisible()){
            this.constrainXY();
        }
    },
    
    
    destroy : function(removeEl){
        YAHOO.ext.EventManager.removeResizeListener(this.adjustViewport, this);
        if(this.tabs){
            this.tabs.destroy(removeEl);
        }
        if(removeEl === true){
            this.el.update('');
            this.el.remove();
        }
        YAHOO.ext.DialogManager.unregister(this);
    },
    
    startMove : function(){
        if(this.proxyDrag){
            this.proxy.show();
        }
        if(this.constraintoviewport !== false){
            this.dd.constrainTo(document.body, {right: this.shadowOffset, bottom: this.shadowOffset});
        }
    },
    
    endMove : function(){
        if(!this.proxyDrag){
            YAHOO.util.DD.prototype.endDrag.apply(this.dd, arguments);
        }else{
            YAHOO.util.DDProxy.prototype.endDrag.apply(this.dd, arguments);
            this.proxy.hide();
        }
        this.refreshSize();
        this.adjustAssets();
        this.fireEvent('move', this, this.xy[0], this.xy[1])
    },
    
    
    toFront : function(){
        YAHOO.ext.DialogManager.bringToFront(this);  
        return this; 
    },
    
    
    toBack : function(){
        YAHOO.ext.DialogManager.sendToBack(this);  
        return this; 
    },
    
    
    center : function(){
        this.moveTo(this.el.getCenterXY(true));
        return this; 
    },
    
    
    moveTo : function(x, y){
        this.xy = [x,y];
        if(this.isVisible()){
            this.el.setXY(this.xy);
            this.adjustAssets();
        }
        return this; 
    },
    
    
    isVisible : function(){
        return this.el.isVisible();    
    },
    
    animHide : function(callback){
        var b = getEl(this.animateTarget, true).getBox();
        this.proxy.show();
        this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
        this.el.hide();
        this.proxy.setBounds(b.x, b.y, b.width, b.height, true, .35, 
                    this.hideEl.createDelegate(this, [callback]));
    },
    
    
    hide : function(callback){
        if (this.fireEvent('beforehide', this) === false)
            return;
        
        if(this.shadow){
            this.shadow.hide();
        }
        if(this.shim) {
          this.shim.hide();
        }
        if(this.animateTarget){
           this.animHide(callback);
        }else{
            this.el.hide();
            this.hideEl(callback);
        }
        return this; 
    },
    
    hideEl : function(callback){
        this.proxy.hide();
        if(this.modal){
            this.mask.hide();
            YAHOO.util.Dom.removeClass(document.body, 'masked');
        }
        this.fireEvent('hide', this);
        if(typeof callback == 'function'){
            callback();
        }
    },
    
    hideAction : function(){
        this.setLeft('-10000px');  
        this.setTop('-10000px');
        this.setStyle('visibility', 'hidden'); 
    },
    
    refreshSize : function(){
        this.size = this.el.getSize();
        this.xy = this.el.getXY();
        YAHOO.ext.state.Manager.set(this.el.id + '-state', this.el.getBox());
    },
    
    setZIndex : function(index){
        if(this.modal){
            this.mask.setStyle('z-index', index);
        }
        if(this.shadow){
            this.shadow.setStyle('z-index', ++index);
        }
        if(this.shim){
            this.shim.setStyle('z-index', ++index);
        }
        this.el.setStyle('z-index', ++index);
        if(this.proxy){
            this.proxy.setStyle('z-index', ++index);
        }
        if(this.resizer){
            this.resizer.proxy.setStyle('z-index', ++index);
        }
        
        this.lastZIndex = index;
    },
    
    
    getEl : function(){
        return this.el;
    }
});


YAHOO.ext.DialogManager = function(){
    var list = {};
    var accessList = [];
    var front = null;
    
    var sortDialogs = function(d1, d2){
        return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
    };
    
    var orderDialogs = function(){
        accessList.sort(sortDialogs);
        var seed = YAHOO.ext.DialogManager.zseed;
        for(var i = 0, len = accessList.length; i < len; i++){
            if(accessList[i]){
                accessList[i].setZIndex(seed + (i*10));
            }  
        }
    };
    
    return {
        
        zseed : 10000,
        
        
        register : function(dlg){
            list[dlg.id] = dlg;
            accessList.push(dlg);
        },
        
        unregister : function(dlg){
            delete list[dlg.id];
            if(!accessList.indexOf){
                for(var i = 0, len = accessList.length; i < len; i++){
                    accessList.splice(i, 1);
                    return;
                }
            }else{
                var i = accessList.indexOf(dlg);
                if(i != -1){
                    accessList.splice(i, 1);
                }
            }
        },
        
        
        get : function(id){
            return typeof id == 'object' ? id : list[id];
        },
        
        
        bringToFront : function(dlg){
            dlg = this.get(dlg);
            if(dlg != front){
                front = dlg;
                dlg._lastAccess = new Date().getTime();
                orderDialogs();
            }
            return dlg;
        },
        
        
        sendToBack : function(dlg){
            dlg = this.get(dlg);
            dlg._lastAccess = -(new Date().getTime());
            orderDialogs();
            return dlg;
        }
    };
}();


YAHOO.ext.LayoutDialog = function(el, config){
    config.autoTabs = false;
    YAHOO.ext.LayoutDialog.superclass.constructor.call(this, el, config);
    this.body.setStyle({overflow:'hidden', position:'relative'});
    this.layout = new YAHOO.ext.BorderLayout(this.body.dom, config);
    this.layout.monitorWindowResize = false;
    
    this.center = YAHOO.ext.BasicDialog.prototype.center;
    this.on('show', this.layout.layout, this.layout, true);
};
YAHOO.extendX(YAHOO.ext.LayoutDialog, YAHOO.ext.BasicDialog, {
    
    endUpdate : function(){
        this.layout.endUpdate();
    },
    
    beginUpdate : function(){
        this.layout.beginUpdate();
    },
    
    getLayout : function(){
        return this.layout;
    },
    syncBodyHeight : function(){
        YAHOO.ext.LayoutDialog.superclass.syncBodyHeight.call(this);
        if(this.layout)this.layout.layout();
    }
});

YAHOO.ext.Button = function(renderTo, config){
    YAHOO.ext.util.Config.apply(this, config);
    this.events = {
        
	    'click' : true  
    };
    if(renderTo){
        this.render(renderTo);
    }
};

YAHOO.extendX(YAHOO.ext.Button, YAHOO.ext.util.Observable, {
    render : function(renderTo){
        var btn;
        if(!this.dhconfig){
            if(!YAHOO.ext.Button.buttonTemplate){
                
                YAHOO.ext.Button.buttonTemplate = new YAHOO.ext.DomHelper.Template('<a href="#" class="ybtn-focus"><table border="0" cellpadding="0" cellspacing="0" class="ybtn-wrap"><tbody><tr><td class="ybtn-left">&#160;</td><td class="ybtn-center" unselectable="on">{0}</td><td class="ybtn-right">&#160;</td></tr></tbody></table></a>');
            }
            btn = YAHOO.ext.Button.buttonTemplate.append(
               getEl(renderTo).dom, [this.text], true);
            this.tbl = getEl(btn.dom.firstChild, true);
        }else{
            btn = YAHOO.ext.DomHelper.append(this.footer.dom, this.dhconfig, true);
        }
        this.el = btn;
        this.autoWidth();
        btn.addClass('ybtn');
        btn.mon('click', this.onClick, this, true);
        btn.on('mouseover', this.onMouseOver, this, true);
        btn.on('mouseout', this.onMouseOut, this, true);
        btn.on('mousedown', this.onMouseDown, this, true);
        btn.on('mouseup', this.onMouseUp, this, true);
    },
    
    getEl : function(){
        return this.el;  
    },
    
    autoWidth : function(){
        if(this.tbl){
            this.el.setWidth('auto');
            this.tbl.setWidth('auto');
            if(this.minWidth){
                 if(this.tbl.getWidth() < this.minWidth){
                     this.tbl.setWidth(this.minWidth);
                 }
            }
            this.el.setWidth(this.tbl.getWidth());
        } 
    },
    
    setHandler : function(handler, scope){
        this.handler = handler;
        this.scope = scope;  
    },
    
    
    setText : function(text){
        this.el.dom.firstChild.firstChild.firstChild.childNodes[1].innerHTML = text;
        this.autoWidth();
    },
    
    
    show: function(){
        this.el.setStyle('display', '');
    },
    
    
    hide: function(){
        this.el.setStyle('display', 'none'); 
    },
    
    
    setVisible: function(visible){
        if(visible) {
            this.show();
        }else{
            this.hide();
        }
    },
    
    
    focus : function(){
        this.el.focus();    
    },
    
    
    disable : function(){
        this.el.addClass('ybtn-disabled');
        this.disabled = true;
    },
    
    
    enable : function(){
        this.el.removeClass('ybtn-disabled');
        this.disabled = false;
    },
    
    onClick : function(e){
        e.preventDefault();
        if(!this.disabled){
            this.fireEvent('click', this, e);
            this.handler.call(this.scope || window, this, e);
        }
    },
    onMouseOver : function(e){
        if(!this.disabled){
            this.el.addClass('ybtn-over');
        }
    },
    onMouseOut : function(e){
        this.el.removeClass('ybtn-over');
    },
    onMouseDown : function(){
        if(!this.disabled){
            this.el.addClass('ybtn-click');
        }
    },
    onMouseUp : function(){
        this.el.removeClass('ybtn-click');
    }    
});

YAHOO.ext.View = function(container, tpl, dataModel, config){
    this.el = getEl(container, true);
    this.nodes = this.el.dom.childNodes;
    if(typeof tpl == 'string'){
        tpl = new YAHOO.ext.Template(tpl);
    }
    tpl.compile();
    
    this.tpl = tpl;
    this.setDataModel(dataModel);
    var CE = YAHOO.util.CustomEvent;
	
	this.events = {
	    
        'click' : true,
	    
        'dblclick' : true,
	    
        'contextmenu' : true,
	    
        'selectionchange' : true,
        
        
        'beforeselect' : true
	};
	this.el.mon("click", this.onClick, this, true);
    this.el.mon("dblclick", this.onDblClick, this, true);
    this.el.mon("contextmenu", this.onContextMenu, this, true);
    
    
    this.selectedClass = 'ydataview-selected';
    
    this.emptyText = '';
    
    this.selections = [];
    this.lastSelection = null;
    
    
    this.jsonRoot = null;
    YAHOO.ext.util.Config.apply(this, config);
    if(this.renderUpdates || this.jsonRoot){
        var um = this.el.getUpdateManager();
        um.setRenderer(this);
    }
};

YAHOO.extendX(YAHOO.ext.View, YAHOO.ext.util.Observable, {
    
    getEl : function(){
        return this.el;  
    },
    
    render : function(el, response){
        this.clearSelections();
        this.el.update('');
        var o;
        try{
            o = YAHOO.ext.util.JSON.decode(response.responseText);
            if(this.jsonRoot){
                o = eval('o.' + this.jsonRoot);
            }
        }catch(e){}
        
        this.jsonData = o;
        this.beforeRender();
        this.refresh();
    },
    
    beforeRender : function(){
        
    },
    
    
     refresh : function(){
        this.clearSelections();
        this.el.update('');
        this.html = [];
        if(this.renderUpdates || this.jsonRoot){
            var o = this.jsonData;
            if(o){
                for(var i = 0, len = o.length; i < len; i++) {
                	this.renderEach(o[i]);
                }
            }
        }else{
           this.dataModel.each(this.renderEach, this);
        }
        var strHtml;
        if(this.html.length > 0){
            strHtml = this.html.join('');
        }else{
            strHtml = this.emptyText;
        }
        this.el.update(strHtml);
        this.html = null;
        this.nodes = this.el.dom.childNodes;
        this.updateIndexes(0);
    },
    
    
    prepareData : function(data, index){
        return data;  
    },
    
    renderEach : function(data){
        this.html[this.html.length] = this.tpl.applyTemplate(this.prepareData(data));
    },
    
    
    refreshNode : function(index){
        this.refreshNodes(index, index);
    },
    
    refreshNodes : function(dm, startIndex, endIndex){
        this.clearSelections();
        var dm = this.dataModel;
        var ns = this.nodes;
        for(var i = startIndex; i <= endIndex; i++){
            var d = this.prepareData(dm.getRow(i), i);
            if(i < ns.length-1){
                var old = ns[i];
                this.tpl.insertBefore(old, d);
                this.el.dom.removeChild(old);
            }else{
                this.tpl.append(this.el.dom, d);
            }
        }
        this.updateIndexes(startIndex, endIndex);
    },
    
    deleteNodes : function(dm, startIndex, endIndex){
        this.clearSelections();
        if(startIndex == 0 && endIndex >= this.nodes.length-1){
            this.el.update('');
        }else{
            var el = this.el.dom;
            for(var i = startIndex; i <= endIndex; i++){
                el.removeChild(this.nodes[startIndex]);
            }
            this.updateIndexes(startIndex);
        }
    },
    
    insertNodes : function(dm, startIndex, endIndex){
        if(this.nodes.length == 0){
            this.refresh();
        }else{
            this.clearSelections();
            var t = this.tpl;
            var before = this.nodes[startIndex];
            var dm = this.dataModel;
            if(before){
                for(var i = startIndex; i <= endIndex; i++){
                    t.insertBefore(before, this.prepareData(dm.getRow(i), i));
                }
            }else{
                var el = this.el.dom;
                for(var i = startIndex; i <= endIndex; i++){
                    t.append(el, this.prepareData(dm.getRow(i), i));
                }
            }
            this.updateIndexes(startIndex);
        }
    },
    
    updateIndexes : function(dm, startIndex, endIndex){
        var ns = this.nodes;
        startIndex = startIndex || 0;
        endIndex = endIndex || ns.length-1;
        for(var i = startIndex; i <= endIndex; i++){
            ns[i].nodeIndex = i;
        }
    },
    
    
     setDataModel : function(dm){
        if(!dm) return;
        this.unplugDataModel(this.dataModel);
        this.dataModel = dm;
        dm.on('cellupdated', this.refreshNode, this, true);
        dm.on('datachanged', this.refresh, this, true);
        dm.on('rowsdeleted', this.deleteNodes, this, true);
        dm.on('rowsinserted', this.insertNodes, this, true);
        dm.on('rowsupdated', this.refreshNodes, this, true);
        dm.on('rowssorted', this.refresh, this, true);
        this.refresh();
    },
    
    
    unplugDataModel : function(dm){
        if(!dm) return;
        dm.removeListener('cellupdated', this.refreshNode, this);
        dm.removeListener('datachanged', this.refresh, this);
        dm.removeListener('rowsdeleted', this.deleteNodes, this);
        dm.removeListener('rowsinserted', this.insertNodes, this);
        dm.removeListener('rowsupdated', this.refreshNodes, this);
        dm.removeListener('rowssorted', this.refresh, this);
        this.dataModel = null;
    },
    
    
    findItemFromChild : function(node){
        var el = this.el.dom;
        if(!node || node.parentNode == el){
		    return node;
	    }
	    var p = node.parentNode;
	    while(p && p != el){
            if(p.parentNode == el){
            	return p;
            }
            p = p.parentNode;
        }
	    return null;
    },
    
    
    onClick : function(e){
        var item = this.findItemFromChild(e.getTarget());
        if(item){
            var index = this.indexOf(item);
            this.onItemClick(item, index, e);
            this.fireEvent('click', this, index, item, e);
        }else{
            this.clearSelections();
        }
    },

    
    onContextMenu : function(e){
        var item = this.findItemFromChild(e.getTarget());
        if(item){
            this.fireEvent('contextmenu', this, this.indexOf(item), item, e);
        }
    },

    
    onDblClick : function(e){
        var item = this.findItemFromChild(e.getTarget());
        if(item){
            this.fireEvent('dblclick', this, this.indexOf(item), item, e);
        }
    },
    
    onItemClick : function(item, index, e){
        if(this.multiSelect || this.singleSelect){
            if(this.multiSelect && e.shiftKey && this.lastSelection){
                this.select(this.getNodes(this.indexOf(this.lastSelection), index), false);
            }else{
                this.select(item, this.multiSelect && e.ctrlKey);
                this.lastSelection = item;
            }
        }
    },
    
    
     getSelectionCount : function(){
        return this.selections.length;
    },
    
    
    getSelectedNodes : function(){
        return this.selections;
    },
    
    
    getSelectedIndexes : function(){
        var indexes = [];
        for(var i = 0, len = this.selections.length; i < len; i++) {
        	indexes.push(this.selections[i].nodeIndex);
        }
        return indexes;
    },
    
    
    clearSelections : function(suppressEvent){
        if(this.multiSelect || this.singleSelect){
            YAHOO.util.Dom.removeClass(this.selections, this.selectedClass);
            this.selections = [];
            if(!suppressEvent){
                this.fireEvent('selectionchange', this, this.selections);
            }
        }
    },
    
    
    select : function(nodeInfo, keepExisting, suppressEvent){
        if(!keepExisting){
            this.clearSelections(true);
        }
        if(nodeInfo instanceof Array){
            for(var i = 0, len = nodeInfo.length; i < len; i++) {
            	this.select(nodeInfo[i], true, true);
            }
        }else{
            var node = this.getNode(nodeInfo);
            if(node){
                if(this.fireEvent('beforeselect', this, node, this.selections) !== false){
                    YAHOO.util.Dom.addClass(node, this.selectedClass);
                    this.selections.push(node);
                }
            }
        }
        if(!suppressEvent){
            this.fireEvent('selectionchange', this, this.selections);
        }
    },
    
    
     getNode : function(nodeInfo){
        if(typeof nodeInfo == 'object'){
            return nodeInfo;
        }else if(typeof nodeInfo == 'string'){
            return document.getElementById(nodeInfo);
        }else if(typeof nodeInfo == 'number'){
            return this.nodes[nodeInfo];
        }
        return null;
    },
    
    
    getNodes : function(start, end){
        var ns = this.nodes;
        startIndex = startIndex || 0;
        endIndex = typeof endIndex == 'undefined' ? ns.length-1 : endIndex;
        var nodes = [];
        for(var i = start; i <= end; i++) {
        	nodes.push(ns[i]);
        }
        return nodes;
    },
    
    
     indexOf : function(node){
        node = this.getNode(node);
        if(typeof node.nodeIndex == 'number'){
            return node.nodeIndex;
        }
        var ns = this.nodes;
        for(var i = 0, len = ns.length; i < len; i++) {
        	if(ns[i] == node){
        	    return i;
        	}
        }
        return -1;
    }
});

 
YAHOO.ext.JsonView = function(container, tpl, config){
    var cfg = config || {};
    cfg.renderUpdates = true;
    YAHOO.ext.JsonView.superclass.constructor.call(this, container, tpl, null, cfg);        
    
     this.events['beforerender'] = true;
     
     this.events['load'] = true;
     
     this.events['loadexception'] = true;
     this.el.getUpdateManager().on('update', this.onLoad, this, true);
     this.el.getUpdateManager().on('failure', this.onLoadException, this, true);
};
YAHOO.extendX(YAHOO.ext.JsonView, YAHOO.ext.View, {
    
    load : function(){
        var um = this.el.getUpdateManager();
        um.update.apply(um, arguments);
    },
    
    
    getCount : function(){
        return this.jsonData ? this.jsonData.length : 0;  
    },
    
    beforeRender : function(){
        this.snapshot = this.jsonData;    
        if(this.sortInfo){
            this.sort.apply(this, this.sortInfo);    
        }
        this.fireEvent('beforerender', this, this.jsonData);
    },
    
    onLoad : function(el, o){
       this.fireEvent('load', this, this.jsonData, o);
    },
    
    onLoadException : function(el, o){
       this.fireEvent('loadexception', this, o);
    },
    
    
    filter : function(property, value){
        if(this.jsonData){
            var data = [];
            var ss = this.snapshot;
            if(typeof value == 'string'){
                var vlen = value.length;
                if(vlen == 0){
                    this.clearFilter();
                    return;
                }
                for(var i = 0, len = ss.length; i < len; i++){
    				var o = ss[i];
    				if(o[property].substr(0, vlen) == value){
    					data.push(o);
    				}
    			}
            }else if(value.exec){ 
                for(var i = 0, len = ss.length; i < len; i++){
    				var o = ss[i];
    				if(value.test(o[property])){
    					data.push(o);
    				}
    			}
            }else{
                return;
            }
            this.jsonData = data;
    		this.refresh();
        }
	},
    
    
    filterBy : function(fn, scope){
        if(this.jsonData){
            var data = [];
            var ss = this.snapshot;
            for(var i = 0, len = ss.length; i < len; i++){
    			var o = ss[i];
    			if(fn.call(scope|| this, o)){
    				data.push(o);
    			}
    		}
    		this.jsonData = data;
    		this.refresh();
        }
    },
    
    
    clearFilter : function(){
        if(this.snapshot && this.jsonData != this.snapshot){
            this.jsonData = this.snapshot;
            this.refresh();
        }   
    },
    
    
    
    sort : function(property, dir, sortType){
        this.sortInfo = Array.prototype.slice.call(arguments, 0);
        if(this.jsonData){
            var p = property;
            var dsc = dir && dir.toLowerCase() == 'desc';
            var f = function(o1, o2){
            	var v1 = sortType ? sortType(o1[p]) : o1[p];
            	var v2 = sortType ? sortType(o2[p]) : o2[p];;
            	if(v1 < v2){
        			return dsc ? +1 : -1;
        		}else if(v1 > v2){
        			return dsc ? -1 : +1;
                }else{
        	    	return 0;
                }
            };
            this.jsonData.sort(f);
            this.refresh();
            if(this.jsonData != this.snapshot){
            	this.snapshot.sort(f);
            }
        }
    }
});
;
/* Andrew Urquhart : Client-Side Request Object for javascript :
   http://andrewu.co.uk/tools/request/ COPYRIGHT:You are free to use
   this script for any use you wish if this comment is left
   intact. Feel free to enhance the script and send me the updated
   version. Please don't redistribute. This script is provided as
   is,with no warranty of any kind. Use it at your own risk. Copyright
   Andrew R Urquhart; VERSION:#1.3 2005-05-11 17:52 UTC*/

function RObj(ea) 
{
	 var LS="";
	 var QS=new Object();
	 var un="undefined";
	 var x=null;
	 var f="function";
	 var n="number";
	 var r="string";
	 var e1="ERROR:Index out of range in\r\nRequest.QueryString";
	 var e2="ERROR:Wrong number of arguments or invalid property assignment\r\nRequest.QueryString";
	 var e3="ERROR:Object doesn't support this property or method\r\nRequest.QueryString.Key";
	 function Err(arg)
	 {
		  if(ea)
		  {
			   alert("Request Object:\r\n"+arg);
		  }
	 };
	 function URID(t)
	 {
		  var d="";
		  if(t)
		  {
			   for(var i=0;i<t.length;++i)
			   {
					var c=t.charAt(i);
					d+=(c=="+"?" ":c);
			   }
		  };
		  return unescape(d)};
	 function OL(o)
	 {
		  var l=0;
		  for(var i in o)
		  {
			   if(typeof o[i]!=f)
			   {
					l++;
			   }
		  };
		  return l;
	 };
	 function AK(key)
	 {
		  var auk=true;
		  for(var u in QS)
		  {
			   if(typeof QS[u]!=f&&u.toString().toLowerCase()==key.toLowerCase())
			   {
					auk=false;
					return u;
			   }
		  }
		  if(auk)
		  {
			   QS[key]=new Object();
			   QS[key].toString=function()
					{
						 return TS(QS[key]);
					};
			   QS[key].Count=function()
					{
						 return OL(QS[key]);
					};
			   QS[key].Count.toString=function()
					{
						 return OL(QS[key]).toString();
					};
			   QS[key].Item=function(e)
					{
						 if(typeof e==un)
						 {
							  return QS[key];
						 }
						 else 
						 {
							  if(typeof e==n)
							  {
								   var a=QS[key][Math.ceil(e)];
								   if(typeof a==un)
								   {
										Err(e1+"(\""+key+"\").Item("+e+")")};
								   return a;
							  }
							  else 
							  {
								   Err("ERROR:Expecting numeric input in\r\nRequest.QueryString(\""+key+"\").Item(\""+e+"\")");
							  }
						 }
					};
			   QS[key].Item.toString=function(e)
					{
						 if(typeof e==un)
						 {
							  return QS[key].toString();
						 }
						 else 
						 {
							  var a=QS[key][e];
							  if(typeof a==un)
							  {
								   Err(e1+"(\""+key+"\").Item("+e+")");
							  };
							  return a.toString();
						 }
					};
			   QS[key].Key=function(e)
					{
						 var t=typeof e;
						 if(t==r)
						 {
							  var a=QS[key][e];
							  return(typeof a!=un&&a&&a.toString()?e:"");
						 }
						 else 
						 {
							  Err(e3+"("+(e?e:"")+")");
						 }
					};
			   QS[key].Key.toString=function()
					{
						 return x;
					}
		  };
		  return key;
	 };
	 function AVTK(key,val)
	 {
		  if(key!="")
		  {
			   var key=AK(key);
			   var l=OL(QS[key]);
			   QS[key][l+1]=val;
		  }
	 };
	 function TS(o)
	 {
		  var s="";
		  for(var i in o)
		  {
			   var ty=typeof o[i];
			   if(ty=="object")
			   {
					s+=TS(o[i]);
			   }
			   else if(ty!=f)
			   {
					s+=o[i]+", ";
			   }
		  };
		  var l=s.length;
		  if(l>1)
		  {
			   return(s.substring(0,l-2));
		  }
		  return(s==""?x:s);
	 };
	 function KM(k,o)
	 {
		  var k=k.toLowerCase();
		  for(var u in o)
		  {
			   if(typeof o[u]!=f&&u.toString().toLowerCase()==k)
			   {
					return u;
			   }
		  }
	 }
	 if(window.location&&window.location.search)
	 {
		  LS=window.location.search;
		  var l=LS.length;
		  if(l>0)
		  {
			   LS=LS.substring(1,l);
			   var preAmpAt=0;
			   var ampAt=-1;
			   var eqAt=-1;
			   var k=0;
			   var skip=false;
			   for(var i=0; i<l; ++i)
			   {
					var c=LS.charAt(i);
					if(LS.charAt(preAmpAt)=="="||(preAmpAt==0&&i==0&&c=="="))
					{
						 skip=true;
					}
					if(c=="="&&eqAt==-1&&!skip)
					{
						 eqAt=i;
					}
					if(c=="&"&&ampAt==-1)
					{
						 if(eqAt!=-1)
						 {
							  ampAt=i;
						 }
						 if(skip)
						 {
							  preAmpAt=i+1;
						 };
						 skip=false;
					}
					if(ampAt>eqAt)
					{
						 AVTK(URID(LS.substring(preAmpAt,eqAt)),URID(LS.substring(eqAt+1,ampAt)));
						 preAmpAt=ampAt+1;
						 eqAt=ampAt=-1;
						 ++k;
					}
			   }
			   if(LS.charAt(preAmpAt)!="="&&(preAmpAt!=0||i!=0||c!="="))
			   {
					if(preAmpAt!=l)
					{
						 if(eqAt!=-1)
						 {
							  AVTK(URID(LS.substring(preAmpAt,eqAt)),URID(LS.substring(eqAt+1,l)));
						 }
						 else if(preAmpAt!=l-1)
						 {
							  AVTK(URID(LS.substring(preAmpAt,l)),"");
						 }
					}
					if(l==1)
					{
						 AVTK(LS.substring(0,1),"");
					}
			   }
		  }
	 };
	 var TC=OL(QS);
	 if(!TC)
	 {
		  TC=0;
	 };
	 QS.toString=function(){return LS.toString()};
	 QS.Count=function(){return(TC?TC:0)};
	 QS.Count.toString=function(){return(TC?TC.toString():"0")};
	 QS.Item=function(e)
		  {
			   if(typeof e==un)
			   {
					return LS;
			   }
			   else 
			   {
					if(typeof e==n)
					{
						 var e=Math.ceil(e);
						 var c=0;
						 for(var i in QS)
						 {
							  if(typeof QS[i]!=f&&++c==e)
							  {
								   return QS[i];
							  }
						 };
						 Err(e1+"().Item("+e+")")
					}
					else 
					{
						 return QS[KM(e,QS)]
					}
			   };
			   return x
		  };
	 QS.Item.toString=function()
		  {
			   return LS.toString()
		  };
	 QS.Key=function(e)
		  {
			   var t=typeof e;
			   if(t==n)
			   {
					var e=Math.ceil(e);
					var c=0;
					for(var i in QS)
					{
						 if(typeof QS[i]!=f&&++c==e)
						 {
							  return i;
						 }
					}
			   }
			   else if(t==r)
			   {
					var e=KM(e,QS);
					var a=QS[e];
					return(typeof a!=un&&a&&a.toString()?e:"");
			   }
			   else 
			   {
					Err(e2+"().Key("+(e?e:"")+")")
			   };
			   Err(e1+"().Item("+e+")");
		  };
	 QS.Key.toString=function(){Err(e2+"().Key")};
	 this.QueryString=function(k)
		  {
			   if(typeof k==un)
			   {
					return QS
			   }
			   else 
			   {
					var k=KM(k,QS);
					if(typeof QS[k]==un)
					{
						 t=new Object();
						 t.Count=function(){return 0};
						 t.Count.toString=function(){return "0"};
						 t.toString=function(){return x};
						 t.Item=function(e){return x};
						 t.Item.toString=function(){return x};
						 t.Key=function(e){Err(e3+"("+(e?e:"")+")")};
						 t.Key.toString=function(){return x};
						 return t;
					}
					if(typeof k==n)
					{
						 return QS.Item(k)
					}
					else 
					{
						 return QS[k];
					}
			   }
		  };
	 this.QueryString.toString=function(){return LS.toString()};
	 this.QueryString.Count=function(){return(TC?TC:0)};
	 this.QueryString.Count.toString=function(){return(TC?TC.toString():"0")};
	 this.QueryString.Item=function(e)
		  {
			   if(typeof e==un)
			   {
					return LS.toString()
			   }
			   else 
			   {
					if(typeof e==n)
					{
						 var e=Math.ceil(e);
						 var c=0;
						 for(var i in QS)
						 {
							  if(typeof QS[i]!=f&&++c==e)
							  {
								   return QS[i];
							  }
						 };
						 Err(e1+".Item("+e+")")
					}
					else 
					{
						 return QS[KM(e,QS)];
					}
			   }
			   if(typeof e==n)
			   {
					Err(e1+".Item("+e+")");
			   };
			   return x
		  };
	 this.QueryString.Item.toString=function(){return LS.toString()};
	 this.QueryString.Key=function(e)
		  {
			   var t=typeof e;
			   if(t==n)
			   {
					var e=Math.ceil(e);
					var c=0;
					for(var i in QS)
					{
						 if(typeof QS[i]=="object"&&(++c==e))
						 {
							  return i;
						 }
					}
			   }
			   else if(t==r)
			   {
					var e=KM(e,QS);
					var a=QS[e];
					return(typeof a!=un&&a&&a.toString()?e:"");
			   }
			   else 
			   {
					Err(e2+".Key("+(e?e:"")+")");
			   };
			   Err(e1+".Item("+e+")")};
	 this.QueryString.Key.toString=function(){Err(e2+".Key");
	 };
	 this.Version=1.3;
	 this.Author="Andrew Urquhart (www.andrewu.co.uk)";
};
var Request=new RObj(false);

;
/* Nifty Corners Cube - rounded corners with CSS and Javascript
Copyright 2006 Alessandro Fulciniti (a.fulciniti@html.it)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

var niftyOk=(document.getElementById && document.createElement && Array.prototype.push);
var niftyCss=false;

String.prototype.find=function(what){
return(this.indexOf(what)>=0 ? true : false);
}

var oldonload=window.onload;
if(typeof(NiftyLoad)!='function') NiftyLoad=function(){};
if(typeof(oldonload)=='function')
    window.onload=function(){oldonload();AddCss();NiftyLoad()};
else window.onload=function(){AddCss();NiftyLoad()};

function AddCss(){
niftyCss=true;
return;
var l=CreateEl("link");
l.setAttribute("type","text/css");
l.setAttribute("rel","stylesheet");
l.setAttribute("href","niftyCorners.css");
l.setAttribute("media","screen");
document.getElementsByTagName("head")[0].appendChild(l);
}

function Nifty(selector,options){
if(niftyOk==false) return;
if(niftyCss==false) AddCss();
var i,v=selector.split(","),h=0;
if(options==null) options="";
if(options.find("fixed-height"))
    h=getElementsBySelector(v[0])[0].offsetHeight;
for(i=0;i<v.length;i++)
    Rounded(v[i],options);
if(options.find("height")) SameHeight(selector,h);
}

function Rounded(selector,options){
var i,top="",bottom="",v=new Array();
if(options!=""){
    options=options.replace("left","tl bl");
    options=options.replace("right","tr br");
    options=options.replace("top","tr tl");
    options=options.replace("bottom","br bl");
    options=options.replace("transparent","alias");
    if(options.find("tl")){
        top="both";
        if(!options.find("tr")) top="left";
        }
    else if(options.find("tr")) top="right";
    if(options.find("bl")){
        bottom="both";
        if(!options.find("br")) bottom="left";
        }
    else if(options.find("br")) bottom="right";
    }
if(top=="" && bottom=="" && !options.find("none")){top="both";bottom="both";}
v=getElementsBySelector(selector);
for(i=0;i<v.length;i++){
    FixIE(v[i]);
    if(top!="") AddTop(v[i],top,options);
    if(bottom!="") AddBottom(v[i],bottom,options);
    }
}

function AddTop(el,side,options){
var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
d.style.marginLeft="-"+getPadding(el,"Left")+"px";
d.style.marginRight="-"+getPadding(el,"Right")+"px";
if(options.find("alias") || (color=getBk(el))=="transparent"){
    color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
    }
else{
    bk=getParentBk(el); border=Mix(color,bk);
    }
d.style.background=bk;
d.className="niftycorners";
p=getPadding(el,"Top");
if(options.find("small")){
    d.style.marginBottom=(p-2)+"px";
    btype+="s"; lim=2;
    }
else if(options.find("big")){
    d.style.marginBottom=(p-10)+"px";
    btype+="b"; lim=8;
    }
else d.style.marginBottom=(p-5)+"px";
for(i=1;i<=lim;i++)
    d.appendChild(CreateStrip(i,side,color,border,btype));
el.style.paddingTop="0";
el.insertBefore(d,el.firstChild);
}

function AddBottom(el,side,options){
var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
d.style.marginLeft="-"+getPadding(el,"Left")+"px";
d.style.marginRight="-"+getPadding(el,"Right")+"px";
if(options.find("alias") || (color=getBk(el))=="transparent"){
    color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
    }
else{
    bk=getParentBk(el); border=Mix(color,bk);
    }
d.style.background=bk;
d.className="niftycorners";
p=getPadding(el,"Bottom");
if(options.find("small")){
    d.style.marginTop=(p-2)+"px";
    btype+="s"; lim=2;
    }
else if(options.find("big")){
    d.style.marginTop=(p-10)+"px";
    btype+="b"; lim=8;
    }
else d.style.marginTop=(p-5)+"px";
for(i=lim;i>0;i--)
    d.appendChild(CreateStrip(i,side,color,border,btype));
el.style.paddingBottom=0;
el.appendChild(d);
}

function CreateStrip(index,side,color,border,btype){
var x=CreateEl("b");
x.className=btype+index;
x.style.backgroundColor=color;
x.style.borderColor=border;
if(side=="left"){
    x.style.borderRightWidth="0";
    x.style.marginRight="0";
    }
else if(side=="right"){
    x.style.borderLeftWidth="0";
    x.style.marginLeft="0";
    }
return(x);
}

function CreateEl(x){
return(document.createElement(x));
}

function FixIE(el){
if(el.currentStyle!=null && el.currentStyle.hasLayout!=null && el.currentStyle.hasLayout==false)
    el.style.display="block";
}

function SameHeight(selector,maxh){
var i,v=selector.split(","),t,j,els=[],gap;
for(i=0;i<v.length;i++){
    t=getElementsBySelector(v[i]);
    els=els.concat(t);
    }
for(i=0;i<els.length;i++){
    if(els[i].offsetHeight>maxh) maxh=els[i].offsetHeight;
    els[i].style.height="auto";
    }
for(i=0;i<els.length;i++){
    gap=maxh-els[i].offsetHeight;
    if(gap>0){
        t=CreateEl("b");t.className="niftyfill";t.style.height=gap+"px";
        nc=els[i].lastChild;
        if(nc.className=="niftycorners")
            els[i].insertBefore(t,nc);
        else els[i].appendChild(t);
        }
    }
}

function getElementsBySelector(selector){
var i,j,selid="",selclass="",tag=selector,tag2="",v2,k,f,a,s=[],objlist=[],c;
if(selector.find("#")){ //id selector like "tag#id"
    if(selector.find(" ")){  //descendant selector like "tag#id tag"
        s=selector.split(" ");
        var fs=s[0].split("#");
        if(fs.length==1) return(objlist);
        f=document.getElementById(fs[1]);
        if(f){
            v=f.getElementsByTagName(s[1]);
            for(i=0;i<v.length;i++) objlist.push(v[i]);
            }
        return(objlist);
        }
    else{
        s=selector.split("#");
        tag=s[0];
        selid=s[1];
        if(selid!=""){
            f=document.getElementById(selid);
            if(f) objlist.push(f);
            return(objlist);
            }
        }
    }
if(selector.find(".")){      //class selector like "tag.class"
    s=selector.split(".");
    tag=s[0];
    selclass=s[1];
    if(selclass.find(" ")){   //descendant selector like tag1.classname tag2
        s=selclass.split(" ");
        selclass=s[0];
        tag2=s[1];
        }
    }
var v=document.getElementsByTagName(tag);  // tag selector like "tag"
if(selclass==""){
    for(i=0;i<v.length;i++) objlist.push(v[i]);
    return(objlist);
    }
for(i=0;i<v.length;i++){
    c=v[i].className.split(" ");
    for(j=0;j<c.length;j++){
        if(c[j]==selclass){
            if(tag2=="") objlist.push(v[i]);
            else{
                v2=v[i].getElementsByTagName(tag2);
                for(k=0;k<v2.length;k++) objlist.push(v2[k]);
                }
            }
        }
    }
return(objlist);
}

function getParentBk(x){
var el=x.parentNode,c;
while(el.tagName.toUpperCase()!="HTML" && (c=getBk(el))=="transparent")
    el=el.parentNode;
if(c=="transparent") c="#FFFFFF";
return(c);
}

function getBk(x){
var c=getStyleProp(x,"backgroundColor");
if(c==null || c=="transparent" || c.find("rgba(0, 0, 0, 0)"))
    return("transparent");
if(c.find("rgb")) c=rgb2hex(c);
return(c);
}

function getPadding(x,side){
var p=getStyleProp(x,"padding"+side);
if(p==null || !p.find("px")) return(0);
return(parseInt(p));
}

function getStyleProp(x,prop){
if(x.currentStyle)
    return(x.currentStyle[prop]);
if(document.defaultView.getComputedStyle)
    return(document.defaultView.getComputedStyle(x,'')[prop]);
return(null);
}

function rgb2hex(value){
var hex="",v,h,i;
var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
var h=regexp.exec(value);
for(i=1;i<4;i++){
    v=parseInt(h[i]).toString(16);
    if(v.length==1) hex+="0"+v;
    else hex+=v;
    }
return("#"+hex);
}

function Mix(c1,c2){
var i,step1,step2,x,y,r=new Array(3);
if(c1.length==4)step1=1;
else step1=2;
if(c2.length==4) step2=1;
else step2=2;
for(i=0;i<3;i++){
    x=parseInt(c1.substr(1+step1*i,step1),16);
    if(step1==1) x=16*x+x;
    y=parseInt(c2.substr(1+step2*i,step2),16);
    if(step2==1) y=16*y+y;
    r[i]=Math.floor((x*50+y*50)/100);
    r[i]=r[i].toString(16);
    if(r[i].length==1) r[i]="0"+r[i];
    }
return("#"+r[0]+r[1]+r[2]);
};
/*Javascript for Bubble Tooltips by Alessandro Fulciniti
http://pro.html.it - http://web-graphics.com */

function enableTooltips(id){
var links,i,h;
if(!document.getElementById || !document.getElementsByTagName) return;
// AddCss();
h=document.createElement("span");
h.id="btc";
h.setAttribute("id","btc");
h.style.position="absolute";
document.getElementsByTagName("body")[0].appendChild(h);
if(id==null) links=document.getElementsByTagName("a");
else links=document.getElementById(id).getElementsByTagName("a");
for(i=0;i<links.length;i++){
    Prepare(links[i]);
    }
}

function Prepare(el){
var tooltip,t,b,s,l;
// remove t allow html
//t=el.getAttribute("title");
t=el.getAttribute("title");
// Changed to display no bubble
if(t==null || t.length==0) return; // t="link:";
el.removeAttribute("title");
tooltip=CreateEl("span","tooltip");
s=CreateEl("span","top");
// Allow HTML
// s.appendChild(document.createTextNode(t));
var oDiv=document.createElement("DIV");
s.appendChild(oDiv);
oDiv.innerHTML = t; 
tooltip.appendChild(s);
b=CreateEl("b","bottom");
l=el.getAttribute("href");
// if(l.length>28) l=l.substr(0,25)+"...";
// b.appendChild(document.createTextNode(l));
tooltip.appendChild(b);
setOpacity(tooltip);
el.tooltip=tooltip;
el.onmouseover=showTooltip;
el.onmouseout=hideTooltip;
el.onmousemove=Locate;
}

function showTooltip(e){
document.getElementById("btc").appendChild(this.tooltip);
Locate(e);
}

function hideTooltip(e){
var d=document.getElementById("btc");
if(d.childNodes.length>0) d.removeChild(d.firstChild);
}

function setOpacity(el){
el.style.filter="alpha(opacity:95)";
el.style.KHTMLOpacity="0.95";
el.style.MozOpacity="0.95";
el.style.opacity="0.95";
}

function CreateEl(t,c){
var x=document.createElement(t);
x.className=c;
x.style.display="block";
return(x);
}

function Locate(e){
var posx=0,posy=0;
if(e==null) e=window.event;
if(e.pageX || e.pageY){
    posx=e.pageX; posy=e.pageY;
    }
else if(e.clientX || e.clientY){
    if(document.documentElement.scrollTop){
        posx=e.clientX+document.documentElement.scrollLeft;
        posy=e.clientY+document.documentElement.scrollTop;
        }
    else{
        posx=e.clientX+document.body.scrollLeft;
        posy=e.clientY+document.body.scrollTop;
        }
    }
document.getElementById("btc").style.top=(posy+10)+"px";
document.getElementById("btc").style.left=(posx-20)+"px";
}

;
/*
  Developed by Robert Nyman, http://www.robertnyman.com
  Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/	
var getElementsByClassName = function (className, tag, elm)
{
	 if (document.getElementsByClassName) 
	 {        
		  getElementsByClassName = function (className, tag, elm) 
		  {
			   elm = elm || document;
			   var elements = elm.getElementsByClassName(className),
			   nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
			   returnElements = [],
			   current;
			   for(var i=0, il=elements.length; i<il; i+=1)
			   {
					current = elements[i];
					if(!nodeName || nodeName.test(current.nodeName)) 
					{
						 returnElements.push(current);
					}
			   }
			   return returnElements;
		  };
	 }
	 else if (document.evaluate) 
	 {
		  getElementsByClassName = function (className, tag, elm) 
		  {
			   tag = tag || "*";
			   elm = elm || document;
			   var classes = className.split(" "),
			   classesToCheck = "",
			   xhtmlNamespace = "http://www.w3.org/1999/xhtml",
			   namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
			   returnElements = [],
			   elements,
			   node;
			   for(var j=0, jl=classes.length; j<jl; j+=1)
			   {
					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			   }
			   try	
			   {
					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			   }
			   catch (e) 
			   {
					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			   }
			   while ((node = elements.iterateNext())) 
			   {
					returnElements.push(node);
			   }
			   return returnElements;
		  };
	 }
	 else 
	 {
		  getElementsByClassName = function (className, tag, elm) 
		  {
			   tag = tag || "*";
			   elm = elm || document;
			   var classes = className.split(" "),
			   classesToCheck = [],
			   elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
			   current,
			   returnElements = [],
			   match;
			   for(var k=0, kl=classes.length; k<kl; k+=1)
			   {
					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			   }
			   for(var l=0, ll=elements.length; l<ll; l+=1)
			   {
					current = elements[l];
					match = false;
					for(var m=0, ml=classesToCheck.length; m<ml; m+=1)
					{
						 match = classesToCheck[m].test(current.className);
						 if (!match) 
						 {
							  break;
						 }
					}
					if (match) 
					{
						 returnElements.push(current);
					}
			   }
			   return returnElements;
		  };
	 }
	 return getElementsByClassName(className, tag, elm);
};

function btns_submitHandler()
{
	 var form = this.form;
	 var ok = true;

	 if(form && typeof(form.onsubmit) == 'function')
	 { 
		  ok = form.onsubmit(); 
	 }
	 else if (!form)
	 {
	 	  ok = false;
	 }
	 if(ok)
	 {
		  if(this.name) 
		  {
			   var field = document.createElement("input");
			   field.setAttribute("type","hidden");
			   field.setAttribute("name", this.name);
			   form.appendChild(field);
		  }
		  form.submit();
		  return true;
	 }
	 return false;
};

function btns_resetHandler()
{
	 var form = this.form;
	 form.reset();
};

var btn = {
	 init: function() 
	 {
		  if (!document.createElement || 
			  !document.appendChild )
		  {
			   return false;
		  }

		  as = getElementsByClassName('btn');
		  for (i=0; i<as.length; i++) 
		  {
			   if ( as[i].tagName.toLowerCase() == "input" && 
					( as[i].type.toLowerCase() == "submit" || 
					  as[i].type.toLowerCase() == "button" ||
					  as[i].type.toLowerCase() == "reset" ) ) 
			   {
					var a1 = document.createElement("a");
					if(as[i].value)
					{
						 a1.appendChild(document.createTextNode(as[i].value));
					}
					else
					{
						 a1.appendChild(document.createTextNode('Submit'));
					}
					a1.className = as[i].className;
					a1.id = as[i].id;
					if(as[i].onclick) 
					{
						 a1.onclick = as[i].onclick;
					} 
					if(as[i].name) 
					{ 
						 a1.name = as[i].name;
					}
					if(as[i].form)
					{
						 a1.form = as[i].form;
					}
					as[i] = as[i].parentNode.replaceChild(a1, as[i]);
					as[i] = a1;
					as[i].style.cursor = "pointer";
			   }
			   else if (as[i].tagName.toLowerCase() == "a") 
			   {
					;
			   }
			   else 
			   { 
					continue;
			   }
			   if(as[i].id)
			   {
					if(as[i].id == 'submit_btn')
					{
						 YAHOO.util.Event.on(as[i], 'click', btns_submitHandler); 
					}
					if(as[i].id == 'reset_btn')
					{
						 YAHOO.util.Event.on(as[i], 'click', btns_resetHandler); 
					}
			   }

			   var i1 = document.createElement('i');
			   var i2 = document.createElement('i');
			   var s1 = document.createElement('div');
			   var s2 = document.createElement('div');
			   s1.appendChild(i1);
			   s1.appendChild(s2);
			   while (as[i].firstChild) 
			   {
					s1.appendChild(as[i].firstChild);
			   }
			   as[i].appendChild(s1);
			   as[i] = as[i].insertBefore(i2, s1);
		  }
		  return true;
	 }
};
function IEContentLoaded (w, fn) 
{
	 var d = w.document;
	 done = false;
	 // only fire once
	 var init = function () 
		  {
			   if (!done) 
			   {
					done = true;
					fn();
			   }
		  };
	 // polling for no errors
	 (function () 
	 {
		  try 
		  {
			   // throws errors until after ondocumentready
			   d.documentElement.doScroll('left');
		  } 
		  catch (e) 
		  {
			   setTimeout(arguments.callee, 50);
			   return;
		  }
		  // no errors, fire
		  init();
	 })();
	 // trying to always fire before onload
	 d.onreadystatechange = function() 
		  {
			   if (d.readyState == 'complete') 
			   {
					d.onreadystatechange = null;
					init();
			   }
		  };
}
if (typeof document.fileSize != 'undefined') 
{
	 IEContentLoaded(window, btn.init);
}
else
{
	 YAHOO.ext.EventManager.onDocumentReady(btn.init);
}

;
function overlimit_alert() 
{ 
	 alert( translate("We're sorry, ordering this item would exceed the spending limit set by the originator of this order.") ); 
	 return false; 
}
function checkout_check_spending(checkout_spending_limit, checkout_current_subtotal) {
	 if (checkout_spending_limit < checkout_current_subtotal) {
	      alert( translate("We're sorry, you are currently over your spending limit.  Please delete something from your shopping cart to continue.") ); 
		  return false; 
	 }
	 return true;
}
function checkout_check_delivery(checkout_delivery_minimum, checkout_current_subtotal) {
	 if (checkout_delivery_minimum > checkout_current_subtotal) 
	 {
	      s = translate("We're sorry, but your current order is less than our delivery minimum of") + " $" + roundToPennies(checkout_delivery_minimum);
	      alert( s + ".  " + translate("Please add a bit more to this order." )); 
		  return false; 
	 }
	 return true;
}
function checkout_check_minicart(spending, delivery, subtotal, url)
{
	 if(!(spending || delivery))
	 {
		  window.location = url;
		  return true;
	 }
	 if(spending) 
	 {
		  if (checkout_check_spending(spending, subtotal))
		  {
			   window.location = url;
			   return true;
		  }
	 }
	 if(delivery)
	 {
		  if(checkout_check_delivery(delivery, subtotal))
		  {
			   window.location = url;
			   return true;
		  }            
	 }
	 return false;
}
function roundToPennies(n)
{
	 pennies = n;
	 pennies = Math.round(pennies);

	 strPennies = "" + pennies;
	 len = strPennies.length;
	 return strPennies.substring(0, len - 2) + "." + strPennies.substring(len - 2, len);
}
;
timeoutPeriod = 800;

if(!translate){
	function translate(toTranslate){
		return toTranslate;
	}
}

PythonDateStringObject = function(pyDateString, offset){
	function getSplitDate(pyDateStringThis){
		x = pyDateStringThis;
		x = x.split(' ');
		
		d = x[0];
		t = x[1];
	
		t = t.split('-')[0];
		t = t.split(':');
		hr = t[0];
		min = t[1];
		
		d = d.split('-');
		yr = d[0];
		mo = d[1];
		dy = d[2];

		dateObject = {year:yr, month:mo, day:dy, hour:hr, minute:min, second:0};
		return dateObject;
	};
	splitDate = getSplitDate(pyDateString);
	return new GoTimerDateObject(splitDate, offset);
}

JavaScriptDateObject = function(jsDateObject, offset){
	function getSplitDate(thisJsDateObject){
		hr = thisJsDateObject.getHours();
		min = thisJsDateObject.getMinutes();
		
		yr = thisJsDateObject.getFullYear();
		mo = thisJsDateObject.getMonth()+1;
		dy = thisJsDateObject.getDate();

		dateObject = {year:yr, month:mo, day:dy, hour:hr, minute:min};
		return dateObject;
	};
	splitDate = getSplitDate(jsDateObject);
	return new GoTimerDateObject(splitDate, offset);
}

GoTimerDateObject = function(splitDate, offset){
	if(!offset){
		offset = 0;
	}
	function getDateObject(splitDate, offset){
		ret = new Date();
	
		ret.setYear(splitDate.year);
		ret.setMonth(splitDate.month-1);
		ret.setDate(splitDate.day);
		ret.setHours(splitDate.hour);
		ret.setMinutes(splitDate.minute);
		seconds = offset;
		if(typeof splitDate.second != "undefined"){
			seconds = seconds + splitDate.second;
		}
		ret.setSeconds(seconds)

		return ret;
	};

	function prettyDiff(splitDiff){
		if(splitDiff.days != 0){
			periodOffset = 6*60*60*1000;
			period = translate('day');
			len = splitDiff.days.toString();
		}
		else if(splitDiff.hours != 0){
			periodOffset = 15*60*1000;
			period = translate('hour');
			len = splitDiff.hours.toString();
		}
		else if(splitDiff.minutes != 0){
			periodOffset = 15*1000;
			period =  translate('minute');
			len = splitDiff.minutes.toString();
		}
		else {
			periodOffset = 800;
			period = translate('second');
			len = splitDiff.seconds.toString();
		}
		if(len > 1){
			period = period + 's';
		}
		return len + ' ' + period;
	};
	function splitDiff(rawDiff){
		dayAll = (((rawDiff/1000)/60)/60)/24;
		days = parseInt(dayAll);
		hourAll = (dayAll-days)*24;
		hours = parseInt(hourAll);
		minuteAll = (hourAll-hours)*60;
		minutes = parseInt(minuteAll);
		secondAll = (minuteAll-minutes)*60;
		seconds = parseInt(secondAll);
		return {days:days, hours:hours, minutes:minutes, seconds:seconds};
	};

	function rightAlign(start, pad, spaces){
		toApp = start.toString();
		pad = pad.toString();
		while(toApp.length < spaces)
			toApp = pad + toApp;
		return toApp;
	}

	thisDate= getDateObject(splitDate, offset)
	ret = {
		ret:thisDate, 
		splitDate:splitDate,
		minus:function(otherDate){
			thisValue = this.ret.valueOf();
			otherValue = otherDate.valueOf();
			difference = thisValue - otherValue;
			return difference;
		},
		prettyMinus:function(otherDate){
			difference = this.minus(otherDate);
			splitDifference = splitDiff(difference);
			prettyDifference = prettyDiff(splitDifference);
			return prettyDifference;
		},
		getPretty:function(){
			ampm = 'AM';
			ret = '';
			ret = ret + (this.ret.getMonth()+1).toString();
			ret = ret + '/';
			ret = ret + this.ret.getDate().toString();
			ret = ret + '/';
			ret = ret + this.ret.getFullYear().toString();
			ret = ret + ' ';
			prn = this.ret.getHours()
			if(this.ret.getHours() > 12){
				prn = prn - 12;
				ampm = 'PM';
			}
			ret = ret + prn.toString();
			ret = ret + ':';
			ret = ret + rightAlign(this.ret.getMinutes().toString(), '0', 2);
			ret = ret + ' ';
			ret = ret + ampm;
			return ret
		}
	};
	return ret;
}

function initialRun(){
	untilHidden = document.getElementById('goTimer_until');
	cutoffHidden = document.getElementById('goTimer_cutoff');

	if(!untilHidden || !cutoffHidden){
		return;
	}

	cutoff = new PythonDateStringObject(cutoffHidden.value);
	now = new JavaScriptDateObject(new Date());
	offset = cutoff.minus(now.ret);
	offset = untilHidden.value - parseInt(offset/1000);

	cutoff = new PythonDateStringObject(cutoffHidden.value, offset);
	go();
}
function zeroFireworks(){
	alert (document.getElementById('goTimer_zeroMessage').value);
	window.location = '/mp/patrons/session_timeout';
}
function go(){
	leftDisplay = document.getElementById('goTimer_leftDisplay');
    if(leftDisplay){
    	now = new JavaScriptDateObject(new Date());
	    left = cutoff.prettyMinus(now.ret);
    	leftDisplay.innerHTML = left;
	    if(cutoff.minus(now.ret) <= 0){
		    return zeroFireworks();
    	}
    }
	setTimeout('go()', timeoutPeriod);
}

