var Js = {};

Js.ext = {};
Js.lang = {};
Js.util = {};
Js.widget = {};

Js.nue = function(object) {
	if(Jrun.typeOf(object) == "object") {
		var node = {};

		for(var method in object) {
			if(object.hasOwnProperty(method)) {
				node[method] = object[method];
			}
		}
		return node;
	} else {
		return object;
	}
};

// Add a numbers of function to Js.fn
var Jrun = Js.code = {
	// Check browser behaviour to determine whether it's based on IE, IE6, IE7, GECKO, OPERA or KHTML.
	behaviour: function() {
		// Return Object containing Boolean value of each browser object.
		return function() {
			var win = window;
			var doc = document;
			// make sure ie6 or ie7 is either false or true only.
			var items = {
				ie: false,
				ie6: false,
				ie7: false,
				khtml: false,
				gecko: false,
				opera: false
			};
			// detect IE
			items.ie = items[win.XMLHttpRequest ? "ie7" : "ie6"] = (win.ActiveXObject ? true : false);
			// detect KHTML
			items.khtml = ((doc.childNodes && !doc.all && !navigator.taintEnabled) ? true : false);
			// detect Gecko
			items.gecko = (doc.getBoxObjectFor != null ? true : false);
			// detect Opera
			items.opera = (items.opera ? true : false);
			// return the object
			return items;
		}();
	}(),
	// (c) modified based on Douglas Crockford is function (taken from Pro JavaScript Technique - John Resig)
	browser: function() {
		return function() {
			var items = {
				ie: navigator.appName == 'Microsoft Internet Explorer',
				java: navigator.javaEnabled(),
				ns: navigator.appName == 'Netscape',
				ua: navigator.userAgent.toLowerCase(),
				version: parseFloat(navigator.appVersion.substr(21)) || parseFloat(navigator.appVersion),
				win: navigator.platform == 'Win32',
				opera: false,
				gecko: false,
				mac: false
			};
			items.mac = items.ua.indexOf('mac') >= 0;

			if(items.ua.indexOf('opera') >= 0) {
				items.ns = items.ie = false;
				items.opera = true;
			}
			if(items.ua.indexOf('gecko') >= 0) {
				items.ie = items.ns = false;
				items.gecko = true;
			}

			return items;
		}();
	}(),
	camelize: function(values) {
		var data = values.split(/\-/);

		if(data.length) {
			return data[0];
		}

		var value = (values.indexOf('-') == 0 ? data[0].charAt(0).toUpperCase() + data[0].substr(1) : data[0]);

		for(var i = 1; i < data.length && data[i]; i++) {
			value += data[i].charAt(0).toUpperCase() + data[i].substr(1);
		}

		return value;
	},
	// create a callback function for node
	callback: function(node, fn, args) {
		if(this.isfunction(fn)) {
			try {
				// try to use apply (support multiple arguments)
				var args = this.toArray(arguments, 2);
				fn.apply(node, args);
			} catch(e) {
				// alternatively use call, but only can support one arguments
				fn.call(node, args);
			}
		}
		return node;
	},
	// loop callback function to each of the node
	each: function(node, fn) {
		if(this.isfunction(fn)) {
			// loop each node (node should be an array)
			for(var i = 0; i < node.length && !!node[i]; i++) {
				try {
					fn.apply(node[i], [node[i], i]);
				} catch(e) {
					// alternatively use call, but only can support one arguments
					try {
						fn.call(node[i], node[i] + "," + i);
					} catch(e) {
						fn(node[i], i);
					}
				}
			}
		}
	},
	// finds whether HTML Elements existed.
	finds: function(element) {
		return (document.getElementById(this.trim(element)) ? true : false);
	},
	// prepare whether object or element have been send
	prepare: function(node, element, value) {
		var value = (this.isset(value) && value.match(/(object|element)/g) ? value : "element");
		var data = [this.isset(node), this.isset(element)];

		return (function(node, element, value, data) {
			if(data[0] && data[1]) {
				// both first and second are equal
				return (Js.attr.get(node, "id") == elem ? (value == "object" ? node : element) : false);
			} else if(data[1]) {
				// return second element
				return (value == "object" ? document.getElementById(element) : element);
			} else if(data[0]) {
				// return first element
				return (value == "object" ? node : Js.attr.get(node, "id"));
			} else {
				// all failed
				return false;
			}
		})(node, element, value, data);
	},
	// Load a URL location using JavaScript,
	// equivalent to JavaScript native location.href.
	href: function(url, target) {
		try {

			if(this.isnull(target)) {
				// load new URL in same window
				window.location.href = url;
			} else {
				// load new URL in a new window
				window.open(url, target);
			}
		} catch(e) {
			Js.debug.log("Jrun.href() failed: " + e);
		}
	},
	// Convert all string characters to HTML entities
	htmlEntities: function(value) {
		return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\+/g, "&#43;");
	},
	htmlEntityDecode: function(value) {
		return value.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&#43;/g, "+");
	},
	// Get the indexOf based array's value
	'indexOf': function(data, value) {
		for(var i = data.length; i-- && data[i] !== value;);
		return i;
	},
	// Check whether the value is in an array
	inArray: function(data, value) {
		// loop the array to check each of it's value
		for(var i = 0; i < data.length && !!data[i]; i++) {
			if(data[i] === value) {
				return true;
				break;
			}
		}
		return false;
	},
	// Check whether the object is null or undefined.
	isnull: function(value) {
		// false if the object is defined and true if null/undefined.
		return (typeof(value) == "undefined" || value == null);
	},
	// Check whether the object is defined and not null.
	isset: function(value) {
		// true if the object is defined and false if null/undefined.
		return (this.isnull(value) ? false : true);
	},
	isfunction: function(value) {
		return ((!!value && typeof(value) === "function") ? true : false);
	},
	// Trim left of a string.
	ltrim: function(value) {
		return new String(value).replace(/^\s+/g, "");
	},
	// create a event handler function for any HTML Element
	on: function(node, handler, fn1, fn2) {
		var handler = this.trim(handler);
		try {
			if(!!node && node !== document) {
				if(handler === "hover") {
					// Add special event handler for "hover"
					if(this.isfunction(fn1)) {
						node["onmouseover"] = fn1;
					}
					if(this.isfunction(fn2)) {
						node["onmouseout"] = fn2;
					}
				} else {
					// Anything else
					if(this.isfunction(fn1)) {
						node["on" + handler] = fn1;
					} else {
						return node["on" + handler];
					}
				}
			}
		} catch(e) {
			Js.debug.log("Jrun.on: " + e);
		}
	},
	// Loop each option until find an option which does not return null and return it.
	pick: function(value) {
		var data = arguments;
		// loop all arguments.
		for(var i = 0; i < data.length; i++) {
			// Return the first option/n-option only if the previous option return null.
			if(this.isset(data[i])) {
				return data[i];
			}
		}
		return null;
	},
	prettyList: function(data, between, last) {
		var length = data.length;
		var value = new String;
		if(length > 1) {
			for(var i = 0; i < (length - 1); i++) {
				value = value + (i == 0 ? "" : between).data[i];
			}
			value = value + last + data[(length - 1)];
		} else {
			value = data[0];
		}

		return value;
	},
	rand: function(args) {
		var args = this.toArray(arguments);
		var length = 0;
		var offset = 0;

		if(args.length === 2) {
			offset = args[0];
			length = args[1];
		} else if(args.length === 1) {
			length = args[0];
		}
		return (Math.floor(Math.random() * length) + offset);
	},
	// Trim right of a string.
	rtrim: function(value) {
		return new String(value).replace(/\s$/g, "");
	},
	stripTags: function(value) {
		return new String(value).replace(/<([^>]+)>/g, "");
	},
	serialize: function(data) {
		var value = [];

		if(this.typeOf(data) === "array") {
			for(var i = 0; i < data.length && data[i]; i++) {
				if(!!Js.parse) {
					data[i].value = Js.parse.html.to(data[i].value);
				}
				value[value.length] = data[i].name + "=" + data[i].value;
			}
		} else if(this.typeOf(data) == "object") {
			for(var values in data) {
				if(!!Js.parse) {
					data[values] = Js.parse.html.to(data[values]);
				}

				value[value.length] = values + "=" + data[values];
			}
		} else {
			return "";
		}

		return value.join("&");
	},
	// Parse input string value as Number using ParseInt
	toNumber: function(value) {
		// return possible integer value of a string, if not a string then return self
		return (typeof(value) == "string" ? parseInt(value, 10) : value);
	},
	toProperCase: function(value) {
		var data = value.split(/ /g);
		var rdata = [];

		Jrun.each(data, function() {
			var val = this.toString();
			var first = val.substr(0, 1).toUpperCase();
			var other = val.substr(1);
			rdata[rdata.length] = [first, other].join("");
		});

		return rdata.join(" ");
	},
	// convert a object (mainly use for arguments) to array
	// & require on .length to check the length to object to convert
	toArray: function(values, offset) {
		var offset = (this.isnull(offset) || offset < 1 ? 0 : offset);

		// return empty array
		if(this.isnull(values)) {
			return [];
		} else {
			// ensure the offset
			var offsetLength = (values.length - offset);
			var valueLength = values.length;
			var rdata = [];
			// loop and prepare r to be return
			while(offsetLength > 0) {
				--offsetLength;
				--valueLength;
				rdata[offsetLength] = values[valueLength];
			}
			return rdata;
		}
	},
	// Trim both left and right of a string.
	trim: function(value) {
		return new String(value).replace(/^\s+|\s+$/g, "");
	},
	typeOf: function(value) {
		if(typeof(value) == "object") {
			if(value.length > 0 && value[0].nodeType) {
				return "element";
			} else if(value.constructor === Array) {
				return "array";
			} else if(value.nodeType) {
				return "element";
			} else if(value.constructor !== Object) {
				return "function";
			} else {
				return "object";
			}
		} else {
			return typeof(value);
		}
	},
	// return only unique value of an array
	unique: function(data, repeat) {
		// when option equal true it only reject value which is repeating
		var repeat = this.pick(repeat, false);
		var rdata = [];

		for(var i = 0; i < data.length && !!data[i]; i++) {
			if(!repeat) {
				// add only if unique
				if(!this.inArray(rdata, data[i])) {
					rdata[rdata.length] = data[i];
				}
			} else {
				// add only if previous value isn't the same
				if(i == 0) {
					rdata[rdata.length] = data[i];
				} else if(data[i] !== this.trim(data[i - 1])) {
					rdata[rdata.length] = data[i];
				}
			}
		}

		return rdata;
	}
};

