﻿//cody by ctf_wren 2008
var ct = {
	Emptyfun: function(){},

	extend: function(destination) {
		var source, i = 1;
		while(source = arguments[i++])
			for (var property in source)
				destination[property] = source[property];
		return destination;
	},

	Browser: {
		IE:     !!(window.attachEvent && !window.opera),
		FF:		navigator.userAgent.indexOf('Firefox') > -1,
		Opera:  !!window.opera,
		WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
		Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
	},

	ScriptFragment: "<script[^>]*>([\\S\\s]*?)<\/script>",
	
	Dom: {
		create: function(tagName,args){
			var elm = $(document.createElement(tagName));
			if(args && args.attrs)
				elm.attr(args.attrs);
			if(args && args.style)
				elm.setStyle(args.style);
			return elm;			
		}	
	},
	
	array: function(destination){
		var results = [];
		for(var i=0,l=destination.length;i<l;i++)
			results.push(destination[i]);
		return results;		
	}
};
if(window.Event){
	document._getElementsByXPath = function(expression, parentElement) {
		var results = [];
		var query = document.evaluate(expression, $(parentElement) || document,
						null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for (var i = 0, length = query.snapshotLength; i < length; i++)
			results.push(query.snapshotItem(i));
		return results;
	};

	document.getElementsByClassName = function(className, parentElement) {
		var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
		return document._getElementsByXPath(q, parentElement);
	}
	
	Event.prototype.__defineSetter__("returnValue",function(b){
		if(!b)this.preventDefault();
		return b;
	});
	Event.prototype.__defineSetter__("cancelBubble",function(b){// 设置或者检索当前事件句柄的层次冒泡
		if(b)this.stopPropagation();
		return b;
	});
	Event.prototype.__defineGetter__("srcElement",function(){
		var node=this.target;
		while(node.nodeType!=1)node=node.parentNode;
		return node;
	});
	Event.prototype.__defineGetter__("fromElement",function(){// 返回鼠标移出的源节点
		var node;
		if(this.type=="mouseover")
			node=this.relatedTarget;
		else if(this.type=="mouseout")
			node=this.target;
		if(!node)return;
		while(node.nodeType!=1)node=node.parentNode;
		return node;
	});
	Event.prototype.__defineGetter__("toElement",function(){// 返回鼠标移入的源节点
		var node;
		if(this.type=="mouseout")
			node=this.relatedTarget;
		else if(this.type=="mouseover")
			node=this.target;
		if(!node)return;
		while(node.nodeType!=1)node=node.parentNode;
		return node;
	});
	Event.prototype.__defineGetter__("offsetX",function(){
		return this.layerX;
	});
	Event.prototype.__defineGetter__("offsetY",function(){
		return this.layerY;
	});
	// 修正Node的DOM
	Node.prototype.replaceNode=function(Node){// 替换指定节点
		this.parentNode.replaceChild(Node,this);
	}
	Node.prototype.removeNode=function(removeChildren){// 删除指定节点
		if(removeChildren)
			return this.parentNode.removeChild(this);
		else{
			var range=document.createRange();
			range.selectNodeContents(this);
			return this.parentNode.replaceChild(range.extractContents(),this);
		}
	}
	Node.prototype.swapNode=function(Node){// 交换节点
		var nextSibling=this.nextSibling;
		var parentNode=this.parentNode;
		node.parentNode.replaceChild(this,Node);
		parentNode.insertBefore(node,nextSibling);
	}
	HTMLElement.prototype.__defineGetter__("all",function(){
		var a=this.getElementsByTagName("*");
		var node=this;
		a.tags=function(sTagName){
			return node.getElementsByTagName(sTagName);
		}
		return a;
	});
	HTMLElement.prototype.__defineGetter__("parentElement",function(){
		if(this.parentNode==this.ownerDocument)return null;
		return this.parentNode;
	});
	HTMLElement.prototype.__defineGetter__("children",function(){
		var tmp=[];
		var j=0;
		var n;
		for(var i=0;i<this.childNodes.length;i++){
			n=this.childNodes[i];
			if(n.nodeType==1){
				tmp[j++]=n;
				if(n.name){
					if(!tmp[n.name])
					tmp[n.name]=[];
					tmp[n.name][tmp[n.name].length]=n;
				}
				if(n.id)
				tmp[n.id]=n;
			}
		}
		return tmp;
	});
	HTMLElement.prototype.__defineGetter__("currentStyle", function(){
		return this.ownerDocument.defaultView.getComputedStyle(this,null);
	});
	HTMLElement.prototype.__defineSetter__("outerHTML",function(sHTML){
		var r=this.ownerDocument.createRange();
		r.setStartBefore(this);
		var df=r.createContextualFragment(sHTML);
		this.parentNode.replaceChild(df,this);
		return sHTML;
	});
	HTMLElement.prototype.__defineGetter__("outerHTML",function(){
		var attr;
		var attrs=this.attributes;
		var str="<"+this.tagName;
		for(var i=0;i<attrs.length;i++){
			attr=attrs[i];
			if(attr.specified)
				str+=" "+attr.name+'="'+attr.value+'"';
		}
		if(!this.canHaveChildren)
		return str+">";
		return str+">"+this.innerHTML+"</"+this.tagName+">";
	});
	HTMLElement.prototype.__defineGetter__("canHaveChildren",function(){
		switch(this.tagName.toLowerCase()){
			case "area":
			case "base":
			case "basefont":
			case "col":
			case "frame":
			case "hr":
			case "img":
			case "br":
			case "input":
			case "isindex":
			case "link":
			case "meta":
			case "param":
			return false;
		}
		return true;
	});

	HTMLElement.prototype.__defineSetter__("innerText",function(sText){
		var parsedText=document.createTextNode(sText);
		this.innerHTML=parsedText;
		return parsedText;
	});
	HTMLElement.prototype.__defineGetter__("innerText",function(){
		var r=this.ownerDocument.createRange();
		r.selectNodeContents(this);
		return r.toString();
	});
	HTMLElement.prototype.__defineSetter__("outerText",function(sText){
		var parsedText=document.createTextNode(sText);
		this.outerHTML=parsedText;
		return parsedText;
	});
	HTMLElement.prototype.__defineGetter__("outerText",function(){
		var r=this.ownerDocument.createRange();
		r.selectNodeContents(this);
		return r.toString();
	});
	HTMLElement.prototype.attachEvent=function(sType,fHandler){
		var shortTypeName=sType.replace(/on/,"");
		fHandler._ieEmuEventHandler=function(e){
			window.event=e;
			return fHandler();
		}
		this.addEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
	}
	HTMLElement.prototype.detachEvent=function(sType,fHandler){
		var shortTypeName=sType.replace(/on/,"");
		if(typeof(fHandler._ieEmuEventHandler)=="function")
			this.removeEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
		else
			this.removeEventListener(shortTypeName,fHandler,true);
	}
	HTMLElement.prototype.contains=function(Node){// 是否包含某节点
		do if(Node==this)return true;
		while(Node=Node.parentNode);
		return false;
	}
	HTMLElement.prototype.insertAdjacentElement=function(where,parsedNode){
		switch(where){
			case "beforeBegin":
				this.parentNode.insertBefore(parsedNode,this);
				break;
			case "afterBegin":
				this.insertBefore(parsedNode,this.firstChild);
				break;
			case "beforeEnd":
				this.appendChild(parsedNode);
				break;
			case "afterEnd":
				if(this.nextSibling)
					this.parentNode.insertBefore(parsedNode,this.nextSibling);
			else
				this.parentNode.appendChild(parsedNode);
				break;
		}
	}
	HTMLElement.prototype.insertAdjacentHTML=function(where,htmlStr){
		var r=this.ownerDocument.createRange();
		r.setStartBefore(this);
		var parsedHTML=r.createContextualFragment(htmlStr);
		this.insertAdjacentElement(where,parsedHTML);
	}
	HTMLElement.prototype.insertAdjacentText=function(where,txtStr){
		var parsedText=document.createTextNode(txtStr);
		this.insertAdjacentElement(where,parsedText);
	}
	HTMLElement.prototype.attachEvent=function(sType,fHandler){
		var shortTypeName=sType.replace(/on/,"");
		fHandler._ieEmuEventHandler=function(e){
			window.event=e;
			return fHandler();
		}
		this.addEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
	}
	HTMLElement.prototype.detachEvent=function(sType,fHandler){
		var shortTypeName=sType.replace(/on/,"");
		if(typeof(fHandler._ieEmuEventHandler)=="function")
			this.removeEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
		else
			this.removeEventListener(shortTypeName,fHandler,true);
	}
}else{
	document.getElementsByClassName = function(className, parentElement) {
		var children = ($(parentElement) || document.body).getElementsByTagName('*');
		var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
		for (var i = 0, length = children.length; i < length; i++) {
			child = children[i];
			var elementClassName = child.className;
			if (elementClassName.length == 0) continue;
			if (elementClassName == className || elementClassName.match(pattern))
			elements.push(Element.extend(child));
		}
		return elements;
	}
	window.XMLHttpRequest=function(){var msxmls=['MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','MICROSOFT.XMLHTTP.1.0','MICROSOFT.XMLHTTP.1','MICROSOFT.XMLHTTP'];for(var i=0;i<msxmls.length;i++){try{return new ActiveXObject(msxmls[i]);}catch(e){}}return null;}
}

function $(element) {
	if (arguments.length > 1) {
		for (var i = 0, elements = [], length = arguments.length; i < length; i++)
			elements.push($(arguments[i]));
		return elements;
	}
	if (typeof element == 'string')
		element = document.getElementById(element);
	return Element.extend(element);
}

var $A = ct.array;

if (!window.Element) var Element = {};
var T = {};
Element.extend = function(element) {
	if (!element || !element.tagName || element.nodeType == 3 ||
	element._extended || element == window)
	return element;
	var methods = {}, tagName = element.tagName;

	ct.extend(methods, Element.Methods);

	if (T[tagName]) ct.extend(methods, T[tagName]);

	for (var property in methods) {
		var value = methods[property];
		if (typeof value == 'function' && !(property in element))
		element[property] = value;
	}

	element._extended = ct.Emptyfun;
	return element;
}
//通用方法
Element.Methods = {
	visible: function() {
		return this.style.display != 'none';
	},

	toggle: function() {
		this[this.visible() ? 'hide' : 'show']();
		return this;
	},

	hide: function() {
		this.style.display = 'none';
		return this;
	},

	show: function() {
		this.style.display = '';
		return this;
	},

	remove: function() {
		this.parentNode.removeChild(this);
		return this;
	},

	update: function(html) {
		this.innerHTML = html;
		return this;
	},

	replace: function(html) {
		this.outerHTML = html;
		return this;
	},

	append: function(content,where,type){
		where = where || "beforeEnd";
		if("element html text".indexOf(where)>-1){
			type = where;
			where = "beforeEnd";
		}
		else{
			type = type==undefined?(typeof content)=="object"?"element":"html":type;
		}
		if(type=="element")
			this.insertAdjacentElement(where,content);
		else if(type=="text")
			this.insertAdjacentText(where,content);
		else
			this.insertAdjacentHTML(where,content);
			
		return this;
	},

	recursivelyCollect: function(property) {
		var element = this;
		var elements = [];
		while (element = element[property])
			if (element.nodeType == 1)
				elements.push($(element));
		return elements;
	},

	ancestors: function() {
		return this.recursivelyCollect('parentNode');
	},

	firstDescendant: function() {
		var element = this.firstChild;
		while (element && element.nodeType != 1) element = element.nextSibling;
		return $(element);
	},

	immediateDescendants: function() {
		var element = this;
		if (!(element = element.firstChild)) return [];
		while (element && element.nodeType != 1) element = element.nextSibling;
		if (element) return [element].concat($(element).nextSiblings());
		return [];
	},

	childElements: function(){
		return this.immediateDescendants();
	},

	previousSiblings: function() {
		return this.recursivelyCollect('previousSibling');
	},

	nextSiblings: function() {
		return this.recursivelyCollect('nextSibling');
	},

	siblings: function() {
		return this.previousSiblings().reverse().concat(this.nextSiblings());
	},


	getElementsByClassName: function(className) {
		return document.getElementsByClassName(className, this);
	},

	attr: function(name,value){
		if(value!=undefined) {
			this.setAttribute(name,value);
			return this;
		}
		else if(typeof name=="object"){
			for(var p in name)
				this.setAttribute(p,name[p]);
			return this;
		}
		else{
			return this.getAttribute(name,value);
		}
	},
	val: function(value){
		if(value==undefined) {
			return this.value;
		}
		else{
			this.value=value;
			return this;
		}
	},
	html: function(value){
		if(value==undefined) {
			return this.innerHTML;
		}
		else{
			this.innerHTML=value;
			return this;
		}
	},

	getHeight: function() {
		return this.getDimensions().height;
	},

	getWidth: function() {
		return this.getDimensions().width;
	},

	hasClassName: function(className) {
		return new RegExp("(^| )" + className + "( |$)","gi").test(this.className);
	},

	addClassName: function(className) {
		if(this.className=="")
			this.className = className;
		else
			this.className = (this.className+" "+className).replace(new RegExp("(^| )"+ className +"( )","gi"),"");
		return this;
	},

	removeClassName: function(className) {
		var classname = this.className.replace(new RegExp("(^| )"+className+"( |$)","gi")," ");
		this.className = classname.trim();
		return this;
	},

	toggleClassName: function(className) {
		this[this.hasClassName(className) ? 'removeClassName' : 'addClassName'](className);
		return className;
	},

	// removes whitespace-only text node children
	cleanWhitespace: function() {
		var node = this.firstChild;
		while (node) {
			var nextNode = node.nextSibling;
			if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
				this.removeChild(node);
			node = nextNode;
		}
		return this;
	},

	empty: function() {
		this.innerHTML = "";
		return this;
	},

	descendantOf: function(ancestor) {
		var element = this;
		ancestor = $(ancestor);
		while (element = element.parentNode)
			if (element == ancestor) return true;
		return false;
	},
	childOf: function(ancestor){
		return this.descendantOf(ancestor);
	},

	getStyle: function(style) {
		style = style == 'float' ? 'cssFloat' : style.camelize();
		var value = this.style[style];
		if (!value) {
			var css = document.defaultView.getComputedStyle(this, null);
			value = css ? css[style] : null;
		}
		if (style == 'opacity') return value ? parseFloat(value) : 1.0;
		return value == 'auto' ? null : value;
	},

	getOpacity: function() {
		return this.getStyle('opacity');
	},

	setStyle: function(styles, camelized) {
		var elementStyle = this.style;
		for (var property in styles)
			if (property == 'opacity')
				this.setOpacity(styles[property])
			else
				elementStyle[(property == 'float' || property == 'cssFloat') ?
				(elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
				(camelized ? property : property.camelize())] = styles[property];
		return this;
	},

	setOpacity: function(value) {
		this.style.opacity = (value == 1 || value === '') ? '' :
			(value < 0.00001) ? 0 : value;
		return this;
	},

	getDimensions: function() {
		var display = this.getStyle('display');
		if (display != 'none' && display != null) // Safari bug
			return {width: this.offsetWidth, height: this.offsetHeight};

		// All *Width and *Height properties give 0 on elements with display none,
		// so enable the element temporarily
		var els = this.style;
		var originalVisibility = els.visibility;
		var originalPosition = els.position;
		var originalDisplay = els.display;
		els.visibility = 'hidden';
		els.position = 'absolute';
		els.display = 'block';
		var originalWidth = this.clientWidth;
		var originalHeight = this.clientHeight;
		els.display = originalDisplay;
		els.position = originalPosition;
		els.visibility = originalVisibility;
		return {width: originalWidth, height: originalHeight};
	},
	getPositionedOffset:function(){
		var valueT = 0, valueL = 0, element = this;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = $(element.offsetParent);
			if (element) {
				if(element.tagName=='BODY') break;
				var p = element.getStyle('position');
				if (p == 'relative' || p == 'absolute') break;
			}
		} while (element);
		return {left:valueL, top:valueT};
	},

	makePositioned: function() {
		var pos = this.getStyle('position');
		if (pos == 'static' || !pos) {
			this._madePositioned = true;
			this.style.position = 'relative';
			// Opera returns the offset relative to the positioning context, when an
			// element is position relative but top and left have not been defined
			if (ct.Browser.opera) {
				element.style.top = 0;
				element.style.left = 0;
			}
		}
		return this;
	},

	undoPositioned: function() {
		if (this._madePositioned) {
			this._madePositioned = undefined;
			this.style.position =
			this.style.top =
			this.style.left =
			this.style.bottom =
			this.style.right = '';
		}
		return this;
	},

	makeClipping: function() {
		if (this._overflow) return this;
		this._overflow = this.style.overflow || 'auto';
		if ((this.getStyle('overflow') || 'visible') != 'hidden')
			this.style.overflow = 'hidden';
		return this;
	},

	undoClipping: function() {
		if (!this._overflow) return this;
		this.style.overflow = this._overflow == 'auto' ? '' : this._overflow;
		this._overflow = null;
		return this;
	}
	
};

if (ct.Browser.Opera) {
	Element.Methods._getStyle = Element.Methods.getStyle;
	Element.Methods.getStyle = function(style) {
		switch(style) {
			case 'left':
			case 'top':
			case 'right':
			case 'bottom':
				if (this._getStyle('position') == 'static') return null;
			default: return this._getStyle(style);
		}
	};
}
else if (ct.Browser.IE) {
	Element.Methods.getStyle = function(style) {
		style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
		var value = this.style[style];
		if (!value && this.currentStyle) value = this.currentStyle[style];

		if (style == 'opacity') {
			if (value = (this.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
				if (value[1]) return parseFloat(value[1]) / 100;
			return 1.0;
		}

		if (value == 'auto') {
			if ((style == 'width' || style == 'height') && (this.getStyle('display') != 'none'))
				return this['offset'+style.capitalize()] + 'px';
			return null;
		}
		return value;
	};

	Element.Methods.setOpacity = function(value) {
		var filter = this.getStyle('filter'), style = this.style;
		if (value == 1 || value === '') {
			style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
			return this;
		} else if (value < 0.00001)
			value = 0;

		style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
						'alpha(opacity=' + (value * 100) + ')';
		return this;
	};
}
else if (ct.Browser.Gecko) {
	Element.Methods.setOpacity = function(value) {
		this.style.opacity = (value == 1) ? 0.999999 :
		(value === '') ? '' : (value < 0.00001) ? 0 : value;
		return this;
	};
}

ct.extend(String, {
	interpret: function(value) {
		return value == null ? '' : String(value);
	},
	specialChar: {
		'\b': '\\b',
		'\t': '\\t',
		'\n': '\\n',
		'\f': '\\f',
		'\r': '\\r',
		'\\': '\\\\'
	}
});
ct.extend(String.prototype, {
	truncate: function(length, truncation) {
		length = length || 30;
		truncation = truncation === undefined ? '...' : truncation;
		return this.length > length ?
		this.slice(0, length - truncation.length) + truncation : this;
	},

	trim: function() {
		return this.replace(/(^\s+)|(\s+$)/g, '');
	},

	trimTags: function() {
		return this.replace(/<[^>]+>/g, '');
	},

	trimScripts: function() {
		return this.replace(new RegExp(ct.ScriptFragment, 'img'), '');
	},

	succ: function() {
		return this.slice(0, this.length - 1) +
		String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
	},

	startsWith: function(pattern,specialChar,mode) {
		pattern = specialChar?specialChar.replace(/\\/g,"\\\\"):pattern;
		mode = mode||"gi";
		return new RegExp("^"+pattern,mode).test(this);
	},

	endsWith: function(pattern,specialChar,mode) {
		pattern = specialChar?specialChar.replace(/\\/g,"\\\\"):pattern;
		mode = mode||"gi";
		return new RegExp(pattern+"$",mode).test(this);
	},

	blank: function() {
		return /\S/.test(this);
	},

	capitalize: function() {
		return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
	},

	camelize: function() {
		return this.replace(/-([a-zA-Z])/g,function(){return arguments[1].toUpperCase()});
	},

	getParam: function(Param){
    	var value = this.match(new RegExp("[\?&]"+Param+"=([^&]*)","i"))
		return value?unescape(value[1]):"";
	},

	addParam: function(name,value){
		if(!value)return this;
		var temp = this;
		if(!/\?/.test(temp))temp+="?";
		if(!/\?$/.test(temp))temp+="&";
		temp+=name+"="+escape(value);
		return temp;
	},

	//v支持2种格式 json 和 Array
	format: function(v){
		return this.replace(/\{([^\{\}]+)\}/g,function(){
			if(arguments[1].indexOf(".")!=-1){
				var name;
				return arguments[1].replace(/^([^\.]+)\.(.*)/,function(){
					name = arguments[1];
					return "{"+arguments[2]+"}";
				}).format(v[name]);
			}
			return v[arguments[1]]==undefined?"{"+arguments[1]+"}":v[arguments[1]];
		});
	},

	len: function(){
		return this.replace(/[^\x00-\xff]/g,"aa").length;
	}

});

if (ct.Browser.WebKit || ct.Browser.IE) ct.extend(String.prototype, {
	escapeHTML: function() {
		return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
	},
	unescapeHTML: function() {
		return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
	}
});

ct.extend(Array.prototype,{
	popByVal: function(val){
		for(var i=0,l=this.length;i<l;i++){
			if( this[i]==val ){
				this.splice(i,1);
				return this;
			}
		}
		return this;
	},
	each: function(fun){
		for(var i=0,l=this.length;i<l;i++)
			fun(this[i],i);
		return this;
	}
});

var Cookie = {
	get : function(name){
		var matchs = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
		if(matchs != null)return unescape(matchs[2]);else return "";
	},
	set : function(name,value,p){
		p = typeof p=="number"?{days:p}:{};
		var s = [];
		s.push(name + "=" + escape(value));
		if(p.days)s.push("expires=" + new Date(new Date().getTime() + p.days*86400000).toGMTString());
		if(p.path)s.push("path=" + escape(p.path));
		if(p.domain)s.push("domain=" + escape(p.domain));
		s.push("")
		document.cookie = s.join(";");
	},
	del : function(name,p){
		p = p||{};
		var s = [];
		s.push(name + "=");
		s.push("expires=" + new Date().toGMTString());
		if(p.path)s.push("path=" + escape(p.path));
		if(p.domain)s.push("domain=" + escape(p.domain));
		document.cookie = s.join(";");
	}
}
function ctAjax(arg){
	this.getReq = function(){
		this.req = new XMLHttpRequest();
	}
	
	this.getReq();
	if(this.req==null){
		alert("浏览器不支持xmlhttp");
		return;
	}
	if(this.req.overrideMimeTyp)this.req.overrideMimeType('text/xml');
	this.receiveTypes = {text:'responseText',xml:'responseXML',json:'responseText'};
	
	this.url = '';
	this.method = 'post';
	this.async = true;
	this.data = {};
	this.timeout = 0;
	this.TimerID = null;
	this.contentType = 'application/x-www-form-urlencoded';
	this.encoding = 'UTF-8';
	this.receiveType = 'text';

	this.State = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
	this.ErrorState = {"400": "Bad Request 请求出现语法错误",
		"404": "无法找到指定位置的资源",
		"405": "Method Not Allowed 请求方法（GET、POST、HEAD、DELETE、PUT、TRACE等）对指定的资源不适用"};
		//这里自己定义吧
	this.init = ct.Emptyfun;//创建的时候执行 new Ajax({init:});
	this.onCreate = ct.Emptyfun;//req.onreadystatechange=0 的时候
	this.onComplete = ct.Emptyfun;
	this.onDoing = ct.Emptyfun;//从开始到结束，0-4状态
	this.onTimeout = ct.Emptyfun;
	this.onError = function(status,ErrorMsg,eMsg){alert("Status: "+status+"\nErrors: "+ErrorMsg+"\n        "+eMsg);}
	this.getSendData = function(arg){
		if(typeof arg=="string")
			return arg;
		var s = [];
		for(var p in arg)
			s.push(p + "=" + escape(arg[p]))
		return s.join("&");
	}
	this.EvalJson = function(str){
		try{
			return eval("("+str+")");
		}
		catch(e){
			return {};
		}
	}
	ct.extend(this,arg||{});

	this.method = this.method.toUpperCase();
	if(this.method=="GET")
		this.url += ((this.url.indexOf("?")>0)?"&":"?")+this.getSendData(this.data);
	this.url += ((this.url.indexOf("?")>0)?"&":"?")+"randnum=" + Math.random();
	
	this.init();
	
	This = this;
	
	this.send = function(){
		var s = [];
		if(This.async){
			This.onCreate(0,This.State[0]);
			This.onDoing(0,This.State[0]);
			This.req.onreadystatechange=function(){
				var _state = This.req.readyState;
				This.onDoing(_state,This.State[_state]);
				switch(_state){
					case 4:
						var reqStatus = This.req.status;
						if(This.timeout>0)clearTimeout(This.TimerID);
						if( reqStatus==200 )
							This.onComplete(
								This.receiveType=="json"?
									This.EvalJson(This.req[This.receiveTypes[This.receiveType]])
									:This.req[This.receiveTypes[This.receiveType]],
								_state,
								This.State[_state]);
						else if( reqStatus>200 )
							This.onError(reqStatus,This.ErrorState[reqStatus],This.req["responseText"]);
						//This.req.onreadystatechange = ct.Emptyfun;
						//This.req = null;
						break;
				}
			}
		}
		try{
			This.req.open(This.method, This.url, This.async);
			if(This.method=="POST")
				This.req.setRequestHeader('Content-Type', This.contentType+'; charset='+This.encoding);
			if(This.async && This.timeout>0){
				This.TimerID = setTimeout(function(){
					try{
						if(This.req!=null && This.readyState!=4){
						This.onTimeout();This.req.abort();This.req=null;}}
					catch(e){}},This.timeout);
			}
			This.req.send(This.getSendData(This.data));
			//只要不是status=200,都算try失败,执行catch
			if(!This.async){
				This.onComplete(This.req[This.receiveTypes[This.receiveType]]);
				//This.req = null;
			}
		}
		catch(e){
			try{This.onError(This.req.status,This.ErrorState[req.status],e);}
			catch(e){This.onError(0,"",e);}
			finally{
				//This.req.abort(); 
				//This.req=null;
			}
		}
	}
	
}
function Validator(){
	this.Require = /.+/;
	this.Email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
	this.Phone = /^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$/;
	this.Mobile = /^1[358]\d{9}$/;
	this.Url = /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/;
	this.IdCard = /^\d{15}(\d{2}[A-Za-z0-9])?$/;
	this.Currency = /^\d+(\.\d+)?$/;
	this.Number = /^\d+$/;
	this.Zip = /^[0-9]\d{5}$/;
	this.QQ = /^[1-9]\d{4,9}$/;
	this.Integer = /^[-\+]?\d+$/;
	this.Double = /^[-\+]?\d+(\.\d+)?$/;
	this.English = /^[A-Za-z]+$/;
	this.Chinese =  /^[\u0391-\uFFE5]+$/;
	this.UnSafe = /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/;
	this.IsSafe = function(str){return !this.UnSafe.test(str);};
	this.SafeString = "this.IsSafe(value)";
	this.Filter = "this.DoFilter(value, getAttribute('accept'))";
	this.Limit = "this.limit(value.length,getAttribute('min'),  getAttribute('max'))";
	this.LimitB = "this.limit(this.LenB(value), getAttribute('min'), getAttribute('max'))";
	this.Date = "this.IsDate(value, getAttribute('min'), getAttribute('format'))";
	this.Repeat = "value == document.getElementById(getAttribute('to')).value";
	this.Range = "parseFloat(getAttribute('min')) <= parseFloat(value) && parseFloat(value) <= parseFloat(getAttribute('max'))";
	this.Compare = "this.compare(value,getAttribute('operator'),getAttribute('to'))";
	this.Custom = "this.Exec(value, getAttribute('regexp'))";
	this.Group = "this.MustChecked(getAttribute('name'), getAttribute('min'), getAttribute('max'))";
	this.ErrorItem = [document.forms[0]];
	this.ErrorMessage = ["错误:\t\t\t\t"];
	this.Check = function(theForm, mode){
		var obj = theForm || event.srcElement;
		var count = obj.elements.length;
		this.ErrorMessage.length = 1;
		this.ErrorItem.length = 1;
		this.ErrorItem[0] = obj;
		for(var i=0;i<count;i++){
			with(obj.elements[i]){
				var _dataType = getAttribute("dataType");
				if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined")  continue;
				this.ClearState(obj.elements[i]);
				//if(getAttribute("require") == "false" && value == "") continue;
				switch(_dataType){
					case "Date" :
					case "Repeat" :
					case "Range" :
					case "Compare" :
					case "Custom" :
					case "Group" : 
					case "Limit" :
					case "Filter" :
					case "LimitB" :
					case "SafeString" :
						if(!eval(this[_dataType]))	{
							this.AddError(i, getAttribute("msg"));
						}
						break;
					default :
						if(!this[_dataType].test(value)){
							this.AddError(i, getAttribute("msg"));
						}
						break;
				}
			}
		}
		if(this.ErrorMessage.length > 1){
			mode = mode || 1;
			var errCount = this.ErrorItem.length;
			switch(mode){
				case 2 :
					for(var i=1;i<errCount;i++)
						this.ErrorItem[i].style.color = "red";
				case 1 :
					alert(this.ErrorMessage.join("\n"));
					this.ErrorItem[1].focus();
					break;
				case 3 :
					for(var i=1;i<errCount;i++){
					try{
						var span = document.createElement("SPAN");
						span.id = "__ErrorMessagePanel";
						span.style.color = "red";
						this.ErrorItem[i].parentNode.appendChild(span);
						span.innerHTML = this.ErrorMessage[i].replace(/\d+:/,"*");
						}
						catch(e){alert(e.description);}
					}
					this.ErrorItem[1].focus();
					break;
				default :
					alert(this.ErrorMessage.join("\n"));
					break;
			}
			return false;
		}
		return true;
	};
	this.limit = function(len,min, max){
		min = min || 0;
		max = max || Number.MAX_VALUE;
		return min <= len && len <= max;
	};
	this.LenB = function(str){
		return str.replace(/[^\x00-\xff]/g,"**").length;
	};
	this.ClearState = function(elem){
		with(elem){
			if(style.color == "red")
				style.color = "";
			var lastNode = parentNode.childNodes[parentNode.childNodes.length-1];
			if(lastNode.id == "__ErrorMessagePanel")
				parentNode.removeChild(lastNode);
		}
	};
	this.AddError = function(index, str){
		this.ErrorItem[this.ErrorItem.length] = this.ErrorItem[0].elements[index];
		this.ErrorMessage[this.ErrorMessage.length] = this.ErrorMessage.length + ":" + str;
	};
	this.Exec = function(op, reg){
		return new RegExp(reg,"g").test(op);
	};
	this.compare = function(op1,operator,op2){
		switch (operator) {
			case "NotEqual":
				return (op1 != op2);
			case "GreaterThan":
				return (op1 > op2);
			case "GreaterThanEqual":
				return (op1 >= op2);
			case "LessThan":
				return (op1 < op2);
			case "LessThanEqual":
				return (op1 <= op2);
			default:
				return (op1 == op2);            
		}
	},
	this.MustChecked = function(name, min, max){
		var groups = document.getElementsByName(name);
		var hasChecked = 0;
		min = min || 1;
		max = max || groups.length;
		for(var i=groups.length-1;i>=0;i--)
			if(groups[i].checked) hasChecked++;
		return min <= hasChecked && hasChecked <= max;
	};
	this.DoFilter = function(input, filter){
	this.exp_str1 = filter.split(",").join("|");
	this.exp_str2 = exp_str1.replace(/\s+/g,"");
		return new RegExp("^.+\.(?=EXT)(EXT)$".replace(/EXT/g, exp_str2), "gi").test(input);
	};
	this.IsDate = function(op, formatString){
		formatString = formatString || "ymd";
		var m, year, month, day;
		switch(formatString){
			case "ymd" :
				m = op.match(new RegExp("^((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})$"));
				if(m == null ) return false;
				day = m[6];
				month = m[5]--;
				year =  (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
				break;
			case "dmy" :
				m = op.match(new RegExp("^(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))$"));
				if(m == null ) return false;
				day = m[1];
				month = m[3]--;
				year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10));
				break;
			default :
				break;
		}
		if(!parseInt(month)) return false;
		month = month==12 ?0:month;
		var date = new Date(year, month, day);
        return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate());
		function GetFullYear(y){return ((y<30 ? "20" : "19") + y)|0;}
	}
} 