/*
 * copy from http://www.json.org/json.js
 * modified by hobo at 2007-4-19 to fix ie5
 */

if (!Object.prototype.toJSONString)
{
	Boolean.prototype.toJSONString = Date.prototype.toJSONString
		= Number.prototype.toJSONString = function()
	{
		return this.toString();
	};

	Array.prototype.toJSONString = function()
	{
		var a = ['['], b, i, l = this.length, v;

		function p(s)
		{
			if (b)
			{
				a.push(',');
			}
			a.push(s);
			b = true;
		}

		for (i = 0; i < l; i += 1)
		{
			v = this[i];
			switch (typeof v)
			{
				case 'object':
					if (v)
					{
						if (typeof v.toJSONString === 'function')
						{
							p(v.toJSONString());
						}
					}
					else
					{
						p("null");
					}
					break;

				case 'string':
				case 'number':
				case 'boolean':
					p(v.toJSONString());
			}
		}

		a.push(']');
		return a.join('');
	};

	Object.prototype.toJSONString = function()
	{
		var a = ['{'], b, k, v;

		function p(s)
		{
			if (b)
			{
				a.push(',');
			}
			a.push(k.toJSONString(), ':', s);
			b = true;
		}

		for (k in this)
		{
			v = this[k];
			switch (typeof v)
			{
				case 'object':
					if (v) {
						if (typeof v.toJSONString === 'function')
						{
							p(v.toJSONString());
						}
					}
					else
					{
						p("null");
					}
					break;

				case 'string':
				case 'number':
				case 'boolean':
					p(v.toJSONString());
			}
		}

		a.push('}');
		return a.join('');
	};

	String.prototype.toJSONString = function()
	{
		var m = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};

		if (/["\\\x00-\x1f]/.test(this))
		{
			return '"' + this.replace(/([\x00-\x1f\\"])/g, function (a, b) {
				var c = m[b];
				if (c)
				{
					return c;
				}
				c = b.charCodeAt();
				return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
			}) + '"';
		}

		return '"' + this + '"';
	};

	String.prototype.parseJSON = function ()
	{
		try
		{
			return eval('(' + this + ')');
		}
		catch (e)
		{
			return null;
		}
	};

	Array.prototype.jsonSort = function(field, order)
	{
		var _property = field;
		var _desc = order && order.toLowerCase()=="desc";

		return this.sort(function(a, b)
		{
			if (a[_property] < b[_property])
			{
				return _desc ? +1 : -1;
			}
			else if (a[_property] > b[_property])
			{
				return _desc ? -1 : +1;
			}
			else
			{
				return 0;
			}
		});
	};
}

/*
 * Created by Hobo <hobowo#tencent.com>
 * Http://www.qq.com/
 */

// Global variable
window.version = "2007-06-29";
window.undefined = window.undefined;
window.debug = false;

//print window error
window.onerror = function(msg, url, line)
{
	if (window.debug)
	{
		var err = "url  ：" + url + "\nline ：" + line + " 行\nerror：" + msg;

		if (!window.confirm(err + "\n\n页面含有如上脚本错误,是否继续报告错误?"))
		{
			window.debug = false;
		}
	}

	return true;
};

//Browser check
var Browser = new Object();

Browser.ua = window.navigator.userAgent.toLowerCase();
Browser.ie = /msie/.test(Browser.ua);
Browser.moz = /gecko/.test(Browser.ua);
Browser.opera = /opera/.test(Browser.ua);

//shortcut method
var $ = function(s)
{
	return (typeof s == "object") ? s: document.getElementById(s);
};

var $N = function(s)
{
	return (typeof s == "object") ? s: document.getElementsByName(s);
};

var $T = function(s)
{
	return (typeof s == "object") ? s: document.getElementsByTagName(s);
};

var $C = function(tag)
{
	return document.createElement(tag);
};

var $A = function(a)
{
	if (!a)
	{
		return new Array();
	}
	else
	{
		var r = new Array();

		for (var i=0; i<a.length; i++)
		{
			r.push(a[i]);
		}

		return r;
	}
};

//Object Prototype extension
String.prototype.trim = function()
{
	return this.replace(/^\s*|\s*$/ig, "");
};

String.prototype.left = function(n)
{
	return this.substr(0, n);
};

String.prototype.empty = function()
{
	return this.trim() == "";
};

String.prototype.stripTags = function()
{
	return this.replace(/<\/?[^>]+>/gi, '');
};

String.prototype.escapeHTML = function()
{
	var div = document.createElement('div');
	var text = document.createTextNode(this);
	div.appendChild(text);
	return div.innerHTML;
};

String.prototype.unescapeHTML = function()
{
	var div = document.createElement('div');
	div.innerHTML = this.stripTags();
	return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
};

String.prototype.toParam = function()
{
	return this.replace(/\r/g, '')
		.replace(/\n/g, "")
		.replace(/\'/g, '\\\'')
		.replace(/\"/g, '&#34;')
		.replace(/</g,"&#60;")
		.replace(/>/g,"&#62;");
};

String.prototype.toTitle = function()
{
	return this.replace(/\r/g, '')
		.replace(/\n/g, "")
		.replace(/\'/g, '&#39;')
		.replace(/\"/g, '&#34;')
		.replace(/</g,"&#60;")
		.replace(/>/g,"&#62;");
};

String.prototype.toValue = function()
{
	return this.replace(/&/g,"&#38;")
		.replace(/\"/g,"&#34;")
		.replace(/\'/g,'&#39;')
		.replace(/</g,"&#60;")
		.replace(/>/g,"&#62;")
		.replace(/\t/g,"")
		.replace(/\n/g,'');
};

String.prototype.toTextareaValue = function()
{
	return this.replace(/&/g,"&#38;")
		.replace(/\"/g,"&#34;")
		.replace(/\'/g,'&#39;')
		.replace(/</g,"&#60;")
		.replace(/>/g,"&#62;")
		.replace(/\t/g,"　");
};

String.format = function(s)
{
	for (var i=1; i<arguments.length; i++)
	{
		s = s.replace(new RegExp("\\{"+(i-1)+"\\}", "g"), arguments[i]);
	}

	return s;
};

if (!String.prototype.localeCompare)
{
	String.prototype.localeCompare = function(s)
	{
		return (this>s) ? 1 : (this<s ? -1 : 0);
	};
}

if (!Array.prototype.pop)
{
	Array.prototype.pop = function()
	{
		return this.length!=0 ? this[--this.length] : null;
	};
}

if (!Array.prototype.push)
{
	Array.prototype.push = function()
	{
		var startLength = this.length;
		
		for (var i = 0; i < arguments.length; i++)
		{
			this[startLength + i] = arguments[i];
		}

		return this.length;
	};
}

if (Array.prototype.shift)
{
	Array.prototype.shift = function()
	{
		var r = this[0];

		for (var i=0; i<this.length-1; i++)
		{
			this[i] = this[i + 1];
		}

		this.length--;
		return r;
	};
}

Array.prototype.sortByAlpha = function()
{
	return this.sort(function(a, b)
	{
		if (a.length < b.length)
		{
			return 1;
		}
		else if (a.length == b.length)
		{
			return b.localeCompare(a);
		}
		else
		{
			return -1;
		}
	});
};

String.prototype.isQQ = function()
{
	return /^[1-9]\d{4,9}$/.test(this);
};

String.prototype.isNumber = function()
{
	return /^[1-9]\d*$/.test(this);
};

Array.prototype.repeat = function()
{
	return /(\x0f[^\x0f]+)\x0f[\s\S]*\1\x0f/
		.test("\x0f" + this.join("\x0f\x0f") + "\x0f");
};

Array.prototype.indexOf = function(o, n)
{
	if (n == null)
	{
		n = 0;
	}
	else if (n < 0)
	{
		n = Math.max(0, this.length + n);
	}

	for (var i=n; i<this.length; i++)
	{
		if (this[i] == o)
		{
			return i;
		}
	}
	
	return -1;
};

Array.prototype.contains = function(o)
{
	return this.indexOf(o) != -1
};

Number.prototype.format = function(n)
{
	if (this.toString().length >= n)
	{
		return this;
	}

	return ((new Array(n).join("0")+(this|0)).slice(-n));
};

Date.prototype.format = function(s)
{
	var o = {
		"y+": this.getFullYear(),
		"M+": this.getMonth()+1,
		"d+": this.getDate(),
		"h+": this.getHours(),
		"m+": this.getMinutes(),
		"s+": this.getSeconds(),
		"q+": Math.floor((this.getMonth()+3)/3),
		"S" : this.getMilliseconds()
	};

	for (var k in o)
	{
		if (new RegExp("("+ k +")").test(s))
		{
			s = s.replace(RegExp.$1, o[k].format(RegExp.$1.length));
		}
	}

	return s;
};

//Math.random extension
if (!window._rnd)
{
	window._rnd = Math.random;

	Math.random = function(n)
	{
		if (n == undefined)
		{
			return window._rnd();
		}
		else if (n.toString().match(/^\-?\d*$/g))
		{
			return Math.ceil(window._rnd() * n);
		}
		else
		{
			return null;
		}
	};
}

//window.setTimeout extension
if (!window._sT)
{
	window._sT = window.setTimeout;

	window.setTimeout = function(fCallback, nDelay, oObject)
	{
		if (typeof fCallback == 'function')
		{
			if (!oObject)
			{
				oObject = window;
			}

			var argu = Array.prototype.slice.call(arguments, 3);
			var newFunc = (function(){ fCallback.apply(oObject, argu); });

			return window._sT(newFunc, nDelay);
		}

		return window._sT(fCallback, nDelay);
	};
}

//Function.bind
Function.prototype.bind = function()
{
	var _this = this, args = $A(arguments), object = args.shift();

	return function()
	{
		return _this.apply(object, args);
	};
};

//Function.call & Function.apply (ie5)
if (!Function.prototype.call)
{
	Function.prototype.apply = function(object, argu)
	{
		object = object || window;
		argu = argu || new Array();

		try
		{
			object.__apply__ = this;
			var result = eval("object.__apply__(" + argu.join(", ") + ")");
			object.__apply__ = null;
		}
		catch (e)
		{
			var result = this(argu[0], argu[1], argu[2], argu[3], argu[4]);
		}

		return result;
	};

	Function.prototype.call = function()
	{
		var args = $A(arguments), object = args.shift();

		return this.apply(object, args)
	};
}

//Mozilla browser Event*HTMLElement extension
if (Browser.moz)
{
	var GetEvent = function()
	{
		var _f = GetEvent.caller;

		while (_f)
		{
			if (_f.arguments[0])
			{
				var _fac = _f.arguments[0].constructor;

				if (_fac==Event || _fac==MouseEvent || _fac==KeyboardEvent)
				{
					return _f.arguments[0];
				}
			}

			_f = _f.caller;
		}

		return null;
	};

	window.constructor.prototype.__defineGetter__("event", function()
	{
		return GetEvent();
	});

	Window.prototype.attachEvent =HTMLElement.prototype.attachEvent
		= Node.prototype.attachEvent = function(sType, fHandler)
	{
		this.addEventListener(sType.replace(/^on/i, ""), fHandler, false);
	};

	Window.prototype.detachEvent = HTMLElement.prototype.detachEvent
		= Node.prototype.detachEvent = function(sType, fHandler)
	{
		this.removeEventListener(sType.replace(/^on/i, ""), fHandler, false);
	};
}

//Switch
var Switch = {
	set: function(s, v)
	{
		return this[s] = v ? true : false;
	},

	get: function(s)
	{
		return this[s] ? this[s] : (this[s] = false);
	},

	toggle: function(s)
	{
		return this[s] ? this[s]=!this[s] : (this[s] = true);
	}
};

//Element
var Element = {
	isEmpty: function(e)
	{
		return /^\s*$/.test($(e).innerHTML);
	},

	isVisible: function(e)
	{
		return $(e).style.display != 'none';
	},

	show: function()
	{
		for (var i=0; i<arguments.length; i++)
		{
			$(arguments[i]).style.display = "block";
		}
	},

	hide: function()
	{
		for (var i=0; i<arguments.length; i++)
		{
			$(arguments[i]).style.display = "none";
		}
	},

	toggle: function()
	{
		for (var i=0; i<arguments.length; i++)
		{
			Element[Element.isVisible($(arguments[i])) ? 'hide': 'show']($(arguments[i]));
		}
	},

	remove: function()
	{
		for (var i=0; i<arguments.length; i++)
		{
			try
			{
				$(arguments[i]).parentNode.removeChild($(arguments[i]));
			}
			catch (e)
			{
			}
		}
	},

	create: function(parent, tag, attr)
	{
		var _e = $C(tag);

		for (var i=0; i<attr.length; i++)
		{
			_e.setAttribute(attr[i][0], attr[i][1]);
		}

		$(parent).appendChild(_e);
	},

	getElementWidth: function(e)
	{
		return $(e).offsetWidth;
	},

	getElementHeight: function(e)
	{
		return $(e).offsetHeight;
	},

	getElementLeft: function(e)
	{
		return (e==null) ? 0 : ($(e).offsetLeft + Element.getElementLeft($(e).offsetParent));
	},

	getElementTop: function(e)
	{
		return (e==null) ? 0 : ($(e).offsetTop + Element.getElementTop($(e).offsetParent));
	},

	scrollIntoView: function(e)
	{
		var x = Element.getElementLeft(e);
		var y = Element.getElementTop(e);
		window.scrollTo(x, y);
	}
};

//UrlParser
var UrlParser = function(sUrl)
{
	this.__construct(sUrl);
};

UrlParser.prototype = {
	__construct: function(sUrl)
	{
		this._href = sUrl || document.location.href;
	},

	getDomain: function()
	{
		if (this._href.match(new RegExp('^(([a-z]+)://([^\\/]+)\/?)(.*)', 'i')))
		{
			return RegExp.$1;
		}
		else
		{
			return null;
		}
	},

	getParam: function(sName)
	{
		if (this._href.match(new RegExp("(&|\\u003F|#)" + sName + "=([^&#]*)(&|$|#)")))
		{
			return RegExp.$2;
		}
		else
		{
			return null;
		}
	}
};

UrlParser.getInstance = function()
{
	if (!this.__instance__)
	{
		this.__instance__ = new UrlParser();
	};

	return this.__instance__;
};

//Hash
var HashTable = function()
{
	this.__construct();
};

HashTable.prototype = {
	__construct: function()
	{
		this._hash = new Object();
	},

	set: function(key, value, rewrite)
	{
		if (rewrite !== false)
		{
			this._hash[key] = value;
		}
		else if (this.get(key) != null)
		{
			this._hash[key] = value;
		}
	},

	get: function(key)
	{
		if (typeof this._hash[key] != "undefined")
		{
			return this._hash[key];
		}
		else
		{
			return null;
		}
	},

	remove: function(key)
	{
		delete this._hash[key];
	}
};

HashTable.getInstance = function()
{
	if (!this.__instance__)
	{
		this.__instance__ = new HashTable();
	};

	return this.__instance__;
};

//XmlHttp object
var XmlHttp = function()
{
	if (Browser.ie)
	{
		var msxmls = ["MSXML3", "MSXML2", "Microsoft"];

		for (var i=0; i<msxmls.length; i++)
		{
			try
			{
				return new ActiveXObject(msxmls[i] + ".XmlHttp");
			}
			catch (e)
			{
			}
		}
	}
	else
	{
		return new XMLHttpRequest();
	}
};

//AsynLoader
var AsynLoader = {
	config: {
		queueCount: 5,  
		curQueue: 0     
	},

	load: function(sUrl, oOption)
	{
		AsynLoader.initOption(oOption);

		if (AsynLoader.config.curQueue >= AsynLoader.config.queueCount)
		{
			if (typeof oOption.onQueue == "function")
			{
				oOption.onQueue();
			}

			window.setTimeout(AsynLoader.load, 100, window, sUrl, oOption);
			return;
		}
		else
		{
			AsynLoader.config.curQueue++;
		}

		var xmlHttp = new XmlHttp();
		xmlHttp.open(oOption.method, sUrl, true);
		var _loadCount = 0;

		xmlHttp.onreadystatechange = function()
		{
			if (xmlHttp.readyState == 4)
			{
				if (_loadCount == 0)
				{
					_loadCount++;
					AsynLoader.config.curQueue--;

					if (AsynLoader.isSuccess(xmlHttp))
					{
						var _xmlHttp = {
							status: xmlHttp.status,
							responseXML: xmlHttp.responseXML,
							responseText: xmlHttp.responseText,
							responseJS: xmlHttp.responseText.parseJSON()
						};

						oOption.onSuccess(_xmlHttp);
					}
					else
					{
						if (--oOption.decay)
						{
							AsynLoader.load(sUrl, oOption);
						}
						else
						{
							if (typeof oOption.onFailure == "function")
							{
								oOption.onFailure(_xmlHttp);
							}
						}
					}
				}
			}
		}

		xmlHttp.send(oOption.data);
	},

	initOption: function(oOption)
	{
		oOption.method = (typeof oOption.data == "undefined" || oOption.data == null) ? "get" : "post";
		oOption.asyn = oOption.asyn || true;
		oOption.decay = oOption.decay || 1;

		if (typeof oOption.data != "string" && oOption.data != null)
		{
			oOption.data = oOption.data.toJSONString();
		}
		else if (typeof oOption.data == "undefined")
		{
			oOption.data = null;
		}
	},

	isSuccess: function(oXmlHttp)
	{
		return oXmlHttp.status == undefined
			|| oXmlHttp.status == 0
			|| (oXmlHttp.status >= 200 && oXmlHttp.status < 300);
	}
};

//ProxyLoader
var ProxyLoader = {
	config: {
		queueCount: 5,  
		curQueue: 0,
		proxyStatus: {},
		proxyQueue: {}
	},

	load: function(sUrl, oOption)
	{
		var proxyDomain = new UrlParser(sUrl).getDomain();
		var proxyPage = proxyDomain + "proxy.html";
		var proxyFrames = document.getElementsByTagName("iframe");

		for (var i=0; i<proxyFrames.length; i++)
		{
			if (proxyFrames[i].src == proxyPage)
			{
				if (typeof ProxyLoader.config.proxyStatus[proxyDomain] != "undefined")
				{
					if (Browser.ie)
					{
						window.frames[i].AsynLoader.load(sUrl, oOption);
					}
					else
					{
						proxyFrames[i].contentWindow.AsynLoader.load(sUrl, oOption);
					}
				}
				else
				{
					if (typeof ProxyLoader.config.proxyQueue[proxyDomain] == "undefined")
					{
						ProxyLoader.config.proxyQueue[proxyDomain] = new Array();
					}

					ProxyLoader.config.proxyQueue[proxyDomain].push(new Array(sUrl, oOption));
				}

				return;
			}
		}

		if (typeof ProxyLoader.config.proxyQueue[proxyDomain] == "undefined")
		{
			ProxyLoader.config.proxyQueue[proxyDomain] = new Array();
		}
		ProxyLoader.config.proxyQueue[proxyDomain].push(new Array(sUrl, oOption));

		ProxyLoader.createProxyPage(proxyPage);
	},

	createProxyPage: function(proxyPage)
	{
		var proxyFrames = document.getElementsByTagName("iframe");

		for (var i=0; i<proxyFrames.length; i++)
		{
			if (proxyFrames[i].src == proxyPage)
			{
				return;
			}
		}

		var _iframe = document.createElement("iframe");

		_iframe.style.display = "none";
		_iframe.src = proxyPage;

		try
		{
			$("proxy").appendChild(_iframe);
		}
		catch (e)
		{
			if (typeof Object.prototype.isPrototypeOf == "undefined")
			{
				document.getElementsByTagName("body")[0].innerHTML += _iframe.outerHTML;
			}
			else
			{
				document.getElementsByTagName("body")[0].appendChild(_iframe);
			}
		}

	}
};

//JsLoader
var JsLoader = {
	load: function(sId, sUrl, fCallback)
	{
		Element.remove(sId);

		var _script = document.createElement("script");
		_script.setAttribute("id", sId);
		_script.setAttribute("type", "text/javascript");
		_script.setAttribute("src", sUrl);
		document.getElementsByTagName("head")[0].appendChild(_script);

		if (Browser.ie)
		{
			_script.onreadystatechange = function()
			{
				if (this.readyState=="loaded" || this.readyState=="complete")
				{
					Element.remove(_script);
					fCallback();
				}
			};
		}
		else if (Browser.moz)
		{
			_script.onload = function()
			{
				Element.remove(_script);
				fCallback();
			};
		}
		else
		{
			Element.remove(_script);
			fCallback();
		}
	}
};


//Cookie operate
var Cookie = {
	setCookie: function(name, value, expires, path, domain)
	{
		document.cookie = name + "=" + escape(value) +
			((expires) ? "; expires=" + expires.toGMTString() : "") +
			((path) ? "; path=" + path : "; path=/") +
			((domain) ? "; domain=" + domain : "");
	},

	getCookie: function(name)
	{
		var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));

		if (arr != null)
		{
			return unescape(arr[2]);
		
		}

		return null;
	},

	clearCookie: function(name, path, domain)
	{
		if (Cookie.getCookie(name))
		{
			document.cookie = name + "=" +
				((path) ? "; path=" + path : "; path=/") +
				((domain) ? "; domain=" + domain : "") +
				";expires=Fri, 02-Jan-1970 00:00:00 GMT";
		}
	},

	getUserUin: function()
	{
		var tmp = Cookie.getCookie('uin');
		if (!tmp)
		{
			return '';
		}
		var uin = '';
		var start = 0;
		for (i = 0; i < tmp.length; ++i)
		{
			var c = tmp.charAt(i);
			if (c == 'o' || c == '0' && start == 0)
			{
				continue;
			}
			else
			{
				start = 1;
				uin += c;
			}
		}
		return uin;
	}
};


/*
 * copy from http://www.trimpath.com/
 * modified by hobo at 2006-12-6  add blockType "while"
 */

var TrimPath;

(function()
{
	if (TrimPath == null)
	{
		TrimPath = new Object();
	}

	if (TrimPath.evalEx == null)
	{
		TrimPath.evalEx = function(src) { return eval(src); };
	}

	var UNDEFINED;

	if (Array.prototype.pop == null)
	{
		Array.prototype.pop = function()
		{
			if (this.length === 0)
			{
				return UNDEFINED;
			}

			return this[--this.length];
		};
	}

	if (Array.prototype.push == null)
	{
		Array.prototype.push = function()
		{
			for (var i = 0; i < arguments.length; ++i)
			{
				this[this.length] = arguments[i];
			}

			return this.length;
		};
	}

	TrimPath.parseTemplate = function(tmplContent, optTmplName, optEtc)
	{
		if (optEtc == null)
		{
			optEtc = TrimPath.parseTemplate_etc;
		}

		var funcSrc = parse(tmplContent, optTmplName, optEtc);
		var func = TrimPath.evalEx(funcSrc, optTmplName, 1);

		if (func != null)
		{
			return new optEtc.Template(optTmplName, tmplContent, funcSrc, func, optEtc);
		}

		return null;
	}

	try
	{
		String.prototype.process = function(context, optFlags)
		{
			var template = TrimPath.parseTemplate(this, null);

			if (template != null)
			{
				return template.process(context, optFlags);
			}

			return this;
		}
	}
	catch (e)
	{
	}

	TrimPath.parseTemplate_etc = {};
	TrimPath.parseTemplate_etc.statementTag = "while|forelse|for|if|elseif|else|var|macro";
	TrimPath.parseTemplate_etc.statementDef = {
		"if":
		{
			delta: 1,
			prefix: "if (", suffix: ") {",
			paramMin: 1
		},
		"else": { delta:  0, prefix: "} else {" },
		"elseif": { delta:  0, prefix: "} else if (", suffix: ") {", paramDefault: "true" },
		"/if": { delta: -1, prefix: "}" },
		"while": {
			delta: 1,
			prefix: "while (",
			suffix: ") {",
			paramMin: 1
		},
		"/while": { delta: -1, prefix: "}" },
		"for": {
			delta: 1,
			paramMin: 3,
			prefixFunc : function(stmtParts, state, tmplName, etc)
			{
				if (stmtParts[2] != "in")
					throw new etc.ParseError(tmplName, state.line, "bad for loop statement: " + stmtParts.join(' '));
				var iterVar = stmtParts[1];
				var listVar = "__LIST__" + iterVar;
				return [ "var ", listVar, " = ", stmtParts[3], ";",
					"var __LENGTH_STACK__;",
					"if (typeof(__LENGTH_STACK__) == 'undefined' || !__LENGTH_STACK__.length) __LENGTH_STACK__ = new Array();",
					"__LENGTH_STACK__[__LENGTH_STACK__.length] = 0;",
					"if ((", listVar, ") != null) { ",
					"var ", iterVar, "_ct = 0;",
					"for (var ", iterVar, "_index in ", listVar, ") { ",
					iterVar, "_ct++;",
					"if (typeof(", listVar, "[", iterVar, "_index]) == 'function') {continue;}",
					"__LENGTH_STACK__[__LENGTH_STACK__.length - 1]++;",
					"var ", iterVar, " = ", listVar, "[", iterVar, "_index];" ].join("");
			}
		},
		"forelse" : { delta:  0, prefix: "} } if (__LENGTH_STACK__[__LENGTH_STACK__.length - 1] == 0) { if (", suffix: ") {", paramDefault: "true" },
		"/for" : { delta: -1, prefix: "} }; delete __LENGTH_STACK__[__LENGTH_STACK__.length - 1];" },
		"var" : { delta:  0, prefix: "var ", suffix: ";" },
		"macro" : {
			delta:  1,
			prefixFunc : function(stmtParts, state, tmplName, etc)
			{
				var macroName = stmtParts[1].split('(')[0];
				return [ "var ", macroName, " = function",
					stmtParts.slice(1).join(' ').substring(macroName.length),
					"{ var _OUT_arr = []; var _OUT = { write: function(m) { if (m) _OUT_arr.push(m); } }; " ].join('');
			}
		},
		"/macro"  : { delta: -1, prefix: " return _OUT_arr.join(''); };" }
	}
	TrimPath.parseTemplate_etc.modifierDef = {
		"eat" : function(v)
		{
			return "";
		},
		"escape" : function(s)
		{
			return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
		},
		"capitalize" : function(s)
		{
			return String(s).toUpperCase();
		},
		"default" : function(s, d)
		{
			return s != null ? s : d;
		}
	}

	TrimPath.parseTemplate_etc.modifierDef.h = TrimPath.parseTemplate_etc.modifierDef.escape;

	TrimPath.parseTemplate_etc.Template = function(tmplName, tmplContent, funcSrc, func, etc)
	{
		this.process = function(context, flags)
		{
			if (context == null)
			{
				context = {};
			}
			if (context._MODIFIERS == null)
			{
				context._MODIFIERS = {};
			}
			if (context.defined == null)
			{
				context.defined = function(str) { return (context[str] != undefined); };
			}
			for (var k in etc.modifierDef)
			{
				if (context._MODIFIERS[k] == null)
				{
					context._MODIFIERS[k] = etc.modifierDef[k];
				}
			}
			if (flags == null)
			{
				flags = {};
			}
			var resultArr = [];
			var resultOut = { write: function(m) { resultArr.push(m); } };
			try
			{
				func(resultOut, context, flags);
			}
			catch (e)
			{
				if (flags.throwExceptions == true)
				{
					throw e;
				}
				var result = new String(resultArr.join("") + "[ERROR: " + e.toString() + (e.message ? '; ' + e.message : '') + "]");
				result["exception"] = e;
				return result;
			}

			return resultArr.join("");
		}

		this.name = tmplName;
		this.source = tmplContent;
		this.sourceFunc = funcSrc;
		this.toString = function() { return "TrimPath.Template [" + tmplName + "]"; }
	}

	TrimPath.parseTemplate_etc.ParseError = function(name, line, message)
	{
		this.name = name;
		this.line = line;
		this.message = message;
	}

	TrimPath.parseTemplate_etc.ParseError.prototype.toString = function()
	{
		return ("TrimPath template ParseError in " + this.name + ": line " + this.line + ", " + this.message);
	}

	var parse = function(body, tmplName, etc)
	{
		body = cleanWhiteSpace(body);
		var funcText = [ "var TrimPath_Template_TEMP = function(_OUT, _CONTEXT, _FLAGS) { with (_CONTEXT) {" ];
		var state	= { stack: [], line: 1 };
		var endStmtPrev = -1;

		while (endStmtPrev + 1 < body.length)
		{
			var begStmt = endStmtPrev;
			begStmt = body.indexOf("{", begStmt + 1);

			while (begStmt >= 0)
			{
				var endStmt = body.indexOf('}', begStmt + 1);
				var stmt = body.substring(begStmt, endStmt);
				var blockrx = stmt.match(/^\{(cdata|minify|eval)/);

				if (blockrx)
				{
					var blockType = blockrx[1];
					var blockMarkerBeg = begStmt + blockType.length + 1;
					var blockMarkerEnd = body.indexOf('}', blockMarkerBeg);

					if (blockMarkerEnd >= 0)
					{
						var blockMarker;

						if( blockMarkerEnd - blockMarkerBeg <= 0 )
						{
							blockMarker = "{/" + blockType + "}";
						}
						else
						{
							blockMarker = body.substring(blockMarkerBeg + 1, blockMarkerEnd);
						}

						var blockEnd = body.indexOf(blockMarker, blockMarkerEnd + 1);

						if (blockEnd >= 0)
						{
							emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
							var blockText = body.substring(blockMarkerEnd + 1, blockEnd);

							if (blockType == 'cdata')
							{
								emitText(blockText, funcText);
							}
							else if (blockType == 'minify')
							{
								emitText(scrubWhiteSpace(blockText), funcText);
							}
							else if (blockType == 'eval')
							{
								if (blockText != null && blockText.length > 0)
								{
									funcText.push('_OUT.write( (function() { ' + blockText + ' })() );');
								}
							}

							begStmt = endStmtPrev = blockEnd + blockMarker.length - 1;
						}
					}
				}
				else if (body.charAt(begStmt - 1) != '$' && body.charAt(begStmt - 1) != '\\')
				{
					var offset = (body.charAt(begStmt + 1) == '/' ? 2 : 1);

					if (body.substring(begStmt + offset, begStmt + 10 + offset).search(TrimPath.parseTemplate_etc.statementTag) == 0)
					{
						break;
					}
				}

				begStmt = body.indexOf("{", begStmt + 1);
			}

			if (begStmt < 0)
			{
				break;
			}

			var endStmt = body.indexOf("}", begStmt + 1);

			if (endStmt < 0)
			{
				break;
			}
			
			emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
			emitStatement(body.substring(begStmt, endStmt + 1), state, funcText, tmplName, etc);
			endStmtPrev = endStmt;
		}

		emitSectionText(body.substring(endStmtPrev + 1), funcText);
		if (state.stack.length != 0)
		{
			throw new etc.ParseError(tmplName, state.line, "unclosed, unmatched statement(s): " + state.stack.join(","));
		}
		
		funcText.push("}}; TrimPath_Template_TEMP");
		return funcText.join("");
	}

	var emitStatement = function(stmtStr, state, funcText, tmplName, etc)
	{
		var parts = stmtStr.slice(1, -1).split(' ');
		var stmt = etc.statementDef[parts[0]];

		if (stmt == null)
		{
			emitSectionText(stmtStr, funcText);
			return;
		}

		if (stmt.delta < 0)
		{
			if (state.stack.length <= 0)
			{
				throw new etc.ParseError(tmplName, state.line, "close tag does not match any previous statement: " + stmtStr);
			}

			state.stack.pop();
		}

		if (stmt.delta > 0)
		{
			state.stack.push(stmtStr);
		}

		if (stmt.paramMin != null && stmt.paramMin >= parts.length)
		{
			throw new etc.ParseError(tmplName, state.line, "statement needs more parameters: " + stmtStr);
		}
		
		if (stmt.prefixFunc != null)
		{
			funcText.push(stmt.prefixFunc(parts, state, tmplName, etc));
		}
		else
		{
			funcText.push(stmt.prefix);
		}

		if (stmt.suffix != null)
		{
			if (parts.length <= 1)
			{
				if (stmt.paramDefault != null)
				{
					funcText.push(stmt.paramDefault);
				}
			}
			else
			{
				for (var i = 1; i < parts.length; i++)
				{
					if (i > 1)
					{
						funcText.push(' ');
					}
					
					funcText.push(parts[i]);
				}
			}

			funcText.push(stmt.suffix);
		}
	}

	var emitSectionText = function(text, funcText)
	{
		if (text.length <= 0)
		{
			return;
		}

		var nlPrefix = 0;
		var nlSuffix = text.length - 1;

		while (nlPrefix < text.length && (text.charAt(nlPrefix) == '\n'))
		{
			nlPrefix++;
		}

		while (nlSuffix >= 0 && (text.charAt(nlSuffix) == ' ' || text.charAt(nlSuffix) == '\t'))
		{
			nlSuffix--;
		}

		if (nlSuffix < nlPrefix)
		{
			nlSuffix = nlPrefix;
		}

		if (nlPrefix > 0)
		{
			funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');
			var s = text.substring(0, nlPrefix).replace('\n', '\\n');

			if (s.charAt(s.length - 1) == '\n')
			{
				s = s.substring(0, s.length - 1);
			}

			funcText.push(s);
			funcText.push('");');
		}

		var lines = text.substring(nlPrefix, nlSuffix + 1).split('\n');

		for (var i = 0; i < lines.length; i++)
		{
			emitSectionTextLine(lines[i], funcText);
			if (i < lines.length - 1)
			{
				funcText.push('_OUT.write("\\n");\n');
			}
		}

		if (nlSuffix + 1 < text.length)
		{
			funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');
			var s = text.substring(nlSuffix + 1).replace('\n', '\\n');

			if (s.charAt(s.length - 1) == '\n')
			{
				s = s.substring(0, s.length - 1);
			}

			funcText.push(s);
			funcText.push('");');
		}
	}

	var emitSectionTextLine = function(line, funcText)
	{
		var endMarkPrev = '}';
		var endExprPrev = -1;

		while (endExprPrev + endMarkPrev.length < line.length)
		{
			var begMark = "${", endMark = "}";
			var begExpr = line.indexOf(begMark, endExprPrev + endMarkPrev.length);

			if (begExpr < 0)
			{
				break;
			}

			if (line.charAt(begExpr + 2) == '%')
			{
				begMark = "${%";
				endMark = "%}";
			}

			var endExpr = line.indexOf(endMark, begExpr + begMark.length);

			if (endExpr < 0)
			{
				break;
			}

			emitText(line.substring(endExprPrev + endMarkPrev.length, begExpr), funcText);
			var exprArr = line.substring(begExpr + begMark.length, endExpr).replace(/\|\|/g, "#@@#").split('|');

			for (var k in exprArr)
			{
				if (exprArr[k].replace)
				{
					exprArr[k] = exprArr[k].replace(/#@@#/g, '||');
				}
			}

			funcText.push('_OUT.write(');
			emitExpression(exprArr, exprArr.length - 1, funcText);
			funcText.push(');');
			endExprPrev = endExpr;
			endMarkPrev = endMark;
		}

		emitText(line.substring(endExprPrev + endMarkPrev.length), funcText);
	}

	var emitText = function(text, funcText)
	{
		if (text == null || text.length <= 0)
		{
			return;
		}

		text = text.replace(/\\/g, '\\\\');
		text = text.replace(/\n/g, '\\n');
		text = text.replace(/"/g,  '\\"');
		funcText.push('_OUT.write("');
		funcText.push(text);
		funcText.push('");');
	}

	var emitExpression = function(exprArr, index, funcText)
	{
		var expr = exprArr[index];

		if (index <= 0)
		{
			funcText.push(expr);
			return;
		}

		var parts = expr.split(':');
		funcText.push('_MODIFIERS["');
		funcText.push(parts[0]);
		funcText.push('"](');
		emitExpression(exprArr, index - 1, funcText);

		if (parts.length > 1)
		{
			funcText.push(',');
			funcText.push(parts[1]);
		}

		funcText.push(')');
	}

	var cleanWhiteSpace = function(result)
	{
		result = result.replace(/\t/g, "	");
		result = result.replace(/\r\n/g, "\n");
		result = result.replace(/\r/g, "\n");
		result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1');

		return result;
	}

	var scrubWhiteSpace = function(result)
	{
		result = result.replace(/^\s+/g, "");
		result = result.replace(/\s+$/g, "");
		result = result.replace(/\s+/g, " ");
		result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1');

		return result;
	}

	TrimPath.parseDOMTemplate = function(elementId, optDocument, optEtc)
	{
		if (optDocument == null)
		{
			optDocument = document;
		}

		var element = optDocument.getElementById(elementId);
		var content = element.value;

		if (content == null)
		{
			content = element.innerHTML;
		}

		content = content.replace(/&lt;/g, "<").replace(/&gt;/g, ">");

		return TrimPath.parseTemplate(content, elementId, optEtc);
	}

	TrimPath.processDOMTemplate = function(elementId, context, optFlags, optDocument, optEtc)
	{
		return TrimPath.parseDOMTemplate(elementId, optDocument, optEtc).process(context, optFlags);
	}
})();

var hexcase = 1;
var b64pad = "";
var chrsz = 8;
var mode = 32;
 
function preprocess(form)
{
  var str = "";
  str += form.verifycode.value;
  str = str.toUpperCase();
  form.p.value = md5(md5_3(form.p.value)+str);
  return true;
}

function md5_3(s)
{
  var tmp = new Array;
  tmp = core_md5(str2binl(s), s.length * chrsz);
  tmp = core_md5(tmp, 16 * chrsz);
  tmp = core_md5(tmp, 16 * chrsz);
  return binl2hex(tmp);
}

function md5(s)
{
  return hex_md5(s);
}
function hex_md5(s)
{
  return binl2hex(core_md5(str2binl(s), s.length * chrsz));
}

function b64_md5(s)
{
  return binl2b64(core_md5(str2binl(s), s.length * chrsz));
}

function str_md5(s)
{
  return binl2str(core_md5(str2binl(s), s.length * chrsz));
}

function hex_hmac_md5(key, data)
{
  return binl2hex(core_hmac_md5(key, data));
}

function b64_hmac_md5(key, data)
{
  return binl2b64(core_hmac_md5(key, data));
}

function str_hmac_md5(key, data)
{
  return binl2str(core_hmac_md5(key, data));
}

function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

function core_md5(x, len)
{
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a = 1732584193;
  var b =  - 271733879;
  var c =  - 1732584194;
  var d = 271733878;

  for (var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i + 0], 7,  - 680876936);
    d = md5_ff(d, a, b, c, x[i + 1], 12,  - 389564586);
    c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
    b = md5_ff(b, c, d, a, x[i + 3], 22,  - 1044525330);
    a = md5_ff(a, b, c, d, x[i + 4], 7,  - 176418897);
    d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
    c = md5_ff(c, d, a, b, x[i + 6], 17,  - 1473231341);
    b = md5_ff(b, c, d, a, x[i + 7], 22,  - 45705983);
    a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
    d = md5_ff(d, a, b, c, x[i + 9], 12,  - 1958414417);
    c = md5_ff(c, d, a, b, x[i + 10], 17,  - 42063);
    b = md5_ff(b, c, d, a, x[i + 11], 22,  - 1990404162);
    a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
    d = md5_ff(d, a, b, c, x[i + 13], 12,  - 40341101);
    c = md5_ff(c, d, a, b, x[i + 14], 17,  - 1502002290);
    b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);

    a = md5_gg(a, b, c, d, x[i + 1], 5,  - 165796510);
    d = md5_gg(d, a, b, c, x[i + 6], 9,  - 1069501632);
    c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
    b = md5_gg(b, c, d, a, x[i + 0], 20,  - 373897302);
    a = md5_gg(a, b, c, d, x[i + 5], 5,  - 701558691);
    d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
    c = md5_gg(c, d, a, b, x[i + 15], 14,  - 660478335);
    b = md5_gg(b, c, d, a, x[i + 4], 20,  - 405537848);
    a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
    d = md5_gg(d, a, b, c, x[i + 14], 9,  - 1019803690);
    c = md5_gg(c, d, a, b, x[i + 3], 14,  - 187363961);
    b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
    a = md5_gg(a, b, c, d, x[i + 13], 5,  - 1444681467);
    d = md5_gg(d, a, b, c, x[i + 2], 9,  - 51403784);
    c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
    b = md5_gg(b, c, d, a, x[i + 12], 20,  - 1926607734);

    a = md5_hh(a, b, c, d, x[i + 5], 4,  - 378558);
    d = md5_hh(d, a, b, c, x[i + 8], 11,  - 2022574463);
    c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
    b = md5_hh(b, c, d, a, x[i + 14], 23,  - 35309556);
    a = md5_hh(a, b, c, d, x[i + 1], 4,  - 1530992060);
    d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
    c = md5_hh(c, d, a, b, x[i + 7], 16,  - 155497632);
    b = md5_hh(b, c, d, a, x[i + 10], 23,  - 1094730640);
    a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
    d = md5_hh(d, a, b, c, x[i + 0], 11,  - 358537222);
    c = md5_hh(c, d, a, b, x[i + 3], 16,  - 722521979);
    b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
    a = md5_hh(a, b, c, d, x[i + 9], 4,  - 640364487);
    d = md5_hh(d, a, b, c, x[i + 12], 11,  - 421815835);
    c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
    b = md5_hh(b, c, d, a, x[i + 2], 23,  - 995338651);

    a = md5_ii(a, b, c, d, x[i + 0], 6,  - 198630844);
    d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
    c = md5_ii(c, d, a, b, x[i + 14], 15,  - 1416354905);
    b = md5_ii(b, c, d, a, x[i + 5], 21,  - 57434055);
    a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
    d = md5_ii(d, a, b, c, x[i + 3], 10,  - 1894986606);
    c = md5_ii(c, d, a, b, x[i + 10], 15,  - 1051523);
    b = md5_ii(b, c, d, a, x[i + 1], 21,  - 2054922799);
    a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
    d = md5_ii(d, a, b, c, x[i + 15], 10,  - 30611744);
    c = md5_ii(c, d, a, b, x[i + 6], 15,  - 1560198380);
    b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
    a = md5_ii(a, b, c, d, x[i + 4], 6,  - 145523070);
    d = md5_ii(d, a, b, c, x[i + 11], 10,  - 1120210379);
    c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
    b = md5_ii(b, c, d, a, x[i + 9], 21,  - 343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  if (mode == 16)
  {
    return Array(b, c);
  }
  else
  {
    return Array(a, b, c, d);
  }
}

function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}

function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}

function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}

function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}

function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if (bkey.length > 16)
    bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for (var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512+data.length * chrsz);
  return core_md5(opad.concat(hash), 512+128);
}

function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

function bit_rol(num, cnt)
{
  return (num << cnt) | (num  >>> (32-cnt));
}

function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for (var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
  return bin;
}

function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for (var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
  return str;
}

function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";

  for (var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8+4)) & 0xF) +
      hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
  }
  return str;
}

function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for (var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) | ((
      (binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) | ((binarray[i
      + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
    for (var j = 0; j < 4; j++)
    {
      if (i * 8+j * 6 > binarray.length * 32)
        str += b64pad;
      else
        str += tab.charAt((triplet >> 6 * (3-j)) & 0x3F);
    }
  }
  return str;
}  