Js.base = function() {};
Js.base.prototype = {
	__destruct: function() {
		// remove all properties and method for this object
		for (var method in this) {
			this[method] = null;
		}

		for (var method in this.prototype) {
			this.prototype[method] = null;
		}

		delete this;
		return null;
	}
};

Js.base.create = function(js) {
	var initialize = true;
	var prototype = new Js.base;
	initialize = false;

	function Class() {
		if(!initialize && !!this.construct) {
			this.construct.apply(this, Jrun.toArray(arguments));
		}
	};

	Class.prototype = prototype;
	Class.prototype.construct = Jrun.pick(js.__construct, null);
	Class.constructor = Class;
	Class.extend = function(js) {
		js.ext = this;
		return Js.base.create(js);
	};

	var ext = Jrun.pick(js.ext, null);

	if(Jrun.isset(ext)) {
		try {
			// try to copy parent object.
			(function(js) {
				var list = ["ext", "__construct", "__destruct", "_super", "prototype"];
				// start adding parent method and properties to this object
				for (var method in js.prototype) {
					if (js.prototype.hasOwnProperty(method) && (!Jrun.inArray(list, method) && !this[method])) {
						this[method] = js.prototype[method];
					}
				}
				for (var method in js) {
					if (js.hasOwnProperty(method) && (!Jrun.inArray(list, method) && !this[method])) {
						this[method] = js[method];
					}
				}
				// create a linkage to the parent object
				this._super = js.prototype;
			}).call(prototype, ext);
		} catch(e) {
			Js.debug.log(e);
		}
	}

	// add this object user defined properties and methods
	(function(js) {
		// the following object shouldn't be extended
		var mtd = ["ext", "__construct", "__destruct", "_super", "prototype"];

		// start adding method and properties to this object
		for (var method in js) {
			if (js.hasOwnProperty(method) && (!Jrun.inArray(mtd, method) && !this[method])) {
				this[method] = js[method];
			}
		};
	}).call(prototype, js);

	// avoid this.ext to be duplicated in this.prototype
	delete ext;

	return Class;
};
Js.parse = {
	html: {
		to: function(value) {
			var value = new String(value);
			value = Jrun.htmlEntities(value);
			value = encodeURIComponent(value);
			//value = value.toUpperCase();

			return value;
		},
		from: function(value) {
			var value = new String(value);
			value = decodeURIComponent(value);
			value = Jrun.htmlEntityDecode(value);

			return value;
		}
	},
	// Convert back bbml string to normal string
	bbml: function(value) {
		return new String(value).replace(/\[lt\]/g, "<").replace(/\[gt\]/g, ">").replace(/\[n\]/g, "&").replace(/\&quot\;/g, "\"").replace(/\&rsquo\;/g, "\'").replace(/\[br\]/g, "\n").replace(/\[break\]/g, "<br />");
	},
	response: {
		init: function(reply) {
			var data = eval("(" + reply + ")");
			if(!!data.SUIXHR) {
				Js.parse.response.notice(data);
				Js.parse.response.href(data);
				Js.parse.response.update(data);
			}
		},
		status: function() {
			var r = this.object.status;
			try {
				var local = (!r && location.protocol == 'file:');
				var range = (r >= 200 && r < 300);
				var unmodified = (r == 304);
				var safari = (jQuery.browser.safari && typeof(r) == "undefined");
				return  (local || range || unmodified || safari);
			} catch(e) { }
			return false;
		},
		notice: function(data) {
			var note = Jrun.pick(data.notice);

			if(Jrun.isset(note) && note !== "") {
				window.alert(note);
			}
		},
		href: function(data) {
			var href = Jrun.pick(data.href);
			var xhref = Jrun.pick(data.xhref);
			if(Jrun.isset(xhref) && href !== "") {
				Jrun.href(xhref, "_blank");
			} else if(Jrun.isset(href) && href !== "") {
				Jrun.href(href);
			}
		},
		update: function(data) {
			var args = Jrun.pick(data.text, null);
			var id = Jrun.pick(data.id, null);
			var object = Jrun.pick(data.exec, data.callback, null);

			if(!!args) {
				if(!!id && typeof(id) === "string") {
					jQuery("#" + id).html(Js.parse.bbml(args));
				} else if(Jrun.isset(object)) {
					var func = eval(object);
					func(args);

					//(window.evalScript ? window.evalScript : eval).apply(window, [object + '(' + args + ');']);
					//object(args);
				}
			}
		}
	}
};

