var HTML_AJAX_Util = {registerEvent: function(element, event, handler) {if (typeof element == 'string')	{element = document.getElementById(element);}if (typeof element.addEventListener != "undefined") {element.addEventListener(event, handler, false);} else if (typeof element.attachEvent != "undefined") {element.attachEvent("on" + event, handler);} else {if (element["on" + event] != null) {var oldHandler = element["on" + event];element["on" + event] = function(e) {oldHander(e);handler(e);};} else {element["on" + event] = handler;}}},
eventTarget: function(event){if (!event) var event = window.event;if (event.target) return event.target;if (event.srcElement) return event.srcElement;},
getType: function(inp){var type = typeof inp, match;if(type == 'object' && !inp){return 'null';}if (type == "object") {if(!inp.constructor){return 'object';}var cons = inp.constructor.toString();if (match = cons.match(/(\w+)\(/)) {cons = match[1].toLowerCase();}var types = ["boolean", "number", "string", "array"];for (key in types) {if (cons == types[key]) {type = types[key];break;}}}return type;},
strRepeat: function(inp, multiplier) {var ret = "";while (--multiplier > 0) ret += inp;return ret;},
varDump: function(inp, printFuncs, _indent, _recursionLevel){if (!_recursionLevel) _recursionLevel = 0;if (!_indent) _indent = 1;var tab = this.strRepeat("  ", ++_indent);var type = this.getType(inp), out = type;var consrx = /(\w+)\(/;consrx.compile();if (++_recursionLevel > 6) {return tab + inp + "Loop Detected\n";}
switch (type) {case "boolean":case "number":out += "(" + inp.toString() + ")";break;case "string":out += "(" + inp.length + ") \"" + inp + "\"";break;case "function":if (printFuncs) {out += inp.toString().replace(/\n/g, "\n" + tab);}break;case "array":case "object":var atts = "", attc = 0;try {for (k in inp) {atts += tab + "[" + (/\D/.test(k) ? "\"" + k + "\"" : k)+ "]=>\n" + tab + this.varDump(inp[k], printFuncs, _indent, _recursionLevel);++attc;}} catch (e) {}if (type == "object") {var objname, objstr = inp.toString();if (objname = objstr.match(/^\[object (\w+)\]$/)) {objname = objname[1];} else {try {objname = inp.constructor.toString().match(consrx)[1];} catch (e) {objname = 'unknown';}}out += "(" + objname + ") ";}out += "(" + attc + ") {\n" + atts + this.strRepeat("  ", _indent - 1) +"}";break;}return out + "\n";},
quickPrint: function(input,sep) {if (!sep) {var sep = "\n";}var type = HTML_AJAX_Util.getType(input);switch (type) {case 'string':return input;case 'array':var ret = "";for(var i = 0; i < input.length; i++) {ret += i+':'+input[i]+sep;}return ret;default:var ret = "";for(var i in input) {ret += i+':'+input[i]+sep;}return ret;}},
getAllElements: function(parentElement){if( document.all){if(!parentElement) {var allElements = document.all;}else{var allElements = [], rightName = new RegExp( parentElement, 'i' ), i;for( i=0; i<document.all.length; i++ ) {if( rightName.test( document.all[i].parentElement ) )allElements.push( document.all[i] );}}return allElements;}else{if (!parentElement) { parentElement = document.body; }return parentElement.getElementsByTagName('*');}},
getElementsByProperty: function(property, regex, parentElement) {var allElements = HTML_AJAX_Util.getAllElements(parentElement);var items = [];for(var i=0,j=allElements.length; i<j; i++){if(regex.test(allElements[i][property])){items.push(allElements[i]);}}return items;},
getElementsByClassName: function(className, parentElement) {return HTML_AJAX_Util.getElementsByProperty('className',new RegExp('(^| )' + className + '( |$)'),parentElement);},getElementsById: function(id, parentElement) {return HTML_AJAX_Util.getElementsByProperty('id',new RegExp(id),parentElement);},
getElementsByCssSelector: function(selector,parentElement) {return cssQuery(selector,parentElement);},
htmlEscape: function(inp) {var div = document.createElement('div');var text = document.createTextNode(inp);div.appendChild(text);return div.innerHTML;},
baseURL: function(absolute, filename) {var qPos = absolute.indexOf('?');if (qPos >= 0) {absolute = absolute.substr(0, qPos);}var slashPos = Math.max(absolute.lastIndexOf('/'), absolute.lastIndexOf('\\'));if (slashPos < 0) {return absolute;}return (filename ? absolute.substr(slashPos + 1) : absolute.substr(0, slashPos + 1));},queryString: function(url) {var qPos = url.indexOf('?');if (qPos >= 0) {return url.substr(qPos+1);}},
absoluteURL: function(rel, absolute) {if (/^https?:\/\//i.test(rel)) {
return rel;}if (!absolute) {var bases = document.getElementsByTagName('base');for (i in bases) {if (bases[i].href) {absolute = bases[i].href;break;}}if (!absolute) {absolute = window.location.href;}}if (rel == '') {return absolute;}
if (rel.substr(0, 2) == '//') {var slashesPos = absolute.indexOf('//');if (slashesPos < 0) {return 'http:' + rel;}return absolute.substr(0, slashesPos) + rel;}var base = this.baseURL(absolute);var absParts = base.substr(0, base.length - 1).split('/');var absHost = absParts.slice(0, 3).join('/') + '/';if (rel.substr(0, 1) == '/') {return absHost + rel;}if (rel.substr(0, 1) == '.' && rel.substr(1, 1) != '.') {return base + rel.substr(1);}absParts.splice(0, 3);var relParts = rel.split('/');var loopStart = relParts.length - 1;
relParts = absParts.concat(relParts);for (i = loopStart; i < relParts.length;) {if (relParts[i] == '..') {if (i == 0) {return absolute;}relParts.splice(i - 1, 2);--i;continue;}i++;}return absHost + relParts.join('/');},
setInnerHTML: function(node, innerHTML, type){if (HTML_AJAX_Util.getType(node) == 'string') {var node = document.getElementById(node);}if (type != 'append') {if (type == 'prepend') {var oldHtml = node.innerHTML;}node.innerHTML = '';}var good_browser = (window.opera || navigator.product == 'Gecko');var regex = /^([\s\S]*?)<script([\s\S]*?)>([\s\S]*?)<\/script>([\s\S]*)$/i;var regex_src = /src=["'](.*?)["']/i;var matches, id, script, output = '', subject = innerHTML;var scripts = [];
while (true) {matches = regex.exec(subject);if (matches && matches[0]) {subject = matches[4];id = 'ih_' + Math.round(Math.random()*9999) + '_' + Math.round(Math.random()*9999);
var startLen = matches[3].length;script = matches[3].replace(/document\.write\(([\s\S]*?)\)/ig,'document.getElementById("' + id + '").innerHTML+=$1');output += matches[1];if (startLen != script.length) {output += '<span id="' + id + '"></span>';}
output += '<script' + matches[2] + '>' + script + '</script>';if (good_browser) {continue;}if (script) {scripts.push(script);}if (regex_src.test(matches[2])) {var script_el = document.createElement("SCRIPT");var atts_regex = /(\w+)=["'](.*?)["']([\s\S]*)$/;
var atts = matches[2];for (var i = 0; i < 5; i++) { var atts_matches = atts_regex.exec(atts);if (atts_matches && atts_matches[0]) {script_el.setAttribute(atts_matches[1], atts_matches[2]);atts = atts_matches[3];} else {break;}}scripts.push(script_el);}} else {output += subject;break;}}innerHTML = output;
if (good_browser) {var el = document.createElement('span');el.innerHTML = innerHTML;for(var i = 0; i < el.childNodes.length; i++) {node.appendChild(el.childNodes[i].cloneNode(true));}}else {node.innerHTML = innerHTML;}if (oldHtml) {node.innerHTML += oldHtml;}if (!good_browser) {for(var i = 0; i < scripts.length; i++) {if (HTML_AJAX_Util.getType(scripts[i]) == 'string') {window.eval(scripts[i]);}else {node.appendChild(scripts[i]);}}}return;},
classSep: '(^|$| )',
hasClass: function(o, className) {var o = this.getElement(o);var regex = new RegExp(this.classSEP + className + this.classSEP);return regex.test(o.className);},
addClass: function(o, className) {var object = this.getElement(object);if(!this.hasClass(o, className)) {o.className += " " + className;}},
removeClass: function(o, className) {var object = this.getElement(object);var regex = new RegExp(this.classSEP + className + this.classSEP);o.className = o.className.replace(regex, " ");},
replaceClass: function(o, oldClass, newClass) {var o = this.getElement(o);var regex = new RegExp(this.classSEP + oldClass + this.classSEP);o.className = o.className.replace(regex, newClass);},
getElement: function(el) {if (typeof el == 'string') {return document.getElementById(el);}return el;}}/**
 * JavaScript library for use with HTML_AJAX
 *
 * This library 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 library 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 library; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @category   HTML
 * @package    Ajax
 * @author     Joshua Eichorn <josh@bluga.net>
 * @author     Arpad Ray <arpad@php.net>
 * @author     David Coallier <davidc@php.net>
 * @author     Elizabeth Smith <auroraeosrose@gmail.com>
 * @copyright  2005 Joshua Eichorn, Arpad Ray, David Coallier, Elizabeth Smith
 * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
 */

/**
 *  Functions for compatibility with older browsers
 */
if (!String.fromCharCode && !String.prototype.fromCharCode) {
    String.prototype.fromCharCode = function(code)
    {
        var h = code.toString(16);
        if (h.length == 1) {
            h = '0' + h;
        }
        return unescape('%' + h);
    }
}
if (!String.charCodeAt && !String.prototype.charCodeAt) {
    String.prototype.charCodeAt = function(index)
    {
        var c = this.charAt(index);
        for (i = 1; i < 256; i++) {
            if (String.fromCharCode(i) == c) {
                return i;
            }
        } 
    }
}
// http://www.crockford.com/javascript/remedial.html
if (!Array.splice && !Array.prototype.splice) {
    Array.prototype.splice = function(s, d)
    {
        var max = Math.max,
        min = Math.min,
        a = [], // The return value array
        e,  // element
        i = max(arguments.length - 2, 0),   // insert count
        k = 0,
        l = this.length,
        n,  // new length
        v,  // delta
        x;  // shift count

        s = s || 0;
        if (s < 0) {
            s += l;
        }
        s = max(min(s, l), 0);  // start point
        d = max(min(typeof d == 'number' ? d : l, l - s), 0);    // delete count
        v = i - d;
        n = l + v;
        while (k < d) {
            e = this[s + k];
            if (!e) {
                a[k] = e;
            }
            k += 1;
        }
        x = l - s - d;
        if (v < 0) {
            k = s + i;
            while (x) {
                this[k] = this[k - v];
                k += 1;
                x -= 1;
            }
            this.length = n;
        } else if (v > 0) {
            k = 1;
            while (x) {
                this[n - k] = this[l - k];
                k += 1;
                x -= 1;
            }
        }
        for (k = 0; k < i; ++k) {
            this[s + k] = arguments[k + 2];
        }
        return a;
    }
}
if (!Array.push && !Array.prototype.push) {
    Array.prototype.push = function()
    {
        for (var i = 0, startLength = this.length; i < arguments.length; i++) {
            this[startLength + i] = arguments[i];
        }
        return this.length;
    }
}
if (!Array.pop && !Array.prototype.pop) {
    Array.prototype.pop = function()
    {
        return this.splice(this.length - 1, 1)[0];
    }
}

/**
 * HTML_AJAX static methods, this is the main proxyless api, it also handles global error and event handling
 */
var HTML_AJAX = {
	defaultServerUrl: false,
	defaultEncoding: 'JSON',
    queues: false,
    clientPools: {},
    // get an HttpClient, supply a name to use the pool of that name or the default if it isn't found
    httpClient: function(name) {
        if (name) {
            if (this.clientPools[name]) {
                return this.clientPools[name].getClient();
            }
        }
        return this.clientPools['default'].getClient();
    },
    // Pushing the given request to queue specified by it, in default operation this will immediately make a request
    // request might be delayed or never happen depending on the queue setup
    // making a sync request to a non immediate queue will cause you problems so just don't do it
    makeRequest: function(request) {
        if (!HTML_AJAX.queues[request.queue]) {
            var e = new Error('Unknown Queue: '+request.queue);
            if (HTML_AJAX.onError) {
                HTML_AJAX.onError(e);
                return false;
            }
            else {
                throw(e);
            }
        }
        else {
            var qn = request.queue;
            var q = HTML_AJAX.queues[qn];

            HTML_AJAX.queues[request.queue].addRequest(request);
            return HTML_AJAX.queues[request.queue].processRequest();
        }
    },
    // get a serializer object for a specific encoding
    serializerForEncoding: function(encoding) {
        for(var i in HTML_AJAX.contentTypeMap) {
            if (encoding == HTML_AJAX.contentTypeMap[i] || encoding == i) {
                return eval("new HTML_AJAX_Serialize_"+i+";");
            }
        }
        return new HTML_AJAX_Serialize_Null();
    },
	fullcall: function(url,encoding,className,method,callback,args, options) {
        var serializer = HTML_AJAX.serializerForEncoding(encoding);

        var request = new HTML_AJAX_Request(serializer);
		if (callback) {
            request.isAsync = true;
		}
        request.requestUrl = url;
        request.className = className;
        request.methodName = method;
        request.callback = callback;
        request.args = args;
        if (options) {
            for(var i in options) {
                request[i] = options[i];
            }
            if (options.grab) {
                if (!request.args || !request.args.length) {
                    request.requestType = 'GET';
                }
            }
        }

        return HTML_AJAX.makeRequest(request);
	},
    phpCallback: function(callee, callback) {
        HTML_AJAX.fullcall(HTML_AJAX.defaultServerUrl, HTML_AJAX.defaultEncoding,
            false, false, callback, arguments.slice(2), {phpCallback: callee});
    },
	call: function(className,method,callback) {
        var args = new Array();
        for(var i = 3; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
		return HTML_AJAX.fullcall(HTML_AJAX.defaultServerUrl,HTML_AJAX.defaultEncoding,className,method,callback,args);
	},
	grab: function(url,callback,options) {
        if (!options) {
            options = {grab:true};
        }
        else {
            options['grab'] = true;
        }
		return HTML_AJAX.fullcall(url,'Null',false,null,callback, '', options);
	},
	replace: function(id) {
        var callback = function(result) {
            HTML_AJAX_Util.setInnerHTML(document.getElementById(id),result);
        }
		if (arguments.length == 2) {
			// grab replacement
            HTML_AJAX.grab(arguments[1],callback);
		}
		else {
			// call replacement
			var args = new Array();
			for(var i = 3; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			HTML_AJAX.fullcall(HTML_AJAX.defaultServerUrl,HTML_AJAX.defaultEncoding,arguments[1],arguments[2],callback,args, {grab:true});
		}
	},
    append: function(id) {
        var callback = function(result) {
            HTML_AJAX_Util.setInnerHTML(document.getElementById(id),result,'append');
        }
        if (arguments.length == 2) {
            // grab replacement
            HTML_AJAX.grab(arguments[1],callback);
        }
        else {
            // call replacement
            var args = new Array();
            for(var i = 3; i < arguments.length; i++) {
                args.push(arguments[i]);
            }
            HTML_AJAX.fullcall(HTML_AJAX.defaultServerUrl,HTML_AJAX.defaultEncoding,arguments[1],arguments[2],callback,args, {grab:true});
        }
    }, 
    // override to add top level loading notification (start)
    Open: function(request) {
    },
    // override to add top level loading notification (finish)
    Load: function(request) {
    },
    /*
    // A really basic error handler 
    onError: function(e) {
        msg = "";
        for(var i in e) {
            msg += i+':'+e[i]+"\n";
        }
        alert(msg);
    },
    */
    // Class postfix to content-type map
    contentTypeMap: {
        'JSON':         'application/json',
        'Null':         'text/plain',
        'Error':        'application/error',
        'PHP':          'application/php-serialized',
		'HA' :           'application/html_ajax_action',
        'Urlencoded':   'application/x-www-form-urlencoded'
    },
    // used internally to make queues work, override Load or onError to perform custom events when a request is complete
    // fires on success and error
    requestComplete: function(request,error) {
        for(var i in HTML_AJAX.queues) {
            if (HTML_AJAX.queues[i].requestComplete) {
                HTML_AJAX.queues[i].requestComplete(request,error);
            }
        }
    },
    
    // turns a form into a urlencoded string
    formEncode: function(form, array_format) {
        if (HTML_AJAX_Util.getType(form) == 'string') {
            form = document.getElementById(form);
        }
        var el, inpType, value, name, escName;
        var out = (array_format) ? {} : '';
		var inputTags = form.getElementsByTagName('INPUT');
		var selectTags = form.getElementsByTagName('SELECT');
		var buttonTags = form.getElementsByTagName('BUTTON');
		var textareaTags = form.getElementsByTagName('TEXTAREA');
        var arrayRegex = /.+\[\]/;

        var validElement = function (element) {
            if (!element || !element.getAttribute) {
                return false;
            }
            el = element;
            name = el.getAttribute('name');
            if (!name) {
                // no element name so skip
                return false;
            }
            escName = escape(name);
            value = escape(el.value);
            inpType = el.getAttribute('type');
            return true;
        }
        
        inputLoop:
        for (var i=0; i < inputTags.length; i++) {
            if (!validElement(inputTags[i])) {
                continue;
            }
            if (inpType == 'checkbox' || inpType == 'radio') {
                if (!el.checked) {
                    // unchecked radios/checkboxes don't get submitted
                    continue inputLoop;
                }
                if (array_format && arrayRegex.test(name)) {
                    if (!out[escName]) {
                        out[escName] = new Array();
                    }
                    out[escName].push(value);
                    continue inputLoop;
                }
            }
            // add element to output array
			if (array_format) {
				out[escName] = value;
			} else {
				out += escName + '=' + value + '&';
			}
        } // end inputLoop

        selectLoop:
        for (var i=0; i<selectTags.length; i++) {
            if (!validElement(selectTags[i])) {
                continue selectLoop;
            }
            var options = el.options;
            for (var z=0; z<options.length; z++){
                var option=options[z];
                if(option.selected){
                    if (array_format) {
                        if (el.type == 'select-one') {
                            out[escName] = escape(option.value);
                            //only one item can be selected
                            continue selectLoop;
                        } else {
                            if (!out[escName]) {
                                out[name] = new Array();
                            }
                            out[escName].push(escape(option.value));
                        }
                    } else {
                        out += escName + '=' + escape(option.value) + '&';
                    }
                }
            }
        } // end selectLoop

        buttonLoop:
        for (var i=0; i<buttonTags.length; i++) {
            if (!validElement(buttonTags[i])) {
                continue;
            }
            // add element to output array
			if (array_format) {
				out[escName] = value;
			} else {
				out += escName + '=' + value + '&';
			}
        } // end buttonLoop

        textareaLoop:
        for (var i=0; i<textareaTags.length; i++) {
            if (!validElement(textareaTags[i])) {
                continue;
            }
            // add element to output array
			if (array_format) {
				out[escName] = value;
			} else {
				out += escName + '=' + value + '&';
			}
        } // end textareaLoop
        
        return out;
    },
    // submits a form through ajax. both arguments can be either DOM nodes or IDs, if the target is omitted then the form is set to be the target
    formSubmit: function (form, target, options)
    {
        if (HTML_AJAX_Util.getType(form) == 'string') {
            form = document.getElementById(form);
            if (!form) {
                // let the submit be processed normally
                return false;
            }
        }

        var out = HTML_AJAX.formEncode(form);
        if (HTML_AJAX_Util.getType(target) == 'string') {
            target = document.getElementById(target);
        }
        if (!target) {
            target = form;
        }
        var action = form.getAttribute('action');
        var callback = function(result) {
            HTML_AJAX_Util.setInnerHTML(target,result);
        }

        var serializer = HTML_AJAX.serializerForEncoding('Null');
        var request = new HTML_AJAX_Request(serializer);
        request.isAsync = true;
        request.callback = callback;

        switch (form.getAttribute('method').toLowerCase()) {
        case 'post':
            var headers = {};
            headers['Content-Type'] = 'application/x-www-form-urlencoded';
            request.customHeaders = headers;
            request.requestType = 'POST';
            request.requestUrl = action;
            request.args = out;
            break;
        default:
            if (action.indexOf('?') == -1) {
                out = '?' + out.substr(0, out.length - 1);
            }
            request.requestUrl = action+out;
            request.requestType = 'GET';
        }

        if(options) {
            for(var i in options) {
                request[i] = options[i];
            }
        }
        HTML_AJAX.makeRequest(request);
        return true;
    }, // end formSubmit()
    makeFormAJAX: function(form,target,options) {
        if (HTML_AJAX_Util.getType(form) == 'string') {
            var form = document.getElementById(form);
        }
        var preSubmit = false;
        if(form.onsubmit) {
            preSubmit = form.onsubmit;
            form.onsubmit = function() {};
        }
        form.HAOptions = options;
        var handler = function(e) {
            var form = HTML_AJAX_Util.eventTarget(e);

            var valid = true;
            if (preSubmit) {
                valid = preSubmit();
            }
		    if (valid) {
			    HTML_AJAX.formSubmit(form,target,form.HAOptions);
			}
            // cancel submission in IE
            e.returnValue = false;
            // cancel submission in FF
            if (e.preventDefault) {
                e.preventDefault();
            }
        }
		HTML_AJAX_Util.registerEvent(form,'submit',handler);
    }
}




// small classes that I don't want to put in there own file

function HTML_AJAX_Serialize_Null() {}
HTML_AJAX_Serialize_Null.prototype = {
	contentType: 'text/plain; charset=utf-8',
	serialize: function(input) {
		return new String(input).valueOf();
	},
	
	unserialize: function(input) {
		return new String(input).valueOf();	
	}
}

// serialization class for JSON, wrapper for JSON.stringify in json.js
function HTML_AJAX_Serialize_JSON() {}
HTML_AJAX_Serialize_JSON.prototype = {
	contentType: 'application/json; charset=utf-8',
	serialize: function(input) {
		return HTML_AJAX_JSON.stringify(input);
	},
	unserialize: function(input) {
        try {
            return eval(input);
        } catch(e) {
            // sometimes JSON encoded input isn't created properly, if eval of it fails we use the more forgiving but slower parser so will at least get something
            return HTML_AJAX_JSON.parse(input);
        }
	}
}

function HTML_AJAX_Serialize_Error() {}
HTML_AJAX_Serialize_Error.prototype = {
	contentType: 'application/error; charset=utf-8',
	serialize: function(input) {
        var ser = new HTML_AJAX_Serialize_JSON();
        return ser.serialize(input);
	},
	unserialize: function(input) {
        var ser = new HTML_AJAX_Serialize_JSON();
        var data = new ser.unserialize(input);

        var e = new Error('PHP Error: '+data.errStr);
        for(var i in data) {
            e[i] = data[i];
        }
        throw e;
	}
}

// Processing Queues

// simple queue, just processes the request immediately
function HTML_AJAX_Queue_Immediate() {}
HTML_AJAX_Queue_Immediate.prototype = {
    request: false,
    addRequest: function(request) {
        this.request = request;
    },
    processRequest: function() {
        var client = HTML_AJAX.httpClient();
        client.request = this.request;
        return client.makeRequest();
    }
    // requestComplete: function() {} // this is also possible but this queue doesn't need it
}

// Single Buffer queue with interval
// works by attempting to send a request every x miliseconds
// if an item is currently in the queue when a new item is added it will be replaced
// simple queue, just processes the request immediately
// the first request starts the interval timer
function HTML_AJAX_Queue_Interval_SingleBuffer(interval) {
    this.interval = interval;
}
HTML_AJAX_Queue_Interval_SingleBuffer.prototype = {
    request: false,
    _intervalId: false,
    addRequest: function(request) {
        this.request = request;
    },
    processRequest: function() {
        if (!this._intervalId) {
            this.runInterval();
            this.start();
        }
    }, 
    start: function() {
        var self = this;
        this._intervalId = setInterval(function() { self.runInterval() },this.interval);
    },
    stop: function() {
        clearInterval(this._intervalId);
    },
    runInterval: function() {
        if (this.request) {
            var client = HTML_AJAX.httpClient();
            client.request = this.request;
            this.request = false;
            client.makeRequest();
        }
    }
}


// create a default queue, has to happen after the Queue class has been defined
HTML_AJAX.queues = new Object();
HTML_AJAX.queues['default'] = new HTML_AJAX_Queue_Immediate();

/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
HTML_AJAX_Client_Pool = function(maxClients, startingClients)
{
    this.maxClients = maxClients;
    this._clients = [];
    this._len = 0;
    while (--startingClients > 0) {
        this.addClient();
    }
}

HTML_AJAX_Client_Pool.prototype = {
    isEmpty: function()
    {
        return this._len == 0;
    },
    addClient: function()
    {
        if (this.maxClients != 0 && this._len > this.maxClients) {
            return false;
        }
        var key = this._len++;
        this._clients[key] = new HTML_AJAX_HttpClient();
        return this._clients[key];
    },
    getClient: function ()
    {
        for (i = 0; i < this._len; i++) {
            if (!this._clients[i].callInProgress()) {
                return this._clients[i];
            }
        }
        var client = this.addClient();
        if (client) {
            return client;
        }
        return false;
    },
    removeClient: function (client)
    {
        for (i = 0; i < this._len; i++) {
            if (!this._clients[i] == client) {
                this._clients.splice(i, 1);
                return true;
            }
        }
        return false;
    },
    clear: function ()
    {
        this._clients = [];
        this._len = 0;
    }
};

// create a default client pool with unlimited clients
HTML_AJAX.clientPools['default'] = new HTML_AJAX_Client_Pool(0);/**
 * Class that contains everything needed to make a request
 * This includes:
 *    The url were calling
 *    If were calling a remote method, the class and method name
 *    The payload, unserialized
 *    The timeout for async calls
 *    The callback method
 *    Optional event handlers: onError, Load, Send
 *    A serializer instance
 *
 * @category   HTML
 * @package    AJAX
 * @author     Joshua Eichorn <josh@bluga.net>
 * @copyright  2005 Joshua Eichorn
 * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
 *
 * See Main.js for author/license details
 */
function HTML_AJAX_Request(serializer) {
    this.serializer = serializer;
}
HTML_AJAX_Request.prototype = {

    // Instance of a serializer
    serializer: null,
    
    // Is this an async request
    isAsync: false,

    // HTTP verb
    requestType: 'POST',
    
    // The actual URL the request is sent to
    requestUrl: '',
    
    // Remote Class
    className: null,

    // Remote Method
    methodName: null,

    // Timeout in milliseconds for requests
    timeout: 20000,

    // unserialized data, for rpc calls use add args, to send raw data just set this directly
    args: null,

    // async callback method
    callback: null,

    // Queue to push this request too
    queue: 'default',
    
    // default priority
    priority: 0,
    
    // a hash of headers to add to add to this request
    customHeaders: {},

    // true if this request will be sent using iframes
    iframe: false,
    
    // is this a grab request? if so we need to proxy for iframes
    grab: false,
    
    // true if this request should expect a multipart response
    multipart: false,

    // remote callback
    phpCallback: false,
    
    /**
     * Add an argument for the remote method
     * @param string argument name
     * @param mixed value
     * @return void
     * @throws Error code 1004
     */
    addArg: function(name, value) 
    {
        if ( !this.args ) {
            this.args = [];
        }
        if (!/[^a-zA-Z_0-9]/.test(name) ) {
            this.args[name] = value;
        } else {
            throw new Error('Invalid parameter name ('+name+')');
        }
    },

    /**
     * Get the payload in a serialized manner
     */
    getSerializedPayload: function() {
        return this.serializer.serialize(this.args);
    },

    /**
     * Get the content type
     */
    getContentType: function() {
        return this.serializer.contentType;
    },

    /**
     * Get the complete url, adding in any needed get params for rpc
     */
    completeUrl: function() {
        if (this.className || this.methodName) {
            this.addGet('c', this.className);
            this.addGet('m', this.methodName);
        }
        if (this.phpCallback) {
            if (HTML_AJAX_Util.getType(this.phpCallback) == 'array') {
                this.phpCallback = this.phpCallback.join('.');
            }
            this.addGet('cb', this.phpCallback);
        }
        if (this.multipart) {
            this.addGet('multipart', '1');
        }
        return this.requestUrl;
    },
    
    /**
     * Compare to another request by priority
     */
    compareTo: function(other) {
        if (this.priority == other.priority) {
            return 0;
        }
        return (this.priority > other.priority ? 1 : -1);
    },

    /**
     * Add a GET argument
     */
    addGet: function(name, value) {
        var url = new String(this.requestUrl);
        url += (url.indexOf('?') < 0 ? '?' : '&') + escape(name) + '=' + escape(value);
        this.requestUrl = url;
    }
}
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
function HTML_AJAX_HttpClient(){ }HTML_AJAX_HttpClient.prototype={request: null,_timeoutId: null,init:function(){try{this.xmlhttp=new XMLHttpRequest();}catch(e){var XMLHTTP_IDS=new Array('MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP');var success=false;for(var i=0;i<XMLHTTP_IDS.length && !success;i++){try{this.xmlhttp=new ActiveXObject(XMLHTTP_IDS[i]);success=true;}catch(e){}}if(!success){try{this.xmlhttp=new HTML_AJAX_IframeXHR();this.request.iframe=true;}catch(e){throw new Error('Unable to create XMLHttpRequest.');}}}},
callInProgress:function(){switch(this.xmlhttp.readyState){case 1:case 2:case 3:return true;break;default:return false;break;}},
makeRequest:function(){if(!this.xmlhttp){this.init();}try{if(this.request.Open){this.request.Open();}else if(HTML_AJAX.Open){HTML_AJAX.Open(this.request);}if(this.request.multipart){if(document.all){this.iframe=true;}else{this.xmlhttp.multipart=true;}}
var self=this;this.xmlhttp.open(this.request.requestType,this.request.completeUrl(),this.request.isAsync);if(this.request.customHeaders){for(i in this.request.customHeaders){this.xmlhttp.setRequestHeader(i,this.request.customHeaders[i]);}}if(this.request.customHeaders && !this.request.customHeaders['Content-Type']){if(window.opera){this.xmlhttp.setRequestHeader('Content-Type','text/plain; charset=utf-8');this.xmlhttp.setRequestHeader('x-Content-Type',this.request.getContentType()+'; charset=utf-8');}else{this.xmlhttp.setRequestHeader('Content-Type',this.request.getContentType()+'; charset=utf-8');}}if(this.request.isAsync){this.xmlhttp.onreadystatechange=function(){self._readyStateChangeCallback();}}var payload=this.request.getSerializedPayload();if(payload){this.xmlhttp.setRequestHeader('Content-Length',payload.length);}
this.xmlhttp.send(payload);if(!this.request.isAsync){if(this.xmlhttp.status==200){HTML_AJAX.requestComplete(this.request);if(this.request.Load){this.request.Load();}else if(HTML_AJAX.Load){HTML_AJAX.Load(this.request);}return this._decodeResponse();}else{var e=new Error('['+this.xmlhttp.status +'] '+this.xmlhttp.statusText);e.headers=this.xmlhttp.getAllResponseHeaders();this._handleError(e);}}else{var self=this;this._timeoutId=window.setTimeout(function() { self.abort(true); },this.request.timeout);}}catch(e){this._handleError(e);}},
abort:function(automatic){if(this.callInProgress()){this.xmlhttp.abort();if(automatic){HTML_AJAX.requestComplete(this.request);this._handleError(new Error('Request Timed Out: time out was '+this.request.timeout+'ms'));}}},
_readyStateChangeCallback:function(){try{switch(this.xmlhttp.readyState){case 1:break;case 2:if(this.request.Send){this.request.Send();}else if(HTML_AJAX.Send){HTML_AJAX.Send(this.request);}break;case 3:if(this.request.Progress){this.request.Progress();}else if(HTML_AJAX.Progress){HTML_AJAX.Progress(this.request);}break;case 4:window.clearTimeout(this._timeoutId);if(this.xmlhttp.status==200){HTML_AJAX.requestComplete(this.request);if(this.request.Load){this.request.Load();}else if(HTML_AJAX.Load){HTML_AJAX.Load(this.request);}var response=this._decodeResponse();if(this.request.callback){this.request.callback(response);}}else{var e=new Error('HTTP Error Making Request: ['+this.xmlhttp.status+'] '+this.xmlhttp.statusText);this._handleError(e);}break;}}catch(e){this._handleError(e);}},
_decodeResponse:function(){var content=null;try{content=this.xmlhttp.getResponseHeader('X-Content-Type');}catch(e){}if(!content||content==null){content=this.xmlhttp.getResponseHeader('Content-Type');}if(content.indexOf(';') != -1){content=content.substring(0,content.indexOf(';'));}var unserializer=HTML_AJAX.serializerForEncoding(content);return unserializer.unserialize(this.xmlhttp.responseText);},
_handleError:function(e){HTML_AJAX.requestComplete(this.request,e);if(this.request.onError){this.request.onError(e);}else if(HTML_AJAX.onError){HTML_AJAX.onError(e,this.request);}else{throw e;}}}/**
 * Class that is used by generated stubs to make actual AJAX calls
 *
 * @category   HTML
 * @package    AJAX
 * @author     Joshua Eichorn <josh@bluga.net>
 * @copyright  2005 Joshua Eichorn
 * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
 */
function HTML_AJAX_Dispatcher(className,mode,callback,serverUrl,serializerType) 
{
	this.className = className;
	this.mode = mode;
	this.callback = callback;
    this.serializerType = serializerType;

	if (serverUrl) {
		this.serverUrl = serverUrl
	}
	else {
		this.serverUrl = window.location;
	}
}

HTML_AJAX_Dispatcher.prototype = {
    /**
     * Queue to use when making a request
     */
    queue: 'default',

    /**
     * Timeout for async calls
     */
	timeout: 20000,
 
    /**
     * Default request priority
     */
    priority: 0,
    
    /**
     * Make an ajax call
     *
     * @param   string callName
     * @param   Array   args    arguments to the report method
     */
	doCall: function(callName,args) 
    {
        var request = new HTML_AJAX_Request();
		request.requestUrl = this.serverUrl;
        request.className = this.className;
        request.methodName = callName;
		request.timeout = this.timeout;
        request.contentType = this.contentType;
        request.serializer = eval('new HTML_AJAX_Serialize_'+this.serializerType);
        request.queue = this.queue;
        request.priority = this.priority;
        
		for(var i=0; i < args.length; i++) {
		    request.addArg(i,args[i]);
		};

		if ( this.mode == "async" ) {
		    request.isAsync = true;
            if (this.callback[callName]) {
                var self = this;
                request.callback = function(result) { self.callback[callName](result); }
            }

		} else {
		    request.isAsync = false;
		}

        return HTML_AJAX.makeRequest(request);
	},

    Sync: function() 
    {
        this.mode = 'sync';
    },

    Async: function(callback)
    {
        this.mode = 'async';
        if (callback) {
            this.callback = callback;
        }
    }
    
};
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**

ModifiedBehavior v1.0 by Ron Lancaster based on Ben Nolan's Behaviour, June 2005 implementation.
Modified to use Dean Edward's CSS Query.

Description
----------

Uses css selectors  to apply javascript Behaviors to enable unobtrusive javascript in html documents.

Dependencies
------------

Requires [Dean Edwards CSSQuery](http://dean.edwards.name/my/cssQuery/ "CSSQuery").

Usage
------

		Behavior.register(
			"b.someclass",
			function(element) {
				element.onclick = function(){
					alert(this.innerHTML);
				}
			}
		);

		Behavior.register(
			"#someid u",
			function(element) {
				element.onmouseover = function(){
					this.innerHTML = "BLAH!";
				}
			},
			getElementByID("parent")
		);

Call `Behavior.apply()` to re-apply the rules (if you update the dom, etc).

License
------

Reproduced under BSD licensed. Same license as Ben Nolan's implementation.

More information for Ben Nolan's implementation: <http://ripcord.co.nz/behaviour/>

*/

var Behavior = {

	// private data member
	list : new Array(),

	// private method
	addLoadEvent : function(func) {
		var oldonload = window.onload;

		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			}
		}
	},

	// void apply() : Applies the registered ruleset.
	apply : function() {
		for (i = 0; i < Behavior.list.length; i++) {
			var rule = Behavior.list[i];
			var tags = cssQuery(rule.selector, rule.from);
			if (tags) {
				for (j = 0; j < tags.length; j++) {
					rule.action(tags[j]);
				}
			}
		}
	},

	// void register() : register a css selector, and the action (function) to take,
	// from (optional) is a document, element or array of elements which is filtered by selector.
	register : function(selector, action, from) {
		Behavior.list.push(new BehaviorRule(selector, from, action));
	},

	// void start() : initial application of ruleset at document load.
	start : function() {
		Behavior.addLoadEvent(function() {
			Behavior.apply();
		});
	}
}

function BehaviorRule(selector, from, action) {
	this.selector = selector;
	this.from = from;
	this.action = action;
}

Behavior.start();/*
	cssQuery, version 2.0.2 (2005-08-19)
	Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/)
	License: http://creativecommons.org/licenses/LGPL/2.1/
*/
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 x=6(){7 1D="2.0.2";7 C=/\\s*,\\s*/;7 x=6(s,A){33{7 m=[];7 u=1z.32.2c&&!A;7 b=(A)?(A.31==22)?A:[A]:[1g];7 1E=18(s).1l(C),i;9(i=0;i<1E.y;i++){s=1y(1E[i]);8(U&&s.Z(0,3).2b("")==" *#"){s=s.Z(2);A=24([],b,s[1])}1A A=b;7 j=0,t,f,a,c="";H(j<s.y){t=s[j++];f=s[j++];c+=t+f;a="";8(s[j]=="("){H(s[j++]!=")")a+=s[j];a=a.Z(0,-1);c+="("+a+")"}A=(u&&V[c])?V[c]:21(A,t,f,a);8(u)V[c]=A}m=m.30(A)}2a x.2d;5 m}2Z(e){x.2d=e;5[]}};x.1Z=6(){5"6 x() {\\n  [1D "+1D+"]\\n}"};7 V={};x.2c=L;x.2Y=6(s){8(s){s=1y(s).2b("");2a V[s]}1A V={}};7 29={};7 19=L;x.15=6(n,s){8(19)1i("s="+1U(s));29[n]=12 s()};x.2X=6(c){5 c?1i(c):o};7 D={};7 h={};7 q={P:/\\[([\\w-]+(\\|[\\w-]+)?)\\s*(\\W?=)?\\s*([^\\]]*)\\]/};7 T=[];D[" "]=6(r,f,t,n){7 e,i,j;9(i=0;i<f.y;i++){7 s=X(f[i],t,n);9(j=0;(e=s[j]);j++){8(M(e)&&14(e,n))r.z(e)}}};D["#"]=6(r,f,i){7 e,j;9(j=0;(e=f[j]);j++)8(e.B==i)r.z(e)};D["."]=6(r,f,c){c=12 1t("(^|\\\\s)"+c+"(\\\\s|$)");7 e,i;9(i=0;(e=f[i]);i++)8(c.l(e.1V))r.z(e)};D[":"]=6(r,f,p,a){7 t=h[p],e,i;8(t)9(i=0;(e=f[i]);i++)8(t(e,a))r.z(e)};h["2W"]=6(e){7 d=Q(e);8(d.1C)9(7 i=0;i<d.1C.y;i++){8(d.1C[i]==e)5 K}};h["2V"]=6(e){};7 M=6(e){5(e&&e.1c==1&&e.1f!="!")?e:23};7 16=6(e){H(e&&(e=e.2U)&&!M(e))28;5 e};7 G=6(e){H(e&&(e=e.2T)&&!M(e))28;5 e};7 1r=6(e){5 M(e.27)||G(e.27)};7 1P=6(e){5 M(e.26)||16(e.26)};7 1o=6(e){7 c=[];e=1r(e);H(e){c.z(e);e=G(e)}5 c};7 U=K;7 1h=6(e){7 d=Q(e);5(2S d.25=="2R")?/\\.1J$/i.l(d.2Q):2P(d.25=="2O 2N")};7 Q=6(e){5 e.2M||e.1g};7 X=6(e,t){5(t=="*"&&e.1B)?e.1B:e.X(t)};7 17=6(e,t,n){8(t=="*")5 M(e);8(!14(e,n))5 L;8(!1h(e))t=t.2L();5 e.1f==t};7 14=6(e,n){5!n||(n=="*")||(e.2K==n)};7 1e=6(e){5 e.1G};6 24(r,f,B){7 m,i,j;9(i=0;i<f.y;i++){8(m=f[i].1B.2J(B)){8(m.B==B)r.z(m);1A 8(m.y!=23){9(j=0;j<m.y;j++){8(m[j].B==B)r.z(m[j])}}}}5 r};8(![].z)22.2I.z=6(){9(7 i=0;i<1z.y;i++){o[o.y]=1z[i]}5 o.y};7 N=/\\|/;6 21(A,t,f,a){8(N.l(f)){f=f.1l(N);a=f[0];f=f[1]}7 r=[];8(D[t]){D[t](r,A,f,a)}5 r};7 S=/^[^\\s>+~]/;7 20=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1y(s){8(S.l(s))s=" "+s;5 s.P(20)||[]};7 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;7 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;7 18=6(s){5 s.O(W,"$1").O(I,"$1*$2")};7 1u={1Z:6(){5"\'"},P:/^(\'[^\']*\')|("[^"]*")$/,l:6(s){5 o.P.l(s)},1S:6(s){5 o.l(s)?s:o+s+o},1Y:6(s){5 o.l(s)?s.Z(1,-1):s}};7 1s=6(t){5 1u.1Y(t)};7 E=/([\\/()[\\]?{}|*+-])/g;6 R(s){5 s.O(E,"\\\\$1")};x.15("1j-2H",6(){D[">"]=6(r,f,t,n){7 e,i,j;9(i=0;i<f.y;i++){7 s=1o(f[i]);9(j=0;(e=s[j]);j++)8(17(e,t,n))r.z(e)}};D["+"]=6(r,f,t,n){9(7 i=0;i<f.y;i++){7 e=G(f[i]);8(e&&17(e,t,n))r.z(e)}};D["@"]=6(r,f,a){7 t=T[a].l;7 e,i;9(i=0;(e=f[i]);i++)8(t(e))r.z(e)};h["2G-10"]=6(e){5!16(e)};h["1x"]=6(e,c){c=12 1t("^"+c,"i");H(e&&!e.13("1x"))e=e.1n;5 e&&c.l(e.13("1x"))};q.1X=/\\\\:/g;q.1w="@";q.J={};q.O=6(m,a,n,c,v){7 k=o.1w+m;8(!T[k]){a=o.1W(a,c||"",v||"");T[k]=a;T.z(a)}5 T[k].B};q.1Q=6(s){s=s.O(o.1X,"|");7 m;H(m=s.P(o.P)){7 r=o.O(m[0],m[1],m[2],m[3],m[4]);s=s.O(o.P,r)}5 s};q.1W=6(p,t,v){7 a={};a.B=o.1w+T.y;a.2F=p;t=o.J[t];t=t?t(o.13(p),1s(v)):L;a.l=12 2E("e","5 "+t);5 a};q.13=6(n){1d(n.2D()){F"B":5"e.B";F"2C":5"e.1V";F"9":5"e.2B";F"1T":8(U){5"1U((e.2A.P(/1T=\\\\1v?([^\\\\s\\\\1v]*)\\\\1v?/)||[])[1]||\'\')"}}5"e.13(\'"+n.O(N,":")+"\')"};q.J[""]=6(a){5 a};q.J["="]=6(a,v){5 a+"=="+1u.1S(v)};q.J["~="]=6(a,v){5"/(^| )"+R(v)+"( |$)/.l("+a+")"};q.J["|="]=6(a,v){5"/^"+R(v)+"(-|$)/.l("+a+")"};7 1R=18;18=6(s){5 1R(q.1Q(s))}});x.15("1j-2z",6(){D["~"]=6(r,f,t,n){7 e,i;9(i=0;(e=f[i]);i++){H(e=G(e)){8(17(e,t,n))r.z(e)}}};h["2y"]=6(e,t){t=12 1t(R(1s(t)));5 t.l(1e(e))};h["2x"]=6(e){5 e==Q(e).1H};h["2w"]=6(e){7 n,i;9(i=0;(n=e.1F[i]);i++){8(M(n)||n.1c==3)5 L}5 K};h["1N-10"]=6(e){5!G(e)};h["2v-10"]=6(e){e=e.1n;5 1r(e)==1P(e)};h["2u"]=6(e,s){7 n=x(s,Q(e));9(7 i=0;i<n.y;i++){8(n[i]==e)5 L}5 K};h["1O-10"]=6(e,a){5 1p(e,a,16)};h["1O-1N-10"]=6(e,a){5 1p(e,a,G)};h["2t"]=6(e){5 e.B==2s.2r.Z(1)};h["1M"]=6(e){5 e.1M};h["2q"]=6(e){5 e.1q===L};h["1q"]=6(e){5 e.1q};h["1L"]=6(e){5 e.1L};q.J["^="]=6(a,v){5"/^"+R(v)+"/.l("+a+")"};q.J["$="]=6(a,v){5"/"+R(v)+"$/.l("+a+")"};q.J["*="]=6(a,v){5"/"+R(v)+"/.l("+a+")"};6 1p(e,a,t){1d(a){F"n":5 K;F"2p":a="2n";1a;F"2o":a="2n+1"}7 1m=1o(e.1n);6 1k(i){7 i=(t==G)?1m.y-i:i-1;5 1m[i]==e};8(!Y(a))5 1k(a);a=a.1l("n");7 m=1K(a[0]);7 s=1K(a[1]);8((Y(m)||m==1)&&s==0)5 K;8(m==0&&!Y(s))5 1k(s);8(Y(s))s=0;7 c=1;H(e=t(e))c++;8(Y(m)||m==1)5(t==G)?(c<=s):(s>=c);5(c%m)==s}});x.15("1j-2m",6(){U=1i("L;/*@2l@8(@\\2k)U=K@2j@*/");8(!U){X=6(e,t,n){5 n?e.2i("*",t):e.X(t)};14=6(e,n){5!n||(n=="*")||(e.2h==n)};1h=1g.1I?6(e){5/1J/i.l(Q(e).1I)}:6(e){5 Q(e).1H.1f!="2g"};1e=6(e){5 e.2f||e.1G||1b(e)};6 1b(e){7 t="",n,i;9(i=0;(n=e.1F[i]);i++){1d(n.1c){F 11:F 1:t+=1b(n);1a;F 3:t+=n.2e;1a}}5 t}}});19=K;5 x}();',62,190,'|||||return|function|var|if|for||||||||pseudoClasses||||test|||this||AttributeSelector|||||||cssQuery|length|push|fr|id||selectors||case|nextElementSibling|while||tests|true|false|thisElement||replace|match|getDocument|regEscape||attributeSelectors|isMSIE|cache||getElementsByTagName|isNaN|slice|child||new|getAttribute|compareNamespace|addModule|previousElementSibling|compareTagName|parseSelector|loaded|break|_0|nodeType|switch|getTextContent|tagName|document|isXML|eval|css|_1|split|ch|parentNode|childElements|nthChild|disabled|firstElementChild|getText|RegExp|Quote|x22|PREFIX|lang|_2|arguments|else|all|links|version|se|childNodes|innerText|documentElement|contentType|xml|parseInt|indeterminate|checked|last|nth|lastElementChild|parse|_3|add|href|String|className|create|NS_IE|remove|toString|ST|select|Array|null|_4|mimeType|lastChild|firstChild|continue|modules|delete|join|caching|error|nodeValue|textContent|HTML|prefix|getElementsByTagNameNS|end|x5fwin32|cc_on|standard||odd|even|enabled|hash|location|target|not|only|empty|root|contains|level3|outerHTML|htmlFor|class|toLowerCase|Function|name|first|level2|prototype|item|scopeName|toUpperCase|ownerDocument|Document|XML|Boolean|URL|unknown|typeof|nextSibling|previousSibling|visited|link|valueOf|clearCache|catch|concat|constructor|callee|try'.split('|'),0,{}))
/**
 * Default loading implementation
 *
 * @category   HTML
 * @package    Ajax
 * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
 * @copyright  2005 Joshua Eichorn
 * see Main.js for license Author details
 */
HTML_AJAX.Open = function(request) {
    var loading = document.getElementById('HTML_AJAX_LOADING');
    if (!loading) {
        loading = document.createElement('div');
        loading.id = 'HTML_AJAX_LOADING';
        /*
		loading.innerHTML = 'Loading...';
        
        loading.style.color           = '#FFFFFF';
        loading.style.position        = 'absolute';
        loading.style.top             = 0;
        loading.style.right           = 0;
        loading.style.backgroundColor = '#96110E';
        loading.style.border          = '1px solid #f99';
        loading.style.width           = '80px';
        loading.style.padding         = '2px';
        //loading.style.fontFamily      = 'Arial, Helvetica, sans';
		*/
		loading.innerHTML = '<b>&nbsp;Loading ...</b>';
        
        //get width and hight
		//var topPX;
		//var leftPX;
		//var myWidth = self.screen.width;
		//var myHeight = self.screen.height;
		
		//alert (navigator.appName);
		if (parseInt(navigator.appVersion)>3) {
			if (navigator.appName=="Netscape") {
				myWidth = window.innerWidth;
				myHeight = window.innerHeight;
			}
			if ((navigator.appName.indexOf("Microsoft")!=-1) || (navigator.appName=="Microsoft Internet Explorer")) {
				//myWidth = document.body.offsetWidth;
				//myHeight = document.body.offsetHeight;
				myHeight = document.documentElement.clientHeight;
				myWidth = document.documentElement.clientWidth;
			}
		}
		loading.style.color           = '#B42027';
        loading.style.position        = 'fixed';
		//loading.style.position        = 'relative';
        //loading.style.top             = (myHeight / 2) - 15 + 'px';
        //loading.style.right           = (myWidth / 2) - 80 + 'px';
		loading.style.top             = '1px';
		loading.style.right           = '1px';
        loading.style.backgroundColor = '#FFFFFF';
        loading.style.border          = '1px solid #000000';
        loading.style.width           = '65px';
		loading.style.height		  = '16px';
        loading.style.padding         = '1px';
		//loading.style.zIndex 		  = "9999";
        loading.count = 0;
		
        document.body.insertBefore(loading,document.body.firstChild);
    }
    else {
        if (loading.count == undefined) {
            loading.count = 0;
        }
    }
    loading.count++;
    if (request.isAsync) {
        request.loadingId = window.setTimeout(function() { loading.style.display = 'block'; },500);
    }
    else {
        loading.style.display = 'block';
    }
}
HTML_AJAX.Load = function(request) {
    if (request.loadingId) {
        window.clearTimeout(request.loadingId);
    }
    var loading = document.getElementById('HTML_AJAX_LOADING');
    loading.count--;

    if (loading.count == 0) {
        loading.style.display = 'none';
    }
}
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

Array.prototype.______array = '______array';

var HTML_AJAX_JSON = {
    org: 'http://www.JSON.org',
    copyright: '(c)2005 JSON.org',
    license: 'http://www.crockford.com/JSON/license.html',

    stringify: function (arg) {
        var c, i, l, s = '', v;

        switch (typeof arg) {
        case 'object':
            if (arg) {
                if (arg.______array == '______array') {
                    for (i = 0; i < arg.length; ++i) {
                        v = this.stringify(arg[i]);
                        if (s) {
                            s += ',';
                        }
                        s += v;
                    }
                    return '[' + s + ']';
                } else if (typeof arg.toString != 'undefined') {
                    for (i in arg) {
                        v = arg[i];
                        if (typeof v != 'undefined' && typeof v != 'function') {
                            v = this.stringify(v);
                            if (s) {
                                s += ',';
                            }
                            s += this.stringify(i) + ':' + v;
                        }
                    }
                    return '{' + s + '}';
                }
            }
            return 'null';
        case 'number':
            return isFinite(arg) ? String(arg) : 'null';
        case 'string':
            l = arg.length;
            s = '"';
            for (i = 0; i < l; i += 1) {
                c = arg.charAt(i);
                if (c >= ' ') {
                    if (c == '\\' || c == '"') {
                        s += '\\';
                    }
                    s += c;
                } else {
                    switch (c) {
                        case '\b':
                            s += '\\b';
                            break;
                        case '\f':
                            s += '\\f';
                            break;
                        case '\n':
                            s += '\\n';
                            break;
                        case '\r':
                            s += '\\r';
                            break;
                        case '\t':
                            s += '\\t';
                            break;
                        default:
                            c = c.charCodeAt();
                            s += '\\u00' + Math.floor(c / 16).toString(16) +
                                (c % 16).toString(16);
                    }
                }
            }
            return s + '"';
        case 'boolean':
            return String(arg);
        default:
            return 'null';
        }
    },
    parse: function (text) {
        var at = 0;
        var ch = ' ';

        function error(m) {
            throw {
                name: 'JSONError',
                message: m,
                at: at - 1,
                text: text
            };
        }

        function next() {
            ch = text.charAt(at);
            at += 1;
            return ch;
        }

        function white() {
            while (ch) {
                if (ch <= ' ') {
                    next();
                } else if (ch == '/') {
                    switch (next()) {
                        case '/':
                            while (next() && ch != '\n' && ch != '\r') {}
                            break;
                        case '*':
                            next();
                            for (;;) {
                                if (ch) {
                                    if (ch == '*') {
                                        if (next() == '/') {
                                            next();
                                            break;
                                        }
                                    } else {
                                        next();
                                    }
                                } else {
                                    error("Unterminated comment");
                                }
                            }
                            break;
                        default:
                            error("Syntax error");
                    }
                } else {
                    break;
                }
            }
        }

        function string() {
            var i, s = '', t, u;

            if (ch == '"') {
outer:          while (next()) {
                    if (ch == '"') {
                        next();
                        return s;
                    } else if (ch == '\\') {
                        switch (next()) {
                        case 'b':
                            s += '\b';
                            break;
                        case 'f':
                            s += '\f';
                            break;
                        case 'n':
                            s += '\n';
                            break;
                        case 'r':
                            s += '\r';
                            break;
                        case 't':
                            s += '\t';
                            break;
                        case 'u':
                            u = 0;
                            for (i = 0; i < 4; i += 1) {
                                t = parseInt(next(), 16);
                                if (!isFinite(t)) {
                                    break outer;
                                }
                                u = u * 16 + t;
                            }
                            s += String.fromCharCode(u);
                            break;
                        default:
                            s += ch;
                        }
                    } else {
                        s += ch;
                    }
                }
            }
            error("Bad string");
        }

        function array() {
            var a = [];

            if (ch == '[') {
                next();
                white();
                if (ch == ']') {
                    next();
                    return a;
                }
                while (ch) {
                    a.push(value());
                    white();
                    if (ch == ']') {
                        next();
                        return a;
                    } else if (ch != ',') {
                        break;
                    }
                    next();
                    white();
                }
            }
            error("Bad array");
        }

        function object() {
            var k, o = {};

            if (ch == '{') {
                next();
                white();
                if (ch == '}') {
                    next();
                    return o;
                }
                while (ch) {
                    k = string();
                    white();
                    if (ch != ':') {
                        break;
                    }
                    next();
                    o[k] = value();
                    white();
                    if (ch == '}') {
                        next();
                        return o;
                    } else if (ch != ',') {
                        break;
                    }
                    next();
                    white();
                }
            }
            error("Bad object");
        }

        function number() {
            var n = '', v;
            if (ch == '-') {
                n = '-';
                next();
            }
            while (ch >= '0' && ch <= '9') {
                n += ch;
                next();
            }
            if (ch == '.') {
                n += '.';
                while (next() && ch >= '0' && ch <= '9') {
                    n += ch;
                }
            }
            if (ch == 'e' || ch == 'E') {
                n += 'e';
                next();
                if (ch == '-' || ch == '+') {
                    n += ch;
                    next();
                }
                while (ch >= '0' && ch <= '9') {
                    n += ch;
                    next();
                }
            }
            v = +n;
            if (!isFinite(v)) {
                ////error("Bad number");
            } else {
                return v;
            }
        }

        function word() {
            switch (ch) {
                case 't':
                    if (next() == 'r' && next() == 'u' && next() == 'e') {
                        next();
                        return true;
                    }
                    break;
                case 'f':
                    if (next() == 'a' && next() == 'l' && next() == 's' &&
                            next() == 'e') {
                        next();
                        return false;
                    }
                    break;
                case 'n':
                    if (next() == 'u' && next() == 'l' && next() == 'l') {
                        next();
                        return null;
                    }
                    break;
            }
            error("Syntax error");
        }

        function value() {
            white();
            switch (ch) {
                case '{':
                    return object();
                case '[':
                    return array();
                case '"':
                    return string();
                case '-':
                    return number();
                default:
                    return ch >= '0' && ch <= '9' ? number() : word();
            }
        }

        return value();
    }
};
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
HTML_AJAX_IframeXHR_instances = new Object();
function HTML_AJAX_IframeXHR(){this._id='HAXHR_iframe_'+new Date().getTime();HTML_AJAX_IframeXHR_instances[this._id]=this;}
HTML_AJAX_IframeXHR.prototype={onreadystatechange: null,readyState: 0,responseText: '',responseXML: null,status: 0,statusText: '',iframe: true,_id: null,_url: null,_method: null,_async: null,_headers: new Object(),_response: new Object(),_phpclass: null,_phpmethod: null,_history: null,
abort:function(){var iframe=document.getElementById(this._id);if(iframe){document.body.removeChild(iframe);}if(this._timeout){window.clearTimeout(this._timeout);}this.readyState=1;if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}},
getAllResponseHeaders:function(){var string='';for(i in this._response){string+=i+' : '+this._response[i]+"\n";}return string;},getResponseHeader:function(header){return(this._response[header]?this._response[header]:null);},setRequestHeader:function(label,value){this._headers[label]=value;return;},
open:function(method,url,async,username,password){if(!document.body){throw('CANNOT_OPEN_SEND_IN_DOCUMENT_HEAD');}if(!method||!url){throw('NOT_ENOUGH_ARGUMENTS:METHOD_URL_REQUIRED');}this._method=(method.toUpperCase()=='POST'?'POST':'GET');this._decodeUrl(url);this._async = async;if(!this._async && document.readyState && !window.opera){throw('IE_DOES_NOT_SUPPORT_SYNC_WITH_IFRAMEXHR');}this.readyState=1;if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}},
send:function(content){if(window.opera){this._history=window.history.length;}var form='<html><body><form method="'+(this._url.indexOf('px=')<0?this._method:'post')+'" action="'+this._url+'">';form+='<input name="Iframe_XHR" value="1" />';
if(this._phpclass!=null){form+='<input name="Iframe_XHR_class" value="'+this._phpclass+'" />';}if(this._phpmethod!=null){form+='<input name="Iframe_XHR_method" value="'+this._phpmethod+'" />';}for(label in this._headers){form+='<textarea name="Iframe_XHR_headers[]">'+label+':'+this._headers[label]+'</textarea>';}form+='<textarea name="Iframe_XHR_id">'+this._id+'</textarea>';if(content!=null && content.length>0){form+='<textarea name="Iframe_XHR_data">'+content+'</textarea>';}form+='<input name="Iframe_XHR_HTTP_method" value="'+this._method+'" />';form+='<s'+'cript>document.forms[0].submit();</s'+'cript></form></body></html>';form="javascript:document.write('"+form.replace(/\'/g,"\\'") + "');void(0);";
this.readyState=2;if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}try{var iframe=document.createElement('iframe');iframe.id=this._id;iframe.style.visibility='hidden';iframe.style.border='0';iframe.style.width='0';iframe.style.height='0';
if(document.all){iframe.src=form;document.body.appendChild(iframe);}else{document.body.appendChild(iframe);iframe.src=form;}}catch(exception){var html='<iframe src="'+form+'" id="'+this._id+'" style="visibility:hidden;border:0;height:0;width:0;"></iframe>';document.body.innerHTML+=html;}if(this._async==true){if(this.readyState<3){this.readyState=3;if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}}}else{while(this.readyState!=4){if(this.readyState<3){this.readyState=3;if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}}}}},
isLoaded:function(headers,data){this.readyState=4;this.status=200;this.statusText='OK';this.responseText=data;this._response=headers;if(!this._response['Last-Modified']){string+='Last-Modified : '+document.getElementById(this._id).lastModified+"\n";}if(!this._response['Content-Type']){string+='Content-Type : '+document.getElementById(this._id).contentType+"\n";}if(window.opera && window.opera.version){window.history.go(this._history-window.history.length);}if(typeof(this.onreadystatechange)=="function"){this.onreadystatechange();}document.body.removeChild(document.getElementById(this._id));},_decodeUrl:function(querystring){var url=unescape(location.href);url=url.substring(0,url.lastIndexOf("/")+1);var item=querystring.split('?');this._url=url+item[0].substring(item[0].lastIndexOf("/")+1,item[0].length);if(item[1]){item=item[1].split('&');for(i in item){var v=item[i].split('=');if(v[0]=='c'){this._phpclass=v[1];}else if(v[0]=='m'){this._phpmethod=v[1];}}}if(!this._phpclass || !this._phpmethod){var cloc=window.location.href;this._url=cloc+(cloc.indexOf('?')>=0?'&':'?')+'px='+escape(HTML_AJAX_Util.absoluteURL(querystring));}}}/**
 * HTML_AJAX_Serialize_HA  - custom serialization
 *
 * This class is used with the JSON serializer and the HTML_AJAX_Action php class
 * to allow users to easily write data handling and dom manipulation related to
 * ajax actions directly from their php code
 *
 * See Main.js for Author/license details
 */
function HTML_AJAX_Serialize_HA() { }
HTML_AJAX_Serialize_HA.prototype =
{
    /**
     *  Takes data from JSON - which should be parseable into a nice array
     *  reads the action to take and pipes it to the right method
     *
     *  @param    string payload incoming data from php
     *  @return   true on success, false on failure
     */
    unserialize: function(payload)
    {
        var actions = eval(payload);
        for(var i = 0; i < actions.length; i++)
        {
            var action = actions[i];
            switch(action.action)
            {
                case 'prepend':
                    this._prependAttr(action.id, action.attributes);
                    break;
                case 'append':
                    this._appendAttr(action.id, action.attributes);
                    break;
                case 'assign':
                    this._assignAttr(action.id, action.attributes);
                    break;
                case 'clear':
                    this._clearAttr(action.id, action.attributes);
                    break;
                case 'create':
                    this._createNode(action.id, action.tag, action.attributes, action.type);
                    break;
                case 'replace':
                    this._replaceNode(action.id, action.tag, action.attributes);
                    break;
                case 'remove':
                    this._removeNode(action.id);
                    break;
                case 'script':
                    this._insertScript(action.data);
                    break;
                case 'alert':
                    this._insertAlert(action.data);
                    break;
            }
        }
    },
	_prependAttr: function(id, attributes)
	{
		var node = document.getElementById(id);
        for (var i in attributes)
        {
            //innerHTML hack bailout
            if(i == 'innerHTML')
            {
                node.innerHTML = attributes[i] + node.innerHTML;
            }
            //value hack
            else if(i == 'value')
            {
                node.value = attributes[i];
            }
            //I'd use hasAttribute but IE is stupid stupid stupid
            else
            {
                var value = node.getAttribute(i);
                if(value)
                {
                    node.setAttribute(i, attributes[i] + value);
                }
                else
                {
                    node.setAttribute(i, attributes[i]);
                }
            }
        }
	},
	_appendAttr: function(id, attributes)
	{
		var node = document.getElementById(id);
        for (var i in attributes)
        {
            //innerHTML hack bailout
            if(i == 'innerHTML')
            {
                node.innerHTML += attributes[i];
            }
            //value hack
            else if(i == 'value')
            {
                node.value = attributes[i];
            }
            //I'd use hasAttribute but IE is stupid stupid stupid
            else
            {
                var value = node.getAttribute(i);
                if(value)
                {
                    node.setAttribute(i, value + attributes[i]);
                }
                else
                {
                    node.setAttribute(i, attributes[i]);
                }
            }
        }
	},
	_assignAttr: function(id, attributes)
	{
		var node = document.getElementById(id);
        for (var i in attributes)
        {
            //innerHTML hack bailout
            if(i == 'innerHTML')
            {
                node.innerHTML = attributes[i];
            }
            //value hack
            else if(i == 'value')
            {
                node.value = attributes[i];
            }
            //IE doesn't support setAttribute on style so we need to break it out and set each property individually
            else if(i == 'style')
            {
		var styles = [];
		if (attributes[i].indexOf(';')) {
			styles = attributes[i].split(';');
		}
		else {
			styles.push(attributes[i]);
		}
		for(var i = 0; i < styles.length; i++) {
			var r = styles[i].match(/^\s*(.+)\s*:\s*(.+)\s*$/);
			if(r) {
				node.style[this._camelize(r[1])] = r[2];
			}
		}
            }
            //no special rules know for this node so lets try our best
            else
            {
		try {
			node[i] = attributes[i];
		} catch(e) {
		}
		node.setAttribute(i, attributes[i]);
            }
        }
	},
    // should we move this to HTML_AJAX_Util???, just does the - case which we need for style
    _camelize: function(instr)
    {
        var p = instr.split('-');
        var out = p[0];
        for(var i = 1; i < p.length; i++) {
            out += p[i].charAt(0).toUpperCase()+p[i].substring(1);
        }
        return out;
    },
	_clearAttr: function(id, attributes)
	{
		var node = document.getElementById(id);
        for(var i = 0; i < attributes.length; i++)
        {
            //innerHTML hack bailout
            if(attributes[i] == 'innerHTML')
            {
                node.innerHTML = '';
            }
            //value hack
            else if(attributes[i] == 'value')
            {
                node.value = '';
            }
            //I'd use hasAttribute but IE is stupid stupid stupid
            else
            {
                node.removeAttribute(attributes[i]);
            }
        }
	},
    _createNode: function(id, tag, attributes, type)
    {
        var newnode = document.createElement(tag);
        for (var i in attributes)
        {
            //innerHTML hack bailout
            if(i == 'innerHTML')
            {
                newnode.innerHTML = attributes[i];
            }
            //value hack
            else if(i == 'value')
            {
                newnode.value = attributes[i];
            }
            //I'd use hasAttribute but IE is stupid stupid stupid
            else
            {
                newnode.setAttribute(i, attributes[i]);
            }
        }
        switch(type)
        {
            case 'append':
                document.getElementById(id).appendChild(newnode);
                break
            case 'prepend':
                var parent = document.getElementById(id);
                var sibling = parent.firstChild;
                parent.insertBefore(newnode, sibling);
                break;
            case 'insertBefore':
                var sibling = document.getElementById(id);
                var parent = sibling.parentNode;
                parent.insertBefore(newnode, sibling);
                break;
            //this one is tricky, if it's the last one we use append child...ewww
            case 'insertAfter':
                var sibling = document.getElementById(id);
                var parent = sibling.parentNode;
                var next = sibling.nextSibling;
                if(next == null)
                {
                    parent.appendChild(newnode);
                }
                else
                {
                    parent.insertBefore(newnode, next);
                }
                break;
        }
	},
    _replaceNode: function(id, tag, attributes)
    {
		var node = document.getElementById(id);
		var parent = node.parentNode;
        var newnode = document.createElement(tag);
		for (var i in attributes)
        {
            //innerHTML hack bailout
            if(i == 'innerHTML')
            {
                newnode.innerHTML = attributes[i];
            }
            //value hack
            else if(i == 'value')
            {
                newnode.value = attributes[i];
            }
        }
        parent.replaceChild(newnode, node);
	},
	_removeNode: function(id)
	{
		var node = document.getElementById(id);
        if(node)
        {
            var parent = node.parentNode;
            parent.removeChild(node);
        }
	},
    _insertScript: function(data)
    {
        eval(data);
    },
    _insertAlert: function(data)
    {
        alert(data);
    }
}
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