Js.test = {
	isString: function(value) {
		return (typeof(value) == "string" && isNaN(value));
	},
	isInteger: function(value) {
		return !isNaN(value);
	},
	isNumber: function(value) {
		return this.isInteger(value);
	},
	isEmail: function(value) {
		return (value.match(/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/));
	},
	isLength: function(datas, value) {
		var data = datas.split(/\-/);
		var length = Jrun.toNumber(data[1]);
		var rdata = null;

		if(data[0] === "max") {
			rdata = (value <= length ? true : false);
		} else if(data[0] === "min") {
			rdata = (value >= length ? true : false);
		} else if(data[0] === "exact") {
			rdata = (value == length ? true : false);
		} else {
			rdata = true;
		}

		return rdata;
	},
	isURL: function(value) {
		return (value.match(/^https?:\/\/([a-z0-9-]+\.)+[a-z0-9]{2,4}.*$/));
	},
	isIpAddress: function(value) {
		return (value.match(/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/));
	}
};
Js.ext.form = function() {
	this.first = null;
	this.object = null;
	return this;
};
Js.ext.form.prototype = {
	validate: function(node, custom) {
		this.object = jQuery(node);

		var formId = this.object.attr("id");
		var custom = custom || null;
		var post = "";

		this.first = null;
		var that = this;

		if(!!this.object) {
			jQuery(":input", this.object).each(function() {
				var errorNode = jQuery(this).siblings("span.extform-errormessage").eq(0);
				if(errorNode.length == 1) {
					errorNode.remove();
				}

				if(this.tagName.toLowerCase().match(/^(input|select|textarea)$/g)) {
					if(this.name != "") {
						this.className = (!!this.className ? this.className : "");
						var klass = this.className.split(/\s/);
						var error = "";

						if(!!Jrun.inArray(klass, "required") && jQuery.trim(this.value) === "") {
							error = Js.lang.form.required;
						}

						if(!!Jrun.inArray(klass, "string") && !Js.test.isString(this.value) && Jrun.trim(this.value) !== "") {
							error = Js.lang.form.string;
						} else if((!!Jrun.inArray(klass, "integer") || !!Jrun.inArray("number", klass)) && !Js.test.isInteger(this.value) && Jrun.trim(this.value) !== "") {
							error = Js.lang.form.number;
						} else if(!!Jrun.inArray(klass, "email") && !Js.test.isEmail(this.value) && Jrun.trim(this.value) !== "") {
							error = Js.lang.form.email;
						}

						if(Jrun.isset(custom)) {
							var validate = custom[jQuery(this).attr("id")];

							if(Jrun.isset(validate)) {
								if(jQuery.isFunction(validate.callback) && !validate.callback(this.value)) {
									error = validate.error || error;
								} else if(validate.test && !this.value.match(validate.test)) {
									error = validate.error || error;
								}
							}
						}

						for(var i = 0; i < klass.length; i++) {
							if(klass[i].match(/(max|min|exact)\-(\d*)/) && Jrun.trim(this.value) !== "") {
								var type = RegExp.$1;
								var value = RegExp.$2;

								if(!Js.test.isLength(klass[i], this.value.length)) {
									if(type == "min") {
										type = Js.lang.form.lengthOption.minimum;
									} else if(type == "max") {
										type = Js.lang.form.lengthOption.maximum;
									} else  if(type == "exact") {
										type = Js.lang.form.lengthOption.exact;
									}


									var note = Js.lang.form.length;

									note = note.replace(/{type}/, type);
									note = note.replace(/{value}/, value);

									that.errorInit(this, note, true);
								}
							}
						}

						if(error !== "") {
							that.errorInit(this, error);
						} else {
							jQuery(this).removeClass("extform-error");
							var errorObject = jQuery(this).siblings("span.extform-errormessage").eq(0);
							if(errorObject.length == 1) {
								errorObject.remove();
							}
						}


						// dump name and value to opt in querystring format ( &name=value )
						if(this.type.toLowerCase().match(/^(checkbox|radio)$/)) {
							if(this.type == "checkbox" && this.checked == true) {
								// only add checked checkbox input
								post += "&" + this.name + "=" + Js.parse.html.to(this.value);
							} else if (this.type == "radio" && this.checked == true) {
								// only add checked radiobox input
								post += "&" + this.name + "=" + Js.parse.html.to(this.value);
							}
						} else {
							// add all input (except radio/checkbox)
							post += "&" + this.name + "=" + Js.parse.html.to(this.value);
						}
					}
				}
			});
		}

		if(Jrun.isset(this.first)) {
			// there an error, set focus to first invalid field
			try {
				this.first.focus();
			} catch(e) {}
			// stop form processing
			return false;
		} else {
			return post; // return all field data in querystring formatting
		}
	},
	errorInit: function(field, text, data) {
		// Mark first error occured!
		this.first = (Jrun.isnull(this.first) ? field : this.first);

		var field = jQuery(field);
		var form = jQuery(this.object);
		var fieldName = field.attr("name");
		var fieldErrorId = [form.attr("id"), fieldName, "error"].join("-");
		var data = data || false;
		var that = this;

		if(jQuery("#" + fieldErrorId).length == 0) {
			field.addClass("jsextform-error");
			jQuery('<span/>').attr({id: fieldErrorId, className: "extform-errormessage"}).html(text).appendTo(field.parent());

			field.change(function() {
				if(jQuery(this).val() != "") {
					var node = jQuery(this).removeClass("extform-error");

					var errorNode = node.siblings("span.extform-errormessage").eq(0);
					if(errorNode.length == 1) {
						errorNode.remove();
					}
					that.first = null;
				}
			});
		} else if(jQuery("#" + fieldErrorId).length == 1 && !!data) {
			field.addClass("extform-error");
			var errorNode = field.siblings("span.extform-errormessage").eq(0);
			var html = errorNode.html();

			if(html.match(text) === false && jQuery.trim(html) != "") {
				errorNode.append(text);
			}

			field.change(function() {
				if(jQuery(this).val() != "") {
					var node = jQuery(this).removeClass("extform-error");

					var errorNode = node.siblings("span.extform-errormessage").eq(0);

					if(errorNode.length == 1) {
						errorNode.remove();
					}

					that.first = null;
				}
			});
		}
	}
};

Js.lang.form = {
	string: "Please fill in alpha-numeric value!",
	number: "Only numbers allowed",
	email: "Please fill in e-mail!",
	required: "Please fill in this field!",
	length: "This field requires {type} {value} characters.",
	lengthOption: {
	exact: "exact",
	minimum: "minimum",
	maximum: "maximum"
	}
};/*
 * JavaScript Library Application
 * Name: SUI.util.dimension
 * Type: Util/Plugin
 * Last Updated: 25th July 2008
 */

Js.util.dimension = {
	// Get scrolled value of a page
	page: {
		scrolls: {
			x: function() {
				var doc = document.body;
				var rdata = 0;
				var offset = window.pageXOffset;
				var el = document.documentElement;

				if(typeof(offset) == "number") {
					rdata = offset;
				} else if(doc && doc.scrollLeft) {
					rdata = doc.scrollLeft;
				} else if(el && el.scrollLeft) {
					rdata = el.scrollLeft;
				}

				return rdata;
			},
			y: function() {
				var doc = document.body;
				var rdata = 0;
				var offset = window.pageYOffset;
				var el = document.documentElement;

				if(typeof(offset) == "number") {
					rdata = offset;
				} else if(doc && doc.scrollTop) {
					rdata = doc.scrollLeft;
				} else if(el && el.scrollTop) {
					rdata = el.scrollLeft;
				}

				return rdata;
			},
			both: function() {
				return [Js.util.dimension.page.scrolls.x(), Js.util.dimension.page.scrolls.y()];
			}
		},
		middle: function(width, height) {
			var doc = document.body;
			var offset = [Jrun.toNumber(doc.offsetWidth), Jrun.toNumber(doc.offsetHeight)];
			var axis = Js.util.dimension.page.scrolls.both();
			var rdata = [];

			rdata[0] = Math.round(((offset[0] - width) / 2) + axis[0]);
			rdata[1] = Math.round((((screen.height - 200) - height) / 2) + axis[1]);
			rdata[0] = (rdata[0] < 0 ? 0 : rdata[0]);
			rdata[1] = (rdata[1] < 0 ? 0 : rdata[1]);
			rdata.reverse();

			return rdata;
		}
	},
	node: {
		scrolls: {},
		size: {},
		offset: function(node) {
			var rdata = [0, 0, 0, 0];
			var loop = false;

			if(Jrun.isset(node)) {
				if(node.offsetParent) {
					loop = true;
					rdata[0] = node.offsetWidth;
					rdata[1] = node.offsetHeight;

					while(node.offsetParent) {
						rdata[2] += node.offsetTop;
						rdata[3] += node.offsetLeft;
						node = node.offsetParent;
					}
				} else {
					if(loop == false) {
						rdata[0] = Jrun.pick(node.scrollWidth, 0);
						rdata[1] = Jrun.pick(node.scrollHeight, 0);
						rdata[2] = Jrun.pick(node.offsetTop, 0);
						rdata[3] = Jrun.pick(node.offsetLeft, 0);
					}
				}
				return rdata;
			} else {
				Js.debug.log("Js.ext.dimension.node.offset error : " + node + " does not exist");
				return ret;
			}
		}
	}
};
/*
 * JavaScript Library Application
 * Name: SUI.util.activeContent
 * Type: Utility/Plug-In
 * Version: 0.1 (alpha-release)
 * Last Updated: 19th June 2008
*/

Js.util.activeContent = Js.base.create({
	last: null,
	interval: null,
	repeat: false,
	init: null,
	element: null,
	option: null,
	__construct: function(selector) {
		this.element = Jrun.pick(selector, null);

		if(Jrun.isset(this.element)) {
			this.selector();
			this.check();
		} else {
			var that = this;
			this.interval = window.setInterval(function() {
				that.check();
			}, 100);
		}
	},
	destruct: function() {
		if(Jrun.isset(this.interval)) {
			clearInterval(this.interval);
			this.interval == null;
		}

		this.element = null;
		this.__destruct();
		return null;
	},
	selector: function() {
		var that = this;

		jQuery(this.element).click(function() {
			var href = jQuery(this).attr("href");
			var anchors = (Jrun.isset(href) ? href : this.href);

			if(anchors.match(/^\#/)) {
				var ahref = ["", anchors.substr(1)];
			} else {
				var ahref = anchors.split(/\#/);
			}

			if(Jrun.isset(ahref[1])) {
				that.repeat = (ahref[1] === that.last);

				that.last = ahref[1];
				var data = ahref[1].split(/\//);
				that.init(data);
			}
		});
	},
	check: function() {
		if(location.hash != this.last && location.hash !== "#") {
			this.last = location.hash;

			var data = location.hash.substr(1).split(/\//);
			this.init(data);
		}
	}
});
/*
 * JavaScript Library Extension
 * Name: Calendar
 * Type: Widget
 * Version: 0.7 (alpha-release)
 * Last Updated: 20th June 2008
 ***************************************************
 * History:
 *	Calendar object based from The Strange Zen of JavaScript's How to build a simple calendar with JavaScript:
 *	<http://jszen.blogspot.com/2007/03/how-to-build-simple-calendar-with.html>
*/

Js.widget.calendar = function(js) {
	this.days = ["S", "M", "T", "W", "T", "F", "S"];
	this.months = ["January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	this.shortmonths = ["Jan", "Feb", "Mac", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"];
	this.daysinmonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	this.field = null;
	this.value = "";
	this.lastdate = null;
	this.fieldtype = "hidden";
	this.type = null;
	this.navigation = null;

	this.object	= null;
	this.element = null;
	this.renderTo = null;
	this.node = {
		content: null,
		option: null
	};

	this.drag = null;
	this.range = null;
	this.onupdate = null;

	this.mindate = null;
	this.maxdate = null;

	this.Dates = new Date();
	this.date = "";
	this.day = null;
	this.month = null;
	this.year = null;

	if (js && typeof(js) === "object") {
		this.init(js);
	}

	return this;
};

Js.widget.calendar.prototype = {
	init: function(js) {
		this.element = Jrun.prepare(js.object, js.element);
		var regexp = new RegExp(/^(\d{2}|\d{4})[.\/-](\d{1,2})[.\/-](\d{1,2})$/);
		this.renderTo = Jrun.pick(js.renderTo, this.renderTo);

		if(!this.renderTo || (typeof(this.renderTo) !== "string" && !this.renderTo.nodeType)) {
			this.renderTo = jQuery("<div/>").appendTo("body");
		} else if(typeof(this.renderTo) === "string" || this.renderTo.nodeType) {
			this.renderTo = jQuery(this.renderTo).eq(0);
		}
		jQuery.facebox(this.renderTo);

		js.range = Jrun.pick(js.range, this.range, [null, null]);
		this.field = Jrun.pick(js.field, this.field, "value");
		this.type = Jrun.pick(js.type, this.type, "single");

		if(!!js.mindate && regexp.test(js.mindate)) {
			this.mindate = Jrun.pick(js.mindate, null);
		}

		if(!!js.maxdate && regexp.test(js.maxdate)) {
			this.maxdate = Jrun.pick(js.maxdate, null);
		}

		if(!!js.value && regexp.test(js.value)) {
			var tdate = js.value.split("-");
			js.month = tdate[1];
			js.year = tdate[0];
			js.day = tdate[2];
		} else if(!!js.value && js.value === "today") {
			var tmpdate = new Date();
			js.month = tmpdate.getMonth();
			js.year = tmpdate.getFullYear();
			js.day = tmpdate.getDate();
		}

		this.month = ((!js.month || isNaN(js.month) || js.month > 12 || js.month < 0) ? this.Dates.getMonth() : Math.abs(js.month - 1));
		this.year = ((!js.year || isNaN(js.year) || js.year < 1000) ? this.Dates.getFullYear() : js.year);
		this.day = Jrun.pick(js.day, this.day);

		this.date = [this.year, (this.month + 1), Jrun.pick(this.day, 1)].join("-");
		this.onupdate = Jrun.pick(js.onUpdate, null);
		this.navigation = Jrun.pick(js.navigate, true);

		if(this.navigation == true) {
			if(!js.range[0] || js.range[0].toLowerCase() == "now") {
				js.range[0] = this.Dates.getFullYear();
			} else if(Js.test.isInteger(js.range[0]) && (js.range[0] > 1000 && js.range[0] < 9999)) {
				js.range[0] = js.range[0];
			} else if(js.range[0].charAt(0) == "-") {
				js.range[0] = (this.Dates.getFullYear() + Jrun.toNumber(js.range[0]));
			} else if(js.range[0].charAt(0) == "+") {
				js.range[0] = (this.Dates.getFullYear() + Jrun.toNumber(js.range[0]));
			}

			if(!js.range[1] || js.range[1].toLowerCase() == "now") {
				js.range[1] = this.Dates.getFullYear();
			} else if(Js.test.isInteger(js.range[1]) && (js.range[1] > 1000 && js.range[1] < 9999)) {
				js.range[1] = s_.range[1];
			} else if(js.range[1].charAt(0) == "-") {
				js.range[1] = (this.Dates.getFullYear() + (Jrun.toNumber(js.range[1]) + 0));
			} else if(js.range[1].charAt(0) == "+") {
				js.range[1] = (this.Dates.getFullYear() + Jrun.toNumber(js.range[1]));
			}

			if(js.range[0] < js.range[1]) {
				var tmp = js.range[0];
				js.range[0] = js.range[1];
				js.range[1] = tmp;
				delete tmp;
			}

			this.range = [this.maxYear(js.range[0]), this.minYear(js.range[1])];
		}

		this.drag = Jrun.pick(js.draggable, false);
		this.renderTo.html("");
		this.callback();

		return this;
	},
	minYear: function(year) {
		var data = year;
		if(this.mindate) {
			var minDate = this.mindate.split("-");
			var newYear = Jrun.toNumber(minDate[0]);

			if(newYear > data) {
				data = newYear;
			}
		}
		return data;
	},
	maxYear: function(year) {
		var data = year;
		if(this.maxdate) {
			var maxDate = this.maxdate.split("-");
			var newYear = Jrun.toNumber(maxDate[0]);

			if(newYear < data) {
				data = newYear;
			}
		}
		return data;
	},
	prevMonth: function() {
		this.day = null;
		this.Dates = new Date(this.year, (this.month - 1));
		this.month = this.Dates.getMonth();
		this.year = this.Dates.getFullYear();
		this.date = [this.year, (this.month + 1), this.dayOfMonth()].join("-");

		if(this.validation()) {
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date(this.year, (this.month + 1));
			this.month = this.Dates.getMonth();
			this.year = this.Dates.getFullYear();
			this.date = [this.year, (this.month + 1), "1"].join("-");
		}

		return this;
	},
	prevYear: function() {
		this.day = null;
		this.Dates = new Date((this.year - 1), this.month);
		this.month = this.Dates.getMonth();
		this.year = this.Dates.getFullYear();
		this.date = [this.year, (this.month + 1), this.dayOfMonth()].join("-");

		if(this.validation()) {
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date((this.year + 1), this.month);
			this.month = this.Dates.getMonth();
			this.year = this.Dates.getFullYear();
			this.date = [this.year, (this.month + 1), "1"].join("-");
		}

		return this;
	},
	nextMonth: function() {
		this.day = null;
		this.Dates = new Date(this.year, (this.month + 1));
		this.month = this.Dates.getMonth();
		this.year = this.Dates.getFullYear();
		this.date = [this.year, (this.month + 1), this.dayOfMonth()].join("-");

		if(this.validation()) {
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date(this.year, (this.month - 1));
			this.month = this.Dates.getMonth();
			this.year = this.Dates.getFullYear();
			this.date = [this.year, (this.month + 1), "1"].join("-");
		}
		return this;
	},
	nextYear: function() {
		this.day = null;
		this.Dates = new Date((this.year + 1), this.month);
		this.month = this.Dates.getMonth();
		this.year = this.Dates.getFullYear();
		this.date = [this.year, (this.month + 1), this.dayOfMonth()].join("-");

		if(this.validation()){
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date((this.year - 1), this.month);
			this.month = this.Dates.getMonth();
			this.year = this.Dates.getFullYear();
			this.date = [this.year, (this.month + 1), "1"].join("-");
		}
		return this;
	},
	customMonth: function(data) {
		this.day = null;
		this.Dates = new Date(this.year, data);
		var tempMonth = this.Dates.getMonth();
		var tempYear = this.Dates.getFullYear();
		this.date = [tempYear, (tempMonth + 1), this.dayOfMonth(tempMonth, tempYear)].join("-");

		if(this.validation()) {
			this.year = tempYear;
			this.month = tempMonth;
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date(this.year, this.month);
			this.date = [this.year, (this.month + 1), "1"].join("-");
			this.renderTo.html("");
			this.callback();
		}
		return this;
	},
	customYear: function(data) {
		this.day = null;
		this.Dates = new Date(data, this.month);
		var tempMonth = this.Dates.getMonth();
		var tempYear = this.Dates.getFullYear();
		this.date = [tempYear, (tempMonth + 1), this.dayOfMonth(tempMonth, tempYear)].join("-");

		if(this.validation()) {
			this.year = tempYear;
			this.month = tempMonth;
			this.renderTo.html("");
			this.callback();
		} else {
			this.Dates = new Date(this.year, this.month);
			this.date = [this.year, (this.month + 1), "1"].join("-");
			this.renderTo.html("");
			this.callback();
		}
		return this;
	},
	today: function() {
		this.Dates = new Date();
		this.year = this.Dates.getFullYear();
		this.month = this.Dates.getMonth();
		this.day = this.Dates.getDate();
		this.date = [this.year, (this.month + 1), this.day].join("-");
		this.renderTo.html("");
		this.callback();
	},
	validation: function() {
		var data = false;
		var minDate = Jrun.isset(this.mindate);
		var maxDate = Jrun.isset(this.maxdate);

		if(minDate && maxDate && this.compare(this.mindate, this.date) && this.compare(this.date, this.maxdate)) {
			data = true;
		} else if(minDate && this.compare(this.mindate, this.date)) {
			data = true;
		} else if(maxDate && this.compare(this.date, this.maxdate)) {
			data = true;
		} else if(!minDate && !maxDate) {
			data = true;
		}

		return data;
	},
	dayOfMonth: function(month, year) {
		var month = Jrun.pick(month, this.month);
		var year = Jrun.pick(year, this.year);

		if(month == 1 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
			var monthLength = 29;
		}

		return Jrun.pick(monthLength, this.daysinmonth[month]);
	},
	compare: function(first, second) {
		var firsts = first.split("-");
		var seconds = second.split("-");

		var firstDate = new Date(firsts[0], (Jrun.toNumber(firsts[1]) - 1));
		firstDate.setDate(firsts[2]);

		var secondDate = new Date(seconds[0], (Jrun.toNumber(seconds[1]) - 1));
		secondDate.setDate(seconds[2]);

		return (secondDate >= firstDate ? true : false);
	},
	updateValue: function(year, month, day) {
		var field = jQuery("#" + this.element + "_" + year + month + day).eq(0);
		var calendar = jQuery("#" + this.element + "-" + this.field).eq(0);

		var months = (month < 10 ? "0" + month : month);
		var days = (day < 10 ? "0" + day : day);

		if(this.type == "single") {
			if(!field.hasClass("calendar-day-selected")) {
				if (Jrun.isset(this.lastdate) && Jrun.finds(this.element + "_" + this.lastdate)) {
					var lastdate = jQuery("#" + this.element + "_" + this.lastdate).removeClass().addClass("calendar-day");
				}

				field.removeClass().addClass("calendar-day-selected");
				this.value = [year, months, days].join("-");

				calendar.val(this.value);
				this.lastdate = [year, month, day].join("");
			} else {
				field.removeClass().addClass("calendar-day");
				calendar.val("");
			}
		} else if (this.type == "multiple") {
			var value = calendar.val();
			var values = value.split("|");

			if(Jrun.inArray(values, [year, months, days].join("-"))){
				values.splice(values.indexOf([year, months, days].join("-")), 1);
				value = values.join("|");

				field.removeClass().addClass("calendar-day");
				this.value = value;
				calendar.val(this.value);
			} else {
				field.removeClass().addClass("calendar-day-selected");
				values[values.length] = [year, months, days].join("-");
				this.value = values.join("|");
				calendar.val(this.value);
			}
		}

		var fn = this.onupdate;
		if(fn != null && typeof(fn) == "function") {
			Jrun.callback(this, fn);
		}

		return this;
	},
	callback: function() {
		var cal = this.renderTo;
		var that = this;
		var first_day = new Date(this.year, this.month, 1);
		var start_day = first_day.getDay();
		var html = "";
		var monthLength = this.dayOfMonth();
		cal.html("");

		var wrapper = this.object = jQuery("<div/>").attr({
			"id": [this.element, "calendar"].join("-"),
			"class": "calendar-panel"
		}).css("display", "block").appendTo(cal);

		var header = jQuery("<div/>").appendTo(wrapper);
		var content = jQuery("<div/>").appendTo(wrapper);
		var footer = jQuery("<div/>").appendTo(wrapper);

		var prevbtn = jQuery("<span/>").appendTo(header);
		var nextbtn = jQuery("<span/>").appendTo(header);
		var title = jQuery("<span/>").appendTo(header);

		this.node.content = jQuery("<div/>").addClass("calendar-content").appendTo(content);
		this.node.option = jQuery("<div/>").addClass("calendar-option").appendTo(content);

		var table = jQuery("<table cellpadding='0' cellspacing='0'></table>").addClass("calendar-body").appendTo(this.node.content);
		var tbody = jQuery("<tbody/>").appendTo(table);

		var trheader = jQuery("<tr/>").addClass("calendar-header").appendTo(tbody);

		for(var i = 0; i <= 6; i++) {
			jQuery("<td/>").addClass("calendar-header-day").text(this.days[i]).appendTo(trheader);
		}

		var day = 1;

		for(var i = 0; i < 6; i++) {
			var weeks = jQuery("<tr/>").addClass("calendar-week").appendTo(tbody);

			for(var j = 0; j <= 6; j++) {
				this.date = [this.year, (this.month + 1), day].join("-");
				var days = jQuery("<td/>").addClass("calendar-" + (this.validation() ? "day" : "invalid")).appendTo(weeks);

				if(day <= monthLength && (i > 0 || j >= start_day)) {
					days.attr("id", this.element + "_" + this.year + (this.month + 1) + day);
					var tday;

					if(this.validation()) {
						days.click(function() {

							var i = jQuery(this).attr("id").split("_");
							var count = (i.length - 1);
							var ym = that.year + "" + that.month;
							tday = i[count].substr((ym.length), i[count].length);
							that.updateValue(that.year, (that.month + 1), Jrun.toNumber(tday));
						});
					}

					if(day == this.day) {
						days.removeClass().addClass("calendar-day-selected");
						this.lastdate = this.year + "" + (this.month + 1) + "" + Jrun.toNumber(this.day);
					}

					days.css("cursor", "pointer");

					days.html(day.toString());
					day++;
				} else {
					days.html("&nbsp;").removeClass().addClass("calendar-invalid");
				}
			}

			if(day > monthLength) {
				break;
			}
		}


		if(this.navigation == true) {
			prevbtn.html("&laquo;").click(function() {
				that.prevMonth();
			}).removeClass().addClass("prev-month");

			nextbtn.html("&raquo;").click(function() {
				that.nextMonth();
			}).removeClass().addClass("next-month");

			jQuery("<p/>").text("Please select month & year:").appendTo(this.node.option);

			var selmonth = jQuery("<select name='month'></select>").change(function() {
				that.customMonth(this.value);
			}).appendTo(this.node.option);

			for(var i = 0; i < 12; i++) {
				if(this.month == i) {
					jQuery("<option value='" + i + "' selected='selected'></option>").text(this.months[i]).appendTo(selmonth);
				} else {
					jQuery("<option value='" + i + "'></option>").text(this.months[i]).appendTo(selmonth);
				}
			}

			var selyear = jQuery("<select name='year'></select>").text(" ").change(function() {
				that.customYear(this.value);
			}).appendTo(this.node.option);

			for(var i = this.range[0]; i >= this.range[1]; i--) {
				if(this.year == i) {
					jQuery("<option value='" + i + "' selected='selected'></option>").text(i.toString()).appendTo(selyear);
				} else {
					jQuery("<option value='" + i + "'></option>").text(i.toString()).appendTo(selyear);
				}
			}

			//var ps = jQuery("<p/>").text("Select ").appendTo();
			jQuery("<input type='button' value='Pilih Hari Ini' name='today' />").click(function() {
				that.today();
			}).addClass("select-today").appendTo(this.node.option);

			title.removeClass().addClass("this-month").html(this.months[this.month] + "&nbsp;" + this.year);
			this.object.data("toggle", 1);
			//Js.hash.set(this.element, "toggle", 1);

			title.css("cursor", "pointer").click(function() {
				var i = that.object.data("toggle");

				if(i === 1) {
					that.node.content.hide("normal");
					that.node.option.show("normal");
					that.object.data("toggle", 0);
				} else {
					that.node.option.hide("normal");
					that.node.content.show("normal");
					that.object.data("toggle", 1);
				}
			});
		} else {
			title.removeClass().addClass("this-month").html(this.months[this.month] + "&nbsp;" + this.year);
		}

		if (Jrun.isset(this.field)) {
			var input = jQuery("<input id='" + [this.element, this.field].join("-") + "' name='" + this.field + "' type='" + this.fieldtype + "' />").appendTo(this.node.content);

			if (Jrun.isset(this.day)) {
				var m = (this.month + 1);
				this.value = [this.year, (m < 10 ? "0" + m : m), this.day].join("-");
				input.val(this.value);
				this.lastdate = [this.year, (this.month + 1), Jrun.toNumber(this.day)].join("");
			}
		}

		return this;
	}
};Js.widget.iconizer = function() {
	this.folder = "icons/";
	this.ext = "png";

	return this;
};
Js.widget.iconizer.prototype = {
	init: function() {
		var that = this;

		jQuery("*[class*=icon]").each(function() {
			var object = jQuery(this);

			var klas = object.attr("className");
			var klass = klas.split(/ /);
			for(var i = 0; i < klass.length; i++) {
				if(klass[i].match(/^icon(\-append)?\-(left|right)\:(\w*)/g)) {
					var append = (RegExp.$1 == "-append" ? true : false);
					var pos = (jQuery.inArray(RegExp.$2, ["left", "right"]) < 0 ? "left" : RegExp.$2);
					var icon = RegExp.$3;

					if(!!append) {
						var obj = jQuery("<span></span>").css({
							"display": "block",
							"cssFloat": pos,
							"width": "16px",
							"height": "16px"
						}).prependTo(object);
						if(pos == "left") {
							obj.css({
								"background": "url('" + that.folder + icon + "." + that.ext + "') no-repeat left",
								"marginRight": "3px"
							});
						} else {
							obj.css({
								"background": "url('" + that.folder + icon + "." + that.ext + "') no-repeat right",
								"marginLeft": "3px"
							});
						}
					} else {
						if(pos == "left") {
							object.css({
								"background": "url('" + that.folder + icon + "." + that.ext + "') no-repeat left center",
								"paddingLeft": "17px"
							});
						} else {
							object.css({
								"background": "url('" + that.folder + icon + "." + that.ext + "') no-repeat right center",
								"paddingRight": "17px"
							});
						}
					}
				}
			}
		});
	}
};/*
 * JavaScript Library Application
 * Name: message
 * Type: Widget
 * Version: 0.1 (alpha-release)
 * Last Updated: 16th June 2008
*/

Js.widget.message = {
	node: null,
	add: function(spec) {
		if(Jrun.isnull(this.node)) {
			this.init();
		}

		var that = this;
		var text = Jrun.pick(spec.text, "");
		var timeout = Jrun.pick(spec.timeout, 8000);
		var type = Jrun.pick(spec.type, "note");
		var closable = Jrun.pick(spec.closable, true);

		timeout = (Js.test.isInteger(timeout) ? timeout : 8000);

		(function() {
			var div = jQuery("<div/>").attr({className: "widgetmessage-box"}).css("margin", "2px 0px").appendTo(that.node).hide();

			if(!!closable) {
				var span = jQuery("<span/>").attr({className: "widgetmessage-close"}).text("x").appendTo(div);
			}

			var p = jQuery("<p/>").html(text).appendTo(div);

			var t = setTimeout(function() {
				div.hide("normal", function() {
					span.remove();
					p.remove();
				});
			}, timeout);

			if(!!closable) {
				span.click(function() {
					clearTimeout(t);
					t = null;

					div.hide("normal", function() {
						span.remove();
						p.remove();
					});
				});
			}
			div.addClass(type);
			div.show("slow");
		})();
	},
	init: function() {
		var that = this;
		this.node = jQuery("<div/>").attr({id: "widgetmessage"}).appendTo("body");

		var whenScroll = function() {
			var y = Js.util.dimension.page.scrolls.y();
			that.node.css("top", y + "px");
		};
		var currentScroll = window.onscroll;
		window.onscroll = function() {
			if(Jrun.isfunction(currentScroll)) {
				currentScroll();
			}
			whenScroll();
		};
		whenScroll();
	}
};
/*
 * JavaScript Library Application
 * Name: SimpleTab
 * Type: Widget
 * Version: 0.2 (alpha-release)
 * Last Updated: 16th June 2008
*/

Js.widget.simpleTab = function(sel, handler) {
	this.temp = null;
	this.height = null;
	this.toolbar = null;
	this.object = null;
	this.header = null;
	this.element = null;
	this.activeTab = null;
	this.activeHeader = null;
	this.handler = null;
	this.status = "off";

	// start __constructor()
	if(Jrun.typeOf(sel) === "object" || Jrun.typeOf(sel) === "string") {
		this.init(sel, handler);
	}

	return this;
};

Js.widget.simpleTab.prototype = {
	init: function(sel, handler) {
		var that = this;
		this.object = jQuery(sel);
		this.object.addClass("simpletab-container");
		this.element = this.object.eq(0).attr("id");
		this.handler = Jrun.pick(handler, "click");

		this.handler = (this.handler.match(/^(click|mouseover)$/g) ? this.handler : 'click');

		var child = jQuery("div.simpletab-panel, div.simpletab", this.object);

		this.activeTab = child.eq(0);

		this.addToolbar(this.element);

		child.each(function() {
			that.addHeader(this);
			jQuery(this).removeClass().addClass("simpletab-hidden");
		});

		this.activeHeader = jQuery("a[href=#" + this.activeTab.attr("id") + "]");
		this.activeHeader.addClass("current");
		this.activeTab.removeClass().addClass("simpletab-active");
		this.status = "on";
	},
	toggle: function() {
		if(this.status == "on") {
			this.toolbar.hide();
			jQuery("div.simpletab-hidden", this.object).removeClass("simpletab-hidden").addClass("simpletab-active");
			this.status = "off";
		} else {
			this.toolbar.show();
			jQuery("div.simpletab-active", this.object).removeClass("simpletab-active").addClass("simpletab-hidden");
			this.activeTab.removeClass().addClass("simpletab-active");
			this.status = "on";
		}
	},
	makeActive: function(hash) {
		var that = this;


		var temp = jQuery(".simpletab-container a[href=" + hash + "]");
		if(temp.length > 0) {
			this.activeHeader.removeClass("current");
			this.activeTab.removeClass().addClass("simpletab-hidden");

			this.activeHeader = temp;
			this.activeTab = jQuery(hash);

			this.activeHeader.addClass("current");
			this.activeTab.removeClass().addClass("simpletab-active");
		}
		return false;
	},
	addTab: function(spec) {
		var that = this;
		if(!!spec.id && Jrun.typeOf(spec.id) === "string") {
			var title = Jrun.pick(spec.title, "Untitled");
			var id = spec.id;
			var content = Jrun.pick(spec.content, "");
			var closable = Jrun.pick(spec.closable, false);
			var set = Jrun.pick(spec.activate, false);

			var obj = jQuery('<div/>').attr({id: id, className: "simpletab-hidden"}).html(content).appendTo(this.object);
			var li = jQuery('<li/>').appendTo(this.header);
			var a = jQuery('<a/>').attr({href: "#" + id, title: title}).appendTo(li);

			jQuery("<em/>").appendTo(a);
			a.text(title).bind(this.handler, function() {
				that.activate(this);
				return false;
			});

			if (!!closable) {
				jQuery("<span/>").css("paddingLeft", "10px").text("x").click(function() {
					var href = jQuery(this.parentNode).attr("href");
					that.activeHeader.removeClass();
					that.activeTab.removeClass().addClass("simpletab-hidden").fadeOut();
					jQuery(href).remove();
					jQuery(this.parentNode.parentNode).remove();
				}).appendTo(a);
			}

			if(!!set) {
				this.activate(obj);
			}
		}
		return this;
	},
	addToolbar: function(el) {
		var div = jQuery("<div/>").attr({className: "simpletab-toolbar-container", id: this.element + "toolbar"}).prependTo(this.object);
		this.toolbar = div;

		this.header = jQuery("<ul/>").attr({id: [el, "toolbar"].join("-"), className: "simpletab-toolbar"}).appendTo(this.toolbar);
		var div2 = jQuery("<div/>").css("display", "block").appendTo(div);
	},
	activate: function(obj) {
		var that = this;
		this.activeHeader.removeClass("current");
		this.activeTab.removeClass().addClass("simpletab-hidden");

		this.activeHeader = jQuery(obj);
		var href = this.activeHeader.attr("href");
		this.activeTab = jQuery(href);

		this.activeHeader.addClass("current");
		this.activeTab.removeClass().addClass("simpletab-active");

		return false;
	},
	revert: function() {
		var activecon = jQuery("li > a", this.header);
		if(activecon.length > 0) {
			this.activate(activecon.eq(0));
		}
	},
	addHeader: function(obj) {
		var that = this;
		var obj = jQuery(obj);
		var title = obj.attr("title");
		var closable = obj.hasClass("tab-closable");

		var li = jQuery("<li/>").appendTo(this.header);
		var a = jQuery("<a/>").attr({href: "#" + obj.attr("id"), title: title}).appendTo(li);
		jQuery("<em/>").appendTo(a);

		a.text(title).bind(this.handler, function() {
			that.activate(this);
			return false;
		});

		if(!!closable) {
			jQuery("<span/>").css("paddingLeft", "10px").text("x").click(function() {
				var my = jQuery(this.parentNode).click(function() {
					return false;
				});

				var href = my.attr("href");
				that.activeHeader.removeClass();
				that.activeTab.removeClass().addClass("simpletab-hidden");
				jQuery(href).remove();
				jQuery(this.parentNode.parentNode).remove();

				that.revert();
			}).appendTo(a);
		}
	}
};/*
 * JavaScript Library Application
 * Name: Js.util.ticker
 * Type: Utility/Plug-in
 * Version: 0.1 (alpha-release)
 * Last Updated: 16th June 2008
*/

// Import Plugin
Js.util.ticker = function(selector) {
		// Define Object's properties
	this.element = null;
	this.node = null;

	// start __constructor()
	if (!!selector && Jrun.trim(selector) !== "") {
		this.init(selector);
	}

	return this;
};
Js.util.ticker.prototype = {
	// Initialize the HTML Element
	init: function(selector) {
		this.element = Jrun.pick(selector, null);

		if (Jrun.isset(this.element)) {
			this.node = jQuery(this.element);
		}

		return this;
	},
	// checked all checkbox
	check: function() {
		// loop all object
		this.node.each(function() {
			// set checked to true
			this.checked = true;
		});
	},
	// uncheck all checkbox
	unCheck: function() {
		// loops all object
		this.node.each(function() {
			// set checked to false
			this.checked = false;
		});
	},
	// invert checkbox selection
	invert: function() {
		// loops all object
		this.node.each(function() {
			// reverse checkbox selection
			if (this.checked == true) {
				this.checked = false; // uncheck
			} else {
				this.checked = true; // checked
			}
		});
	}
};
/*
 * JavaScript Library Widget
 * Name: Toggler
 * Type: Widget
 * Version: 0.1 (alpha-release)
 * Last Updated: 3rd July 2008
 */

Js.widget.toggler = function(js) {
	this.button = null;
	this.container = null;
	this.content = null;

	this.buttonc = null;
	this.containerc = null;
	this.contentc = null;

	if(Jrun.isset(js) && typeof(js) == "object") {
		this.init(js);
	}

	return this;
};
Js.widget.toggler.prototype = {
	init: function(js) {
		var that = this;

		var button = this.button = js.button;
		var container = this.container = js.container;
		var content = this.content = js.content;

		if(Jrun.isset(button) && Jrun.isset(container) && Jrun.isset(content)) {
			jQuery(button).click(function() {
				var dwl = jQuery(container).eq(0);
				var stack = jQuery(content).eq(0);
				var button = jQuery(this).eq(0);

				if(!button.data("done") || button.data("done") == "no") {
					dwl.slideDown();

					button.data("done", "yes");
				} else if(button.data("done") == "yes") {
					dwl.slideUp();

					button.data("done", "no");
				}
				return false;
			});
		}
	}
};