/**
 * Jindo2 Framework
 * @version 1.3.8
 */
/**
 * @fileOverview	$¿Í $Class¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 */

// Core object
if (typeof window != "undefined" && typeof window.rda == "undefined") {
	window.rda = new Object;
}

if (typeof window != "undefined") {
	window.jindo = {};
}else {
	jindo = {};
}

/**
 * $Jindo °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù. $Jindo °´Ã¼´Â ÇÁ·¹ÀÓ¿÷¿¡ ´ëÇÑ Á¤º¸¿Í À¯Æ¿¸®Æ¼ ÇÔ¼ö¸¦ Á¦°øÇÑ´Ù.
 * @constructor
 * @class $Jindo °´Ã¼´Â ÇÁ·¹ÀÓ¿÷¿¡ ´ëÇÑ Á¤º¸¿Í À¯Æ¿¸®Æ¼ ÇÔ¼ö¸¦ Á¦°øÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Jindo = function() {
	var cl=arguments.callee;
	var cc=cl._cached;
	
	if (cc) return cc;
	if (!(this instanceof cl)) return new cl();
	if (!cc) cl._cached = this;
	
	// information
	this.version = "1.3.8";
}

/** 
 * @function
 * $ ÇÔ¼ö´Â ´ÙÀ½ÀÇ µÎ °¡Áö ¿ªÇÒÀ» ÇÑ´Ù. 
 * <ul><li/>ID¸¦ »ç¿ëÇÏ¿© DOM ¿¤¸®¸ÕÆ®¸¦ °¡Á®¿Â´Ù. ÀÎ¼ö¸¦ µÎ °³ ÀÌ»ó ÁöÁ¤ÇÏ¸é °¢°¢ÀÇ DOM ¿¤¸®¸ÕÆ®¸¦ ¹è¿­·Î ¸®ÅÏÇÑ´Ù. 
 * <li>¶ÇÇÑ "<tagName>" °ú °°Àº Çü½ÄÀÇ ¹®ÀÚ¿­À» ÀÔ·ÂÇÏ¸é tagNameÀ» °¡Áö´Â °´Ã¼¸¦ »ý¼ºÇÑ´Ù.</li></ul>
 * @param {String...} sID Ã£À» DOM ¿¤¸®¸ÕÆ®ÀÇ ID. ID´Â ÇÏ³ª ÀÌ»ó ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. 
 * @return {Element|Array} DOM ¿¤¸®¸ÕÆ®¸¦ ¸®ÅÏÇÑ´Ù. ¸¸¾à ID¿¡ ÇØ´çÇÏ´Â DOM ¿¤¸®¸ÕÆ®°¡ ¾ø´Ù¸é nullÀ» ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
// ID¸¦ ÀÌ¿ëÇÏ¿© °´Ã¼ ¹ÝÈ¯
var div1 = $("div1");

// ¿©·¯°³ÀÇ °´Ã¼¸¦ ¹ÝÈ¯
var divs = $("div1","div2"); // [$("div1"),$("div2")] ¿Í °°Àº °á°ú¸¦ ¹ÝÈ¯

// °´Ã¼ »ý¼º
var div = $("<DIV>");
var div = $("<DIV id='div1'><SPAN>hello</SPAN></DIV>");
 */
jindo.$ = function(sID/*, id1, id2*/) {
	var ret = new Array;
	var el  = null;
	var reg = /^<([a-z]+|h[1-5])>$/i;
	var reg2 = /^<([a-z]+|h[1-5])(\s+[^>]+)?>/i;
	
	for(var i=0; i < arguments.length; i++) {
		el = arguments[i];
		if (typeof el == "string") {
			el = el.replace(/^\s+|\s+$/g, "");
			if (reg.test(el)) {
				el = document.createElement(RegExp.$1);
			} else if (reg2.test(el)) {
				var p = { thead:'table', tbody:'table', tr:'tbody', td:'tr', dt:'dl', dd:'dl', li:'ul', legend:'fieldset' };
				var tag = RegExp.$1.toLowerCase();
				
				var parents = [];

 				for (var j = 0; tag = p[tag]; j++) {
 				
 					var o = document.createElement(tag);
 					if (j) o.appendChild(parents[j - 1]);
 					
 					parents.push(o);
 					
 				}
 				
 				if (!parents[0]) parents[0] = document.createElement('div');
 				
 				var first = parents[0];
				jindo.$Element(first).html(el);
				
				for (el = first.firstChild; el; el = el.nextSibling)
					if (el.nodeType == 1) ret[ret.length] = el;					
				
			} else {
				el = document.getElementById(el);
			}
		}
		if (el) ret[ret.length] = el;
	}
	
	return ret.length>1?ret:(ret[0] || null);
}

/**
 * Å¬·¡½º Å¸ÀÔÀ» Á¤ÀÇÇÑ´Ù. 
 * @extends core
 * @class $Class´Â Jindo¿¡¼­ °´Ã¼ ÁöÇâ ÇÁ·Î±×·¡¹Ö(OOP)¸¦ ±¸ÇöÇÏ´Â °´Ã¼ÀÌ´Ù. #ClassÀÇ »ý¼ºÀÚ´Â $init À¸·Î Á¤ÀÇÇÑ´Ù. ¸ðµç ÀÎ½ºÅÏ½º´Â °°Àº ¼Ó¼ºÀ» °øÀ¯ÇÑ´Ù. °¢ ÀÎ½ºÅÏ½º°¡ µ¶¸³ÀûÀÎ ¼Ó¼º°ªÀ» °¡Áö·Á¸é ÇØ´ç ¼Ó¼ºÀ» $init¿¡¼­ ÃÊ±âÈ­ÇÑ´Ù. ÀÚ¼¼ÇÑ °ÍÀº ¿¹Á¦ ÄÚµå¸¦ ÂüÁ¶ÇÑ´Ù.
 * @param {Object} oDef Å¬·¡½º¸¦ Á¤ÀÇÇÏ´Â °´Ã¼. ¸Þ¼­µå, ÇÁ·ÎÆÛÆ¼¿Í »ý¼ºÀÚ¸¦ Á¤ÀÇÇÑ´Ù. 	
 * @return {$Class} Å¬·¡½º °´Ã¼
 * @description [Lite]
 * @example
var CClass = $Class({
    prop : null,
    $init : function() {
         this.prop = $Ajax();
         ...
    }
});

var c1 = new CClass();
var c2 = new CClass();
// c1°ú c2´Â ¼­·Î ´Ù¸¥ $Ajax °´Ã¼¸¦ °¢°¢ °¡Áø´Ù.

 */
jindo.$Class = function(oDef) {
	function typeClass() {
		var t = this;
		var a = [];
						
		var superFunc = function(m, superClass, func) {
			
			if(m!='constructor' && func.toString().indexOf("$super")>-1 ){		
				var funcArg = func.toString().replace(/function\s*\(([^\)]*)[\w\W]*/g,"$1").split(",");
				var funcStr = func.toString().replace(/function\s*\(.*\)\s*\{/,"").replace(/this\.\$super/g,"this.$super.$super");
				funcStr = funcStr.substr(0,funcStr.length-1);
				func = superClass[m] = new Function(funcArg,funcStr);
			}
			
			return function() {
				var f = this.$this[m];
				var t = this.$this;
				var r = (t[m] = func).apply(t, arguments);
				t[m] = f;
	
				return r;
			};
		}
		
		while(typeof t._$superClass != "undefined") {
			t.$super = new Object;
			t.$super.$this = this;
					
			for(var x in t._$superClass.prototype) {
				if (typeof this[x] == "undefined" && x !="$init") this[x] = t._$superClass.prototype[x];
				if (x!='constructor' && x!='_$superClass' && typeof t._$superClass.prototype[x] == "function") {
					t.$super[x] = superFunc(x, t._$superClass, t._$superClass.prototype[x]);
				} else {
					t.$super[x] = t._$superClass.prototype[x];
				}
			}			
			
			if (typeof t.$super.$init == "function") a[a.length] = t;
			t = t.$super;
		}
				
		for(var i=a.length-1; i > -1; i--) a[i].$super.$init.apply(a[i].$super, arguments);

		if (typeof this.$init == "function") this.$init.apply(this,arguments);
	}
	
	if (typeof oDef.$static != "undefined") {
		var i=0, x;
		for(x in oDef) x=="$static"||i++;
		for(x in oDef.$static) typeClass[x] = oDef.$static[x];

		if (!i) return oDef.$static;
		delete oDef.$static;
	}

	typeClass.prototype = oDef;
	typeClass.prototype.constructor = typeClass;
	typeClass.extend = jindo.$Class.extend;

	return typeClass;
 }

/**
 * Å¬·¡½º¸¦ »ó¼ÓÇÑ´Ù.
 * ÇÏÀ§ Å¬·¡½º´Â this.$super.method ·Î »óÀ§ Å¬·¡½ºÀÇ ¸Þ¼­µå¿¡ Á¢±ÙÇÒ ¼ö ÀÖÀ¸³ª, this.$super.$super.method ¿Í °°ÀÌ ÇÑ ´Ü°è ÀÌ»óÀÇ »óÀ§ Å¬·¡½º´Â Á¢±ÙÇÒ ¼ö ¾ø´Ù.
 * @function
 * @param {$Class} superClass ¼öÆÛ Å¬·¡½º °´Ã¼
 * @return {$Class} È®ÀåµÈ Å¬·¡½º
 * @description [Lite]
 * @example
var ClassExt = $Class(classDefinition);
ClassExt.extend(superClass);	
// ClassExt´Â SuperClass¸¦ »ó¼Ó¹Þ´Â´Ù. 

 */
jindo.$Class.extend = function(superClass) { 
 	/**
	* ºÎ¸ð Å¬·¡½ºÀÇ ¸Þ¼­µå¿¡ Á¢±ÙÇÒ ¶§ »ç¿ëÇÑ´Ù.   
	* @memberOf $Class
	* @name $super 
	* @remark $super¸¦ »ç¿ëÇÏ¿© ºÎ¸ð Å¬·¡½ºÀÇ ¸Þ¼­µå¿¡ Á¢±ÙÇÒ ¶§ ºÎ¸ð Å¬·¡½ºÀÇ ¸Å¼­µå°¡ ÀÚ½Ä Å¬·¡½º¿Í µ¿ÀÏÇÑ ÀÌ¸§ÀÇ ¼Ó¼ºÀ» »ç¿ëÇÏ¸é ÀÚ½Ä Å¬·¡½ºÀÇ ¼Ó¼ºÀ» »ç¿ëÇÑ´Ù. 
	* @example
var Parent = $Class ({
	a: 100,
	b: 200,
	c: 300,
	sum2: function () {
		var init = this.sum();
		return init;
	},
	sum: function () {
		return this.a + this.b
	}
});

var Child = $Class ({
	a: 10,
	b: 20,
	sum2 : function () {
		var init = this.sum();
		return init;
	},
	sum: function () {
		return this.b;
	}
}).extend (Parent);

var oChild = new Child();
var oParent = new Parent();
	
oChild.sum();           // 20
oChild.sum2();          // 20
oChild.$super.sum();    // 30 -> ºÎ¸ð Å¬·¡½ºÀÇ 100°ú 200´ë½Å ÀÚ½Ä Å¬·¡½ºÀÇ 10°ú 20À» ´õÇÑ´Ù. 
oChild.$super.sum2();   // 20 -> ºÎ¸ð Å¬·¡½ºÀÇ sum()´ë½Å ÀÚ½Ä Å¬·¡½ºÀÇ sum()À» È£ÃâÇÑ´Ù. 
	*/
	this.prototype._$superClass = superClass;

	// inherit static methods of parent
	for(var x in superClass) {
		if (x == "prototype") continue;
		this[x] = superClass[x];
	}

	return this;
};
/////


/**

 * @fileOverview CSS ¼¿·ºÅÍ¸¦ »ç¿ëÇÑ ¿¤¸®¸ÕÆ® ¼±ÅÃ ¿£Áø

 * @name cssquery.js

 * @author Hooriza

 */



/**

 * CSS ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ¿© °´Ã¼¸¦ Å½»öÇÑ´Ù.

 *

 * @function CSS ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ¿© °´Ã¼¸¦ Å½»öÇÑ´Ù.

 * @param {String} CSS¼¿·ºÅÍ

 * @param {Element} Å½»ö ´ë»óÀÌ µÇ´Â ¿ä¼Ò, ¿ä¼ÒÀÇ ÇÏÀ§ ³ëµå¿¡¼­¸¸ Å½»öÇÑ´Ù.  

 * @return {Array} Á¶°Ç¿¡ ÇØ´çÇÏ´Â ¿ä¼ÒÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.

 * @description [Lite] 

 * @example

 // ¹®¼­¿¡¼­ IMG ÅÂ±×¸¦ Ã£´Â´Ù.

 var imgs = $$('IMG');

 

 // div ¿ä¼Ò ÇÏÀ§¿¡¼­ IMG ÅÂ±×¸¦ Ã£´Â´Ù.

 var imgsInDiv = $$('IMG', $('div'));

 

 // ¹®¼­¿¡¼­ IMG ÅÂ±× Áß °¡Àå Ã¹ ¿ä¼Ò¸¦ Ã£´Â´Ù.

 var firstImg = $$.getSingle('IMG');

 */

jindo.$$ = jindo.cssquery = (function() {

	

	var sVersion = '2.3';

	

	var debugOption = { repeat : 1 };

	

	// ºü¸¥ Ã³¸®¸¦ À§ÇØ ³ëµå¸¶´Ù À¯ÀÏÅ° °ª ¼ÂÆÃ

	var UID = 1;

	

	var cost = 0;

	var validUID = {};

	

	var bSupportByClassName = jindo.$('<DIV>').getElementsByClassName ? true : false;

	var safeHTML = false;

	

	var getUID4HTML = function(oEl) {

		

		var nUID = safeHTML ? (oEl._cssquery_UID && oEl._cssquery_UID[0]) : oEl._cssquery_UID;

		if (nUID && validUID[nUID] == oEl) return nUID;

		

		nUID = UID++;

		oEl._cssquery_UID = safeHTML ? [ nUID ] : nUID;

		validUID[nUID] = oEl;

		

		return nUID;



	};

	

	var getUID4XML = function(oEl) {

		

		var oAttr = oEl.getAttribute('_cssquery_UID');

		var nUID = safeHTML ? (oAttr && oAttr[0]) : oAttr;

		

		if (!nUID) {

			nUID = UID++;

			oEl.setAttribute('_cssquery_UID', safeHTML ? [ nUID ] : nUID);

		}

		

		return nUID;

		

	};

	

	var getUID = getUID4HTML;

	

	var uniqid = function(sPrefix) {

		return (sPrefix || '') + new Date().getTime() + parseInt(Math.random() * 100000000);

	};

	

	function getElementsByClass(searchClass,node,tag) {

        var classElements = new Array();

        if ( node == null )

                node = document;

        if ( tag == null )

                tag = '*';

        var els = node.getElementsByTagName(tag);

        var elsLen = els.length;

        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");

        for (i = 0, j = 0; i < elsLen; i++) {

                if ( pattern.test(els[i].className) ) {

                        classElements[j] = els[i];

                        j++;

                }

        }

        return classElements;

	}



	var getChilds_dontShrink = function(oEl, sTagName, sClassName) {

		if (bSupportByClassName && sClassName) {

			if(oEl.getElementsByClassName)

				return oEl.getElementsByClassName(sClassName);

			if(oEl.querySelectorAll)

				return oEl.querySelectorAll(sClassName);

			return getElementsByClass(sClassName, oEl, sTagName);

		}

		else if (sTagName == '*') return oEl.all || oEl.getElementsByTagName(sTagName);

		return oEl.getElementsByTagName(sTagName);

	};



	var clearKeys = function() {

		 backupKeys._keys = {};

	};

	

	var oDocument_dontShrink = document;

	

	var bXMLDocument = false;

	

	// µû¿ÈÇ¥, [] µî ÆÄ½Ì¿¡ ¹®Á¦°¡ µÉ ¼ö ÀÖ´Â ºÎºÐ replace ½ÃÄÑ³õ±â

	var backupKeys = function(sQuery) {

		

		var oKeys = backupKeys._keys;

		

		// ÀÛÀº µû¿ÈÇ¥ °È¾î³»±â

		sQuery = sQuery.replace(/'(\\'|[^'])*'/g, function(sAll) {

			var uid = uniqid('QUOT');

			oKeys[uid] = sAll;

			return uid;

		});

		

		// Å« µû¿ÈÇ¥ °È¾î³»±â

		sQuery = sQuery.replace(/"(\\"|[^"])*"/g, function(sAll) {

			var uid = uniqid('QUOT');

			oKeys[uid] = sAll;

			return uid;

		});

		

		// [ ] ÇüÅÂ °È¾î³»±â

		sQuery = sQuery.replace(/\[(.*?)\]/g, function(sAll, sBody) {

			if (sBody.indexOf('ATTR') == 0) return sAll;

			var uid = '[' + uniqid('ATTR') + ']';

			oKeys[uid] = sAll;

			return uid;

		});

	

		// ( ) ÇüÅÂ °È¾î³»±â

		var bChanged;

		

		do {

			

			bChanged = false;

		

			sQuery = sQuery.replace(/\(((\\\)|[^)|^(])*)\)/g, function(sAll, sBody) {

				if (sBody.indexOf('BRCE') == 0) return sAll;

				var uid = '_' + uniqid('BRCE');

				oKeys[uid] = sAll;

				bChanged = true;

				return uid;

			});

		

		} while(bChanged);

	

		return sQuery;

		

	};

	

	// replace ½ÃÄÑ³õÀº ºÎºÐ º¹±¸ÇÏ±â

	var restoreKeys = function(sQuery, bOnlyAttrBrace) {

		

		var oKeys = backupKeys._keys;

	

		var bChanged;

		var rRegex = bOnlyAttrBrace ? /(\[ATTR[0-9]+\])/g : /(QUOT[0-9]+|\[ATTR[0-9]+\])/g;

		

		do {

			

			bChanged = false;

	

			sQuery = sQuery.replace(rRegex, function(sKey) {

				

				if (oKeys[sKey]) {

					bChanged = true;

					return oKeys[sKey];

				}

				

				return sKey;

	

			});

		

		} while(bChanged);

		

		// ( ) ´Â ÇÑ²¨Ç®¸¸ ¹þ°Ü³»±â

		sQuery = sQuery.replace(/_BRCE[0-9]+/g, function(sKey) {

			return oKeys[sKey] ? oKeys[sKey] : sKey;

		});

		

		return sQuery;

		

	};

	

	// replace ½ÃÄÑ³õÀº ¹®ÀÚ¿­¿¡¼­ Quot À» Á¦¿ÜÇÏ°í ¸®ÅÏ

	var restoreString = function(sKey) {

		

		var oKeys = backupKeys._keys;

		var sOrg = oKeys[sKey];

		

		if (!sOrg) return sKey;

		return eval(sOrg);

		

	};

	

	var wrapQuot = function(sStr) {

		return '"' + sStr.replace(/"/g, '\\"') + '"';

	};

	

	var getStyleKey = function(sKey) {



		if (/^@/.test(sKey)) return sKey.substr(1);

		return null;

		

	};

	

	var getCSS = function(oEl, sKey) {

		

		if (oEl.currentStyle) {

			

			if (sKey == "float") sKey = "styleFloat";

			return oEl.currentStyle[sKey] || oEl.style[sKey];

			

		} else if (window.getComputedStyle) {

			

			return oDocument_dontShrink.defaultView.getComputedStyle(oEl, null).getPropertyValue(sKey.replace(/([A-Z])/g,"-$1").toLowerCase()) || oEl.style[sKey];

			

		}



		if (sKey == "float" && /MSIE/.test(window.navigator.userAgent)) sKey = "styleFloat";

		return oEl.style[sKey];

		

	};



	var oCamels = {

		'accesskey' : 'accessKey',

		'cellspacing' : 'cellSpacing',

		'cellpadding' : 'cellPadding',

		'class' : 'className',

		'colspan' : 'colSpan',

		'for' : 'htmlFor',

		'maxlength' : 'maxLength',

		'readonly' : 'readOnly',

		'rowspan' : 'rowSpan',

		'tabindex' : 'tabIndex',

		'valign' : 'vAlign'

	};



	var getDefineCode = function(sKey) {

		

		var sVal;

		var sStyleKey;



		if (bXMLDocument) {

			

			sVal = 'oEl.getAttribute("' + sKey + '",2)';

		

		} else {

		

			if (sStyleKey = getStyleKey(sKey)) {

				

				sKey = '$$' + sStyleKey;

				sVal = 'getCSS(oEl, "' + sStyleKey + '")';

				

			} else {

				

				switch (sKey) {

				case 'checked':

					sVal = 'oEl.checked + ""';

					break;

					

				case 'disabled':

					sVal = 'oEl.disabled + ""';

					break;

					

				case 'enabled':

					sVal = '!oEl.disabled + ""';

					break;

					

				case 'readonly':

					sVal = 'oEl.readOnly + ""';

					break;

					

				case 'selected':

					sVal = 'oEl.selected + ""';

					break;

					

				default:

					if (oCamels[sKey]) sVal = 'oEl.' + oCamels[sKey];

					else sVal = 'oEl.getAttribute("' + sKey + '",2)';

				}

				

			}

			

		}

			

		return '_' + sKey + ' = ' + sVal;

	};

	

	var getReturnCode = function(oExpr) {

		

		var sStyleKey = getStyleKey(oExpr.key);

		

		var sVar = '_' + (sStyleKey ? '$$' + sStyleKey : oExpr.key);

		var sVal = oExpr.val ? wrapQuot(oExpr.val) : '';

		

		switch (oExpr.op) {

		case '~=':

			return '(' + sVar + ' && (" " + ' + sVar + ' + " ").indexOf(" " + ' + sVal + ' + " ") > -1)';

		case '^=':

			return '(' + sVar + ' && ' + sVar + '.indexOf(' + sVal + ') == 0)';

		case '$=':

			return '(' + sVar + ' && ' + sVar + '.substr(' + sVar + '.length - ' + oExpr.val.length + ') == ' + sVal + ')';

		case '*=':

			return '(' + sVar + ' && ' + sVar + '.indexOf(' + sVal + ') > -1)';

		case '!=':

			return '(' + sVar + ' != ' + sVal + ')';

		case '=':

			return '(' + sVar + ' == ' + sVal + ')';

		}

	

		return '(' + sVar + ')';

		

	};

	

	var getNodeIndex = function(oEl) {

		

		var nUID = getUID(oEl);

		var nIndex = oNodeIndexes[nUID] || 0;

		

		// ³ëµå ÀÎµ¦½º¸¦ ±¸ÇÒ ¼ö ¾øÀ¸¸é

		if (nIndex == 0) {



			for (var oSib = (oEl.parentNode || oEl._IE5_parentNode).firstChild; oSib; oSib = oSib.nextSibling) {

				

				if (oSib.nodeType != 1) continue;

				nIndex++;

				

				setNodeIndex(oSib, nIndex);

				

			}

						

			nIndex = oNodeIndexes[nUID];

			

		}

				

		return nIndex;

				

	};

	

	// ¸î¹øÂ° ÀÚ½ÄÀÎÁö ¼³Á¤ÇÏ´Â ºÎºÐ

	var oNodeIndexes = {};



	var setNodeIndex = function(oEl, nIndex) {

		var nUID = getUID(oEl);

		oNodeIndexes[nUID] = nIndex;

	};

	

	var unsetNodeIndexes = function() {

		setTimeout(function() { oNodeIndexes = {}; }, 0);

	};

	

	// °¡»ó Å¬·¡½º

	var oPseudoes_dontShrink = {

	

		'contains' : function(oEl, sOption) {

			return (oEl.innerText || oEl.textContent || '').indexOf(sOption) > -1;

		},

		

		'last-child' : function(oEl, sOption) {

			for (oEl = oEl.nextSibling; oEl; oEl = oEl.nextSibling)

				if (oEl.nodeType == 1)

					return false;

			

			return true;

		},

		

		'first-child' : function(oEl, sOption) {

			for (oEl = oEl.previousSibling; oEl; oEl = oEl.previousSibling)

				if (oEl.nodeType == 1)

					return false;

					

			return true;

		},

		

		'only-child' : function(oEl, sOption) {

			var nChild = 0;

			

			for (var oChild = (oEl.parentNode || oEl._IE5_parentNode).firstChild; oChild; oChild = oChild.nextSibling) {

				if (oChild.nodeType == 1) nChild++;

				if (nChild > 1) return false;

			}

			

			return nChild ? true : false;

		},



		'empty' : function(oEl, _) {

			return oEl.firstChild ? false : true;

		},

		

		'nth-child' : function(oEl, nMul, nAdd) {

			var nIndex = getNodeIndex(oEl);

			return nIndex % nMul == nAdd;

		},

		

		'nth-last-child' : function(oEl, nMul, nAdd) {

			var oLast = (oEl.parentNode || oEl._IE5_parentNode).lastChild;

			for (; oLast; oLast = oLast.previousSibling)

				if (oLast.nodeType == 1) break;

				

			var nTotal = getNodeIndex(oLast);

			var nIndex = getNodeIndex(oEl);

			

			var nLastIndex = nTotal - nIndex + 1;

			return nLastIndex % nMul == nAdd;

		}

		

	};

	

	// ´ÜÀÏ part ÀÇ body ¿¡¼­ expression »Ì¾Æ³¿

	var getExpression = function(sBody) {



		var oRet = { defines : '', returns : 'true' };

		

		var sBody = restoreKeys(sBody, true);

	

		var aExprs = [];

		var aDefineCode = [], aReturnCode = [];

		var sId, sTagName;

		

		// À¯»çÅ¬·¡½º Á¶°Ç ¾ò¾î³»±â

		var sBody = sBody.replace(/:([\w-]+)(\(([^)]*)\))?/g, function(_1, sType, _2, sOption) {

			

			switch (sType) {

			case 'not':

				var oInner = getExpression(sOption); // °ýÈ£ ¾È¿¡ ÀÖ´Â°Å Àç±ÍÆÄ½ÌÇÏ±â

				

				var sFuncDefines = oInner.defines;

				var sFuncReturns = oInner.returnsID + oInner.returnsTAG + oInner.returns;

				

				aReturnCode.push('!(function() { ' + sFuncDefines + ' return ' + sFuncReturns + ' })()');

				break;

				

			case 'nth-child':

			case 'nth-last-child':

				sOption =  restoreString(sOption);

				

				if (sOption == 'even') sOption = '2n';

				else if (sOption == 'odd') sOption = '2n+1';



				var nMul, nAdd;

				

				if (/([0-9]*)n([+-][0-9]+)*/.test(sOption)) {

					nMul = parseInt(RegExp.$1) || 1;

					nAdd = parseInt(RegExp.$2) || 0;

				} else {

					nMul = Infinity;

					nAdd = parseInt(sOption);

				}

				

				aReturnCode.push('oPseudoes_dontShrink[' + wrapQuot(sType) + '](oEl, ' + nMul + ', ' + nAdd + ')');

				break;

				

			case 'first-of-type':

			case 'last-of-type':

				sType = (sType == 'first-of-type' ? 'nth-of-type' : 'nth-last-of-type');

				sOption = 1;

				

			case 'nth-of-type':

			case 'nth-last-of-type':

				sOption =  restoreString(sOption);

				

				if (sOption == 'even') sOption = '2n';

				else if (sOption == 'odd') sOption = '2n+1';



				var nMul, nAdd;

				

				if (/([0-9]*)n([+-][0-9]+)*/.test(sOption)) {

					nMul = parseInt(RegExp.$1) || 1;

					nAdd = parseInt(RegExp.$2) || 0;

				} else {

					nMul = Infinity;

					nAdd = parseInt(sOption);

				}

				

				oRet.nth = [ nMul, nAdd, sType ];

				break;

				

			default:

				sOption = sOption ? restoreString(sOption) : '';

				aReturnCode.push('oPseudoes_dontShrink[' + wrapQuot(sType) + '](oEl, ' + wrapQuot(sOption) + ')');

				break;

			}

			

			return '';

			

		});

		

		// [key=value] ÇüÅÂ Á¶°Ç ¾ò¾î³»±â

		var sBody = sBody.replace(/\[(@?[\w-]+)(([!^~$*]?=)([^\]]*))?\]/g, function(_1, sKey, _2, sOp, sVal) {

			

			sKey = restoreString(sKey);

			sVal = restoreString(sVal);

			

			if (sKey == 'checked' || sKey == 'disabled' || sKey == 'enabled' || sKey == 'readonly' || sKey == 'selected') {

				

				if (!sVal) {

					sOp = '=';

					sVal = 'true';

				}

				

			}

			

			aExprs.push({ key : sKey, op : sOp, val : sVal });

			return '';

	

		});

		

		var sClassName = null;

	

		// Å¬·¡½º Á¶°Ç ¾ò¾î³»±â

		var sBody = sBody.replace(/\.([\w-]+)/g, function(_, sClass) { 

			aExprs.push({ key : 'class', op : '~=', val : sClass });

			if (!sClassName) sClassName = sClass;

			return '';

		});

		

		// id Á¶°Ç ¾ò¾î³»±â

		var sBody = sBody.replace(/#([\w-]+)/g, function(_, sIdValue) {

			if (bXMLDocument) aExprs.push({ key : 'id', op : '=', val : sIdValue });

			else sId = sIdValue;

			return '';

		});

		

		sTagName = sBody == '*' ? '' : sBody;

	

		// match ÇÔ¼ö ÄÚµå ¸¸µé¾î ³»±â

		var oVars = {};

		

		for (var i = 0, oExpr; oExpr = aExprs[i]; i++) {

			

			var sKey = oExpr.key;

			

			if (!oVars[sKey]) aDefineCode.push(getDefineCode(sKey));

			aReturnCode.unshift(getReturnCode(oExpr)); // À¯»çÅ¬·¡½º Á¶°Ç °Ë»ç°¡ ¸Ç µÚ·Î °¡µµ·Ï unshift »ç¿ë

			oVars[sKey] = true;

			

		}

		

		if (aDefineCode.length) oRet.defines = 'var ' + aDefineCode.join(',') + ';';

		if (aReturnCode.length) oRet.returns = aReturnCode.join('&&');

		

		oRet.quotID = sId ? wrapQuot(sId) : '';

		oRet.quotTAG = sTagName ? wrapQuot(bXMLDocument ? sTagName : sTagName.toUpperCase()) : '';

		

		if (bSupportByClassName) oRet.quotCLASS = sClassName ? wrapQuot(sClassName) : '';

		

		oRet.returnsID = sId ? 'oEl.id == ' + oRet.quotID + ' && ' : '';

		oRet.returnsTAG = sTagName && sTagName != '*' ? 'oEl.tagName == ' + oRet.quotTAG + ' && ' : '';

		

		return oRet;

		

	};

	

	// Äõ¸®¸¦ ¿¬»êÀÚ ±âÁØÀ¸·Î Àß¶ó³¿

	var splitToParts = function(sQuery) {

		

		var aParts = [];

		var sRel = ' ';

		

		var sBody = sQuery.replace(/(.*?)\s*(!?[+>~ ]|!)\s*/g, function(_, sBody, sRelative) {

			

			if (sBody) aParts.push({ rel : sRel, body : sBody });

	

			sRel = sRelative.replace(/\s+$/g, '') || ' ';

			return '';

			

		});

	

		if (sBody) aParts.push({ rel : sRel, body : sBody });

		

		return aParts;

		

	};

	

	var isNth_dontShrink = function(oEl, sTagName, nMul, nAdd, sDirection) {

		

		var nIndex = 0;

		for (var oSib = oEl; oSib; oSib = oSib[sDirection])

			if (oSib.nodeType == 1 && (!sTagName || sTagName == oSib.tagName))

					nIndex++;



		return nIndex % nMul == nAdd;



	};

	

	// Àß¶ó³½ part ¸¦ ÇÔ¼ö·Î ÄÄÆÄÀÏ ÇÏ±â

	var compileParts = function(aParts) {

		

		var aPartExprs = [];

		

		// Àß¶ó³½ ºÎºÐµé Á¶°Ç ¸¸µé±â

		for (var i = 0, oPart; oPart = aParts[i]; i++)

			aPartExprs.push(getExpression(oPart.body));

		

		//////////////////// BEGIN

		

		var sFunc = '';

		var sPushCode = 'aRet.push(oEl); if (oOptions.single) { bStop = true; }';



		for (var i = aParts.length - 1, oPart; oPart = aParts[i]; i--) {

			

			var oExpr = aPartExprs[i];

			var sPush = (debugOption.callback ? 'cost++;' : '') + oExpr.defines;

			

			// console.log(oExpr);



			var sReturn = 'if (bStop) {' + (i == 0 ? 'return aRet;' : 'return;') + '}';

			

			if (oExpr.returns == 'true') sPush += (sFunc ? sFunc + '(oEl);' : sPushCode) + sReturn;

			else sPush += 'if (' + oExpr.returns + ') {' + (sFunc ? sFunc + '(oEl);' : sPushCode ) + sReturn + '}';

			

			var sCheckTag = 'oEl.nodeType != 1';

			if (oExpr.quotTAG) sCheckTag = 'oEl.tagName != ' + oExpr.quotTAG;

			

			var sTmpFunc =

				'(function(oBase' +

					(i == 0 ? ', oOptions) { var bStop = false; var aRet = [];' : ') {');



			if (oExpr.nth) {

				sPush =

					'if (isNth_dontShrink(oEl, ' +

					(oExpr.quotTAG ? oExpr.quotTAG : 'false') + ',' +

					oExpr.nth[0] + ',' +

					oExpr.nth[1] + ',' +

					'"' + (oExpr.nth[2] == 'nth-of-type' ? 'previousSibling' : 'nextSibling') + '")) {' + sPush + '}';

			}

			

			switch (oPart.rel) {

			case ' ':

				if (oExpr.quotID) {

					

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oCandi = oEl;' +

						'for (; oCandi; oCandi = (oCandi.parentNode || oCandi._IE5_parentNode)) {' +

							'if (oCandi == oBase) break;' +

						'}' +

						'if (!oCandi || ' + sCheckTag + ') return aRet;' +

						sPush;

					

				} else {

					

					sTmpFunc +=

						'var aCandi = getChilds_dontShrink(oBase, ' + (oExpr.quotTAG || '"*"') + ', ' + (oExpr.quotCLASS || 'null') + ');' +

						'for (var i = 0, oEl; oEl = aCandi[i]; i++) {' +

							(oExpr.quotCLASS ? 'if (' + sCheckTag + ') continue;' : '') +

							sPush +

						'}';

					

				}

			

				break;

				

			case '>':

				if (oExpr.quotID) {

	

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'if ((oEl.parentNode || oEl._IE5_parentNode) != oBase || ' + sCheckTag + ') return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'for (var oEl = oBase.firstChild; oEl; oEl = oEl.nextSibling) {' +

							'if (' + sCheckTag + ') { continue; }' +

							sPush +

						'}';

					

				}

				

				break;

				

			case '+':

				if (oExpr.quotID) {

	

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oPrev;' +

						'for (oPrev = oEl.previousSibling; oPrev; oPrev = oPrev.previousSibling) { if (oPrev.nodeType == 1) break; }' +

						'if (!oPrev || oPrev != oBase || ' + sCheckTag + ') return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) { if (oEl.nodeType == 1) break; }' +

						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +

						sPush;

					

				}

				

				break;

			

			case '~':

	

				if (oExpr.quotID) {

	

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oCandi = oEl;' +

						'for (; oCandi; oCandi = oCandi.previousSibling) { if (oCandi == oBase) break; }' +

						'if (!oCandi || ' + sCheckTag + ') return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) {' +

							'if (' + sCheckTag + ') { continue; }' +

							'if (!markElement_dontShrink(oEl, ' + i + ')) { break; }' +

							sPush +

						'}';

	

				}

				

				break;

				

			case '!' :

			

				if (oExpr.quotID) {

					

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'for (; oBase; oBase = (oBase.parentNode || oBase._IE5_parentNode)) { if (oBase == oEl) break; }' +

						'if (!oBase || ' + sCheckTag + ') return aRet;' +

						sPush;

						

				} else {

					

					sTmpFunc +=

						'for (var oEl = (oBase.parentNode || oBase._IE5_parentNode); oEl; oEl = (oEl.parentNode || oEl._IE5_parentNode)) {'+

							'if (' + sCheckTag + ') { continue; }' +

							sPush +

						'}';

					

				}

				

				break;

	

			case '!>' :

			

				if (oExpr.quotID) {

	

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oRel = (oBase.parentNode || oBase._IE5_parentNode);' +

						'if (!oRel || oEl != oRel || (' + sCheckTag + ')) return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'var oEl = (oBase.parentNode || oBase._IE5_parentNode);' +

						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +

						sPush;

					

				}

				

				break;

				

			case '!+' :

				

				if (oExpr.quotID) {

	

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oRel;' +

						'for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { if (oRel.nodeType == 1) break; }' +

						'if (!oRel || oEl != oRel || (' + sCheckTag + ')) return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) { if (oEl.nodeType == 1) break; }' +

						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +

						sPush;

					

				}

				

				break;

	

			case '!~' :

				

				if (oExpr.quotID) {

					

					sTmpFunc +=

						'var oEl = oDocument_dontShrink.getElementById(' + oExpr.quotID + ');' +

						'var oRel;' +

						'for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { ' +

							'if (oRel.nodeType != 1) { continue; }' +

							'if (oRel == oEl) { break; }' +

						'}' +

						'if (!oRel || (' + sCheckTag + ')) return aRet;' +

						sPush;

					

				} else {

	

					sTmpFunc +=

						'for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) {' +

							'if (' + sCheckTag + ') { continue; }' +

							'if (!markElement_dontShrink(oEl, ' + i + ')) { break; }' +

							sPush +

						'}';

					

				}

				

				break;

			}

	

			sTmpFunc +=

				(i == 0 ? 'return aRet;' : '') +

			'})';

			

			sFunc = sTmpFunc;

			

		}

		

		// alert(sFunc);

		//console.log(sFunc);

		eval('var fpCompiled = ' + sFunc + ';');

		//alert(fpCompiled);

		return fpCompiled;

		

	};

	

	// Äõ¸®¸¦ match ÇÔ¼ö·Î º¯È¯

	var parseQuery = function(sQuery) {

		

		var sCacheKey = sQuery;

		

		var fpSelf = arguments.callee;

		var fpFunction = fpSelf._cache[sCacheKey];

		

		if (!fpFunction) {

			

			sQuery = backupKeys(sQuery);

			

			var aParts = splitToParts(sQuery);

			

			fpFunction = fpSelf._cache[sCacheKey] = compileParts(aParts);

			fpFunction.depth = aParts.length;

			

		}

		

		return fpFunction;

		

	};

	

	parseQuery._cache = {};

	

	// test Äõ¸®¸¦ match ÇÔ¼ö·Î º¯È¯

	var parseTestQuery = function(sQuery) {

		

		var fpSelf = arguments.callee;

		

		var aSplitQuery = backupKeys(sQuery).split(/\s*,\s*/);

		var aResult = [];

		

		var nLen = aSplitQuery.length;

		var aFunc = [];

		

		for (var i = 0; i < nLen; i++) {



			aFunc.push((function(sQuery) {

				

				var sCacheKey = sQuery;

				var fpFunction = fpSelf._cache[sCacheKey];

				

				if (!fpFunction) {

					

					sQuery = backupKeys(sQuery);

					var oExpr = getExpression(sQuery);

					

					eval('fpFunction = function(oEl) { ' + oExpr.defines + 'return (' + oExpr.returnsID + oExpr.returnsTAG + oExpr.returns + '); };');

					

				}

				

				return fpFunction;

				

			})(restoreKeys(aSplitQuery[i])));

			

		}

		

		return aFunc;

		

	};

	

	parseTestQuery._cache = {};

	

	var distinct = function(aList) {

	

		var aDistinct = [];

		var oDummy = {};

		

		for (var i = 0, oEl; oEl = aList[i]; i++) {

			

			var nUID = getUID(oEl);

			if (oDummy[nUID]) continue;

			

			aDistinct.push(oEl);

			oDummy[nUID] = true;

		}

	

		return aDistinct;

	

	};

	

	var markElement_dontShrink = function(oEl, nDepth) {

		

		var nUID = getUID(oEl);

		if (cssquery._marked[nDepth][nUID]) return false;

		

		cssquery._marked[nDepth][nUID] = true;

		return true;



	};

	

	var oResultCache = null;

	var bUseResultCache = false;

		

	/**

	 * CSS ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ¿© ¿¤¸®¸ÕÆ® ¸ñ·ÏÀ» ¾ò¾î¿Â´Ù

	 * @param {String} selector	CSS ¼¿·ºÅÍ

	 * @param {Document | Element} el	Å½»öÀ» ÁøÇàÇÏ´Â ±âÁØÀÌ µÇ´Â ¿¤¸®¸ÕÆ® ¶Ç´Â ¹®¼­ (»ý·«½Ã ÇöÀç ¹®¼­ÀÇ document °´Ã¼)

	 * @remark el ·Î´Â XMLDocument ¶Ç´Â XMLElement µµ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

	 * @return {Array} ¼±ÅÃµÈ ¿¤¸®¸ÕÆ® ¸ñ·ÏÀÇ ¹è¿­

	 */

	var cssquery = function(sQuery, oParent, oOptions) {

		

		if (typeof sQuery == 'object') {

			

			var oResult = {};

			

			for (var k in sQuery)

				oResult[k] = arguments.callee(sQuery[k], oParent, oOptions);

			

			return oResult;

		}

		

		cost = 0;

		

		var executeTime = new Date().getTime();

		var aRet;

		

		for (var r = 0, rp = debugOption.repeat; r < rp; r++) {

			

			aRet = (function(sQuery, oParent, oOptions) {

				

				oOptions = oOptions || {};

				

				if (!oParent) oParent = document;

					

				// ownerDocument Àâ¾ÆÁÖ±â

				oDocument_dontShrink = oParent.ownerDocument || oParent.document || oParent;

				

				// ºê¶ó¿ìÀú ¹öÁ¯ÀÌ IE5.5 ÀÌÇÏ

				if (/\bMSIE\s([0-9]+(\.[0-9]+)*);/.test(navigator.userAgent) && parseFloat(RegExp.$1) < 6) {

					

					try { oDocument_dontShrink.location; } catch(e) { oDocument_dontShrink = document; }

					

					oDocument_dontShrink.firstChild = oDocument_dontShrink.getElementsByTagName('html')[0];

					oDocument_dontShrink.firstChild._IE5_parentNode = oDocument_dontShrink;

				}

				

				// XMLDocument ÀÎÁö Ã¼Å©

				bXMLDocument = (typeof XMLDocument != 'undefined') ? (oDocument_dontShrink.constructor === XMLDocument) : (!oDocument_dontShrink.location);

				getUID = bXMLDocument ? getUID4XML : getUID4HTML;

		

				clearKeys();

				

				// Äõ¸®¸¦ ½°Ç¥·Î ³ª´©±â

				var aSplitQuery = backupKeys(sQuery).split(/\s*,\s*/);

				var aResult = [];

				

				var nLen = aSplitQuery.length;

				

				for (var i = 0; i < nLen; i++)

					aSplitQuery[i] = restoreKeys(aSplitQuery[i]);

				

				// ½°Ç¥·Î ³ª´²Áø Äõ¸® ·çÇÁ

				for (var i = 0; i < nLen; i++) {

					

					var sSingleQuery = aSplitQuery[i];

					var aSingleQueryResult = null;

					

					var sResultCacheKey = sSingleQuery + (oOptions.single ? '_single' : '');

		

					// °á°ú Ä³½¬ µÚÁü

					var aCache = bUseResultCache ? oResultCache[sResultCacheKey] : null;

					if (aCache) {

						

						// Ä³½ÌµÇ¾î ÀÖ´Â°Ô ÀÖÀ¸¸é parent °¡ °°Àº°ÇÁö °Ë»çÇÑÈÄ aSingleQueryResult ¿¡ ´ëÀÔ

						for (var j = 0, oCache; oCache = aCache[j]; j++) {

							if (oCache.parent == oParent) {

								aSingleQueryResult = oCache.result;

								break;

							}

						}

						

					}

					

					if (!aSingleQueryResult) {

						

						var fpFunction = parseQuery(sSingleQuery);

						// alert(fpFunction);

						

						cssquery._marked = [];

						for (var j = 0, nDepth = fpFunction.depth; j < nDepth; j++)

							cssquery._marked.push({});

						

						aSingleQueryResult = distinct(fpFunction(oParent, oOptions));

						

						// °á°ú Ä³½¬¸¦ »ç¿ëÁßÀÌ¸é Ä³½¬¿¡ ÀúÀå

						if (bUseResultCache) {

							if (!(oResultCache[sResultCacheKey] instanceof Array)) oResultCache[sResultCacheKey] = [];

							oResultCache[sResultCacheKey].push({ parent : oParent, result : aSingleQueryResult });

						}

						

					}

					

					aResult = aResult.concat(aSingleQueryResult);

					

				}

		

				unsetNodeIndexes();

		

				return aResult;

				

			})(sQuery, oParent, oOptions);

			

		}

		

		executeTime = new Date().getTime() - executeTime;



		if (debugOption.callback) debugOption.callback(sQuery, cost, executeTime);

		

		return aRet;

		

	};



	/**

	 * Æ¯Á¤ ¿¤¸®¸ÕÆ®°¡ ÇØ´ç CSS ¼¿·ºÅÍ¿¡ ºÎÇÕÇÏ´Â ¿¤¸®¸ÕÆ®ÀÎÁö ÆÇ´ÜÇÑ´Ù

	 * @remark CSS ¼¿·ºÅÍ¿¡ ¿¬°áÀÚ´Â »ç¿ëÇÒ ¼ö ¾øÀ½¿¡ À¯ÀÇÇÑ´Ù.

	 * @param {Element} element	°Ë»çÇÏ°íÀÚ ÇÏ´Â ¿¤¸®¸ÕÆ®

	 * @param {String} selector	CSS ¼¿·ºÅÍ

	 * @return {Boolean} ¼¿·ºÅÍ Á¶°Ç¿¡ ºÎÇÕÇÏ¸é true, ºÎÇÕÇÏÁö ¾ÊÀ¸¸é false

	 * @example



// oEl ÀÌ div ÅÂ±× ¶Ç´Â p ÅÂ±×, ¶Ç´Â align=center ÀÎ ¿¤¸®¸ÕÆ®ÀÎÁö

if (cssquery.test(oEl, 'div, p, [align=center]')) alert('ÇØ´ç Á¶°Ç ¸¸Á·');// oEl ÀÌ div ÅÂ±× ¶Ç´Â p ÅÂ±×, ¶Ç´Â align=center ÀÎ ¿¤¸®¸ÕÆ®ÀÎÁö

if (cssquery.test(oEl, 'div, p, [align=center]')) alert('ÇØ´ç Á¶°Ç ¸¸Á·');



	 */

	cssquery.test = function(oEl, sQuery) {



		clearKeys();

		

		var aFunc = parseTestQuery(sQuery);

		

		for (var i = 0, nLen = aFunc.length; i < nLen; i++)

			if (aFunc[i](oEl)) return true;

			

		return false;

		

	};



	/**

	 * cssquery ¿¡ °á°ú Ä³½¬¸¦ »ç¿ëÇÒ °ÍÀÎÁö ÁöÁ¤ÇÏ°Å³ª È®ÀÎÇÑ´Ù.

	 * @remark °á°ú Ä³½¬¸¦ »ç¿ëÇÏ¸é µ¿ÀÏÇÑ ¼¿·ºÅÍ¸¦ »ç¿ëÇßÀ» °æ¿ì »õ·Î Å½»öÀ» ÇÏÁö ¾Ê°í ±âÁ¸ Å½»ö °á°ú¸¦ ±×´ë·Î ¹ÝÈ¯ÇÏ±â ¶§¹®¿¡ »ç¿ëÀÚ°¡ º¯¼ö Ä³½¬¿¡ ½Å°æ¾²Áö ¾Ê°í ÆíÇÏ°í ºü¸£°Ô ¾µ ¼ö ÀÖ´Â ÀåÁ¡ÀÌ ÀÖÁö¸¸ °á°úÀÇ ½Å·Ú¼ºÀ» À§ÇØ DOM ¿¡ º¯È­°¡ ¾ø´Ù´Â °ÍÀÌ È®½ÇÇÒ¶§¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù.

	 * @param {Boolean} flag	»ç¿ëÇÒ °Í ÀÎÁö ¿©ºÎ (»ý·«½Ã »ç¿ë ¿©ºÎ¸¸ ¹ÝÈ¯)

	 * @return {Boolean} °á°ú Ä³½¬¸¦ »ç¿ëÇÏ´ÂÁö ¿©ºÎ

	 */

	cssquery.useCache = function(bFlag) {

	

		if (typeof bFlag != 'undefined') {

			bUseResultCache = bFlag;

			cssquery.clearCache();

		}

		

		return bUseResultCache;

		

	};

	

	/**

	 * °á°ú Ä³½¬¸¦ »ç¿ë Áß¿¡ DOM ÀÇ º¯È­°¡ »ý±â´Â µîÀÇ ÀÌÀ¯·Î Ä³½¬¸¦ ¸ðµÎ ºñ¿öÁÖ°í ½ÍÀ»¶§ »ç¿ëÇÑ´Ù.

	 * @return {Void} ¹ÝÈ¯°ª ¾øÀ½

	 */

	cssquery.clearCache = function() {

		oResultCache = {};

	};

	

	/**

	 * CSS ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ¿© DOM ¿¡¼­ ¿øÇÏ´Â ¿¤¸®¸ÕÆ®¸¦ ÇÏ³ª¸¸ ¾ò¾î³½´Ù. ¹ÝÈ¯ÇÏ´Â °ªÀº ¹è¿­ÀÌ ¾Æ´Ñ °´Ã¼ ¶Ç´Â null ÀÌ´Ù.

	 * @remark °á°ú¸¦ ÇÏ³ª¸¸ ¾ò¾î³»¸é ÀÌÈÄÀÇ ¸ðµç Å½»ö ÀÛ¾÷À» Áß´ÜÇÏ±â ¶§¹®¿¡ °á°ú°¡ ÇÏ³ª¶ó´Â º¸ÀåÀÌ ÀÖÀ»¶§ ºü¸¥ ¼Óµµ·Î °á°ú¸¦ ¾ò¾î¿Ã ¼ö ÀÖ´Ù.

	 * @param {String} selector	CSS ¼¿·ºÅÍ

	 * @param {Document | Element} el	Å½»öÀ» ÁøÇàÇÏ´Â ±âÁØÀÌ µÇ´Â ¿¤¸®¸ÕÆ® ¶Ç´Â ¹®¼­ (»ý·«½Ã ÇöÀç ¹®¼­ÀÇ document °´Ã¼)

	 * @return {Element} ¼±ÅÃµÈ ¿¤¸®¸ÕÆ®

	 */

	cssquery.getSingle = function(sQuery, oParent) {

		return cssquery(sQuery, oParent, { single : true })[0] || null;

	};

	

	/**

	 * XPath ¹®¹ýÀ» »ç¿ëÇÏ¿© ¿¤¸®¸ÕÆ®¸¦ ¾ò¾î¿Â´Ù.

	 * @remark Áö¿øÇÏ´Â ¹®¹ýÀÌ ¹«Ã´ Á¦ÇÑÀûÀ¸·Î Æ¯¼öÇÑ °æ¿ì¿¡¼­¸¸ »ç¿ëÇÏ´Â °ÍÀ» ±ÇÀåÇÑ´Ù.

	 * @param {String} xpath	XPath

	 * @param {Document | Element} el	Å½»öÀ» ÁøÇàÇÏ´Â ±âÁØÀÌ µÇ´Â ¿¤¸®¸ÕÆ® ¶Ç´Â ¹®¼­ (»ý·«½Ã ÇöÀç ¹®¼­ÀÇ document °´Ã¼)

	 * @return {Array} ¼±ÅÃµÈ ¿¤¸®¸ÕÆ® ¸ñ·ÏÀÇ ¹è¿­

	 */

	cssquery.xpath = function(sXPath, oParent) {

		

		var sXPath = sXPath.replace(/\/(\w+)(\[([0-9]+)\])?/g, function(_1, sTag, _2, sTh) {

			sTh = sTh || '1';

			return '>' + sTag + ':nth-of-type(' + sTh + ')';

		});

		

		return cssquery(sXPath, oParent);

		

	};

	

	/**

	 * cssquery ¸¦ »ç¿ëÇÒ ¶§ÀÇ ¼º´ÉÀ» ÃøÁ¤ÇÏ±â À§ÇÑ ¹æ¹ýÀ» Á¦°øÇÏ´Â ÇÔ¼öÀÌ´Ù.

	 * @param {Function} callback	¼¿·ºÅÍ ½ÇÇà¿¡ ¼Ò¿äµÈ ºñ¿ë°ú ½Ã°£À» ¹Þ¾ÆµéÀÌ´Â ÇÔ¼ö (false ÀÎ °æ¿ì debug ¿É¼ÇÀ» ²û)

	 * @param {Number} repeat	ÇÏ³ªÀÇ ¼¿·ºÅÍ¸¦ ¹Ýº¹ÇÏ¿© ¼öÇàÇÏµµ·Ï ÇØ¼­ ÀÎÀ§ÀûÀ¸·Î ½ÇÇà ¼Óµµ¸¦ ´ÊÃã

	 * @remark callback ÇÔ¼öÀÇ ÇüÅÂ´Â ¾Æ·¡¿Í °°½À´Ï´Ù.

	 * callback : function({String}query, {Number}cost, {Number}executeTime)

	 * <dl>

	 *	<dt>query</dt>

	 *	<dd>½ÇÇà¿¡ »ç¿ëµÈ ¼¿·ºÅÍ</dd>

	 *	<dt>cost</dt>

	 *	<dd>Å½»ö¿¡ »ç¿ëµÈ ºñ¿ë (·çÇÁ È½¼ö)</dd>

	 *	<dt>executeTime</dt>

	 *	<dd>Å½»ö¿¡ ¼Ò¿äµÈ ½Ã°£</dd>

	 * </dl>

	 * @return {Void} ¹ÝÈ¯°ª ¾øÀ½

	 * @example



cssquery.debug(function(sQuery, nCost, nExecuteTime) {

	if (nCost > 5000) 

		console.warn('5000 ÀÌ ³Ñ´Â ºñ¿ëÀÌ?! Ã¼Å©ÇØº¸ÀÚ -> ' + sQuery + '/' + nCost);

	else if (nExecuteTime > 200)

		console.warn('0.2ÃÊ°¡ ³Ñ°Ô ½ÇÇàÀ»?! Ã¼Å©ÇØº¸ÀÚ -> ' + sQuery + '/' + nExecuteTime);

}, 20);



....



cssquery.debug(false);



	 */

	cssquery.debug = function(fpCallback, nRepeat) {

		

		debugOption.callback = fpCallback;

		debugOption.repeat = nRepeat || 1;

		

	};

	

	/**

	 * IE ¿¡¼­ innerHTML À» ¾µ¶§ _cssquery_UID ³ª¿ÀÁö ¾Êµµ·Ï ÇÏ´Â ÇÔ¼öÀÌ´Ù.

	 * true ·Î ¼³Á¤ÇÏ¸é ±×¶§ºÎÅÍ Å½»öÇÏ´Â ³ëµå¿¡ ´ëÇØ¼­´Â innerHTML ¿¡ _cssquery_UID °¡ ³ª¿ÀÁö ¾Êµµ·Ï ÇÏÁö¸¸ Å½»ö¼Óµµ´Â ´Ù¼Ò ´À·ÁÁú ¼ö ÀÖ´Ù.

	 * @param {Boolean} flag	true ·Î ¼ÂÆÃÇÏ¸é _cssquery_UID °¡ ³ª¿ÀÁö ¾ÊÀ½

	 * @return {Boolean}	_cssquery_UID °¡ ³ª¿ÀÁö ¾Ê´Â »óÅÂÀÌ¸é true ¹ÝÈ¯

	 */

	cssquery.safeHTML = function(bFlag) {

		

		var bIE = /MSIE/.test(window.navigator.userAgent);

		

		if (arguments.length > 0)

			safeHTML = bFlag && bIE;

		

		return safeHTML || !bIE;

		

	};

	

	/**

	 * cssquery ÀÇ ¹öÁ¯Á¤º¸¸¦ ´ã°í ÀÖ´Â ¹®ÀÚ¿­ÀÌ´Ù.

	 */

	cssquery.version = sVersion;



	return cssquery;

	

})();




/**
 * @fileOverview $AgentÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 */

/**
 * Agent °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù. Agent °´Ã¼´Â ºê¶ó¿ìÀú¿Í OS¿¡ ´ëÇÑ Á¤º¸¸¦ ¾Ë ¼ö ÀÖµµ·Ï ÇÑ´Ù.
 * @class Agent °´Ã¼´Â ¿î¿µÃ¼Á¦, ºê¶ó¿ìÀú¸¦ ºñ·ÔÇÑ »ç¿ëÀÚ ½Ã½ºÅÛÀÇ Á¤º¸¸¦ °¡Á®¿Â´Ù. 
 * @constructor
 * @author Kim, Taegon
 */
jindo.$Agent = function() {
	var cl = arguments.callee;
	var cc = cl._cached;
		
	if (cc) return cc;
	if (!(this instanceof cl)) return new cl;	
	if (!cc) cl._cached = this;
	
	this._navigator = navigator;	
}

/**
 * navigator ¸Þ¼­µå´Â À¥ ºê¶ó¿ìÀúÀÇ Á¤º¸ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù. 
 * @return {Object} À¥ ºê¶ó¿ìÀú Á¤º¸¸¦ ÀúÀåÇÏ´Â °´Ã¼. 
 * object´Â ºê¶ó¿ìÀú ÀÌ¸§°ú ¹öÀüÀ» ¼Ó¼ºÀ¸·Î °¡Áø´Ù. ºê¶ó¿ìÀú ÀÌ¸§Àº ¿µ¾î ¼Ò¹®ÀÚ·Î Ç¥½ÃÇÏ¸ç, »ç¿ëÀÚÀÇ ºê¶ó¿ìÀú¿Í ÀÏÄ¡ÇÏ´Â ºê¶ó¿ìÀú ÀÌ¸§Àº true¸¦ °¡Áø´Ù. 
 * @example
oAgent = $Agent().navigator(); // »ç¿ëÀÚ°¡ ÆÄÀÌ¾îÆø½º 3¸¦ »ç¿ëÇÑ´Ù°í °¡Á¤ÇÑ´Ù. 
oAgent.camino  // false
oAgent.firefox  // true
oAgent.konqueror // false
oAgent.mozilla  //true
oAgent.netscape  // false
oAgent.omniweb  //false
oAgent.opera  //false
oAgent.webkit  /false
oAgent.safari  //false
oAgent.ie  //false
oAgent.chrome  //false
oAgent.icab  //false
oAgent.version  //3
oAgent.getName() // firefox
*/
 
jindo.$Agent.prototype.navigator = function() {
	var info = new Object;
	var ver  = -1;
	var u    = this._navigator.userAgent;
	var v    = this._navigator.vendor || "";
	
	function f(s,h){ return ((h||"").indexOf(s) > -1) };

	info.getName = function(){
		var name = "";
		for(x in info)
		{
			if(typeof info[x] == "boolean" && info[x])
				name = x;			
		}
		return name;	
	}
		
	info.webkit		= f("WebKit",u);
	info.opera     = (typeof window.opera != "undefined") || f("Opera",u);
	info.ie        = !info.opera && f("MSIE",u);
	info.chrome    = info.webkit && f("Chrome",u);	
	info.safari    = info.webkit && !info.chrome && f("Apple",v);
	info.firefox   = f("Firefox",u);
	info.mozilla   = f("Gecko",u) && !info.safari && !info.chrome && !info.firefox;
	info.camino    = f("Camino",v);
	info.netscape  = f("Netscape",u);
	info.omniweb   = f("OmniWeb",u);
	info.icab      = f("iCab",v);
	info.konqueror = f("KDE",v);

	try {
		if (info.ie) {
			ver = u.match(/(?:MSIE) ([0-9.]+)/)[1];
		} else if (info.firefox||info.opera||info.omniweb) {
			ver = u.match(/(?:Firefox|Opera|OmniWeb)\/([0-9.]+)/)[1];
		} else if (info.mozilla) {
			ver = u.match(/rv:([0-9.]+)/)[1];
		} else if (info.safari) {
			ver = parseFloat(u.match(/Safari\/([0-9.]+)/)[1]);
			if (ver == 100) {
				ver = 1.1;
			} else {
				ver = [1.0,1.2,-1,1.3,2.0,3.0][Math.floor(ver/100)];
			}
		} else if (info.icab) {
			ver = u.match(/iCab[ \/]([0-9.]+)/)[1];
		} else if (info.chrome) {
			ver = u.match(/Chrome[ \/]([0-9.]+)/)[1];
		}

		info.version = parseFloat(ver);
		if (isNaN(info.version)) info.version = -1;
	} catch(e) {
		info.version = -1;
	}
	
	this.navigator = function() {
		return info;
	};
	
	return info;
};

/**
 * os ¸Þ¼­µå´Â ¿î¿µÃ¼Á¦¿¡ ´ëÇÑ Á¤º¸ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @return {Object} ¿î¿µÃ¼Á¦ Á¤º¸ °´Ã¼. ¿î¿µÃ¼Á¦ÀÇ ¿µ¹® ÀÌ¸§À» ¼Ó¼ºÀ¸·Î °¡Áö¸ç, »ç¿ëÀÚ°¡ »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦¿Í µ¿ÀÏÇÑ ÀÌ¸§ÀÇ ¼Ó¼ºÀº true¸¦ °¡Áø´Ù.
 * @example
oOS = $Agent().os();  // »ç¿ëÀÚÀÇ ¿î¿µÃ¼Á¦°¡ Windows XP¶ó°í °¡Á¤ÇÑ´Ù.
oOS.linux  // false
oOS.mac  // false
oOS.vista  // false
oOS.win  // true
oOS.win2000  // false
oOS.winxp  // true
oOS.xpsp2  // false
oOS.win7  // false
oOS.getName() // winxp
 */
jindo.$Agent.prototype.os = function() {
	var info = new Object;
	var u    = this._navigator.userAgent;
	var p    = this._navigator.platform;
	var f    = function(s,h){ return (h.indexOf(s) > -1) };

	info.getName = function(){
		var name = "";
		for(x in info)
		{
			if(typeof info[x] == "boolean" && info[x])
				name = x;			
		}
		return name;	
	}
	
	info.win     = f("Win",p)
	info.mac     = f("Mac",p);
	info.linux   = f("Linux",p);
	info.win2000 = info.win && (f("NT 5.0",u) || f("2000",u));
	info.winxp   = info.win && f("NT 5.1",u);
	info.xpsp2   = info.winxp && f("SV1",u);
	info.vista   = info.win && f("NT 6.0",u);
	info.win7  = info.win && f("NT 6.1",u);

	this.os = function() {
		return info;
	};

	return info;
};

/**
 * flash ¸Þ¼­µå´Â ÇÃ·¡½Ã¿¡ ´ëÇÑ Á¤º¸ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @return {Object} Flash Á¤º¸ °´Ã¼. object.installed´Â ÇÃ·¡½Ã ÇÃ·¹ÀÌ¾î ¼³Ä¡ ¿©ºÎ¸¦ boolean °ªÀ¸·Î °¡Áö°í object.versionÀº ÇÃ·¡½Ã ÇÃ·¹ÀÌ¾îÀÇ ¹öÀüÀ» °¡Áø´Ù. ÇÃ·¡½Ã ¹öÀüÀ» Å½ÁöÇÏÁö ¸øÇÏ¸é flash.versionÀº -1ÀÇ °ªÀ» °¡Áø´Ù.
 * @example
var oFlash = $Agent.flash();
oFlash.installed  // ÇÃ·¡½Ã ÇÃ·¹ÀÌ¾î¸¦ ¼³Ä¡Çß´Ù¸é true
oFlash.version  // ÇÃ·¡½Ã ÇÃ·¹ÀÌ¾îÀÇ ¹öÀü. 
 */
jindo.$Agent.prototype.flash = function() {
	var info = new Object;
	var p    = this._navigator.plugins;
	var m    = this._navigator.mimeTypes;
	var f    = null;

	info.installed = false;
	info.version   = -1;

	if (typeof p != "undefined" && p.length) {
		f = p["Shockwave Flash"];
		if (f) {
			info.installed = true;
			if (f.description) {
				info.version = parseFloat(f.description.match(/[0-9.]+/)[0]);
			}
		}

		if (p["Shockwave Flash 2.0"]) {
			info.installed = true;
			info.version   = 2;
		}
	} else if (typeof m != "undefined" && m.length) {
		f = m["application/x-shockwave-flash"];
		info.installed = (f && f.enabledPlugin);
	} else {
		for(var i=10; i > 1; i--) {
			try {
				f = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+i);

				info.installed = true;
				info.version   = i;
				break;
			} catch(e) {}
		}
	}

	this.flash = function() {
		return info;
	};
	// ÇÏÀ§È£È¯À» À§ÇØ ÀÏ´Ü ³²°ÜµÐ´Ù.
	this.info = this.flash;

	return info;
};

/**
 * silverlight ¸Þ¼­µå´Â ½Ç¹ö¶óÀÌÆ®(SilverLight)¿¡ ´ëÇÑ Á¤º¸ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @returns {Object} Silverlight Á¤º¸ °´Ã¼. object.installedÀº ½Ç¹ö¶óÀÌÆ® ÇÃ·¹ÀÌ¾î ¼³Ä¡ ¿©ºÎ¸¦ boolean °ªÀ¸·Î °¡Áö°í object.versionÀº ½Ç¹ö¶óÀÌÆ® ÇÃ·¹ÀÌ¾îÀÇ ¹öÀüÀ» °¡Áø´Ù. ÇÃ·¹ÀÌ¾îÀÇ ¹öÀüÀ» Å½ÁöÇÏÁö ¸øÇÏ¸é object.versionÀÇ °ªÀº -1ÀÌ µÈ´Ù.
 * @example 
var oSilver = $Agent.silverlight();
oSilver.installed  // SilverLight ÇÃ·¹ÀÌ¾î¸¦ ¼³Ä¡Çß´Ù¸é true
oSilver.version  // SilverLight ÇÃ·¹ÀÌ¾îÀÇ ¹öÀü. 
 */
jindo.$Agent.prototype.silverlight = function() {
	var info = new Object;
	var p    = this._navigator.plugins;
	var s    = null;

	info.installed = false;
	info.version   = -1;

	if (typeof p != "undefined" && p.length) {
		s = p["Silverlight Plug-In"];
		if (s) {
			info.installed = true;
			info.version = parseInt(s.description.split(".")[0]);
			if (s.description == "1.0.30226.2") info.version = 2;
		}
	} else {
		try {
			s = new ActiveXObject("AgControl.AgControl");
			info.installed = true;

			if (s.isVersionSupported("2.0")) {
				info.version = 2;
			} else if (s.isVersionSupported("1.0")) {
				info.version = 1;
			}
		} catch(e) {}
	}

	this.silverlight = function() {
		return info;
	};

	return info;
};

/**
 * @fileOverview $AÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name array.js
 */

/**
 * ¹è¿­, È¤Àº ÄÃ·¢¼ÇÀ» ³»ºÎ ¹è¿­·Î º¯È¯ÇÏ°Å³ª »õ·Î¿î $A °´Ã¼¸¦ »ý¼ºÇÑ´Ù.
 *
 * @extends core
 * @class	$A´Â ¹è¿­ÀÌ³ª ¹è¿­°ú ºñ½ÁÇÑ ÄÃ·º¼Ç(Collection)À» ¹è¿­·Î º¯È¯ÇÑ´Ù. 
 * @param 	{Array} array ¹è¿­ È¤Àº ¹è¿­°ú ºñ½ÁÇÑ ÄÃ·º¼Ç. ¸¸¾à array¸¦ »ý·«ÇÏ¸é ºó ¹è¿­À» °¡Áø »õ·Î¿î $A °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù. 
 * @constructor
 * @description [Lite]
 * @author Kim, Taegon
 */
jindo.$A = function(array) {
	var cl = arguments.callee;
	
	if (typeof array == "undefined") array = [];
	if (array instanceof cl) return array;
	if (!(this instanceof cl)) return new cl(array);

	this._array = [];
	for(var i=0; i < array.length; i++) {
		this._array[this._array.length] = array[i];
	}
};

/**
 * toString ¸Å¼­µå´Â ³»ºÎ ¹è¿­À» ¹®ÀÚ¿­·Î ¸®ÅÏÇÑ´Ù. ÀÚ¹Ù½ºÅ©¸³Æ®ÀÇ Array.toStringÀ» »ç¿ëÇÑ´Ù.
 * @return {String} ³»ºÎ ¹è¿­À» º¯È¯ÇÑ ¹®ÀÚ¿­.
 * @description [Lite]
 */
jindo.$A.prototype.toString = function() {
	return this._array.toString();
};

/**
 * length ¸Å¼­µå´Â ³»ºÎ ¹è¿­ÀÇ Å©±â¸¦ ÁöÁ¤ÇÏ°Å³ª ¹ÝÈ¯ÇÑ´Ù.
 * 
 * @return 	Number ¹è¿­ÀÇ Å©±â
 * @param 	{Number} [nLen]	»õ·Î ¸®ÅÏÇÒ ¹è¿­ÀÇ Å©±â. nLenÀÌ ±âÁ¸ÀÇ ¹è¿­º¸´Ù Å©¸é oValueÀ¸·Î ÃÊ±âÈ­ÇÑ ¿ø¼Ò¸¦ ¸¶Áö¸·¿¡ µ¡ºÙÀÎ´Ù. nLenÀÌ ±âÁ¸ ¹è¿­º¸´Ù ÀÛÀ¸¸é nLen¹øÂ° ÀÌÈÄÀÇ ¿ø¼Ò´Â Á¦°ÅÇÑ´Ù.
 * @param 	{Value} [oValue]	»õ·Î¿î ¿ø¼Ò¸¦ Ãß°¡ÇÒ ¶§ »ç¿ëÇÒ ÃÊ±â°ª
 * @example
var zoo = ["zebra", "giraffe", "bear", "monkey"];
var birds = [];

$A(zoo).length();
// 4

$A(zoo).length(2);				
// zoo.$value = ["zebra", "giraffe"] 

$A(zoo).length(6, "(Empty)");	
//  zoo.$value = ["zebra", "giraffe", "bear", "monkey", "(Empty)", "(Empty)"]

$A(zoo).length(5, birds);
//  zoo.$value = ["zebra", "giraffe", "bear", "monkey", []]
 */
jindo.$A.prototype.length = function(nLen, oValue) {
	if (typeof nLen == "number") {
		var l = this._array.length;
		this._array.length = nLen;
		
		if (typeof oValue != "undefined") {
			for(var i=l; i < nLen; i++) {
				this._array[i] = oValue;
			}
		}

		return this;
	} else {
		return this._array.length;
	}
};

/**
 * has ¸Þ¼­µå´Â ÁÖ¾îÁø ¿ø¼Ò°¡ ¹è¿­¿¡ Á¸ÀçÇÏ´ÂÁö °Ë»öÇÑ´Ù.
 * @return {Boolean} ¹è¿­ÀÇ ¿ø¼ÒÁß ÀÎ¼ö °ª°ú µ¿ÀÏÇÑ ¿ø¼Ò¸¦ °Ë»öÇß´Ù¸é true¸¦, ±×·¸Áö ¾ÊÀ¸¸é false¸¦ ¸®ÅÏÇÑ´Ù. 
 * @param {Value} oValue °Ë»öÇÒ °ª
 * @see $A.indexOf
 * @description [Lite]
 * @example
var arr = $A([1,2,3]);

arr.has(3); // true
arr.has(4); // false
 */
jindo.$A.prototype.has = function(oValue) {
	return (this.indexOf(oValue) > -1);
};

/**
 * indexOf ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¿ø¼Ò¸¦ °Ë»öÇÏ°í, Ã£Àº ¿ø¼ÒÀÇ ÀÎµ¦½º¸¦ ¸®ÅÏÇÑ´Ù.  
 * @param {Value} oValue °Ë»öÇÒ °ª
 * @return {Number} Ã£Àº ¿ø¼ÒÀÇ ÀÎµ¦½º. ¿ø¼ÒÀÇ ÀÎµ¦½º´Â 0ºÎÅÍ ½ÃÀÛÇÑ´Ù. ÀÎ¼ö¿Í µ¿ÀÏÇÑ ¿ø¼Ò¸¦ Ã£Áö ¸øÇÏ¸é -1 À» ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
var zoo = ["zebra", "giraffe", "bear"];

$A(zoo).indexOf("giraffe");
// return 1 
 * @see $A.has
 */
jindo.$A.prototype.indexOf = function(oValue) {
	if (typeof this._array.indexOf != 'undefined') return this._array.indexOf(oValue);

	for(var i=0; i < this._array.length; i++) {
		if (this._array[i] == oValue) return i;
	}
	return -1;
};

/**
 * $value ¸Þ¼­µå´Â ¿øº» ¹è¿­À» ¸®ÅÏÇÑ´Ù.
 * @return {Array} ¹è¿­.
 * @description [Lite]
 */
jindo.$A.prototype.$value = function() {
	return this._array;
};

/**
 * push ¸Þ¼­µå´Â ³»ºÎ ¹è¿­¿¡ ÇÏ³ª ÀÌ»óÀÇ ¿ø¼Ò¸¦ Ãß°¡ÇÑ´Ù. 
 * @param {oValue1, ..., oValueN} oValueN Ãß°¡ÇÒ N °³ÀÇ °ª 
 * @return {Number} ÇÏ³ª ÀÌ»óÀÇ ¿ø¼Ò¸¦ Ãß°¡ÇÑ ³»ºÎ ¹è¿­ÀÇ Å©±â.
 * @description [Lite]
 * @example
var arr = $A([1,2,3]);

arr.push(4); // arr => [1,2,3,4]
arr.push(5,6); // arr => [1,2,3,4,5,6]
 */
jindo.$A.prototype.push = function(oValue1/*, ...*/) {
	return this._array.push.apply(this._array, jindo.$A(arguments).$value());
};

/**
 * pop ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸¶Áö¸· ¿ø¼Ò¸¦ »èÁ¦ÇÑ´Ù.
 * @return {Value} »èÁ¦ÇÑ ¿ø¼Ò
 * @description [Lite]
 * @example
var arr = $A([1,2,3,4,5]);
var elem = arr.pop(); 

document.write(elem); // 5
document.write(arr); // [1,2,3,4]
 */
jindo.$A.prototype.pop = function() {
	return this._array.pop();
};

/**
 * shift ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò¸¦ ÇÑ Ä­¾¿ ¾ÕÀ¸·Î ÀÌµ¿ÇÑ´Ù. ³»ºÎ ¹è¿­ÀÇ Ã¹ ¿ø¼Ò´Â »èÁ¦µÈ´Ù.
 * @return {Value} »èÁ¦ÇÑ Ã¹ ¿ø¼Ò.
 * @see $A#pop
 * @see $A#unshift
 * @description [Lite]
 * @example
var arr  = $A(['Melon','Grape','Apple','Kiwi']);
var elem = arr.shift();

document.write(elem); // Melon
document.write(arr);  // [Grape, Apple, Kiwi]
 */
jindo.$A.prototype.shift = function() {
	return this._array.shift();
};

/**
 * unshift ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ ¸Ç ¾Õ¿¡ ÇÏ³ª ÀÌ»óÀÇ ¿ø¼Ò¸¦ »ðÀÔÇÑ´Ù.
 * @param {oValue1, ..., oValueN} oValueN Ãß°¡ÇÒ ÇÏ³ª ÀÌ»óÀÇ °ª
 * @return {Number} ¿¤¸®¸ÕÆ®¸¦ Ãß°¡ÇÑ ÈÄÀÇ ¹è¿­ °´Ã¼ Å©±â
 * @description [Lite]
 * @example
var arr = $A([4,5]);

arr.unshift('c');
document.write(arr); // [c, 4, 5]

arr.unshift('a', 'b');
document.write(arr); // [a, b, c, 4, 5]
 */
jindo.$A.prototype.unshift = function(oValue1/*, ...*/) {
	this._array.unshift.apply(this._array, jindo.$A(arguments).$value());

	return this._array.length;
};

/**
 * forEach ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò¸¦ ¼øÈ¸ÇÏ¸é¼­ ÄÝ¹é ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù. 
 * @param {Function}	fCallback	¼øÈ¸ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÄÝ¹é ÇÔ¼ö´Â fCallback(value, index, array)ÀÇ Çü½ÄÀ» °¡Áø´Ù. 
 * @param {Object}	[oThis]	ÄÝ¹é ÇÔ¼ö°¡ ¸Þ¼­µåÀÏ ¶§ ÄÝ¹é ÇÔ¼öÀÇ this
 * @return {Object}	$A °´Ã¼ 
 * @import core.$A[Break, Continue]
 * @see $A#map
 * @description [Lite]
 * @example
$A(["zebra", "giraffe", "bear", "monkey"]).forEach(function(v,i,o) {
	document.writeln((i+1)+". " + v);
});
// °á°ú : (ÁÙ ¾ÕÀÇ ÁÖ¼®Ç¥½Ã //´Â Á¦¿Ü)
// 1. zebra
// 2. giraffe
// 3. bear
// 4. monkey
 */
jindo.$A.prototype.forEach = function(fCallback, oThis) {
	var arr         = this._array;
	var errBreak    = this.constructor.Break;
	var errContinue = this.constructor.Continue;
	
	function f(v,i,a) {
		try {
			fCallback.call(oThis, v, i, a);
		} catch(e) {
			if (!(e instanceof errContinue)) throw e;
		}
	};

	if (typeof this._array.forEach == "function") {
		try {
			this._array.forEach(f);
		} catch(e) {
			if (!(e instanceof errBreak)) throw e;
		}
		return this;
	}

	for(var i=0; i < arr.length; i++) {
		try {
			f(arr[i], i, arr);
		} catch(e) {
			if (e instanceof errBreak) break;
			throw e;
			
		}
	}

	return this;
};

/**
 * slice ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ÀÏºÎ¸¦ ÃßÃâÇÑ´Ù.
 * @param {Number} nStart Àß¶ó³¾ ºÎºÐÀÇ ½ÃÀÛ ÀÎµ¦½º
 * @param {Number} nEnd Àß¶ó³¾ ºÎºÐÀÇ ¹Ù·Î µÚ ÀÎµ¦½º
 * @returns {$A} ³»ºÎ ¹è¿­ÀÇ ÀÏºÎ¸¦ ÃßÃâÇÑ »õ·Î¿î $A °´Ã¼. start°¡ endº¸´Ù ÀÛ°Å³ª °°À» °æ¿ì, È¤Àº start°¡ 0º¸´Ù ÀÛÀ» °æ¿ì´Â ºó ¹è¿­À» °¡Áö´Â $A¸¦ ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
var arr = $A([12, 5, 8, 130, 44]);
var newArr = arr.slice(1,3);

document.write(arr); // [12, 5, 8, 130, 44]
document.write(newArr); // [5, 8]
 */
jindo.$A.prototype.slice = function(nStart, nEnd) {
	var a = this._array.slice.call(this._array, nStart, nEnd);
	return jindo.$A(a);
};

/**
 * splice ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ÀÏºÎ¸¦ »èÁ¦ÇÑ´Ù.  
 * @param {Number} nIndex	»èÁ¦ÇÒ ¿ø¼ÒÀÇ ½ÃÀÛ ÀÎµ¦½º
 * @param {Number} nHowMany	»èÁ¦ÇÒ ¿ø¼ÒÀÇ °¹¼ö. ÀÌ °ªÀ» »ý·«ÇÏ¸é index ¹øÂ° ¿ø¼ÒºÎÅÍ ¸¶Áö¸· ¿ø¼Ò±îÁö »èÁ¦ÇÑ´Ù. ??
 * @param {Value1, ...,ValueN} oValueN »èÁ¦ÇÑ ¹è¿­¿¡ Ãß°¡ÇÒ ÇÏ³ª ÀÌ»óÀÇ °ª. »ðÀÔÀº nIndex·Î ÁöÁ¤ÇÑ ½ÃÀÛ ÀÎµ¦½º¿¡¼­ ºÎÅÍ ½ÃÀÛÇÑ´Ù. ??
 * @returns {$A} »èÁ¦ÇÑ ¿ø¼Ò¸¦ Æ÷ÇÔÇÏ´Â »õ·Î¿î $A °´Ã¼.
 * @description [Lite]
 * @example
var arr = $A(["angel", "clown", "mandarin", "surgeon"]);
var removed = arr.splice(2, 0, "drum");

document.write(arr); // [angel, clown, drum, mandarin, surgeon]
document.write(removed); // []

removed = arr.splice(3, 1);

document.write(arr); // [angel, clown, drum, surgeon]
document.write(removed); // [mandarin]

removed = a.splice(2, 1, "trumpet", "parrot");

document.write(arr); // [angel, clown, trumpet, parrot, surgeon]
document.write(removed); // [drum]
 */
jindo.$A.prototype.splice = function(nIndex, nHowMany/*, oValue1,...*/) {
	var a = this._array.splice.apply(this._array, arguments);

	return jindo.$A(a);
};

/**
 * shuffle ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¿ø¼Ò¸¦ ¹«ÀÛÀ§·Î ¼¯´Â´Ù.
 * @returns {$A} Á¤·ÄÇÑ $A °´Ã¼.
 * @description [Lite]
 * @example
var dice = $A([1,2,3,4,5,6]);

dice.shuffle();

document.write("You get the number " + dice[0]);
// °á°ú : 1ºÎÅÍ 6±îÁöÀÇ ¼ýÀÚ Áß ·£´ýÇÑ ¼ýÀÚ
 */
jindo.$A.prototype.shuffle = function() {
	this._array.sort(function(a,b){ return Math.random()>Math.random()?1:-1 });
	
	return this;
};

/**
 * reverse ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¿ø¼Ò ¼ø¼­¸¦ °Å²Ù·Î µÚÁý´Â´Ù.
 * @returns {$A} ¿ø¼Ò ¼ø¼­¸¦ µÚÁýÀº $A °´Ã¼.
 * @description [Lite]
 * @example
var arr = $A([1, 2, 3, 4, 5]);

arr.reverse();
document.write(arr); // [5, 4, 3, 2, 1]
 */
jindo.$A.prototype.reverse = function() {
	this._array.reverse();

	return this;
};

/**
 * empty ¸Þ¼­µå´Â ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò¸¦ Á¦°ÅÇÏ°í, ºó ¹è¿­·Î ¸¸µç´Ù.
 * @returns {$A} ºó ¹è¿­ $A °´Ã¼
 * @description [Lite]
 * @example
var arr = $A([1, 2, 3]);

arr.empty();
document.write(arr); // []
 */
jindo.$A.prototype.empty = function() {
	return this.length(0);
};

/**
 * Break ¸Þ¼­µå´Â each, filter, map ¸Þ¼­µåÀÇ ¼øÈ¸ ·çÇÁ¸¦ Áß´ÜÇÑ´Ù.
 * @description [Lite]
 * @example
$A([1,2,3,4,5]).forEach(function(value,index,array) {
   // °ªÀÌ 4º¸´Ù Å©¸é Á¾·á
  if (value > 4) $A.Break();
   ...
});
 */
jindo.$A.Break = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * Continue ¸Þ¼­µå´Â each, filter, map ¸Þ¼­µåÀÇ ¼øÈ¸ ·çÇÁ¿¡¼­ ³ª¸ÓÁö ¸í·ÉÀ» ½ÇÇàÇÏÁö ¾Ê°í ´ÙÀ½ ·çÇÁ·Î °Ç³Ê¶Ú´Ù.
 * ³»ºÎÀûÀ¸·Î´Â °­Á¦·Î exceptionÀ» ¹ß»ý½ÃÅ°´Â ±¸Á¶ÀÌ¹Ç·Î, try ~ catch ¿µ¿ª¿¡¼­ ÀÌ ¸Þ¼Òµå¸¦ ½ÇÇàÇÏ¸é Á¤»óÀûÀ¸·Î µ¿ÀÛÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.
 * 
 * @description [Lite]
 * @example
$A([1,2,3,4,5]).forEach(function(value,index,array) {
   // °ªÀÌ Â¦¼ö¸é Ã³¸®¸¦ ÇÏÁö ¾ÊÀ½
  if (value%2 == 0) $A.Continue();
   ...
});
 */
jindo.$A.Continue = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * @fileOverview $AÀÇ È®Àå ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name array.extend.js
 */

/**
 * map ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò¸¦ ¼øÈ¸ÇÏ¸é¼­ ÄÝ¹é ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù.
 * @param {Function} fCallback	¼øÈ¸ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÄÝ¹é ÇÔ¼ö´Â fCallback(value, index, array)ÀÇ Çü½ÄÀ» °¡Áø´Ù. 
 * @param {Object} [oThis]	ÄÝ¹é ÇÔ¼ö°¡ ¸Þ¼­µåÀÏ ¶§ ÄÝ¹é ÇÔ¼öÀÇ this		
 * @return {$A} ÄÝ¹é ÇÔ¼ö ¼öÇà °á°ú¸¦ ¹Ý¿µÇÑ $A °´Ã¼
 * @see $A#forEach
 * @example
var animalList = $A(["zebra", "giraffe", "bear", "monkey"]).map(function(v,i,o) {
	return (i+1)+". " + v;
});
	
document.write (animalList.$value());
// °á°ú : [1. zebra, 2. giraffe, 3. bear, 4. moneky]
 */
jindo.$A.prototype.map = function(fCallback, oThis) {
	var arr         = this._array;
	var errBreak    = this.constructor.Break;
	var errContinue = this.constructor.Continue;
	
	function f(v,i,a) {
		try {
			return fCallback.call(oThis, v, i, a);
		} catch(e) {
			if (e instanceof errContinue) return v;
			else throw e;
		}
	};

	if (typeof this._array.map == "function") {
		try {
			this._array = this._array.map(f);
		} catch(e) {
			if(!(e instanceof errBreak)) throw e;
		}
		return this;
	}

	for(var i=0; i < this._array.length; i++) {
		try {
			arr[i] = f(arr[i], i, arr);
		} catch(e) {
			if (e instanceof errBreak) break;
			throw e;
		}
	}

	return this;
};

/**
 * filter ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò¸¦ ¼øÈ¸ÇÏ¸é¼­ ÄÝ¹é ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù. ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·ÇÏ´Â ¿ø¼Ò´Â »õ·Î¿î $A °´Ã¼ÀÇ ³»ºÎ ¹è¿­¿¡ Ãß°¡µÈ´Ù. 
 * @param {Function} fCallback	¼øÈ¸ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÄÝ¹é ÇÔ¼ö´Â Boolean °ªÀ» ¸®ÅÏÇØ¾ß ÇÑ´Ù.
 * @param {Object} oThis	ÄÝ¹é ÇÔ¼ö°¡ ¸Þ¼­µåÀÏ °æ¿ì ÄÝ¹é ÇÔ¼öÀÇ this
 * @returns {$A}	ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·ÇÏ´Â ¿ø¼Ò¸¸ Æ÷ÇÔÇÏ´Â $A °´Ã¼.
 * @example
var arr = $A([1,2,3,4,5]);

// ÇÊÅÍ¸µ ÇÔ¼ö
function filterFunc(element, index, array) {
	if (element > 2) {
		return true;
	} else {
		return false;
	}
}

var newArr = arr.filter(filterFunc);

document.write(arr); // [1,2,3,4,5]
document.write(newArr); // [3,4,5]
 */
jindo.$A.prototype.filter = function(fCallback, oThis) {
	var ar = new Array;

	this.forEach(function(v,i,a) {
		if (fCallback.call(oThis, v, i, a) === true) {
			ar[ar.length] = v;
		}
	});

	return jindo.$A(ar);
};

/**
 * every ¸Þ¼­µå´Â ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò°¡ ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·ÇÏ´ÂÁö °Ë»çÇÑ´Ù.
 * @param {Function} fCallback	¼øÈ¸ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÄÝ¹é ÇÔ¼ö´Â ¹Ýµå½Ã boolean °ªÀ» ¸®ÅÏÇØ¾ß ÇÑ´Ù. 
 * @param {Object} oThis	ÄÝ¹é ÇÔ¼ö°¡ ¸Þ¼­µåÀÏ °æ¿ì ÄÝ¹é ÇÔ¼öÀÇ this
 * @returns {Boolean} ³»ºÎ ¹è¿­ÀÇ ¸ðµç ¿ø¼Ò°¡ ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·ÇÏ¸é true, ±×·¸Áö ¾ÊÀ¸¸é false¸¦ ¸®ÅÏÇÑ´Ù.
 * @example
function isBigEnough(element, index, array) {
		return (element >= 10);
	}

var try1 = $A([12, 5, 8, 130, 44]).every(isBigEnough);
// false

var try2 = $A([12, 54, 18, 130, 44]).every(isBigEnough);
// true
 */
jindo.$A.prototype.every = function(fCallback, oThis) {
	if (typeof this._array.every != "undefined") return this._array.every(fCallback, oThis);

	var result = true;
	this.forEach(function(v, i, a) {
		if (fCallback.call(oThis, v, i, a) === false) {
			result = false;
			jindo.$A.Break();
		}
	});
	return result;
};

/**
 * some ¸Þ¼­µå´Â ³»ºÎ ¹è¿­¿¡ ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·½ÃÅ°´Â ¿ø¼Ò°¡ ÀÖ´ÂÁö °Ë»çÇÑ´Ù. 
 * @param {Function} fCallback	¼øÈ¸ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÄÝ¹é ÇÔ¼ö´Â ¹Ýµå½Ã Boolean °ªÀ» ¸®ÅÏÇØ¾ß ÇÑ´Ù. 
 * @param {Object} oThis	ÄÝ¹é ÇÔ¼ö°¡ ¸Þ¼­µåÀÏ °æ¿ì ÄÝ¹é ÇÔ¼öÀÇ this
 * @returns {Boolean} ³»ºÎ ¹è¿­¿¡ ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·½ÃÅ°´Â ¿ø¼Ò°¡ ÀÖÀ¸¸é true, ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·½ÃÅ°´Â ¿ø¼Ò°¡ ÇÏ³ªµµ ¾ø´Ù¸é false¸¦ ¸®ÅÏÇÑ´Ù.
 * @example
function twoDigitNumber(element, index, array) {
	return (element >= 10 && element < 100);
}

var try1 = $A([12, 5, 8, 130, 44]).some(twoDigitNumber);
// true

var try2 = $A([1, 5, 8, 130, 4]).some(twoDigitNumber);
// false
 */
jindo.$A.prototype.some = function(fCallback, oThis) {
	if (typeof this._array.some != "undefined") return this._array.some(fCallback, oThis);

	var result = false;
	this.forEach(function(v, i, a) {
		if (fCallback.call(oThis, v, i, a) === true) {
			result = true;
			jindo.$A.Break();
		}
	});
	return result;
};

/**
 * refuse ¸Þ¼­µå´Â Æ¯Á¤ °ªÀ» Á¦¿ÜÇÑ »õ·Î¿î $A °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @param {Value, ..., ValueN} oValueN ³»ºÎ ¹è¿­¿¡¼­ Á¦¿ÜÇÒ °ª
 * @returns {$A} ³»ºÎ ¹è¿­¿¡¼­ Æ¯Á¤ °ªÀ» Á¦¿ÜÇÑ »õ·Î¿î $A °´Ã¼
 * @example
var arr = $A([12, 5, 8, 130, 44]);

var newArr1 = arr.refuse(12);

document.write(arr); // [12, 5, 8, 130, 44]
document.write(newArr1); // [5, 8, 130, 44]

var newArr2 = newArr1.refuse(8, 44, 130);

document.write(newArr1); // [5, 8, 130, 44]
document.write(newArr2); // [5]
 */
jindo.$A.prototype.refuse = function(oValue1/*, ...*/) {
	var a = jindo.$A(arguments);
	return this.filter(function(v,i) { return !a.has(v) });
};

/**
 * unique ¸Þ¼­µå´Â ³»ºÎ ¹è¿­¿¡¼­ Áßº¹µÇ´Â ¿ø¼Ò¸¦ »èÁ¦ÇÑ´Ù.
 * @returns {$A} Áßº¹µÇ´Â ¿ø¼Ò¸¦ Á¦°ÅÇÑ $A °´Ã¼. 
 * @example
var arr = $A([10, 3, 76, 5, 4, 3]);

arr.unique();
document.write(arr); // [10, 3, 76, 5, 4]
 */
jindo.$A.prototype.unique = function() {
	var a = this._array, b = [], l = a.length;
	var i, j;

	// Áßº¹µÇ´Â ¿ø¼Ò Á¦°Å
	for(i = 0; i < l; i++) {
		for(j = 0; j < b.length; j++) {
			if (a[i] == b[j]) break;
		}
		
		if (j >= b.length) b[j] = a[i];
	}
	
	this._array = b;
	
	return this;
};

/**
 * @fileOverview $AjaxÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name Ajax.js
 */

/**
 * $Ajax °´Ã¼¸¦ »ý¼º ¹× ¸®ÅÏÇÑ´Ù.
 * @extends core
 * @class $Ajax´Â ajax ¿äÃ»°ú ÀÀ´äÀ» Ã³¸®ÇÑ´Ù.
 * @param {String}   url			  ¼­¹öÃø URL. URLÀÌ "http://" È¤Àº "https://·Î ½ÃÀÛÇÏ¸é ÀÚµ¿À¸·Î Cross-domain ajax¸¦ È£ÃâÇÑ´Ù. Cross-domain ajax¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â http://wiki.nhncorp.com/display/lsuit/Jindo2+Cross-domain+Ajax ¸¦ ÂüÁ¶ÇÑ´Ù.
 * @param {Object}   option		      HTTP ¿äÃ»¿¡ »ç¿ëÇÒ ¸Å°³º¯¼ö.
 * @param {String}   option.type	  ¿äÃ» Å¸ÀÔ. "xhr", "iframe", "jsonp", "flash" Áß¿¡ ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. ÇÏÀ§ È£È¯¼ºÀ» À§ÇØ "post" È¤Àº "get"À» Áö¿øÇÏ¸ç, "post", "get"À¸·Î ¼±ÅÃÇÏ¸é typeÀº ÀÚµ¿ÀûÀ¸·Î "xhr"ÀÌ µÈ´Ù. ±âº»°ªÀº "xhr"ÀÌ´Ù.
 * @param {String}   option.method	  HTTP ¿äÃ»¿¡ »ç¿ëÇÒ ¹æ½Ä. "post" È¤Àº "get"À» ÀÌ¿ëÇÑ´Ù. ´Ü, Æ¯Á¤ type¿¡¼­ ¿äÃ» ¹æ½ÄÀÌ °­Á¦µÇ´Â °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î typeÀ» jsonpÀ¸·Î ¼³Á¤Çß´Ù¸é method´Â °­Á¦ÀûÀ¸·Î getÀÌ µÈ´Ù. ±âº»°ªÀº "post"ÀÌ´Ù.
 * @param {Number}   option.timeout   ¿äÃ»ÀÌ ÀÏÁ¤½Ã°£ µ¿¾È ¿äÃ»ÀÌ ¿Ï·áµÇÁö ¾ÊÀ¸¸é ÁßÁö½ÃÅ²´Ù. ´ÜÀ§´Â ÃÊÀÌ´Ù.
 * @param {Function} option.onload	  ¿äÃ»ÀÌ ¿Ï·áµÇ¸é ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö
 * @param {Function} option.onerror	  ¿äÃ»ÀÌ ½ÇÆÐÇÏ¸é ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö. ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ» °æ¿ì¿¡´Â ¿¡·¯°¡ ¹ß»ýÇØµµ onload¸¦ ½ÇÇàÇÑ´Ù.
 * @param {Function} option.ontimeout Å¸ÀÓ¾Æ¿ôÀÌ µÇ¾úÀ» ¶§ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö
 * @param {String} option.proxy		  Ajax¸¦ ½ÇÇàÇÏ´Â ÇöÀç ¹®¼­¿Í µ¿ÀÏÇÑ µµ¸ÞÀÎ¿¡ Á¸ÀçÇÏ´Â proxy ÆÄÀÏÀÇ À§Ä¡. Jindo¿Í ÇÔ²² ¹èÆ÷ÇÏ´Â ajax_local_callback.htmlÀ» »ç¿ëÇÑ´Ù. typeÀ» iframeÀ¸·Î ¼³Á¤Çß´Ù¸é ¹Ýµå½Ã proxy¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù.
 * @param {String} option.jsonp_charset	typeÀ» jsonp·Î ¼³Á¤ÇßÀ» ¶§ ¿äÃ»¿¡ »ç¿ëÇÒ ÀÎÄÚµù ¹æ½Ä. º¸³»´Â ¹®ÀÚ¼ÂÀº Ç×»ó UTF-8ÀÌ´Ù(0.4.2 ºÎÅÍ Áö¿ø).
 * @param {String} option.callbackid	typeÀ» jsonp·Î ¼³Á¤ÇßÀ» ¶§, callbackÇÔ¼ö ÀÌ¸§¿¡ »ç¿ëÇÒ id¸¦ Á÷Á¢ ÁöÁ¤.(1.3.0 ºÎÅÍ Áö¿ø).
 * @param {String} option.callbackname	typeÀ» jsonp·Î ¼³Á¤ÇßÀ» ¶§, ¼­¹ö¿¡ Àü´ÞÇÏ´Â ÆÄ¶ó¸ÞÅÍ¸¦ º¯°æÇÒ¼ö ÀÖ´Ù.±âº»°ªÀº _callbackÀÓ,(1.3.8 ºÎÅÍ Áö¿ø).
 * @param {Boolean} option.sendheader  ¿äÃ»Çì´õ¸¦ Àü¼ÛÇÒÁö ¿©ºÎ. Flash ¹æ½ÄÀ¸·Î È£Ãâ½Ã crossdomain.xml¿¡ allow-header ¾ø´Â °æ¿ì false¼³Á¤. µðÆúÆ®´Â true(1.3.4ºÎÅÍ Áö¿ø) 
 * @param {Boolean} option.async  ºñµ¿±â È£Ãâ ¿©ºÎ. XHR¹æ½Ä¿¡¼­¸¸ À¯È¿. µðÆúÆ®´Â true(1.3.7ºÎÅÍ Áö¿ø) 
 * @constructor
 * @description [Lite]
 * @author Kim, Taegon
 */
jindo.$Ajax = function (url, option) {
	var cl = arguments.callee;
	if (!(this instanceof cl)) return new cl(url, option);

	function _getXHR() {
		if (window.XMLHttpRequest) {
			return new XMLHttpRequest();
		} else if (ActiveXObject) {
			try { return new ActiveXObject('MSXML2.XMLHTTP'); }
			catch(e) { return new ActiveXObject('Microsoft.XMLHTTP'); }
			return null;
		}
	}

	var loc    = location.toString();
	var domain = '';
	try { domain = loc.match(/^https?:\/\/([a-z0-9_\-\.]+)/i)[1]; } catch(e) {}

	this._status = 0;
	this._url = url;
	this._options  = new Object;
	this._headers  = new Object;
	this._options = {
		type   :"xhr",
		method :"post",
		proxy  :"",
		timeout:0,
		onload :function(req){},
		onerror :null,
		ontimeout:function(req){},
		jsonp_charset : "utf-8",
		callbackid : "",
		callbackname : "",
		sendheader : true,
		async : true
	};

	this.option(option);
	
	// Å×½ºÆ®¸¦ À§ÇØ ¿ì¼± Àû¿ë°¡´ÉÇÑ ¼³Á¤ °´Ã¼°¡ Á¸ÀçÇÏ¸é Àû¿ë
	if(jindo.$Ajax.CONFIG){
		this.option(jindo.$Ajax.CONFIG);
	}	

	var _opt = this._options;

	_opt.type   = _opt.type.toLowerCase();
	_opt.method = _opt.method.toLowerCase();

	if (typeof window.__jindo2_callback == "undefined") {
		window.__jindo2_callback = new Array();
	}

	switch (_opt.type) {
		case "get":
		case "post":
			_opt.method = _opt.type;
			_opt.type   = "xhr";
		case "xhr":
			this._request = _getXHR();
			break;
		case "flash":
			if(!jindo.$Ajax.SWFRequest) throw Error('Require $Ajax.SWFRequest');
			this._request = new jindo.$Ajax.SWFRequest();
			break;
		case "jsonp":
			if(!jindo.$Ajax.JSONPRequest) throw Error('Require $Ajax.JSONPRequest');
			_opt.method = "get";
			this._request = new jindo.$Ajax.JSONPRequest();
			this._request.charset = _opt.jsonp_charset;
			this._request.callbackid = _opt.callbackid;
			this._request.callbackname = _opt.callbackname;
			break;
		case "iframe":
			if(!jindo.$Ajax.FrameRequest) throw Error('Require $Ajax.FrameRequest');
			this._request = new jindo.$Ajax.FrameRequest();
			this._request._proxy = _opt.proxy;
			break;
	}
};

/**
 * @ignore
 */
jindo.$Ajax.prototype._onload = function() {
	var bSuccess = this._request.readyState == 4 && this._request.status == 200;
	var oResult;
	try {
		if (this._request.readyState == 4) {
			if (this._request.status != 200 && typeof this._options.onerror == 'function') 
				this._options.onerror(jindo.$Ajax.Response(this._request));
			else 
				oResult = this._options.onload(jindo.$Ajax.Response(this._request));
		}
	}finally{
		this._status--;
		if(typeof this._oncompleted == 'function') this._oncompleted(bSuccess, oResult);
	}
};

/**
 * request ¸Þ¼­µå´Â ajax ¿äÃ»À» Àü¼ÛÇÑ´Ù. ajax ¿äÃ»¿¡ »ç¿ëÇÒ ¸Å°³º¯¼ö´Â »ý¼ºÀÚ¿¡¼­ ¼³Á¤ÇÏ°Å³ª option ¸Þ¼­µå¿¡¼­ º¯°æÇÒ ¼ö ÀÖ´Ù.  ¿äÃ» Å¸ÀÔÀÌ 'flash'ÀÌ¸é ÀÌ ¸Þ¼Òµå¸¦ ½ÇÇàÇÏ±â Àü¿¡ body ÅÂ±× ³»ºÎ¿¡¼­ $Ajax.SWFRequest.write() ¸í·É¾î¸¦ ¹Ýµå½Ã ½ÇÇàÇØ¾ß ÇÑ´Ù.
 * @param {Object} oData ¼­¹ö·Î Àü¼ÛÇÒ µ¥ÀÌÅÍ.
 * @description [Lite]
 * @example
var ajax = $Ajax("http://www.remote.com", {
   onload : function(res) {
      // onload ÇÚµé·¯
   }
});

ajax.request( {key1:"value1", key2:"value2"} );
 */
jindo.$Ajax.prototype.request = function(oData) {
	this._status++;
	var t   = this;
	var req = this._request;
	var opt = this._options;
	var data, v,a = [], data = "";
	var _timer = null;
	var url = this._url;

	if (typeof oData == "undefined" || !oData) {
		data = null;
	} else {
		for(var k in oData) {
			v = oData[k];
			if (typeof v == "function") v = v();
			
			if (v instanceof Array || v instanceof jindo.$A) {
				jindo.$A(v).forEach(function(value,index,array) {
					a[a.length] = k+"="+encodeURIComponent(value);
				});
			} else {
				a[a.length] = k+"="+encodeURIComponent(v);
			}
		}
		data = a.join("&");
	}
	
	// XHR GET ¹æ½Ä ¿äÃ»ÀÎ °æ¿ì URL¿¡ ÆÄ¶ó¹ÌÅÍ Ãß°¡
	if(opt.type.toUpperCase()=="XHR" && opt.method.toUpperCase()=="GET"){
		if(url.indexOf('?')==-1) url += "?";
		else url += "&";
		url += data;
		data = null;
	}

	req.open(opt.method.toUpperCase(), url, opt.async);
	
	if (opt.sendheader) {
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		req.setRequestHeader("charset", "utf-8");
		for (var x in this._headers) {
			if (typeof this._headers[x] == "function") 
				continue;
			req.setRequestHeader(x, String(this._headers[x]));
		}
	}

	if (typeof req.onload != "undefined") {
		req.onload = function(rq){ clearTimeout(_timer); t._onload(rq) };
	} else {
		req.onreadystatechange = function(rq){ clearTimeout(_timer); t._onload(rq) };
	}

	if (opt.timeout > 0) {
		_timer = setTimeout(function(){ 
				try{ req.abort(); }catch(e){}; 
				opt.ontimeout(req);	
				if(typeof this._oncompleted == 'function') this._oncompleted(false); 
		}, opt.timeout * 1000);
	}

	req.send(data);

	return this;
};

/**
 * isIdle ¸Þ¼­µå´Â ajax °´Ã¼°¡ ÇöÀç ¿äÃ» ´ë±â »óÅÂÀÎÁö ¹ÝÈ¯ÇÑ´Ù.    
 * @return ÇöÀç ´ë±â»óÅÂ ¿©ºÎ ¹ÝÈ¯
 * @since 1.3.5
 * @description [Lite]
 * @example
 var ajax = $Ajax("http://www.remote.com",{
     onload : function(res){
         // onload ÇÚµé·¯
     }
});

if(ajax.isIdle) ajax.request(); 
 
 */
jindo.$Ajax.prototype.isIdle = function(){
	return this._status==0;
}

/**
 * abort ¸Þ¼­µå´Â ¼­¹ö·Î Àü¼ÛÇÑ ajax ¿äÃ»À» Ãë¼ÒÇÑ´Ù. abort ¸Þ¼­µå¸¦ »ç¿ëÇÏ¸é ³×Æ®¿öÅ© ¿¬°áÀ» ´ÝÀ¸¸ç ´ë±âÁßÀÌ´ø ¿äÃ»Àº Ãë¼ÒµÈ´Ù. ajax ¿äÃ»ÀÇ ÀÀ´äÀÌ ³Ê¹« ¿À·¡ °É·Á¼­ Ãë¼ÒÇÏ°í ½ÍÀ» °æ¿ì abort ¸Þ¼­µå¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
 * @return Àü¼ÛÀ» Ãë¼ÒÇÑ $Ajax °´Ã¼
 * @description [Lite]
 * @example
var ajax = $Ajax("http://www.remote.com", {
   onload : function(res) {
      // onload ÇÚµé·¯
   }
}).request( {key1:"value1", key2:"value2"} );

function stopRequest() {
    ajax.abort();
}
 */
jindo.$Ajax.prototype.abort = function() {
	try {
		this._request.abort();
	}finally{
		this._status--;
	}

	return this;
};

/**
 * option ¸Þ¼­µå´Â ajax ¿äÃ»¿¡¼­ »ç¿ëÇÒ ¸Å°³º¯¼ö¸¦ °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù.
 * ¸Å°³º¯¼ö¸¦ ¼³Á¤ÇÏ·Á¸é ¸Å°³ º¯¼öÀÇ ÀÌ¸§°ú °ª, È¤Àº ¸Å°³º¯¼öÀÇ ÀÌ¸§°ú °ªÀ» ¿ø¼Ò·Î °¡Áö´Â ÇÏ³ªÀÇ °´Ã¼¸¦ ÀÎ¼ö·Î »ç¿ëÇÑ´Ù.
 * ¸¸¾à ¿©·¯ °³ÀÇ ¿ø¼Ò¸¦ °¡Áø °´Ã¼¸¦ »ç¿ëÇÏ¸é µÎ °³ ÀÌ»óÀÇ ¸Å°³º¯¼ö¸¦ ÇÑ ¹ø¿¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
 * @param {string|object} name ¸Å°³º¯¼ö·Î ¼³Á¤ÇÒ °´Ã¼, È¤Àº °¡Áö°í ¿Ã ¸Å°³º¯¼öÀÇ ÀÌ¸§
 * @param {String}  [value] »õ·Î ¼³Á¤ÇÒ ¸Å°³º¯¼öÀÇ °ª
 * @return {String|$Ajax}  ¸Å°³º¯¼ö °ªÀ» °¡Á®¿Ã ¶§´Â ¹®ÀÚ¿­À», ¸Å°³º¯¼ö °ªÀ» ¼³Á¤ÇÒ ¶§´Â $Ajax °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
var request_type = ajax.option("type");
// ajaxÀÇ type ¸Å°³º¯¼ö °ªÀ» ¸®ÅÏÇÑ´Ù.

ajax.option("method", "post");
// ajaxÀÇ method ¸Å°³º¯¼ö¸¦ post·Î ÃÊ±âÈ­ÇÑ´Ù.

ajax.option( { timeout : 0, onload : handler_func } );
// ajaxÀÇ timeout, onload ¸Å°³º¯¼ö¸¦ °¢°¢ 0¿Í handler_func·Î ÃÊ±âÈ­ÇÑ´Ù.
 */
jindo.$Ajax.prototype.option = function(name, value) {
	if (typeof name == "undefined") return "";
	if (typeof name == "string") {
		if (typeof value == "undefined") return this._options[name];
		this._options[name] = value;
		return this;
	}

	try { for(var x in name) this._options[x] = name[x] } catch(e) {};

	return this;
};

/**
 * header ¸Þ¼­µå´Â ajax ¿äÃ»¿¡¼­ »ç¿ëÇÒ HTTP ¿äÃ» Çì´õ¸¦ °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù.
 * Çì´õ¸¦ ¼³Á¤ÇÏ·Á¸é Çì´õÀÇ ÀÌ¸§°ú °ª, È¤Àº Çì´õÀÇ ÀÌ¸§°ú °ªÀ» ¿ø¼Ò·Î °¡Áö´Â ÇÏ³ªÀÇ °´Ã¼¸¦ ÀÎ¼ö·Î »ç¿ëÇÑ´Ù.
 * ¸¸¾à ¿©·¯ °³ÀÇ ¿ø¼Ò¸¦ °¡Áø °´Ã¼¸¦ »ç¿ëÇÏ¸é µÎ °³ ÀÌ»óÀÇ Çì´õ¸¦ ÇÑ ¹ø¿¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
 * ¸Å°³ º¯¼öÀÇ °ªÀ» °¡Á®¿À·Á¸é ´Ü¼øÈ÷ °¡Áö°í ¿Ã ¸Å°³º¯¼öÀÇ ÀÌ¸§À» ÁöÁ¤ÇÑ´Ù.
 * @param {String} name °¡Áö°í ¿À°Å³ª ¼³Á¤ÇÒ Çì´õ ÀÌ¸§
 * @param {Value} [value] °ªÀ» ¼³Á¤ÇÒ Çì´õ °ª
 * @return {String|$Ajax} ¼³Á¤µÈ Çì´õ°ª È¤Àº $Ajax °´Ã¼
 * @description [Lite]
 * @example
var customheader = ajax.header("myHeader");
// HTTP ¿äÃ» Çì´õ¿¡¼­ myHeaderÀÇ °ª

ajax.header( "myHeader", "someValue" );
// HTTP ¿äÃ» Çì´õÀÇ myHeader = someValue

ajax.header( { anotherHeader : "someValue2" } );
// HTTP ¿äÃ» Çì´õÀÇ anotherHeader = someValue2
 */
jindo.$Ajax.prototype.header = function(name, value) {
	if (typeof name == "undefined") return "";
	if (typeof name == "string") {
		if (typeof value == "undefined") return this._headers[name];
		this._headers[name] = value;
		return this;
	}

	try { for(var x in name) this._headers[x] = name[x] } catch(e) {};

	return this;
};

/**
 * Ajax ÀÀ´ä °´Ã¼
 * @class
 * @constructor
 * @param {Object} req ¿äÃ» °´Ã¼
 * @description [Lite]
 */
jindo.$Ajax.Response  = function(req) {
	if (this === jindo.$Ajax) return new jindo.$Ajax.Response(req);
	this._response = req;
};

/**
 * ÀÀ´äÀ» XML °´Ã¼·Î ¹ÝÈ¯ÇÑ´Ù.
 * @return {Object} ÀÀ´ä XML °´Ã¼. XHRÀÇ responseXML°ú À¯»çÇÏ´Ù.
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.xml = function() {
	return this._response.responseXML;
};

/**
 * ÀÀ´äÀ» ¹®ÀÚ¿­·Î ¹ÝÈ¯ÇÑ´Ù.
 * @return {String} ÀÀ´ä ¹®ÀÚ¿­. XHRÀÇ responseText¿Í À¯»çÇÏ´Ù.
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.text = function() {
	return this._response.responseText;
};

/**
 * ÀÀ´äÄÚµå¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {int} ÀÀ´ä ÄÚµå. httpÀÀ´äÄÚµåÇ¥ Âü°í.
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.status = function() {
	return this._response.status;
};

/**
 * readyState¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {int}  readyState. 
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.readyState = function() {
	return this._response.readyState;
};

/**
 * ÀÀ´äÀ» Json°´Ã¼·Î ¹ÝÈ¯ÇÑ´Ù.
 * @return {Object} ÀÀ´ä JSON °´Ã¼. ÀÀ´ä ¹®ÀÚ¿­À» ÀÚµ¿À¸·Î JSON °´Ã¼·Î º¯È¯ ÈÄ ¹ÝÈ¯ÇÑ´Ù. º¯È¯ °úÁ¤¿¡¼­ ¿À·ù°¡ ¹ß»ýÇÏ¸é ºó °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.json = function() {
	if (this._response.responseJSON) {
		return this._response.responseJSON;
	} else if (this._response.responseText) {
		try {
			return new Function("return "+this._response.responseText)();
		} catch(e) {
			return {};
		}
	}

	return {};
};

/**
 * ÀÀ´äÇì´õ¸¦ °¡Á®¿Â´Ù. ÀÎÀÚ¸¦ Àü´ÞÇÏÁö ¾ÊÀ¸¸é ¸ðµç Çì´õ¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} name °¡Á®¿Ã ÀÀ´äÇì´õÀÇ ÀÌ¸§
 * @return {String|Object} ÀÎÀÚ°¡ ÀÖÀ» ¶§´Â ÇØ´çÇÏ´Â Çì´õ °ªÀ», ±×·¸Áö ¾ÊÀ¸¸é ÀüÃ¼ Çì´õ¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Ajax.Response.prototype.header = function(name) {
	if (typeof name == "string") return this._response.getResponseHeader(name);
	return this._response.getAllResponseHeaders();
};

/**
 * @fileOverview $AjaxÀÇ È®Àå ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name Ajax.extend.js
 */

/**
 * @class
 */
jindo.$Ajax.RequestBase = jindo.$Class({
	_headers : {},
	_respHeaders : {},
	_respHeaderString : "",
	callbackid:"",
	callbackname:"",
	responseXML  : null,
	responseJSON : null,
	responseText : "",
	status : 404,
	readyState : 0,
	$init  : function(){},
	onload : function(){},
	abort  : function(){},
	open   : function(){},
	send   : function(){},
	setRequestHeader  : function(sName, sValue) {
		this._headers[sName] = sValue;
	},
	getResponseHeader : function(sName) {
		return this._respHeaders[sName] || "";
	},
	getAllResponseHeaders : function() {
		return this._respHeaderString;
	},
	_getCallbackInfo : function() {
		var id = "";

		if(this.callbackid!="") {
			var idx = 0;
			do {
				id = "$" + this.callbackid + "_"+idx;
				idx++;
			}
			while (window.__jindo2_callback[id]);	
		}
		else{
			do {
				id = "$" + Math.floor(Math.random() * 10000);
			}
			while (window.__jindo2_callback[id]);
		}
		if(this.callbackname == ""){
			this.callbackname = "_callback";
		}

		return {id:id,name:"window.__jindo2_callback."+id};
	}
});

/**
 * @class
 */
jindo.$Ajax.JSONPRequest = jindo.$Class({
	charset : "utf-8",
	_script : null,
	_onerror : null,
	_callback : function(data) {
		
		if (this._onerror) {
			clearTimeout(this._onerror);
			this._onerror = null;
		}
			
		var self = this;

		this.responseJSON = data;
		this.onload(this);
		setTimeout(function(){ self.abort() }, 10);
	},
	abort : function() {
		if (this._script) {
			try { this._script.parentNode.removeChild(this._script) }catch(e){};
		}
	},
	open  : function(method, url) {
		this.responseJSON = null;

		this._url = url;
	},
	send  : function(data) {
		var t    = this;
		var info = this._getCallbackInfo();
		var head = document.getElementsByTagName("head")[0];

		this._script = jindo.$("<script>");
		this._script.type    = "text/javascript";
		this._script.charset = this.charset;

		if (head) {
			head.appendChild(this._script);
		} else if (document.body) {
			document.body.appendChild(this._script);
		}

		window.__jindo2_callback[info.id] = function(data){
			try {
				t.readyState = 4;
				t.status = 200;
				t._callback(data);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};
		
		var agent = jindo.$Agent(); 
		if (agent.navigator().ie || agent.navigator().opera) {
			this._script.onreadystatechange = function(){			
				if (this.readyState == 'loaded'){
					if (!t.responseJSON) {
						t.readyState = 4;
						t.status = 500;
						t._onerror = setTimeout(function(){t._callback(null);}, 200);
					}
					this.onreadystatechange = null;
				}
			};
		}
		else {
			this._script.onload = function(){
				if (!t.responseJSON) {
					t.readyState = 4;
					t.status = 500;
					t._onerror = setTimeout(function(){t._callback(null);}, 200);
				}
				this.onload = null;
				this.onerror = null;
			};
			this._script.onerror = function(){
				if (!t.responseJSON) {
					t.readyState = 4;
					t.status = 404;
					t._onerror = setTimeout(function(){t._callback(null);}, 200);
				}
				this.onerror = null;
				this.onload = null;
			};
		}
		this._script.src = this._url+"?"+info.callbackname+"="+info.name+"&"+data;
		
	}
}).extend(jindo.$Ajax.RequestBase);

/**
 * @class
 */
jindo.$Ajax.SWFRequest = jindo.$Class({
	_callback : function(status, data, headers){
		this.readyState = 4;
		// ÇÏÀ§ È£È¯À» À§ÇØ status°¡ boolean °ªÀÎ °æ¿ìµµ Ã³¸®
		if( (typeof status).toLowerCase() == 'number')
			this.status = status;
		else
			if(status==true) this.status=200;
				
		if (this.status==200) {
			if (typeof data == "string") {
				try {
					this.responseText = decodeURIComponent(data);
					if(!this.responseText || this.responseText=="") 
						this.responseText = data;
				} catch(e) {}
			}
			// ÄÝ¹éÄÚµå´Â ³Ö¾úÁö¸¸, ¾ÆÁ÷ SWF¿¡¼­ ÀÀ´äÇì´õ Áö¿ø ¾ÈÇÔ
			if(typeof headers == "object"){
				this._respHeaders = headers;				
			}
		}
		
		this.onload(this);
	},
	open : function(method, url) {
		var re  = /https?:\/\/([a-z0-9_\-\.]+)/i;

		this._url    = url;
		this._method = method;
	},
	send : function(data) {
		this.responseXML  = false;
		this.responseText = "";

		var t    = this;
		var dat  = {};
		var info = this._getCallbackInfo();
		var swf  = window.document[jindo.$Ajax.SWFRequest._tmpId];

		function f(arg) {
			switch(typeof arg){
				case "string":
					return '"'+arg.replace(/\"/g, '\\"')+'"';
					break;
				case "number":
					return arg;
					break;
				case "object":
					var ret = "", arr = [];
					if (arg instanceof Array) {
						for(var i=0; i < arg.length; i++) {
							arr[i] = f(arg[i]);
						}
						ret = "["+arr.join(",")+"]";
					} else {
						for(var x in arg) {
							arr[arr.length] = f(x)+":"+f(arg[x]);
						}
						ret = "{"+arr.join(",")+"}";
					}
					return ret;
				default:
					return '""';
			}
		}

		data = (data || "").split("&");

		for(var i=0; i < data.length; i++) {
			pos = data[i].indexOf("=");
			key = data[i].substring(0,pos);
			val = data[i].substring(pos+1);

			dat[key] = decodeURIComponent(val);
		}

		window.__jindo2_callback[info.id] = function(success, data){
			try {
				t._callback(success, data);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};
	
		var oData = {
			url  : this._url,
			type : this._method,
			data : dat,
			charset  : "UTF-8",
			callback : info.name,
			header_json : this._headers
		};
			
		swf.requestViaFlash(f(oData));
	}
}).extend(jindo.$Ajax.RequestBase);

/**
 * $Ajax.SWFRequest.write´Â ¿äÃ» Å¸ÀÔÀÌ flashÀÏ ¶§, request ¸Þ¼Òµå°¡ È£ÃâµÇ±â Àü ¹Ýµå½Ã ÇÑ ¹ø ½ÇÇàÇØ¾ß ÇÑ´Ù(µÎ ¹ø ÀÌ»ó ½ÇÇàÇØµµ ¹®Á¦°¡ ¹ß»ýÇÑ´Ù). ÀÌ ¸í·É¾î°¡ È£ÃâµÇ¸é Åë½ÅÀ» À§ÇÑ swf °´Ã¼¸¦ ¹®¼­ ³»¿¡ Ãß°¡µÈ´Ù.
 * @param {String} [swf_path] Åë½ÅÀ» ´ã´çÇÒ swf ÆÄÀÏÀÇ °æ·Î. ±âº»°ªÀº "./ajax.swf" ÀÌ´Ù.
 */
jindo.$Ajax.SWFRequest.write = function(swf_path) {
	if(typeof swf_path == "undefined") swf_path = "./ajax.swf";
	jindo.$Ajax.SWFRequest._tmpId = 'tmpSwf'+(new Date).getMilliseconds()+Math.floor(Math.random()*100000);

	document.write('<div style="position:absolute;top:-1000px;left:-1000px"><object id="'+jindo.$Ajax.SWFRequest._tmpId+'" width="1" height="1" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"><param name="movie" value="'+swf_path+'"><param name = "allowScriptAccess" value = "always" /><embed name="'+jindo.$Ajax.SWFRequest._tmpId+'" src="'+swf_path+'" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="1" height="1" allowScriptAccess="always" swLiveConnect="true"></embed></object></div>');
};

/**
 * @class
 */
jindo.$Ajax.FrameRequest = jindo.$Class({
	_frame  : null,
	_proxy  : "",
	_domain : "",
	_callback : function(id, data, header) {
		var self = this;

		this.readyState   = 4;
		this.status = 200;
		this.responseText = data;

		this._respHeaderString = header;
		header.replace(/^([\w\-]+)\s*:\s*(.+)$/m, function($0,$1,$2) {
			self._respHeaders[$1] = $2;
		});

		this.onload(this);

		setTimeout(function(){ self.abort() }, 10);
	},
	abort : function() {
		if (this._frame) {
			try {
				this._frame.parentNode.removeChild(this._frame);
			} catch(e) {}
		}
	},
	open : function(method, url) {
		var re  = /https?:\/\/([a-z0-9_\-\.]+)/i;
		var dom = document.location.toString().match(re);

		this._method = method;
		this._url    = url;
		this._remote = String(url).match(/(https?:\/\/[a-z0-9_\-\.]+)(:[0-9]+)?/i)[0];
		this._frame = null;
		this._domain = (dom[1] != document.domain)?document.domain:"";
	},
	send : function(data) {
		this.responseXML  = "";
		this.responseText = "";

		var t      = this;
		var re     = /https?:\/\/([a-z0-9_\-\.]+)/i;
		var info   = this._getCallbackInfo();
		var url    = this._remote+"/ajax_remote_callback.html?method="+this._method;
		var header = new Array;

		window.__jindo2_callback[info.id] = function(id, data, header){
			try {
				t._callback(id, data, header);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};

		for(var x in this._headers) {
			header[header.length] = "'"+x+"':'"+this._headers[x]+"'";
		}

		header = "{"+header.join(",")+"}";

		url += "&id="+info.id;
		url += "&header="+encodeURIComponent(header);
		url += "&proxy="+encodeURIComponent(this._proxy);
		url += "&domain="+this._domain;
		url += "&url="+encodeURIComponent(this._url.replace(re, ""));
		url += "#"+encodeURIComponent(data);

		var fr = this._frame = jindo.$("<iframe>");
		fr.style.position = "absolute";
		fr.style.visibility = "hidden";
		fr.style.width = "1px";
		fr.style.height = "1px";

		var body = document.body || document.documentElement;
		if (body.firstChild) body.insertBefore(fr, body.firstChild);
		else body.appendChild(fr);

		fr.src = url;
	}
}).extend(jindo.$Ajax.RequestBase);


/**
 * $Ajax °´Ã¼¸¦ ¼ø¼­´ë·Î È£ÃâÇÒ ¼ö ÀÖ´Â ±â´ÉÀ» Á¦°øÇÑ´Ù.
 * @class $Ajax.Queue´Â ajax ¿äÃ»À» ¼ø¼­´ë·Î Ã³¸®ÇÒ ¼ö ÀÖ°Ô Áö¿øÇÑ´Ù.
 * @since 1.3.7 
 * @constructor
 */
jindo.$Ajax.Queue = function (option) {
	var cl = arguments.callee;
	if (!(this instanceof cl)) return new cl(option);
	
	this._options = {
		async : false,
		useResultAsParam : false,
		stopOnFailure : false
	};

	this.option(option);
	
	this._queue = [];	
}

/**
 * $Ajax.Queue ÀÇ ¿É¼ÇÀ» ¼³Á¤ÇÑ´Ù.
 * @param {Object} name
 * @param {Object} value
 */
jindo.$Ajax.Queue.prototype.option = function(name, value) {
	if (typeof name == "undefined") return "";
	if (typeof name == "string") {
		if (typeof value == "undefined") return this._options[name];
		this._options[name] = value;
		return this;
	}

	try { for(var x in name) this._options[x] = name[x] } catch(e) {};

	return this;
};

/**
 * Ajax Queue¿¡ ¿äÃ»À» Ãß°¡ÇÑ´Ù.
 * @param {$Ajax} Ãß°¡ÇÒ Ajax°´Ã¼
 * @param {Object} ¿äÃ»½Ã Àü¼ÛÇÒ ÆÄ¶ó¹ÌÅÍ °´Ã¼
 */
jindo.$Ajax.Queue.prototype.add = function (oAjax, oParam) {
	this._queue.push({obj:oAjax, param:oParam});
}

/**
 * Ajax Queue¸¦ ¿äÃ»ÇÑ´Ù.
 */
jindo.$Ajax.Queue.prototype.request = function () {
	if(this.option('async'))
		this._requestAsync();
	else
		this._requestSync(0);
}

jindo.$Ajax.Queue.prototype._requestSync = function (nIdx, oParam) {
	var t = this;
	if (this._queue.length > nIdx+1) {
		this._queue[nIdx].obj._oncompleted = function(bSuccess, oResult){
			if(!t.option('stopOnFailure') || bSuccess) t._requestSync(nIdx + 1, oResult);
		};
	}
	var _oParam = this._queue[nIdx].param||{};
	if(this.option('useResultAsParam') && oParam){
		try { for(var x in oParam) if(typeof _oParam[x] == 'undefined') _oParam[x] = oParam[x] } catch(e) {};		
	}
	this._queue[nIdx].obj.request(_oParam);
}

jindo.$Ajax.Queue.prototype._requestAsync = function () {
	for( var i=0; i<this._queue.length; i++)
		this._queue[i].obj.request(this._queue[i].param);
}
/**
 * @fileOverview $HÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name hash.js
 */
 
/**
 * $H ÇØ½Ã °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù
 * @class $H Å¬·¡½º´Â Å°¿Í °ªÀ» ¿ø¼Ò·Î °¡Áö´Â ¿­°ÅÇü ¹è¿­ÀÎ ÇØ½Ã¸¦ ±¸ÇöÇÏ°í, ÇØ½Ã¸¦ ´Ù·ç±â À§ÇÑ ¿©·¯ °¡Áö À§ÇÑ ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù.  
 * @param {Object} hashObject ÇØ½Ã·Î ¸¸µé °´Ã¼.
 * @return {$H} ÇØ½Ã °´Ã¼
 * @constructor
 * @example
var h = $H({one:"first", two:"second", three:"third"})
 * @author Kim, Taegon
 */
jindo.$H = function(hashObject) {
	var cl = arguments.callee;
	if (typeof hashObject == "undefined") hashObject = new Object;
	if (hashObject instanceof cl) return hashObject;
	if (!(this instanceof cl)) return new cl(hashObject);

	this._table = {};
	for(var k in hashObject) {
		if (this._table[k] == hashObject[k]) continue;
		this._table[k] = hashObject[k];
	}
};

/**
 * $value ¸Þ¼­µå´Â ÇØ½Ì ´ë»óÀÎ °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {Object} ÇØ½Ì ´ë»ó °´Ã¼
 */
jindo.$H.prototype.$value = function() {
	return this._table;
};

/**
 * $ ¸Þ¼­µå´Â Å°¿Í °ªÀ» ¼³Á¤ÇÏ°Å³ª Å°¿¡ ÇØ´çÇÏ´Â °ªÀ» ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} key Å°
 * @param {void} [value] °ª
 * @return {void|$H} Å°¿¡ ÇØ´çÇÏ´Â °ª È¤Àº $H °´Ã¼
 * @example
 * var hash = $H({one:"first", two:"second"});
 *
 * // °ªÀ» ¼³Á¤ÇÒ ¶§
 * hash.$("three", "third");
 * 
 * // hash => {one:"first", two:"second", three:"third"}
 *
 * // °ªÀ» ¹ÝÈ¯ÇÒ ¶§
 * var three = hash.$("three");
 *
 * // three => "third"
 */
jindo.$H.prototype.$ = function(key, value) {
	if (typeof value == "undefined") {
		return this._table[key];
	} 

	this._table[key] = value;
	return this;
};

/**
 * length ¸Þ¼­µå´Â ÇØ½Ã °´Ã¼ÀÇ Å©±â¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {Number} ÇØ½ÃÀÇ Å©±â
 */
jindo.$H.prototype.length = function() {
	var i = 0;
	for(var k in this._table) {
		if (typeof Object.prototype[k] != "undeifned" && Object.prototype[k] === this._table[k]) continue;
		i++;
	}

	return i;
};

/**
 * forEach ¸Þ¼­µå´Â ÇØ½Ã °´Ã¼ÀÇ Å°¿Í °ªÀ» ÀÎ¼ö·Î ÁöÁ¤ÇÑ ÄÝ¹é ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù.
 * @param {Function} callback ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö 
 * @param {Object} thisObject ÄÝ¹é ÇÔ¼öÀÇ this
 * @example
function printIt(value, key) {
   document.write(key+" => "+value+" <br>");
}
$H({one:"first", two:"second", three:"third"}).forEach(printIt);
 */
jindo.$H.prototype.forEach = function(callback, thisObject) {
	var t = this._table;
	var h = this.constructor;
	
	for(var k in t) {
		if (!t.propertyIsEnumerable(k)) continue;
		try {
			callback.call(thisObject, t[k], k, t);
		} catch(e) {
			if (e instanceof h.Break) break;
			if (e instanceof h.Continue) continue;
			throw e;
		}
	}
	return this;
};

/**
 * filter ¸Þ¼­µå´Â ÇØ½Ã °´Ã¼¿¡¼­ ÇÊÅÍ ÄÝ¹é ÇÔ¼ö¸¦ ¸¸Á·ÇÏ´Â ¿ø¼Ò¸¦ ¼öÁýÇÑ´Ù. ¼öÁýÇÑ ¿ø¼Ò´Â »õ·Î¿î $H °´Ã¼ÀÇ ¿ø¼Ò°¡ µÈ´Ù.
 * ÄÝ¹éÇÔ¼ö´Â Boolean °ªÀ» ¹ÝÈ¯ÇØ¾ß ÇÑ´Ù.
 * @param {Function} callback ÇÊÅÍ ÄÝ¹é ÇÔ¼ö 
 * @param {Object} thisObject ÄÝ¹é ÇÔ¼öÀÇ this
 * @return {$H} ¼öÁýÇÑ ¿ø¼Ò·Î »õ·Î ¸¸µç ÇØ½Ã °´Ã¼
 * @remark ÇÊÅÍ ÄÝ¹é ÇÔ¼öÀÇ °á°ú°¡ trueÀÎ ¿ø¼Ò¸¸ ¼öÁýÇÑ´Ù. ÄÝ¹é ÇÔ¼ö´Â Çü½ÄÀº ¿¹Á¦¸¦ Âü°íÇÑ´Ù.
 * @example
function callback(value, key, object) {
   // value    ÇØ½ÃÀÇ °ª 
   // key      ÇØ½ÃÀÇ °íÀ¯ÇÑ Å° È¤Àº ÀÌ¸§
   // object   JavaScript Core Object °´Ã¼
}
 */
jindo.$H.prototype.filter = function(callback, thisObject) {
	var h = jindo.$H();
	this.forEach(function(v,k,o) {
		if(callback.call(thisObject, v, k, o) === true) {
			h.add(k,v);
		}
	});
	return h;
};

/**
 * map ¸Þ¼­µå´Â ÇØ½Ã °´Ã¼ÀÇ ¿ø¼Ò¸¦ ÀÎ¼ö·Î ÄÝ¹é ÇÔ¼ö¸¦ ½ÇÇàÇÏ°í, ÇÔ¼öÀÇ ¸®ÅÏ °ªÀ» ÇØ´ç ¿ø¼ÒÀÇ °ªÀ¸·Î ÁöÁ¤ÇÑ´Ù.
 * @param {Function} callback ÄÝ¹é ÇÔ¼ö
 * @param {Object} thisObject ÄÝ¹é ÇÔ¼öÀÇ this
 * @return {$H} °ªÀ» º¯°æÇÑ ÇØ½Ã °´Ã¼
 * @remark ÄÝ¹é ÇÔ¼ö´Â Çü½ÄÀº ¿¹Á¦¸¦ Âü°íÇÑ´Ù.
 * @example
function callback(value, key, object ) {
   // value    ÇØ½ÃÀÇ °ª 
   // key      ÇØ½ÃÀÇ °íÀ¯ÇÑ Å° È¤Àº ÀÌ¸§
   // object   JavaScript Core Object °´Ã¼
 
   var r = key+"_"+value;
   document.writeln (r + "<br />"); 
   return r;
}
$H({one:"first", two:"second", three:"third"}).map(callback);
 */
jindo.$H.prototype.map = function(callback, thisObject) {
	var t = this._table;
	this.forEach(function(v,k,o) {
		t[k] = callback.call(thisObject, v, k, o);
	});
	return this;
};

/**
 * ÇØ½Ã Å×ÀÌºí¿¡ °ªÀ» Ãß°¡ÇÑ´Ù.
 * @param {String} key Ãß°¡ÇÑ °ªÀ» À§ÇÑ Å° 
 * @param {String} value ÇØ½Ã Å×ÀÌºí¿¡ Ãß°¡ÇÒ °ª
 * @return {$H} °ªÀ» Ãß°¡ÇÑ ÇØ½Ã °´Ã¼
 */
jindo.$H.prototype.add = function(key, value) {
	//if (this.hasKey(key)) return null;
	this._table[key] = value;

	return this;
};

/**
 * remove ¸Þ¼­µå´Â ÇØ½Ã Å×ÀÌºíÀÇ ¿ø¼Ò¸¦ Á¦°ÅÇÑ´Ù.
 * @param {String} key Á¦°ÅÇÒ ¿ø¼ÒÀÇ Å°
 * @return {void} Á¦°ÅÇÑ Å° °ª
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.remove ("two");
// hÀÇ ÇØ½Ã Å×ÀÌºíÀº {one:"first", three:"third"}
 */
jindo.$H.prototype.remove = function(key) {
	if (typeof this._table[key] == "undefined") return null;
	var val = this._table[key];
	delete this._table[key];
	
	return val;
};

/**
 * search ¸Þ¼­µå´Â ÇØ½Ã Å×ÀÌºí¿¡¼­ ÀÎ¼ö·Î ÁöÁ¤ÇÑ °ªÀ» Ã£´Â´Ù.
 * @param {String} value °Ë»öÇÒ °ª
 * @returns {String | Boolean} °ªÀ» Ã£¾Ò´Ù¸é °ª¿¡ ´ëÇÑ Å°. °ªÀ» Ã£Áö ¸øÇß´Ù¸é false. 
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.search ("second");
// two

h.search ("fist");
// false
 */
jindo.$H.prototype.search = function(value) {
	var result = false;
	this.forEach(function(v,k,o) {
		if (v === value) {
			result = k;
			jindo.$H.Break();
		}
	});
	return result;
};

/**
 * hasKey ¸Þ¼­µå´Â ÇØ½Ã Å×ÀÌºí¿¡ ÀÎ¼ö·Î ÁöÁ¤ÇÑ Å°°¡ ÀÖ´ÂÁö Ã£´Â´Ù.
 * @param {String} key ÇØ½Ã Å×ÀÌºí¿¡¼­ °Ë»öÇÒ Å°
 * @return {Boolean} Å°ÀÇ Á¸Àç ¿©ºÎ
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.hasKey("four"); // false
h.hasKey("one"); // true
 */
jindo.$H.prototype.hasKey = function(key) {
	var result = false;
	
	return (typeof this._table[key] != "undefined");
};

/**
 * hasValue ¸Þ¼­µå´Â ÇØ½Ã Å×ÀÌºí¿¡ ÀÎ¼ö·Î ÁöÁ¤ÇÑ °ªÀÌ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.
 * @param {String} value ÇØ½Ã Å×ÀÌºí¿¡¼­ °Ë»öÇÒ °ª
 * @return {Boolean} °ªÀÇ Á¸Àç ¿©ºÎ
 */
jindo.$H.prototype.hasValue = function(value) {
	return (this.search(value) !== false);
};

/**
 * sort ¸Þ¼­µå´Â °ªÀ» ±âÁØÀ¸·Î ¿ø¼Ò¸¦ ¿À¸§Â÷¼ø Á¤·ÄÇÑ´Ù.
 * @return {$H} ¿ø¼Ò¸¦ Á¤·ÄÇÑ ÇØ½Ã °´Ã¼.
 * @see $H#ksort
 * @example
var h = $H({one:"ÇÏ³ª", two:"µÑ", three:"¼Â"});
h.sort ();
// {two:"µÑ", three:"¼Â", one:"ÇÏ³ª"}
 */
jindo.$H.prototype.sort = function() {
	var o = new Object;
	var a = this.values();
	var k = false;

	a.sort();

	for(var i=0; i < a.length; i++) {
		k = this.search(a[i]);

		o[k] = a[i];
		delete this._table[k];
	}
	
	this._table = o;
	
	return this;
};

/**
 * ksort ¸Þ¼­µå´Â Å°¸¦ ±âÁØÀ¸·Î ¿ø¼Ò¸¦ ¿À¸§Â÷¼ø Á¤·ÄÇÑ´Ù. 
 * @return {$H} ¿ø¼Ò¸¦ Á¤·ÄÇÑ ÇØ½Ã °´Ã¼
 * @see $H#sort
 * @example
var h = $H({one:"ÇÏ³ª", two:"µÑ", three:"¼Â"});
h.sort ();
// h => {one:"ÇÏ³ª", three:"¼Â", two:"µÑ"}
 */
jindo.$H.prototype.ksort = function() {
	var o = new Object;
	var a = this.keys();

	a.sort();

	for(var i=0; i < a.length; i++) {
		o[a[i]] = this._table[a[i]];
	}

	this._table = o;

	return this;
};

/**
 * keys ¸Þ¼­µå´Â ÇØ½Ã Å°ÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @return {Array} ÇØ½Ã Å°ÀÇ ¹è¿­
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.keys ();
// ["one", "two", "three"]
 * @see $H#values
 */
jindo.$H.prototype.keys = function() {
	var keys = new Array;
	for(var k in this._table) {
		keys.push(k);
	}

	return keys;
};

/**
 * values ¸Þ¼­µå´Â ÇØ½Ã °ªÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @return {Array} ÇØ½Ã °ªÀÇ ¹è¿­
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.values();
// ["first", "second", "third"]
 * @see $H#keys
 */
jindo.$H.prototype.values = function() {
	var values = [];
	for(var k in this._table) {
		values[values.length] = this._table[k];
	}

	return values;
};

/**
 * toQueryStringÀº ÇØ½Ã °´Ã¼¸¦ Äõ¸® ½ºÆ®¸µ ÇüÅÂ·Î ¸¸µç´Ù.
 * @return {String} 
 * @example
var h = $H({one:"first", two:"second", three:"third"});
h.toQueryString();
// "one=first&two=second&three=third"
 */
jindo.$H.prototype.toQueryString = function() {
	var buf = [], val = null, idx = 0;
	for(var k in this._table) {
		if (typeof(val = this._table[k]) == "object" && val.constructor == Array) {
			for(i=0; i < val.length; i++) {
				buf[buf.length] = encodeURIComponent(k)+"[]="+encodeURIComponent(val[i]+"");
			}
		} else {
			buf[buf.length] = encodeURIComponent(k)+"="+encodeURIComponent(this._table[k]+"");
		}
	}
	
	return buf.join("&");
};

/**
 * empty´Â ÇØ½Ã °´Ã¼¸¦ ºó °´Ã¼·Î ¸¸µç´Ù.
 * @return {$H} ºñ¿öÁø ÇØ½Ã °´Ã¼
 * @example
var hash = $H({a:1, b:2, c:3});
// hash => {a:1, b:2, c:3}

hash.empty();
// hash => {}
 */
jindo.$H.prototype.empty = function() {
	var keys = this.keys();

	for(var i=0; i < keys.length; i++) {
		delete this._table[keys[i]];
	}

	return this;
};

/**
 * Break ¸Þ¼­µå´Â ¹Ýº¹¹®ÀÇ ½ÇÇàÀ» Áß´ÜÇÒ ¶§ »ç¿ëÇÑ´Ù.
 * @remark forEach, filter, map¿Í °°Àº ·çÇÁ¸¦ Áß´ÜÇÑ´Ù. °­Á¦·Î exceptionÀ» ¹ß»ý½ÃÅ°¹Ç·Î try ~ catch ¿µ¿ª¿¡¼­ ÀÌ ¸Þ¼Òµå¸¦ ½ÇÇàÇÏ¸é Á¤»óÀûÀ¸·Î µ¿ÀÛÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.
 * @example
$H({a:1, b:2, c:3}).forEach(function(v,k,o) {
   ...
   if (k == "b") $H.Break();
   ...
});
 * @see $H.Continue
 */
jindo.$H.Break = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * Continue ¸Þ¼­µå´Â ·çÇÁ¸¦ ½ÇÇàÇÏ´Ù ´ÙÀ½ ´Ü°è·Î ³Ñ¾î°¥ ¶§ »ç¿ëÇÑ´Ù. 
 * @remark forEach, filter, map¿Í °°Àº ·çÇÁ ½ÇÇà µµÁß¿¡ ÇöÀç ·çÇÁ¸¦ Áß´ÜÇÏ°í ´ÙÀ½À¸·Î ³Ñ¾î°£´Ù. °­Á¦·Î exceptionÀ» ¹ß»ý½ÃÅ°¹Ç·Î try ~ catch ¿µ¿ª¿¡¼­ ÀÌ ¸Þ¼Òµå¸¦ ½ÇÇàÇÏ¸é Á¤»óÀûÀ¸·Î µ¿ÀÛÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.
 * @example
$H({a:1, b:2, c:3}).forEach(function(v,k,o) {
   ...
   if (v % 2 == 0) $H.Continue();
   ...
});
 * @see $H.Break
 */
jindo.$H.Continue = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * @fileOverview $JsonÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name json.js
 */

/**
 * $Json °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @class $Json °´Ã¼´Â Javascipt¿¡¼­ JSON(JavaScript Object Notation)À» ´Ù·ç±â À§ÇÑ ´Ù¾çÇÑ ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù.
 * @param {Object | String} sObject °´Ã¼, È¤Àº JSONÀ¸·Î ÀÎÄÚµù °¡´ÉÇÑ ¹®ÀÚ¿­.
 * @return {$Json} ÀÎ¼ö¸¦ ÀÎÄÚµùÇÑ $Json °´Ã¼.
 * @remark XML ¹®ÀÚ¸¦ »ç¿ëÇÏ¿© $Json °´Ã¼¸¦ »ý¼ºÇÏ·Á¸é $Json#fromXML ¸Þ¼­µå¸¦ »ç¿ëÇÑ´Ù.
 * @example 
var oStr = $Json ('{ zoo: "myFirstZoo", tiger: 3, zebra: 2}');

var d = {name : 'nhn', location: 'Bundang-gu'}
var oObj = $Json (d);

 * @constructor
 * @author Kim, Taegon
 */
jindo.$Json = function (sObject) {
	var cl = arguments.callee;
	if (typeof sObject == "undefined") sObject = new Object;
	if (sObject instanceof cl) return sObject;
	if (!(this instanceof cl)) return new cl(sObject);
	
	if (typeof sObject == "string") {
		try {
			sObject = new Function("return "+sObject)();
		} catch(e) {
			sObject = new Object;
		}
	}

	this._object = sObject;
}

/**
 * fromXML ¸Þ¼­µå´Â XML ¹®ÀÚ¿­À» $Json °´Ã¼·Î ÀÎÄÚµùÇÑ´Ù.
 * @param {String} sXML $Json  °´Ã¼·Î ÀÎÄÚµùÇÒ XML ¹®ÀÚ¿­ 
 * @returns {Object} $Json °´Ã¼
 * @remark ¼Ó¼º°ú CDATA¸¦ °¡Áö´Â ÅÂ±×´Â CDATA¸¦ '$cdata' ¼Ó¼º°ú °ªÀ¸·Î ÀÎÄÚµùÇÑ´Ù.  
 * @example
var j1 = $Json.fromXML('<data>only string</data>');
// {"data":"only string"}

var j2 = $Json.fromXML('<data><id>Faqh%$</id><str attr="123">string value</str></data>');
{"data":{"id":"Faqh%$","str":{"attr":"123","$cdata":"string value"}}} 
  */
jindo.$Json.fromXML = function(sXML) {
	var o  = new Object;
	var re = /\s*<(\/?[\w:\-]+)((?:\s+[\w:\-]+\s*=\s*(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'))*)\s*((?:\/>)|(?:><\/\1>|\s*))|\s*<!\[CDATA\[([\w\W]*?)\]\]>\s*|\s*>?([^<]*)/ig;
	var re2= /^[0-9]+(?:\.[0-9]+)?$/;
	var ec = {"&amp;":"&","&nbsp;":" ","&quot;":"\"","&lt;":"<","&gt;":">"};
	var fg = {tags:["/"],stack:[o]};
	var es = function(s){return s.replace(/&[a-z]+;/g, function(m){ return (typeof ec[m] == "string")?ec[m]:m; })};
	var at = function(s,c){s.replace(/([\w\:\-]+)\s*=\s*(?:"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)')/g, function($0,$1,$2,$3){c[$1] = es(($2?$2.replace(/\\"/g,'"'):undefined)||($3?$3.replace(/\\'/g,"'"):undefined));}) };
	var em = function(o){for(var x in o){if(Object.prototype[x])continue;return false;};return true};
	
	// $0 : ÀüÃ¼ 
	// $1 : ÅÂ±×¸í
	// $2 : ¼Ó¼º¹®ÀÚ¿­
	// $3 : ´Ý´ÂÅÂ±×
	// $4 : CDATA¹Ùµð°ª
	// $5 : ±×³É ¹Ùµð°ª 
	var cb = function($0,$1,$2,$3,$4,$5) {
		var cur, cdata = "";
		var idx = fg.stack.length - 1;
		
		if (typeof $1 == "string" && $1) {
			if ($1.substr(0,1) != "/") {
				var has_attr = (typeof $2 == "string" && $2);
				var closed   = (typeof $3 == "string" && $3);
				var newobj   = (!has_attr && closed)?"":{};

				cur = fg.stack[idx];
				
				if (typeof cur[$1] == "undefined") {
					cur[$1] = newobj; 
					cur = fg.stack[idx+1] = cur[$1];
				} else if (cur[$1] instanceof Array) {
					var len = cur[$1].length;
					cur[$1][len] = newobj;
					cur = fg.stack[idx+1] = cur[$1][len];  
				} else {
					cur[$1] = [cur[$1], newobj];
					cur = fg.stack[idx+1] = cur[$1][1];
				}
				
				if (has_attr) at($2,cur);

				fg.tags[idx+1] = $1;

				if (closed) {
					fg.tags.length--;
					fg.stack.length--;
				}
			} else {
				fg.tags.length--;
				fg.stack.length--;
			}
		} else if (typeof $4 == "string" && $4) {
			cdata = $4;
		} else if (typeof $5 == "string" && $5) {
			cdata = es($5);
		}
		
		if (cdata.length > 0) {
			var par = fg.stack[idx-1];
			var tag = fg.tags[idx];

			if (re2.test(cdata)) cdata = parseFloat(cdata);
			else if (cdata == "true" || cdata == "false") cdata = new Boolean(cdata);

			if(typeof par =='undefined') return;
			
			if (par[tag] instanceof Array) {
				var o = par[tag];
				if (typeof o[o.length-1] == "object" && !em(o[o.length-1])) {
					o[o.length-1].$cdata = cdata;
					o[o.length-1].toString = function(){ return cdata; }
				} else {
					o[o.length-1] = cdata;
				}
			} else {
				if (typeof par[tag] == "object" && !em(par[tag])) {
					par[tag].$cdata = cdata;
					par[tag].toString = function(){ return cdata; }
				} else {
					par[tag] = cdata;
				}
			}
		}
	};
	
	sXML = sXML.replace(/<(\?|\!-)[^>]*>/g, "");
	sXML.replace(re, cb);
	
	return jindo.$Json(o);
};

/**
 * get ¸Þ¼­µå´Â $Json °´Ã¼ÀÇ °ªÀ» path ÇüÅÂ·Î ¸®ÅÏÇÑ´Ù.
 * @param {String} sPath path ¹®ÀÚ¿­
 * @return {Array} °´Ã¼ÀÇ ¹è¿­
 * @example
var j = $Json.fromXML('<data><id>Faqh%$</id><str attr="123">string value</str></data>');
var r = j.get ("/data/id");
// Faqh%$

 */
jindo.$Json.prototype.get = function(sPath) {
	var o = this._object;
	var p = sPath.split("/");
	var re = /^([\w:\-]+)\[([0-9]+)\]$/;
	var stack = [[o]], cur = stack[0];
	var len = p.length, c_len, idx, buf, j, e;
	
	for(var i=0; i < len; i++) {
		if (p[i] == "." || p[i] == "") continue;
		if (p[i] == "..") {
			stack.length--;
		} else {
			buf = [];
			idx = -1;
			c_len = cur.length;
			
			if (c_len == 0) return [];
			if (re.test(p[i])) idx = +RegExp.$2;
			
			for(j=0; j < c_len; j++) {
				e = cur[j][p[i]];
				if (typeof e == "undefined") continue;
				if (e instanceof Array) {
					if (idx > -1) {
						if (idx < e.length) buf[buf.length] = e[idx];
					} else {
						buf = buf.concat(e);
					}
				} else if (idx == -1) {
					buf[buf.length] = e;
				}
			}
			
			stack[stack.length] = buf;
		}
		
		cur = stack[stack.length-1];
	}

	return cur;
};

/**
 * toString ¸Þ¼­µå´Â $Json °´Ã¼¸¦ JSON ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @return {String} JSON ¹®ÀÚ¿­
 * @example
var j = $Json({foo:1, bar: 31});
document.write (j.toString());
document.write (j);

 */
jindo.$Json.prototype.toString = function() {
	var func = {
		$ : function($) {
			if (typeof $ == "object" && $ == null) return 'null';
			if (typeof $ == "undefined") return '""';
			if (typeof $ == "boolean") return $?"true":"false";
			if (typeof $ == "string") return this.s($);
			if (typeof $ == "number") return $;
			if ($ instanceof Array) return this.a($);
			if ($ instanceof Object) return this.o($);
		},
		s : function(s) {
			var e = {'"':'\\"',"\\":"\\\\","\n":"\\n","\r":"\\r","\t":"\\t"};
			var c = function(m){ return (typeof e[m] != "undefined")?e[m]:m };
			return '"'+s.replace(/[\\"'\n\r\t]/g, c)+'"';
		},
		a : function(a) {
			var s = "[",c = "",n=a.length;
			for(var i=0; i < n; i++) {
				if (typeof a[i] == "function") continue;
				s += c+this.$(a[i]);
				if (!c) c = ",";
			}
			return s+"]";
		},
		o : function(o) {
			var s = "{",c = "";
			for(var x in o) {
				if (typeof o[x] == "function") continue;
				s += c+this.s(x)+":"+this.$(o[x]);
				if (!c) c = ",";
			}
			return s+"}";
		}
	}

	return func.$(this._object);
};

/**
 * toXML ¸Þ¼­µå´Â $Json °´Ã¼¸¦ XML ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @return {String} XML ¹®ÀÚ¿­
 * @example
var json = $Json({foo:1, bar: 31});
json.toXML();
// <foo>1</foo><bar>31</bar>
 */
jindo.$Json.prototype.toXML = function() {
	var f = function($,tag) {
		var t = function(s,at) { return "<"+tag+(at||"")+">"+s+"</"+tag+">" };
		
		switch (typeof $) {
			case "undefined":
			case "null":
				return t("");
			case "number":
				return t($);
			case "string":
				if ($.indexOf("<") < 0) return t($.replace(/&/g,"&amp;"));
				else return t("<![CDATA["+$+"]]>");
			case "boolean":
				return t(String($));
			case "object":
				var ret = "";
				if ($ instanceof Array) {
					var len = $.length;
					for(var i=0; i < len; i++) { ret += f($[i],tag); };
				} else {
					var at = "";

					for(var x in $) {
						if (x == "$cdata" || typeof $[x] == "function") continue;
						ret += f($[x], x);
					}

					if (tag) ret = t(ret, at);
				}
				return ret;
		}
	};
	
	return f(this._object, "");
};

/**
 * toObject ¸Þ¼­µå´Â $Json °´Ã¼ ³»ºÎÀÇ JSON µ¥ÀÌÅÍ °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {Object} µ¥ÀÌÅÍ °´Ã¼
 * @example
var json = $Json({foo:1, bar: 31});
json.toObject();
// {foo: 1, bar: 31}
 */
jindo.$Json.prototype.toObject = function() {
	return this._object;
};

/**
 * $value ¸Þ¼­µå´Â $Json.toObjectÀÇ º°Äª(Alias)ÀÌ´Ù. 
 * @return {Object} µ¥ÀÌÅÍ °´Ã¼
 */
jindo.$Json.prototype.$value = jindo.$Json.prototype.toObject;
/**

 * @fileOverview $CookieÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ

 * @name cookie.js

 */



/**

 * $Cookie °´Ã¼¸¦ »ý¼ºÇÑ´Ù.

 * @class $Cookie Å¬·¡½º´Â ÄíÅ°(Cookie)¸¦ Ãß°¡, ¼öÁ¤, È¤Àº »èÁ¦ÇÏ°Å³ª ÄíÅ°ÀÇ °ªÀ» °¡Á®¿Â´Ù.

 * @constructor

 * @author Kim, Taegon

 * @example 

var cookie = $Cookie();

cookie.set("session_id", "eac312d1d51ab", 1);



document.write (cookie.keys());

 */

jindo.$Cookie = function() {

	var cl = arguments.callee;

	var cached = cl._cached;

	

	if (cl._cached) return cl._cached;

	if (!(this instanceof cl)) return new cl;

	if (typeof cl._cached == "undefined") cl._cached = this;

};



/**

 * ÄíÅ° ÀÌ¸§ÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.

 * @return {Array} ÄíÅ° ÀÌ¸§ÀÇ ¹è¿­

 */

jindo.$Cookie.prototype.keys = function() {

	var ca = document.cookie.split(";");

	var re = /^\s+|\s+$/g;

	var a  = new Array;

	

	for(var i=0; i < ca.length; i++) {

		a[a.length] = ca[i].substr(0,ca[i].indexOf("=")).replace(re, "");

	}

	

	return a;

};



/**

 * ÀÌ¸§¿¡ ÇØ´çÇÏ´Â ÄíÅ° °ªÀ» °¡Á®¿Â´Ù. °ªÀÌ Á¸ÀçÇÏÁö ¾Ê´Â´Ù¸é nullÀ» ¹ÝÈ¯ÇÑ´Ù.

 * @param {String} sName ÄíÅ° ÀÌ¸§

 * @return {String} ÄíÅ° °ª

 * @example 

var cookie = $Cookie();

cookie.set("session_id", "eac312d1d51ab", 1);



// ...



document.write (cookie.get ("session_id"));

 */

jindo.$Cookie.prototype.get = function(sName) {

	var ca = document.cookie.split(/\s*;\s*/);

	var re = new RegExp("^(\\s*"+sName+"\\s*=)");

	

	for(var i=0; i < ca.length; i++) {

		if (re.test(ca[i])) return unescape(ca[i].substr(RegExp.$1.length));

	}

	

	return null;

};



/**

 * ÀÌ¸§¿¡ ÇØ´çÇÏ´Â ÄíÅ° °ªÀ» ¼³Á¤ÇÑ´Ù.

 * @param {String} sName ÄíÅ° ÀÌ¸§.

 * @param {String} sValue ÄíÅ° °ª.

 * @param {Number} [nDays] ÄíÅ° À¯È¿ ½Ã°£. À¯È¿ ½Ã°£Àº ÀÏ´ÜÀ§·Î ¼³Á¤ÇÑ´Ù. À¯È¿½Ã°£À» »ý·«Çß´Ù¸é ÄíÅ°´Â À¥ ºê¶ó¿ìÀú°¡ Á¾·áµÇ¸é¼­ ¾ø¾îÁø´Ù.

 * @param {String} [sDomain] ÄíÅ° µµ¸ÞÀÎ.

 * @param {String} [sPath] ÄíÅ° ÆÐ½º.

 * @return {$Cookie} $Cookie °´Ã¼

 */

jindo.$Cookie.prototype.set = function(sName, sValue, nDays, sDomain, sPath) {

	var sExpire = "";

	

	if (typeof nDays == "number") {

		sExpire = ";expires="+(new Date((new Date()).getTime()+nDays*1000*60*60*24)).toGMTString();

	}

	if (typeof sDomain == "undefined") sDomain = "";

	if (typeof sPath == "undefined") sPath = "/";

	

	document.cookie = sName+"="+escape(sValue)+sExpire+"; path="+sPath+(sDomain?"; domain="+sDomain:"");

	

	return this;

};



/**

 * ÀÌ¸§¿¡ ÇØ´çÇÏ´Â ÄíÅ° °ªÀ» Á¦°ÅÇÑ´Ù.

 * @param {String} sName ÄíÅ° ÀÌ¸§

 * @return {$Cookie} $Cookie °´Ã¼

 */

jindo.$Cookie.prototype.remove = function(sName, sDomain, sPath) {

	if (this.get(sName) != null) this.set(sName, "", -1, sDomain, sPath);

	

	return this;

};


/**
 * @fileOverview $ElementÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name element.js
 */

/**
 * $Element °´Ã¼¸¦ »ý¼º ¹× ¸®ÅÏÇÑ´Ù.
 * @class $Element Å¬·¡½º´Â DOM ¿¤¸®¸ÕÆ®¸¦ ´Ù·ç±â À§ÇÑ ¿©·¯ °¡Áö ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù.
 * @param {Element | String} el	$Element¸¦ »ç¿ëÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº DOM ¿¤¸®¸ÕÆ®ÀÇ °íÀ¯ÇÑ id. ¸¸¾à °íÀ¯ÇÏÁö ¾ÊÀº id¸¦ ÁöÁ¤ÇÏ¸é °¡Àå ¸ÕÀú ³ª¿À´Â ¿¤¸®¸ÕÆ®¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @constructor
 * @description [Lite]
 * @author Kim, Taegon
 */
jindo.$Element = function(el) {
	var cl = arguments.callee;
	
	if (el && el instanceof cl) return el;
	
	if(!jindo.$(el)) return null;
		
	if (!(this instanceof cl)) return new cl(el);

	this._element = jindo.$(el);
			
	// tagname
	this.tag = (typeof this._element.tagName!='undefined')?this._element.tagName.toLowerCase():''; 

}

/**
 * $value ¸Þ¼­µå´Â ·¡ÇÎµÈ ¿ø·¡ÀÇ DOM ¿¤¸®¸ÕÆ®¸¦ ¸®ÅÏÇÑ´Ù.
 * @return {HTMLElement} DOM ¿¤¸®¸ÕÆ®
 * @description [Lite]
 */
jindo.$Element.prototype.$value = function() {
	return this._element;
};

/**
 * visible ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ CSSÀÇ display ¼Ó¼ºÀ» Á¶»çÇØ¼­ ¿¤¸®¸ÕÆ®°¡ º¸ÀÌ´Â »óÅÂÀÎÁö È®ÀÎÇÑ´Ù.
 * @param {Boolean} bVisible ¿¤¸®¸ÕÆ®¸¦ º¸ÀÌ°Å³ª ¾È º¸ÀÌ°Ô ¼³Á¤ÇÑ´Ù. true¸é show() ¸Þ¼­µå¸¦, false¸é hide() ¸Þ¼­µå¸¦ ½ÇÇàÇÏ´Â °Í°ú µ¿ÀÏÇÑ °á°ú¸¦ ¾ò´Â´Ù.
 * @return {Boolean|$Element} display ¼Ó¼ºÀÌ noneÀÌ¸é false ¸¦, ±× ¿ÜÀÇ °ªÀÌ¸é true¸¦ ¸®ÅÏÇÑ´Ù. ¼³Á¤ÇÏ°Ô µÇ¸é ÇöÀçÀÇ this °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 * @since ¼³Á¤ ±â´ÉÀº 1.1.2ºÎÅÍ
 */
jindo.$Element.prototype.visible = function(bVisible) {
	if (typeof bVisible != "undefined") {
		this[bVisible?"show":"hide"]();
		return this;
	}

	return (this.css("display") != "none");
};

/**
 * show ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®°¡ È­¸é¿¡ º¸ÀÌµµ·Ï CSSÀÇ display ¼Ó¼ºÀ» º¯°æÇÑ´Ù.
 * @return {$Element} display ¼Ó¼ºÀ» º¯°æÇÑ $Element °´Ã¼.
 * @description [Lite]
 * @see $Element#hide
 */
jindo.$Element.prototype.show = function() {
	var s = this._element.style;
	var b = "block";
	var c = {p:b,div:b,form:b,h1:b,h2:b,h3:b,h4:b,ol:b,ul:b,fieldset:b,td:"table-cell",th:"table-cell",li:"list-item",table:"table",thead:"table-header-group",tbody:"table-row-group",tfoot:"table-footer-group",tr:"table-row",col:"table-column",colgroup:"table-column-group",caption:"table-caption",dl:b,dt:b,dd:b};

	try {
		if(typeof c[this.tag] == "string") {
			s.display = c[this.tag];
		} else {
			s.display = "inline";
		}
	} catch(e) {
		s.display = "block";
	}

	return this;
};

/**
 * hide ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®°¡ È­¸é¿¡ º¸ÀÌÁö ¾Êµµ·Ï CSSÀÇ display ¼Ó¼ºÀ» noneÀ¸·Î º¯°æÇÑ´Ù.
 * @returns {Object} this	display ¼Ó¼ºÀ» º¯°æÇÑ $Element °´Ã¼.
 * @see $Element#show
 * @description [Lite]
 */
jindo.$Element.prototype.hide = function() {
	this._element.style.display = "none";

	return this;
};

/**
 * toggle ¸Þ¼­µå´Â CSSÀÇ Display ¼Ó¼ºÀ» º¯°æÇÏ¿© DOM ¿¤¸®¸ÕÆ®¸¦ È­¸é¿¡ º¸ÀÌ°Å³ª º¸ÀÌÁö ¾Ê°Ô ÇÑ´Ù.
 * @returns {Object} this display ¼Ó¼ºÀ» º¯°æÇÑ $Element °´Ã¼.
 * @see $Element#show
 * @see $Element#hide
 * @description [Lite]
 * @example

var isOpen 	= e.toggle().visible();
var bullet	= (isOpen) ? '-' : '+';

 */
jindo.$Element.prototype.toggle = function() {
	this[this.visible()?"hide":"show"]();

	return this;
};

/**
 * opacity ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ Åõ¸íµµ °ªÀ» ¸®ÅÏÇÏ°Å³ª ¼³Á¤ÇÑ´Ù.
 * @param {Number} value	¼³Á¤ÇÒ Åõ¸íµµ °ª. Åõ¸íµµ °ªÀº 0 ~ 1 »çÀÌÀÇ ½Ç¼ö°ªÀ¸·Î Á¤ÇÑ´Ù. °ªÀÌ 0º¸´Ù ÀÛÀ¸¸é 0À», 1º¸´Ù Å©¸é 1À» ¼³Á¤ÇÑ´Ù.
 * @return {Number} DOM ¿¤¸®¸ÕÆ®ÀÇ Åõ¸íµµ °ª.
 * @description [Lite]
 */
jindo.$Element.prototype.opacity = function(value) {
	var v,e = this._element,b=this.visible();
	
	value = parseFloat(value);
	
	if (!isNaN(value)) {
		value = Math.max(Math.min(value,1),0);

		if (typeof e.filters != "undefined") {
			value = Math.ceil(value*100);
			
			if (typeof e.filters != 'unknown' && typeof e.filters.alpha != "undefined") {
				e.filters.alpha.opacity = value;
			}
			else {
				e.style.filter = (e.style.filter + " alpha(opacity=" + value + ")");
			}		
		} else {
			e.style.opacity = value;
		}

		return value;
	}

	if (typeof e.filters != "undefined") {
		v = (typeof e.filters.alpha == "undefined")?(b?100:0):e.filters.alpha.opacity;
		v = v / 100;
	} else {
		v = parseFloat(e.style.opacity);
		if (isNaN(v)) v = b?1:0;
	}

	return v;
};

/**
 * css ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ CSS ¼Ó¼º°ªÀ» °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù. ¼Ó¼º°ªÀÇ
 * ÀÎ¼ö ÇÏ³ª¸¦ »ç¿ëÇÏ¸é CSSS¿¡¼­ String¿¡ ÇØ´çÇÏ´Â CSS ¼Ó¼ºÀÇ °ªÀ» °¡Á®¿Â´Ù.
 * ÀÎ¼ö µÎ °³¸¦ »ç¿ëÇÏ¸é Ã¹¹øÂ° ÀÎ¼ö¿¡ ÇØ´çÇÏ´Â CSS ¼Ó¼ºÀ» µÎ¹øÂ° ÀÎ¼öÀÇ °ªÀ¸·Î ¼³Á¤ÇÑ´Ù.
 * Object È¤Àº $Hash Å¸ÀÔÀÇ °´Ã¼¸¦ »ç¿ëÇÏ¸é µÎ °³ ÀÌ»óÀÇ CSS ¼Ó¼ºÀ» ÇÑ²¨¹ø¿¡ Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.
 * @remark CSS ¼Ó¼ºÀº Camel Ç¥±â¹ýÀ» »ç¿ëÇÑ´Ù. µû¶ó¼­ border-width-bottomÀº borderWidthBottomÀ¸·Î Á¤ÀÇÇÑ´Ù.
 * @remark float ¼Ó¼ºÀº JavascriptÀÇ ¿¹¾à¾î·Î »ç¿ëÇÏ¹Ç·Î css ¸Þ¼­µå¿¡¼­´Â float ´ë½Å cssFloat¸¦ »ç¿ëÇÑ´Ù. (Internet Explorer¿¡¼­´Â styleFloat¸¦, ±× ¿ÜÀÇ ºê¶ó¿ìÀú¿¡¼­´Â cssFloat¸¦ »ç¿ëÇÑ´Ù.)
 * @param {String | Object | $H} sName CSS ¼Ó¼º | ÇÏ³ª ÀÌ»óÀÇ CSS ¼Ó¼º°ú °ªÀ» °¡Áö´Â °´Ã¼.
 * @param {String | Number} [sValue] CSS ¼Ó¼º¿¡ ¼³Á¤ÇÒ °ª. ´ÜÀ§°¡ ÇÊ¿äÇÑ °ªÀº Number, È¤Àº ´ÜÀ§¸¦ Æ÷ÇÔÇÏ´Â StringÀ¸·Î Á¤ÀÇÇÑ´Ù.
 * @return {String | $Element} °ªÀ» °¡Á®¿Ã ¶§´Â String ¼³Á¤°ªÀ», °ªÀ» ¼³Á¤ÇÒ ¶§´Â °ªÀ» ¼³Á¤ÇÑ ÇöÀçÀÇ $Element¸¦ ¸®ÅÏÇÑ´Ù. °ªÀ» ¼³Á¤ÇÒ ¶§ CSS ¼Ó¼ºÀÌ Á¸Á¦ÇÏÁö ¾ÊÀ¸¸é nullÀ» ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example

<style>
	#btn {
		width: 120px;
		height: 30px;
		background-color: blue;
	}
</style>

...

<script type="text/javascript" charset="utf-8">
	window.onload = function () {
		$Element('btn').css('backgroundColor');
		// rgb (0, 0, 256)

		$Element('btn').css('backgroundColor', 'red');
		// $Element('btn').css('backgroundColor') -> reb (255, 0, 0)

		$Element('btn').css({
			width: "200px",
			height: "80px"
		});
		// $Element('btn').css('width') -> "200px"
		// $Element('btn').css('height') -> "80px"
 	}
</script>
 */
jindo.$Element.prototype.css = function(sName, sValue) {
	var e = this._element;

	if (sName == 'opacity') return typeof sValue == 'undefined' ? this.opacity() : this.opacity(sValue);

	if (typeof sName == "string") {
		var view;

		if (typeof sValue == "string" || typeof sValue == "number") {
			var obj = new Object;
			obj[sName] = sValue;
			sName = obj;
		} else {
			if (e.currentStyle) {
				if (sName == "cssFloat") sName = "styleFloat";
				return e.currentStyle[sName]||e.style[sName];
			} else if (window.getComputedStyle) {
				if (sName == "cssFloat") sName = "float";
				var d = e.ownerDocument || e.document || document;
				return d.defaultView.getComputedStyle(e,null).getPropertyValue(sName.replace(/([A-Z])/g,"-$1").toLowerCase())||e.style[sName];
			} else {
				if (sName == "cssFloat" && /MSIE/.test(window.navigator.userAgent)) sName = "styleFloat";
				return e.style[sName];
			}

			return null;
		}
	}

	if (typeof jindo.$H != "undefined" && sName instanceof jindo.$H) {
		sName = sName.$value();
	}

	if (typeof sName == "object") {
		var v, type;

		for(var k in sName) {
			v    = sName[k];
			type = (typeof v);
			if (type != "string" && type != "number") continue;
			if (k == 'opacity') {
				type == 'undefined' ? this.opacity() : this.opacity(v);
				continue;
			}
			if (k == "cssFloat" && navigator.userAgent.indexOf("MSIE") > -1) k = "styleFloat";
			try {
				e.style[k] = v;
			} catch(err) {
				if (k == "cursor" && v == "pointer") {
					e.style.cursor = "hand";
				} else if (("#top#left#right#bottom#").indexOf(k+"#") > 0 && (type == "number" || !isNaN(parseInt(v)))) {
					e.style[k] = parseInt(v)+"px";
				}
			}
		}
	}

	return this;
};

/**
 * attr ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ HTML ¼Ó¼ºÀ» °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù.
 * ÇÏ³ªÀÇ ÀÎ¼ö¸¸ »ç¿ëÇÏ¸é ÇØ´ç HTML ¼Ó¼ºÀÇ ¼Ó¼º°ªÀ» °¡Á®¿Â´Ù.
 * µÎ °³ÀÇ ÀÎ¼ö¸¦ »ç¿ëÇÏ¸é Ã¹¹øÂ° ÀÎ¼ö¿¡ ÇØ´çÇÏ´Â HTML ¼Ó¼ºÀÇ ¼Ó¼º°ªÀ» ¼³Á¤ÇÑ´Ù.
 * Object È¤Àº $Hash Å¸ÀÔÀÇ °´Ã¼¸¦ »ç¿ëÇÏ¸é µÎ °³ ÀÌ»óÀÇ HTML ¼Ó¼ºÀ» ÇÑ²¨¹ø¿¡ Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.
 * @param {String | Object | $H} sName HTML ¼Ó¼º ÀÌ¸§ È¤Àº ¼³Á¤°ª °´Ã¼
 * @param {String | Number} [sValue] ¼³Á¤°ª. ¼³Á¤°ªÀ» null·Î ÁöÁ¤ÇÏ¸é HTML ¼Ó¼ºÀ» Áö¿î´Ù.
 * @return {String | $Element} °ªÀ» °¡Á®¿Ã ¶§´Â String ¼³Á¤°ªÀ», °ªÀ» ¼³Á¤ÇÒ ¶§´Â °ªÀ» ¼³Á¤ÇÑ ÇöÀçÀÇ $Element¸¦ ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Element.prototype.attr = function(sName, sValue) {
	var e = this._element;

	if (typeof sName == "string") {
		if (typeof sValue != "undefined") {
			var obj = new Object;
			obj[sName] = sValue;
			sName = obj;
		} else {
			if (sName == "class" || sName == "className") return e.className;
			return e.getAttribute(sName);
		}
	}

	if (typeof jindo.$H != "undefined" && sName instanceof jindo.$H) {
		sName = sName.$value();
	}

	if (typeof sName == "object") {
		for(var k in sName) {
			if(/^on[a-zA-Z]+$/.test(k)){
				e[k] = sName[k];
				continue;
			}
			if (typeof(sValue) != "undefined" && sValue === null) {
				e.removeAttribute(k);
			}
			else 
				e.setAttribute(k, sName[k]);
		}
	}

	return this;
};

/**
 * width ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ³Êºñ¸¦ °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù.
 * @remark width ¸Þ¼­µå´Â ¿¤¸®¸ÕÆ®ÀÇ ½ÇÁ¦ ³Êºñ¸¦ °¡Á®¿Â´Ù. ºê¶ó¿ìÀú¸¶´Ù Box ¸ðµ¨ÀÇ Å©±â °è»ê ¹æ¹ýÀÌ ´Ù¸£¹Ç·Î CSSÀÇ width ¼Ó¼º°ª°ú width ¸Þ¼­µåÀÇ ¸®ÅÏ °ªÀº ¼­·Î ´Ù¸¦ ¼ö ÀÖ´Ù.
 * @param {Number} [width]	¼³Á¤ÇÒ ³Êºñ. ´ÜÀ§´Â px.
 * @return {Number|$Element} DOM ¿¤¸®¸ÕÆ®ÀÇ ½ÇÁ¦ ³Êºñ. ³Êºñ¸¦ ¼³Á¤ÇÏ¸é this¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Element.prototype.width = function(width) {
	if (typeof width == "number") {
		var e = this._element;

		e.style.width = width+"px";
		if (e.offsetWidth != width) {
			e.style.width = (width*2 - e.offsetWidth) + "px";
		}

		return this;
	}

	return this._element.offsetWidth;
};

/**
 * height ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ³ôÀÌ¸¦ °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù.
 * @remark height ¸Þ¼­µå´Â ¿¤¸®¸ÕÆ®ÀÇ ½ÇÁ¦ ³ôÀÌ¸¦ °¡Á®¿Â´Ù. ºê¶ó¿ìÀú¸¶´Ù Box ¸ðµ¨ÀÇ Å©±â °è»ê ¹æ¹ýÀÌ ´Ù¸£¹Ç·Î CSSÀÇ height ¼Ó¼º°ª°ú height ¸Þ¼­µåÀÇ ¸®ÅÏ °ªÀº ¼­·Î ´Ù¸¦ ¼ö ÀÖ´Ù.
 * @param {Number} height	¼³Á¤ÇÒ ³ôÀÌ. ´ÜÀ§´Â px.
 * @return {Number|$Element} DOM ¿¤¸®¸ÕÆ®ÀÇ ½ÇÁ¦ ³ôÀÌ. ³ôÀÌ¸¦ ¼³Á¤ÇÏ¸é this¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 */
jindo.$Element.prototype.height = function(height) {
	if (typeof height == "number") {
		var e = this._element;

		e.style.height = height+"px";
		if (e.offsetHeight != height) {
			var height = (height*2 - e.offsetHeight);
			if(height>0)
				e.style.height = height + "px";
		}

		return this;
	}

	return this._element.offsetHeight;
};

/**
 * className ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¿¡ Å¬·¡½º ÀÌ¸§À» ¼³Á¤ÇÏ°Å³ª ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sClass 	Å¬·¡½º ÀÌ¸§. µÎ °³ ÀÌ»óÀÇ Å¬·¡½º¸¦ ¼³Á¤Çß´Ù¸é °ø¹éÀ» Æ÷ÇÔÇÑ ¹®ÀÚ¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @description [Lite]
 * @example

<div id="zoo" class="animal rest">

..

<script type="text/javascript">

var el = $Element("zoo");
el.className();
// "animal rest"

el.className("entertainment");
el.className();
// "entertainment"

</script>
 */
jindo.$Element.prototype.className = function(sClass) {
	var e = this._element;

	if (typeof sClass == "undefined") return e.className;
	e.className = sClass;

	return this;
};

/**
 * hasClass ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¿¡¼­ Æ¯Á¤ÇÑ Å¬·¡½º¸¦ »ç¿ëÇÏ°í ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.
 * @param {String} sClass È®ÀÎÇÒ Å¬·¡½º ¼¿·¢ÅÍ
 * @return {Boolean} Å¬·¡½ºÀÇ »ç¿ë ¿©ºÎ.
 * @description [Lite]
 */
jindo.$Element.prototype.hasClass = function(sClass) {
	return (" "+this._element.className+" ").indexOf(" "+sClass+" ") > -1;
};

/**
 * addClass ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¿¡ Å¬·¡½º¸¦ Ãß°¡ÇÑ´Ù.
 * @param {String} sClass Ãß°¡ÇÒ Å¬·¡½º ¼¿·¢ÅÍ
 * @return {$Element} ÇöÀçÀÇ DOM ¿¤¸®¸ÕÆ®
 * @description [Lite]
 */
jindo.$Element.prototype.addClass = function(sClass) {
	var e = this._element;
	if (this.hasClass(sClass)) return this;
	e.className = (e.className+" "+sClass).replace(/^\s+/, "");
	return this;
};

/**
 * removeClass ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¿¡¼­ Æ¯Á¤ Å¬·¡½º¸¦ Á¦°ÅÇÑ´Ù.
 * @param {String} sClass Á¦°ÅÇÒ Å¬·¡½º ÀÌ¸§
 * @return {$Element} ÇöÀçÀÇ DOM ¿¤¸®¸ÕÆ®
 * @description [Lite]
 */
jindo.$Element.prototype.removeClass = function(sClass) {
	var e = this._element;
	e.className = (" "+e.className+" ").replace(" "+sClass+" ", " ").replace(/\s+$/, "").replace(/^\s+/, "");
	
	return this;
};

/**
 * toggle ¸Þ¼­µå´Â Å¬·¡½º ¼¿·ºÅÍÀ» Åä±ÛÇÑ´Ù. ÇÏ³ªÀÇ Å¬·¡½º ¼¿·ºÅÍ¸¦ ÀÎ¼ö·Î »ç¿ëÇÏ¸é ÇØ´ç Å¬·¡½º¸¸ Åä±ÛÇÏ°í, µÎ °³ÀÇ ¼¿·ºÅÍ¸¦ ÀÎ¼ö·Î »ç¿ëÇÏ¸é »ç¿ëÇÏ°í ÀÖ´Â ¼¿·ºÅÍ´Â Áö¿ì°í, ³ª¸ÓÁö ¼¿·ºÅÍ¸¦ Ãß°¡ÇÑ´Ù.
 * @param {Object} sClass	Å¬·¡½º ¼¿·ºÅÍ ÀÌ¸§. ÇÏ³ªÀÇ Å¬·¡½º ¼¿·ºÅÍ¸¸ ÀÎ¼ö·Î »ç¿ëÇÏ¸é, DOM ¿¤¸®¸ÕÆ®¿¡¼­ ÇØ´ç Å¬·¡½º ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ´ÂÁö È®ÀÎÇÑ´Ù. ¸¸¾à ¼¿·ºÅÍ¸¦ »ç¿ëÇÏ°í ÀÖ´Ù¸é ÇØ´ç ¼¿·ºÅÍ¸¦ Áö¿î´Ù. »ç¿ëÇÏ°í ÀÖÁö ¾Ê´Ù¸é ÇØ´ç ¼¿·ºÅÍ¸¦ Ãß°¡ÇÑ´Ù.
 * @param {Object} [sClass2]	Å¬·¡½º ¼¿·ºÅÍ ÀÌ¸§.  µÎ °³ÀÇ Å¬·¡½º ¼¿·ºÅÍ¸¦ ÀÎ¼ö·Î »ç¿ëÇÏ¸é, µÎ ¼¿·ºÅÍ Áß »ç¿ëÇÏ°í ÀÖ´Â ¼¿·¢ÅÍ¸¦ Áö¿ì°í ³ª¸ÓÁö ¼¿·ºÅÍ¸¦ Ãß°¡ÇÑ´Ù.
 * @import core.$Element[hasClass,addClass,removeClass]
 * @description [Lite]
 * @example

<div id="naver" class="search highlight active">Naver</div>

<script>
var r = $Element("naver")
r.toggleClass("highlight");
// <div id="naver" class="search active">Naver</div>

r.toggleClass("highlight");
// <div id="naver" class="search highlight active">Naver</div>

r.toggleClass("active", "deactive");
// <div id="naver" class="search highlight deactive">Naver</div>

r.toggleClass("active", "deactive");
// <div id="naver" class="search highlight active">Naver</div>
</script>

 */
jindo.$Element.prototype.toggleClass = function(sClass, sClass2) {
	sClass2 = sClass2 || "";
	if (this.hasClass(sClass)) {
		this.removeClass(sClass);
		if (sClass2) this.addClass(sClass2);
	} else {
		this.addClass(sClass);
		if (sClass2) this.removeClass(sClass2);
	}

	return this;
};

/**
 * text ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ÅØ½ºÆ® ³ëµå°ªÀ» °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù. String Å¸ÀÔÀÇ ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¸é ÀÎ¼öÀÇ °ªÀ¸·Î ÅØ½ºÆ® ³ëµå¸¦ º¯°æÇÏ°í º¯°æÇÑ °á°ú¸¦ ¸®ÅÏÇÑ´Ù.
 * @param {String} sText ¼³Á¤ÇÒ ÅØ½ºÆ®
 * @returns {String} ¼³Á¤ÇÑ ÅØ½ºÆ® °ª
 * @description [Lite]
 */
jindo.$Element.prototype.text = function(sText) {
	var prop = (typeof this._element.innerText != "undefined")?"innerText":"textContent";

	if (this.tag == "textarea" || this.tag == "input") prop = "value";

	if (typeof sText == "string") {
		try { this._element[prop] = sText; } catch(e) {
			return this.html(sText.replace(/&/g, '&amp;').replace(/</g, '&lt;'));
		}
		return this;
	}

	return this._element[prop];
};

/**
 * html ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ³»ºÎ HTML(innerHTML)À» °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù. String Å¸ÀÔÀÇ ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¸é ÀÎ¼öÀÇ °ªÀ¸·Î ³»ºÎ HTMLÀ» º¯°æÇÏ°í º¯°æÇÑ °á°ú¸¦ ¸®ÅÏÇÑ´Ù.
 * @param {String} sHTML ¼³Á¤ÇÒ HTML ¹®ÀÚ¿­
 * @return {String} ³»ºÎ HTML
 * @description [Lite]
 */
jindo.$Element.prototype.html = function(sHTML) {
	if (typeof sHTML == "string") {

		var oEl = this._element;
		var isIe = (typeof window.opera=="undefined" && navigator.userAgent.indexOf("MSIE")>-1);
		var isFF = (navigator.userAgent.indexOf("Firefox")>-1);
		var bBugAgent = isIe || (isFF && !oEl.parentNode);
		
		if (bBugAgent) {

			/*
				IE ³ª FireFox ÀÇ ÀÏºÎ »óÈ²¿¡¼­ SELECT ÅÂ±×³ª TABLE, TR, THEAD, TBODY ÅÂ±×¿¡ innerHTML À» ¼ÂÆÃÇØµµ
				¹®Á¦°¡ »ý±âÁö ¾Êµµ·Ï º¸¿Ï - hooriza
			*/
			var sId = 'R' + new Date().getTime() + parseInt(Math.random() * 100000);
			var oDoc = oEl.ownerDocument || oEl.document || document;

			var oDummy;
			var sTag = oEl.tagName.toLowerCase();

			switch (sTag) {
			case 'select':
			case 'table':
				oDummy = jindo.$('<div>');
				oDummy.innerHTML = '<' + sTag + ' class="' + sId + '">' + sHTML + '</' + sTag + '>';
				break;

			case 'tr':
			case 'thead':
			case 'tbody':
				oDummy = jindo.$('<div>');
				oDummy.innerHTML = '<table><' + sTag + ' class="' + sId + '">' + sHTML + '</' + sTag + '></table>';
				break;

			default:
				oEl.innerHTML = sHTML;
				break;
			}

			if (oDummy) {

				var oFound;
				for (oFound = oDummy.firstChild; oFound; oFound = oFound.firstChild)
					if (oFound.className == sId) break;

				if (oFound) {
					var notYetSelected = true;
					for (var oChild; oChild = oEl.firstChild;) oChild.removeNode(true); // innerHTML = '';

					for (var oChild = oFound.firstChild; oChild; oChild = oFound.firstChild){
						if(sTag=='select'&&isIe){
							/*
							 * ie¿¡¼­ selectÅ×±×ÀÏ °æ¿ì optionÁß selected°¡ µÇ¾î ÀÖ´Â optionÀÌ ÀÖ´Â °æ¿ì Áß°£¿¡ 
							 * selected°¡ µÇ¾î ÀÖÀ¸¸é ±× ´ÙÀ½ ºÎÅÍ´Â °è¼Ó selected°¡ true·Î µÇ¾î ÀÖ¾î 
							 * ÇØ°áÇÏ±â À§ÇØ cloneNode¸¦ ÀÌ¿ëÇÏ¿© optionÀ» Ä«ÇÇÇÑ ÈÄ selected¸¦ º¯°æÇÔ. - mixed
							 */
							var cloneNode = oChild.cloneNode(true);
							if (oChild.selected && notYetSelected) {
								notYetSelected = false;
								cloneNode.selected = true;
							}
							oEl.appendChild(cloneNode);
							oChild.removeNode(true);
						}else{
							oEl.appendChild(oChild);
						}

					}
					
					oDummy.removeNode && oDummy.removeNode(true);

				}

				oDummy = null;

			}

		} else {

			oEl.innerHTML = sHTML;

		}
		
		return this;

	}

	return this._element.innerHTML;
};


/**
 * outerHTML ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ¿ÜºÎ HTML(outerHTML)À» ¹ÝÈ¯ÇÑ´Ù.
 * @return {String} ¿ÜºÎ HTML
 * @description [Lite]
 */
jindo.$Element.prototype.outerHTML = function() {
	var e = this._element;
	if (typeof e.outerHTML != "undefined") return e.outerHTML;

	var div = jindo.$("<div>");
	var par = e.parentNode;
	
	// »óÀ§³ëµå°¡ ¾øÀ¸¸é innerHTML¹ÝÈ¯
	if(!par) return e.innerHTML;

	par.insertBefore(div, e);
	div.style.display = "none";
	div.appendChild(e);

	var s = div.innerHTML;
	par.insertBefore(e, div);
	par.removeChild(div);

	return s;
};

/**
 * toString ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¸¦ HTML ¹®ÀÚ¿­·Î º¯È¯ÇÏ¿© ¸®ÅÏÇÑ´Ù. ¸®ÅÏ°ªÀº outerHTML°ú µ¿ÀÏÇÏ´Ù.
 * @return {String} ¿ÜºÎ HTML
 */
jindo.$Element.prototype.toString = jindo.$Element.prototype.outerHTML;

/**
 * @fileOverview $ElementÀÇ È®Àå ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name element.extend.js
 */

/**
 * appear ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¸¦ ¼­¼­È÷ ³ªÅ¸³ª°Ô ÇÑ´Ù. (Fade-in È¿°ú)
 * @param {Number} duration DOM ¿¤¸®¸ÕÆ®ÀÇ Åõ¸íµµ°¡ ÇöÀçÀÇ °ª¿¡¼­ ½ÃÀÛÇØ¼­ 1ÀÌ µÉ¶§ ±îÁö °É¸®´Â ½Ã°£. ´ÜÀ§´Â ÃÊ¸¦ »ç¿ëÇÑ´Ù.
 * @param {Function} callback DOM ¿¤¸®¸ÕÆ®°¡ ¿ÏÀüÈ÷ ³ªÅ¸³­ ÈÄ, Áï Åõ¸íµµ°¡ 1ÀÌ µÈ ÈÄ¿¡ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö.
 * @returns {Object} $Element °´Ã¼
 * @see $Element#show
 * @see $Element#disappear
 */
jindo.$Element.prototype.appear = function(duration, callback) {
	var self = this;
	var op   = this.opacity();
	
	if(!this.visible()) op = 0;

	if (op == 1) return this;
	try { clearTimeout(this._fade_timer); } catch(e){};

	callback = callback || new Function;

	var step = (1-op) / ((duration||0.3)*100);
	var func = function(){
		op += step;
		self.opacity(op);

		if (op >= 1) {
			callback(self);
		} else {
			self._fade_timer = setTimeout(func, 10);
		}
	};

	this.show();
	func();

	return this;
};

/**
 * disappear ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¸¦ ¼­¼­È÷ »ç¶óÁö°Ô ÇÑ´Ù. (Fade-out È¿°ú) DOM ¿¤¸®¸ÕÆ®°¡ ¿ÏÀüÈ÷ »ç¶óÁö¸é ¿¤¸®¸ÕÆ®ÀÇ CSS Áß display ¼Ó¼ºÀº noneÀ¸·Î º¯ÇÑ´Ù.
 * @param {Number} duration DOM ¿¤¸®¸ÕÆ®ÀÇ Åõ¸íµµ°¡ ÇöÀçÀÇ °ª¿¡¼­ 0ÀÌ µÉ ¶§±îÁö °É¸®´Â ½Ã°£. ´ÜÀ§´Â ÃÊ¸¦ »ç¿ëÇÑ´Ù.
 * @param {Function} callback DOM ¿¤¸®¸ÕÆ®°¡ ¿ÏÀüÈ÷ »ç¶óÁö°í ³­ ÈÄ, Áï Åõ¸íµµ°¡ 0ÀÌ µÈ ÈÄ¿¡ ½ÇÇàÇÒ ÄÝ¹é ÇÔ¼ö
 * @returns {Object} $Element °´Ã¼
 * @see $Element#hide
 * @see $Element#appear
 */
jindo.$Element.prototype.disappear = function(duration, callback) {
	var self = this;
	var op   = this.opacity();
	
	if (op == 0) return this;
	try { clearTimeout(this._fade_timer); } catch(e){};

	callback = callback || new Function;

	var step = op / ((duration||0.3)*100);
	var func = function(){
		op -= step;
		self.opacity(op);

		if (op <= 0) {
			self.hide();
			self.opacity(1);
			callback(self);
		} else {
			self._fade_timer = setTimeout(func, 10);
		}
	};

	func();

	return this;
};

/**
 * offset ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ À§Ä¡¸¦ °¡Á®¿À°Å³ª ¼³Á¤ÇÑ´Ù. ±âÁØÁ¡Àº ºê¶ó¿ìÀú ¹®¼­ÀÇ ¿ÞÂÊ »ó´ÜÀÌ´Ù. offset ¸Þ¼­µåÀÇ ÀÎ¼ö·Î top, left °ªÀ» ÁöÁ¤ÇÏ¸é DOM ¿¤¸®¸ÕÆ®ÀÇ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù.
 * @remark ÀÏºÎ ºê¶ó¿ìÀú¿Í ÀÏºÎ »óÈ²¿¡¼­ inline ¿¤¸®¸ÕÆ®¿¡ ´ëÇÑ À§Ä¡°¡ ¿Ã¹Ù¸£°Ô ¾ò¾îÁöÁö ¾Ê´Â ¹®Á¦°¡ ÀÖÀ¸¸ç ÀÌ °æ¿ì ÇØ´ç ¿¤¸®¸ÕÆ®¸¦ position:relative; ·Î ¹Ù²ãÁÖ´Â ½ÄÀ¸·Î ÇØ°áÇÒ ¼ö ÀÖ´Ù.
 * @author Hooriza
 * @param {Number} [nTop] ¹®¼­ÀÇ ¸Ç À§¿¡¼­ ºÎÅÍ ¿¤¸®¸ÕÆ® ¸Ç À§±îÁöÀÇ °Å¸®. ´ÜÀ§´Â px.
 * @param {Number} [nLeft] ¹®¼­ÀÇ ¿ÞÂÊ °¡ÀåÀÚ¸®¿¡¼­ ¿¤¸®¸ÕÆ®ÀÇ ¿ÞÂÊ °¡ÀåÀÚ¸®±îÁöÀÇ °Å¸®. ´ÜÀ§´Â px.
 * @return {$Element | Object} ¿¤¸®¸ÕÆ®ÀÇ À§Ä¡¸¦ ¼³Á¤ÇÏ¸é ±âÁ¸ ¿¤¸®¸ÕÆ®¸¦, ¿¤¸®¸ÕÆ®ÀÇ À§Ä¡¸¦ °¡Á®¿À¸é ¿¤¸®¸ÕÆ®ÀÇ x, y ÁÂÇ¥¸¦ ¼Ó¼ºÀ¸·Î °¡Áö´Â °´Ã¼.
 */
jindo.$Element.prototype.offset = function(nTop, nLeft) {

	var oEl = this._element;
	var oPhantom = null;

	// setter
	if (typeof nTop == 'number' && typeof nLeft == 'number') {

		if (isNaN(parseInt(this.css('top')))) this.css('top', 0);
		if (isNaN(parseInt(this.css('left')))) this.css('left', 0);

		var oPos = this.offset();
		var oGap = { top : nTop - oPos.top, left : nLeft - oPos.left };

		oEl.style.top = parseInt(this.css('top')) + oGap.top + 'px';
		oEl.style.left = parseInt(this.css('left')) + oGap.left + 'px';

		return this;

	}

	// getter
	var bSafari = /Safari/.test(navigator.userAgent);
	var bIE = /MSIE/.test(navigator.userAgent);
	var nVer = bIE?navigator.userAgent.match(/(?:MSIE) ([0-9.]+)/)[1]:0;
	
	var fpSafari = function(oEl) {

		var oPos = { left : 0, top : 0 };

		for (var oParent = oEl, oOffsetParent = oParent.offsetParent; oParent = oParent.parentNode; ) {

			if (oParent.offsetParent) {

				oPos.left -= oParent.scrollLeft;
				oPos.top -= oParent.scrollTop;

			}

			if (oParent == oOffsetParent) {

				oPos.left += oEl.offsetLeft + oParent.clientLeft;
				oPos.top += oEl.offsetTop + oParent.clientTop ;

				if (!oParent.offsetParent) {

					oPos.left += oParent.offsetLeft;
					oPos.top += oParent.offsetTop;

				}

				oOffsetParent = oParent.offsetParent;
				oEl = oParent;
			}
		}

		return oPos;

	};

	var fpOthers = function(oEl) {

		var oPos = { left : 0, top : 0 };

		var oDoc = oEl.ownerDocument || oEl.document || document;
		var oHtml = oDoc.documentElement;
		var oBody = oDoc.body;

		if (oEl.getBoundingClientRect) { // has getBoundingClientRect

			if (!oPhantom) {

				if (bIE && nVer<8 && window.external) {

					oPhantom = { left : 2, top : 2 };

					/*
					var oBase = oDoc.createElement('div');
					oBase.style.cssText = 'position:absolute !important; left:0 !important; top:0 !important; margin:0 !important; padding:0 !important;';
					oDoc.body.insertBefore(oBase, oDoc.body.firstChild);

					oPhantom = oBase.getBoundingClientRect();
					oPhantom.left += oHtml.scrollLeft || oBody.scrollLeft;
					oPhantom.top += oHtml.scrollTop || oBody.scrollTop;

					oDoc.body.removeChild(oBase);
					*/

					oBase = null;

				} else {

					oPhantom = { left : 0, top : 0 };

				}

			}

			var box = oEl.getBoundingClientRect();
			if (oEl !== oHtml && oEl !== oBody) {

				oPos.left = box.left - oPhantom.left;
				oPos.top = box.top - oPhantom.top;

				oPos.left += oHtml.scrollLeft || oBody.scrollLeft;
				oPos.top += oHtml.scrollTop || oBody.scrollTop;

			}

		} else if (oDoc.getBoxObjectFor) { // has getBoxObjectFor

			var box = oDoc.getBoxObjectFor(oEl);
			var vpBox = oDoc.getBoxObjectFor(oHtml || oBody);

			oPos.left = box.screenX - vpBox.screenX;
			oPos.top = box.screenY - vpBox.screenY;

		} else {

			for (var o = oEl; o; o = o.offsetParent) {

				oPos.left += o.offsetLeft;
				oPos.top += o.offsetTop;

			}

			for (var o = oEl.parentNode; o; o = o.parentNode) {

				if (o.tagName == 'BODY') break;
				if (o.tagName == 'TR') oPos.top += 2;

				oPos.left -= o.scrollLeft;
				oPos.top -= o.scrollTop;

			}

		}

		return oPos;

	};

	return (bSafari ? fpSafari : fpOthers)(oEl);
};

/**
 * evalScripts ¸Þ¼­µå´Â ÀÎÀÚ·Î µé¾î¿Â ¹®ÀÚ¿­ Áß¿¡¼­ &lt;script&gt; ÅÂ±× ¾È¿¡ ÀÖ´Â ³»¿ëÀ» ÆÄ½ÌÇØ¼­ eval ·Î ¼öÇàÇÑ´Ù.
 * @param {String} sHTML &lt;script&gt; ÅÂ±×°¡ Æ÷ÇÔµÈ HTML ¹®ÀÚ¿­
 * @return {$Element} ÇöÀçÀÇ DOM ¿¤¸®¸ÕÆ®
 */
jindo.$Element.prototype.evalScripts = function(sHTML) {
	
	var aJS = [];
    sHTML = sHTML.replace(new RegExp('<script(\\s[^>]+)*>(.*?)</'+'script>', 'gi'), function(_1, _2, sPart) { aJS.push(sPart); return ''; });
    eval(aJS.join('\n'));
    
    return this;

};

/**
 * append ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ DOM ¿¤¸®¸ÕÆ®¸¦ $Element °´Ã¼ÀÇ ¸¶Áö¸· ÀÚ½Ä ³ëµå·Î Ãß°¡ÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement	Ãß°¡ÇÒ DOM ¿¤¸®¸ÕÆ®
 * @returns {Object} »õ·Î¿î ÀÚ½Ä³ëµå¸¦ Ãß°¡ÇÑ $Element °´Ã¼
 */
jindo.$Element.prototype.append = function(oElement) {
	var o = jindo.$Element(oElement).$value();

	this._element.appendChild(o);

	return jindo.$Element(o);
};

/**
 * prepend ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ DOM ¿¤¸®¸ÕÆ®¸¦ $Element °´Ã¼ÀÇ Ã¹¹øÂ° ÀÚ½Ä ³ëµå·Î Ãß°¡ÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement	Ãß°¡ÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {$Element} »õ·Î¿î ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ $Element °´Ã¼
 */
jindo.$Element.prototype.prepend = function(oElement) {
	var e = this._element;
	var o = jindo.$Element(oElement).$value();

	if (e.childNodes.length > 0) {
		e.insertBefore(o, e.childNodes[0]);
	} else {
		e.appendChild(o);
	}

	return jindo.$Element(o);
};

/**
 * replace ¸Þ¼­µå´Â $Element °´Ã¼ÀÇ ³ëµå¸¦ ÀÎ¼ö·Î ÁöÁ¤ÇÑ DOM ¿¤¸®¸ÕÆ®·Î ´ëÃ¼ÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement	´ëÃ¼ÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {$Element} DOM ¿¤¸®¸ÕÆ®°¡ ´ëÃ¼µÈ $Element °´Ã¼
 */
jindo.$Element.prototype.replace = function(oElement) {
	var e = this._element;
	var o = jindo.$Element(oElement).$value();

	e.parentNode.insertBefore(o, e);
	e.parentNode.removeChild(e);

	return jindo.$Element(o);
};

/**
 * appendTo ¸Þ¼­µå´Â $Element °´Ã¼¸¦ ÀÎ¼ö·Î ÁöÁ¤ÇÑ DOM ¿¤¸®¸ÕÆ®ÀÇ ¸¶Áö¸· ÀÚ½Ä ³ëµå·Î Ãß°¡ÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement Ãß°¡ÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {$Element} ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ $Element °´Ã¼
 */
jindo.$Element.prototype.appendTo = function(oElement) {
	var o = jindo.$Element(oElement).$value();

	o.appendChild(this._element);

	return this;
};

/**
 * prependTo ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ $Element °´Ã¼ÀÇ Ã¹¹øÂ° ÀÚ½Ä ³ëµå·Î Ãß°¡ÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement Ãß°¡ÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {$Element} ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ $Element °´Ã¼
 */
jindo.$Element.prototype.prependTo = function(oElement) {
	var o = jindo.$Element(oElement).$value();

	if (o.childNodes.length > 0) {
		o.insertBefore(this._element, o.childNodes[0]);
	} else {
		o.appendChild(this._element);
	}

	return this;
};

/**
 * before ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ ¿¤¸®¸ÕÆ®¸¦ $Element °´Ã¼ ¹Ù·Î ¾Õ¿¡ »ðÀÔÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement »ðÀÔÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {Object} »ðÀÔÇÑ DOM ¿¤¸®¸ÕÆ®
 */
jindo.$Element.prototype.before = function(oElement) {
	var o = jindo.$Element(oElement).$value();

	this._element.parentNode.insertBefore(o, this._element);

	return jindo.$Element(o);
};

/**
 * after ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ ¿¤¸®¸ÕÆ®¸¦ $Element °´Ã¼ÀÇ ¹Ù·Î µÚ¿¡ ÁöÁ¤ÇÑ DOM ¿¤¸®¸ÕÆ®¸¦ »ðÀÔÇÑ´Ù.
 * @param {$Element | HTMLElement | String} oElement »ðÀÔÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº ¿¤¸®¸ÕÆ®ÀÇ id
 * @returns {Object} »ðÀÔÇÑ DOM ¿¤¸®¸ÕÆ®
 */
jindo.$Element.prototype.after = function(oElement) {
	var o = this.before(oElement);
	o.before(this);

	return o;
};

/**
 * parent ¸Þ¼­µå´Â Æ¯Á¤ ³ëµåÀÇ ºÎ¸ð ³ëµå (ÄÁÅ×ÀÌ³Ê ³ëµå)¸¦ °Ë»öÇÑ´Ù.
 * @param {String} [pFunc] »óÀ§ ³ëµåÀÇ °Ë»ö Á¶°ÇÀ» ÁöÁ¤ÇÑ ÄÝ¹é ÇÔ¼ö. ¿©·¯ »óÀ§ ³ëµå¸¦ Á¶°Ç ¾øÀÌ °Ë»öÇÏ·Á¸é pFunc¸¦ null·Î ¼³Á¤ÇÏ°í limit¿¡ »óÀ§ ³ëµåÀÇ °³¼ö¸¦ ¼³Á¤ÇÑ´Ù.
 * @param {Number} [limit] Å½»öÇÒ »óÀ§ ³ëµåÀÇ °³¼ö.
 * @returns {$Element | Array} ºÎ¸ð ³ëµå, È¤Àº »óÀ§ ³ëµåÀÇ ¹è¿­. ºÎ¸ð ³ëµå¸¸ ¸®ÅÏÇÒ °æ¿ì $Element Å¸ÀÔÀ», »óÀ§ ³ëµåÀÇ ¹è¿­À» ¸®ÅÏÇÒ °æ¿ì $ElementÀÇ ¹è¿­À» ¸®ÅÏÇÑ´Ù.
 */
jindo.$Element.prototype.parent = function(pFunc, limit) {
	var e = this._element;
	var a = [], p = null;

	if (typeof pFunc == "undefined") return jindo.$Element(e.parentNode);
	if (typeof limit == "undefined" || limit == 0) limit = -1;

	while (e.parentNode && limit-- != 0) {
		p = jindo.$Element(e.parentNode);
		if (e.parentNode == document.documentElement) break;
		if (!pFunc || (pFunc && pFunc(p))) a[a.length] = p;

		e = e.parentNode;
	}

	return a;
};

/**
 * child ¸Þ¼­µå´Â ÀÚ½Ä ³ëµå¸¦ °Ë»öÇÑ´Ù.
 * @param {Function} [pFunc]  ÀÚ½Ä ³ëµåÀÇ °Ë»ö Á¶°ÇÀ» ÁöÁ¤ÇÑ ÄÝ¹é ÇÔ¼ö. ¿©·¯ ÇÏÀ§ ³ëµå¸¦ Á¶°Ç ¾øÀÌ °Ë»öÇÏ·Á¸é pFunc¸¦ null·Î ¼³Á¤ÇÏ°í limit¿¡ ÇÏÀ§ ³ëµåÀÇ °³¼ö¸¦ ¼³Á¤ÇÑ´Ù.
 * @param {Number} [limit] Å½»öÇÒ ÇÏÀ§ ³ëµå °³¼ö
 * @returns {$Element | Array} ÀÚ½Ä ³ëµå, È¤Àº Á¶°Ç¿¡ ¸Â´Â ÀÚ½Ä ³ëµåÀÇ ¹è¿­. ÀÚ½Ä ³ëµå ÇÏ³ª¸¸ ¸®ÅÏÇÒ °æ¿ì $Element Å¸ÀÔÀ», ÀÚ½Ä ³ëµåÀÇ ¹è¿­À» ¸®ÅÏÇÒ °æ¿ì $ElementÀÇ ¹è¿­À» ¸®ÅÏÇÑ´Ù.
 */
jindo.$Element.prototype.child = function(pFunc, limit) {
	var e = this._element;
	var a = [], c = null, f = null;

	if (typeof pFunc == "undefined") return jindo.$A(e.childNodes).filter(function(v){ return v.nodeType == 1}).map(function(v){ return jindo.$Element(v) }).$value();
	if (typeof limit == "undefined" || limit == 0) limit = -1;

	(f = function(el, lim){
		var ch = null, o = null;

		for(var i=0; i < el.childNodes.length; i++) {
			ch = el.childNodes[i];
			if (ch.nodeType != 1) continue;

			o = jindo.$Element(el.childNodes[i]);
			if (!pFunc || (pFunc && pFunc(o))) a[a.length] = o;
			if (lim != 0) f(el.childNodes[i], lim-1);
		}
	})(e, limit-1);

	return a;
};

/**
 * prev ¸Þ¼­µå´Â Æ¯Á¤ ³ëµåÀÇ ÀÌÀü¿¡ ³ª¿À´Â ÇüÁ¦ ³ëµå¸¦ °Ë»öÇÑ´Ù.
 * @param {String} [pFunc] ÀÌÀü ÇüÁ¦ ³ëµåÀÇ °Ë»ö Á¶°ÇÀ» ÁöÁ¤ÇÑ ÄÝ¹é ÇÔ¼ö. pFunc¸¦ »ý·«ÇÏ¸é ¹Ù·Î ÀüÀÇ ÇüÁ¦ ³ëµå¸¦ ¸®ÅÏÇÑ´Ù.
 * @returns {$Element | Array} pFuncÀÇ Á¶°Ç¿¡ ¸Â´Â ÇüÁ¦ $ElementÀÇ ¹è¿­, È¤Àº ¹Ù·Î ÀüÀÇ ÇüÁ¦ ³ëµå¸¦ °¡¸®Å°´Â $Element.
 */
jindo.$Element.prototype.prev = function(pFunc) {
	var e = this._element;
	var a = [];
	var b = (typeof pFunc == "undefined");

	if (!e) return b?jindo.$Element(null):a;
	
	do {
		e = e.previousSibling;
		
		if (!e || e.nodeType != 1) continue;
		if (b) return jindo.$Element(e);
		if (!pFunc || pFunc(e)) a[a.length] = jindo.$Element(e);
	} while(e);

	return b?jindo.$Element(e):a;
};

/**
 * next ¸Þ¼­µå´Â Æ¯Á¤ ³ëµåÀÇ ´ÙÀ½¿¡ ³ª¿À´Â ÇüÁ¦ ³ëµå¸¦ °Ë»öÇÑ´Ù.
 * @param {String} pFunc ´ÙÀ½ ÇüÁ¦ ³ëµåÀÇ °Ë»ö Á¶°ÇÀ» ÁöÁ¤ÇÑ ÄÝ¹é ÇÔ¼ö. pFunc¸¦ »ý·«ÇÏ¸é ¹Ù·Î ´ÙÀ½ÀÇ ÇüÁ¦ ³ëµå¸¦ °¡¸®Å°´Â $Element¸¦ ¸®ÅÏÇÑ´Ù.
 * @returns {$Element | Array} pFuncÀÇ Á¶°Ç¿¡ ¸Â´Â ÇüÁ¦ $ElementÀÇ ¹è¿­, È¤Àº ¹Ù·Î ´ÙÀ½ÀÇ ÇüÁ¦ ³ëµå¸¦ °¡¸®Å°´Â $Element.
 */
jindo.$Element.prototype.next = function(pFunc) {
	var e = this._element;
	var a = [];
	var b = (typeof pFunc == "undefined");

	if (!e) return b?jindo.$Element(null):a;
	
	do {
		e = e.nextSibling;
		
		if (!e || e.nodeType != 1) continue;
		if (b) return jindo.$Element(e);
		if (!pFunc || pFunc(e)) a[a.length] = jindo.$Element(e);
	} while(e);

	return b?jindo.$Element(e):a;
};

/**
 * first ¸Þ¼Òµå´Â ÇöÀç ³ëµåÀÇ Ã³À½ ÀÚ½Ä ³ëµå¸¦ ¹ÝÈ¯ÇÑ´Ù. ¿¤¸®¸ÕÆ® ³ëµå¿¡ ´ëÇØ¼­¸¸ Àû¿ëµÈ´Ù.
 * @since 1.2.0
 * @returns {$Element} ¸¶Áö¸· ÀÚ½Ä ³ëµå
 */
jindo.$Element.prototype.first = function() {
	var el = this._element.firstElementChild||this._element.firstChild;
	if (!el) return null;
	while(el && el.nodeType != 1) el = el.nextSibling;

	return el?jindo.$Element(el):null;
}

/**
 * last ¸Þ¼Òµå´Â ÇöÀç ³ëµåÀÇ ¸¶Áö¸· ÀÚ½Ä ³ëµå¸¦ ¹ÝÈ¯ÇÑ´Ù. ¿¤¸®¸ÕÆ® ³ëµå¿¡ ´ëÇØ¼­¸¸ Àû¿ëµÈ´Ù.
 * @since 1.2.0
 * @returns {$Element} ¸¶Áö¸· ÀÚ½Ä ³ëµå
 */
jindo.$Element.prototype.last = function() {
	var el = this._element.lastElementChild||this._element.lastChild;
	if (!el) return null;
	while(el && el.nodeType != 1) el = el.previousSibling;

	return el?jindo.$Element(el):null;
}

/**
 * isChildOf ¸Þ¼­µå´Â ÇöÀç ³ëµå°¡ ÁöÁ¤ÇÑ ³ëµåÀÇ ÀÚ½Ä ³ëµåÀÎÁö È®ÀÎÇÑ´Ù.
 * @param {HTMLElement | String | $Element} element ºÎ¸ð ³ëµåÀÎÁö È®ÀÎÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº DOM ¿¤¸®¸ÕÆ®ÀÇ °íÀ¯ÇÑ id
 * @returns {Boolean} ÇöÀç ³ëµå°¡ ÀÎ¼ö·Î ÁöÁ¤ÇÑ ³ëµåÀÇ ÀÚ½Ä ³ëµåÀÌ¸é true, ±×·¸Áö ¾ÊÀ¸¸é false¸¦ ¸®ÅÏÇÑ´Ù.
 */
jindo.$Element.prototype.isChildOf = function(element) {
	var e  = this._element;
	var el = jindo.$Element(element).$value();

	while(e && e.parentNode) {
		e = e.parentNode;
		if (e == el) return true;
	}
	return false;
};

/**
 * isParentOf ¸Þ¼­µå´Â ÇöÀç ³ëµå°¡ ÁöÁ¤ÇÑ ³ëµåÀÇ ºÎ¸ðÀÎÁö È®ÀÎÇÑ´Ù.
 * @param {HTMLElement,$Element} element	ÀÚ½Ä ³ëµåÀÎÁö È®ÀÎÇÒ DOM ¿¤¸®¸ÕÆ®, È¤Àº DOM ¿¤¸®¸ÕÆ®ÀÇ °íÀ¯ÇÑ id.
 * @returns {Boolean} ÇöÀç ³ëµå°¡ ÀÎ¼ö·Î ÁöÁ¤ÇÑ ³ëµåÀÇ ºÎ¸ðÀÌ¸é true, ±×·¸Áö ¾ÊÀ¸¸é false
 */
jindo.$Element.prototype.isParentOf = function(element) {
	var el = jindo.$Element(element).$value();

	while(el && el.parentNode) {
		el = el.parentNode;
		if (this._element == el) return true;
	}
	return false;
};

/**
 * isEqual ¸Þ¼­µå´Â ÇöÀç °´Ã¼¿Í ÀÎÀÚ·Î ÁÖ¾îÁø °´Ã¼°¡ °°Àº ¿¤¸®¸ÕÆ®ÀÎÁö È®ÀÎÇÑ´Ù.
 * @param {HTMLElement, $Element} element ºñ±³ÇÒ ¿¤¸®¸ÕÆ® °´Ã¼
 * @returns {Boolean} °°Àº ³ëµåÀÌ¸é true, ±×·¸Áö ¾ÊÀ¸¸é false
 */
jindo.$Element.prototype.isEqual = function(element) {
	try {
		return (this._element === jindo.$Element(element).$value());
	} catch(e) {
		return false;
	}
};

/**
 * fireEvent ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®¿¡ ÀÌº¥Æ®¸¦ ¹ß»ý½ÃÅ²´Ù.
 * event°´Ã¼ÀÇ ¼Ó¼ºÀ» ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.  
 * (ÁÖÀÇ: WebKit°è¿­¿¡¼­´Â ÀÌº¥Æ®°´Ã¼ÀÇ keyCode °¡ read-onlyÀÎ °ü°è·Î keyÀÌº¥Æ®¸¦ fireÇÒ °æ¿ì keyCode°ªÀÌ ¼³Á¤µÇÁö ¾Ê´Â´Ù.) 
 * @param {String} sEvent ½ÇÇàÇÒ ÀÌº¥Æ® ÀÌ¸§. on Á¢µÎ»ç´Â »ý·«ÇÑ´Ù.
 * @param {Event} oEvent ÀÌº¥Æ® ½ÇÇà½Ã »ç¿ëÇÒ event°´Ã¼.
 * @return {$Element} ÀÌº¥Æ®¸¦ ¹ß»ý½ÃÅ² DOM ¿¤¸®¸ÕÆ®
 * @example
 	$Element("div").fireEvent("click",{left:true,middle:false,right:false});
 	 	
 	$Element("div").fireEvent("mouseover",{screenX:50,screenY:50,clientX:50,clientY:50});
 	
 	$Element("div").fireEvent("keydown",{keyCode:13,alt:true,shift:false,meta:false,ctrl:true});
 */
jindo.$Element.prototype.fireEvent = function(sEvent, oProps) {
	
	function IE(sEvent, oProps) {
		sEvent = (sEvent+"").toLowerCase();
		var oEvent = document.createEventObject();
		if(oProps){
			for (k in oProps) oEvent[k] = oProps[k];
			oEvent.button = (oProps.left?1:0)+(oProps.middle?4:0)+(oProps.right?2:0);
			oEvent.relatedTarget = oProps.relatedElement||null;
		}
		this._element.fireEvent("on"+sEvent, oEvent);
		return this;
	};

	function DOM2(sEvent, oProps) {
		var sType = "HTMLEvents";
		sEvent = (sEvent+"").toLowerCase();

		if (sEvent == "click" || sEvent.indexOf("mouse") == 0) {
			sType = "MouseEvent";
			if (sEvent == "mousewheel") sEvent = "dommousescroll";
		} else if (sEvent.indexOf("key") == 0) {
			sType = "KeyboardEvent";
		}

		var evt   = document.createEvent(sType);
						
		if (oProps) {
			switch (sType) {
				case 'MouseEvent':
					oProps.button = 0 + (oProps.middle?1:0) + (oProps.right?2:0);
					evt.initMouseEvent(sEvent, true, true, null, oProps.detail, oProps.screenX, oProps.screenY, oProps.clientX, oProps.clientY, oProps.ctrl, oProps.alt, oProps.shift, oProps.meta, oProps.button, oProps.relatedElement);
					break;
				case 'KeyboardEvent':
					if (evt.initKeyboardEvent) {
						evt.initKeyboardEvent(sEvent, true, true, null, null, null, oProps.ctrl, oProps.alt, oProps.shift, oProps.meta);
						evt.keyCode = oProps.keyCode;
						evt.charCode = oProps.keyCode;
					}else{
						evt.initKeyEvent(sEvent, true, true, null, oProps.ctrl, oProps.alt, oProps.shift, oProps.meta, oProps.keyCode, oProps.keyCode);						
					}					
					break;
				default:
					evt.initEvent(sEvent, true, true);				
			}
		}else{			
			evt.initEvent(sEvent, true, true);
		}

		this._element.dispatchEvent(evt);
		return this;
	};

	jindo.$Element.prototype.fireEvent = (typeof this._element.dispatchEvent != "undefined")?DOM2:IE;

	return this.fireEvent(sEvent, oProps);
};

/**
 * empty ¸Þ¼­µå´Â ÇöÀç ³ëµåÀÇ ÀÚ½Ä ³ëµå¸¦ ¸ðµÎ Á¦°ÅÇÑ´Ù.
 * @return {$Element} ÀÚ½Ä ³ëµå¸¦ ¸ðµÎ Á¦°ÅÇÑ ÇöÀç ³ëµå
 */
jindo.$Element.prototype.empty = function() {
	this.html("");
	return this;
};

/**
 * remove ¸Þ¼­µå´Â ÇöÅÂ ³ëµåÀÇ ÀÚ½Ä ³ëµå¸¦ Á¦°ÅÇÑ´Ù.
 * Á¦°ÅµÇ´Â ÀÚ½Ä ³ëµå¿¡ attachµÈ ÀÌº¥Æ® ÇÚµé·¯´Â ¸ðµÎ detach ½ÃÅ²´Ù.
 */
jindo.$Element.prototype.remove = function(oChild) {
	jindo.$Element(oChild).leave();
	return this;
}

/**
 * leave ¸Þ¼­µå´Â ÇöÀç ³ëµå¸¦ ºÎ¸ð ³ëµå¿¡¼­ Á¦°ÅÇÑ´Ù.
 * Á¦°ÅµÇ´Â ³ëµå¿¡ attachµÈ ÀÌº¥Æ® ÇÚµé·¯´Â ¸ðµÎ detach ½ÃÅ²´Ù.
 * @return {$Element} ºÎ¸ð ³ëµå¿¡¼­ Á¦°ÅÇÑ $Element °³Ã¼
 */
jindo.$Element.prototype.leave = function() {
	var e = this._element;

	if (e.parentNode) {
		e.parentNode.removeChild(e);
	}
	
	jindo.$Fn.freeElement(this._element);

	return this;
};

/**
 * wrap ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ ³ëµå·Î ÇöÀç ³ëµå¸¦ °¨½Ñ´Ù.
 * @param {String | HTMLElement} wrapper °¨½Ò ³ëµå È¤Àº ³ëµåÀÇ °íÀ¯ÇÑ id °ª
 * @return {$Element} »õ·Î¿î ³ëµå·Î °¨½ÎÁø $Element °³Ã¼
 */
jindo.$Element.prototype.wrap = function(wrapper) {
	var e = this._element;

	wrapper = jindo.$Element(wrapper).$value();
	if (e.parentNode) {
		e.parentNode.insertBefore(wrapper, e);
	}
	wrapper.appendChild(e);

	return this;
};

/**
 * ellipsis ¸Þ¼­µå´Â DOM ¿¤¸®¸ÕÆ®ÀÇ ÅØ½ºÆ® ³ëµå°¡ ºê¶ó¿ìÀú¿¡ ÇÑ ÁÙ·Î º¸ÀÌµµ·Ï ±æÀÌ¸¦ Á¶ÀýÇÑ´Ù. ±æÀÌ¸¦ Á¶ÀýÇÑ´Ù¸é stringTail¿¡¼­ ÁöÁ¤ÇÑ ¹®ÀÚ¿­À» ÅØ½ºÆ® ³ëµåÀÇ ¸Ç ³¡¿¡ ºÙÀÎ´Ù.
 * @remark ÀÌ ¸Þ¼­µå´Â ¿¤¸®¸ÕÆ®°¡ ÅØ½ºÆ® ³ëµå¸¸ Æ÷ÇÔÇÑ´Ù°í °¡Á¤ÇÑ´Ù. µû¶ó¼­, ÀÌ¿ÜÀÇ »óÈ²¿¡¼­ÀÇ µ¿ÀÛÀº º¸ÀåÇÏÁö ¾Ê´Â´Ù.
 * @remark ºê¶ó¿ìÀú¿¡¼­ÀÇ ¿¤¸®¸ÕÆ® ³Êºñ¸¦ ÃøÁ¤ÇÏ°í ±× ³Êºñ¸¦ ±âÁØÀ¸·Î ÅØ½ºÆ® ³ëµåÀÇ ±æÀÌ¸¦ Á¤ÇÏ¹Ç·Î ¿¤¸®¸ÕÆ®´Â ¹Ýµå½Ã º¸ÀÌ´Â »óÅÂÀÌ¾î¾ß ÇÑ´Ù.
 * @remark È­¸é¿¡ ÀüÃ¼ ÅØ½ºÆ® ³ëµå°¡ º¸¿´´Ù°¡ ÁÙ¾îµå´Â °æ¿ì°¡ ÀÖ´Ù. µû¶ó¼­, ¿¤¸®¸ÕÆ®¿¡¼­ overflow:hidden ¼Ó¼ºÀ» È°¿ëÇÏ¸é ÀÌ·± Çö»óÀ» ÁÙÀÏ ¼ö ÀÖ´Ù. ??
 * @param {String} stringTail ¸»ÁÙÀÓ Ç¥½ÃÀÚ. »ý¶ôÇÏ¸é ¸»ÁÙÀÓÇ¥('...')¸¦ »ç¿ëÇÑ´Ù.
 */
jindo.$Element.prototype.ellipsis = function(stringTail) {
	stringTail = stringTail || "...";

	var txt   = this.text();
	var len   = txt.length;
	var cur_h = this.height();
	var i     = 0;
	var h     = this.text('A').height();

	if (cur_h < h * 1.5) return this.text(txt);

	cur_h = h;
	while(cur_h < h * 1.5) {
		i += Math.max(Math.ceil((len - i)/2), 1);
		cur_h = this.text(txt.substring(0,i)+stringTail).height();
	}

	while(cur_h > h * 1.5) {
		i--;
		cur_h = this.text(txt.substring(0,i)+stringTail).height();
	}
};

/**
 * indexOf ¸Þ¼Òµå´Â ÁÖ¾îÁø ¿¤¸®¸ÕÆ®°¡ ÀÌ °´Ã¼ÀÇ ¸î ¹øÂ° ÀÚ½Ä³ëµåÀÎÁö ¹ÝÈ¯ÇÑ´Ù. ÀÎµ¦½º´Â 0ºÎÅÍ ½ÃÀÛÇÏ¹Ç·Î Ã¹¹øÂ° ÀÚ½Ä ³ëµå¸¦ ÀÎÀÚ·Î Àü´ÞÇÏ¸é 0À» ¹ÝÈ¯ÇÑ´Ù. ÁÖ¾îÁø ¿¤¸®¸ÕÆ®°¡ ÀÌ °´Ã¼ÀÇ ÀÚ½ÄÀÌ ¾Æ´Ï¶ó¸é, ´Ù½Ã ¸»ÇØ, ÁÖ¾îÁø ¿¤¸®¸ÕÆ®¸¦ ÀÚ½Ä ³ëµå¿¡¼­ Ã£Áö ¸øÇß´Ù¸é -1À» ¹ÝÈ¯ÇÑ´Ù.
 * @param {HTMLElement, $Element} element °Ë»öÇÒ ¿¤¸®¸ÕÆ®
 * @since 1.2.0
 * @return {Number} °Ë»ö °á°ú
 */
jindo.$Element.prototype.indexOf = function(element) {
	try {
		var e = jindo.$Element(element).$value();
		var n = this._element.childNodes;
		var c = 0;
		var l = n.length;

		for (var i=0; i < l; i++) {
			if (n[i].nodeType != 1) continue;

			if (n[i] === e) return c;
			c++;
		}
	}catch(e){}

	return -1;
};

/**
 * ¿ä¼ÒÀÇ ÇÏÀ§ ³ëµå¿¡¼­ ÁÖ¾îÁø selector¸¦ ¸¸Á·½ÃÅ°´Â ¿ä¼ÒÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù. ¸¸Á·ÇÏ´Â ¿ä¼Ò°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ºó ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sSelector
 * @return {Array} Á¶°ÇÀ» ¸¸Á·ÇÏ´Â ¿ä¼ÒÀÇ ¹è¿­
 */
jindo.$Element.prototype.queryAll = function(sSelector) { 
	return jindo.$$(sSelector, this._element); 
};

/**
 * ¿ä¼ÒÀÇ ÇÏÀ§ ³ëµå¿¡¼­ ÁÖ¾îÁø selector¸¦ ¸¸Á·½ÃÅ°´Â ¿ä¼ÒÁß Ã¹ ¹øÂ° ¿ä¼Ò¸¦ ¹ÝÈ¯ÇÑ´Ù. ¸¸Á·ÇÏ´Â ¿ä¼Ò°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é nullÀ» ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sSelector
 * @return {Element} Á¶°ÇÀ» ¸¸Á·ÇÏ´Â ¿ä¼ÒÁß Ã¹¹øÂ° ¿ä¼Ò
 */
jindo.$Element.prototype.query = function(sSelector) { 
	return jindo.$$.getSingle(sSelector, this._element); 
};

/**
 * ¿ä¼Ò°¡ ÁÖ¾îÁø selector¸¦ ¸¸Á·½ÃÅ°´Â ¿ä¼ÒÀÎÁö ¿©ºÎ¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sSelector
 * @return {Boolean} Á¶°ÇÀ» ¸¸Á·ÇÏÁö ¿©ºÎ
 */
jindo.$Element.prototype.test = function(sSelector) { 
	return jindo.$$.test(this._element, sSelector); 
};

/**
 * ¿ä¼Ò¸¦ ±âÁØÀ¸·Î  XPath ¹®¹ýÀ» »ç¿ëÇÏ¿© ¿¤¸®¸ÕÆ®¸¦ ¾ò¾î¿Â´Ù.
 * @remark Áö¿øÇÏ´Â ¹®¹ýÀÌ ¹«Ã´ Á¦ÇÑÀûÀ¸·Î Æ¯¼öÇÑ °æ¿ì¿¡¼­¸¸ »ç¿ëÇÏ´Â °ÍÀ» ±ÇÀåÇÑ´Ù.
 * @param {String} sXPath
 * @return {Array} path¿¡ ÇØ´çÇÏ´Â ¿ä¼Ò
 */
jindo.$Element.prototype.xpathAll = function(sXPath) { 
	return jindo.$$.xpath(sSelector, this._element); 
};
/**
 * @fileOverview $FnÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name function.js
 */

/**
 * ÇÔ¼ö °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @name $Fn
 * @extends core
 * @class $Fn Å¬·¡½º´Â Javascript ÇÔ¼öÀÇ ·¹ÆÛ Å¬·¡½ºÀÌ´Ù.  ??
 * @constructor
 * @param {Function | String} func ÇÔ¼ö °´Ã¼ È¤Àº ÇÔ¼öÀÇ ÀÎÀÚ¸¦ ÁöÁ¤ÇÑ ¹®ÀÚ¿­
 * @param {Object | String} thisObject ÇÔ¼ö °´Ã¼°¡ ´Ù¸¥ °´Ã¼ÀÇ ¸Þ¼­µåÀÏ ¶§, ÇØ´ç °´Ã¼µµ °°ÀÌ Àü´ÞÇÑ´Ù. È¤Àº ÇÔ¼ö ¸öÃ¼¸¦ ÁöÁ¤ÇÏ´Â ¹®ÀÚ¿­.
 * @return {$Fn} $Fn °´Ã¼
 * @see $Fn#toFunction
 * @description [Lite]
 * @example
var someObject = {
    func : function() {
       // code here
   }
}

var fn = $Fn(someObject.func, someObject);
 * @author Kim, Taegon
 */
jindo.$Fn = function(func, thisObject) {
	var cl = arguments.callee;
	if (func instanceof cl) return func;
	if (!(this instanceof cl)) return new cl(func, thisObject);

	this._events = [];
	this._tmpElm = null;
	this._key    = null;

	if (typeof func == "function") {
		this._func = func;
		this._this = thisObject;
	} else if (typeof func == "string" && typeof thisObject == "string") {
		this._func = new Function(func, thisObject);
	}
}

/**
 * $value ¸Þ¼­µå´Â ¿ø·¡ÀÇ Function °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {Function} ÇÔ¼ö °´Ã¼
 * @description [Lite]
 */
jindo.$Fn.prototype.$value = function() {
	return this._func;
};

/**
 * bind ¸Þ¼­µå´Â °´Ã¼¿Í ¸Þ¼­µå¸¦ ¹­¾î ÇÏ³ªÀÇ FunctionÀ¸·Î ¹ÝÈ¯ÇÑ´Ù.
 * @return {Function} ¸Þ¼Òµå·Î ¹­ÀÎ Funciton °´Ã¼
 * @see $Fn#bindForEvent
 * @description [Lite]
 */
jindo.$Fn.prototype.bind = function() {
	var a = jindo.$A(arguments).$value();
	var f = this._func;
	var t = this._this;

	var b = function() {
		var args = jindo.$A(arguments).$value();

		// fix opera concat bug
		if (a.length) args = a.concat(args);

		return f.apply(t, args);
	};

	return b;
};

/**
 * bingForEvent´Â °´Ã¼¿Í ¸Þ¼­µå¸¦ ¹­¾î ÇÏ³ªÀÇ ÀÌº¥Æ® ÇÚµé·¯ FunctionÀ¸·Î ¹ÝÈ¯ÇÑ´Ù.
 * @param {Element, ...} [elementN] ÀÌº¥Æ® °´Ã¼¿Í ÇÔ²² Àü´ÞÇÒ °ª
 * @see $Fn#bind
 * @see $Event
 * @description [Lite]
 */
jindo.$Fn.prototype.bindForEvent = function() {
	var a = arguments;
	var f = this._func;
	var t = this._this;
	var m = this._tmpElm || null;

	var b = function(e) {
		var args = jindo.$A(a);
		if (typeof e == "undefined") e = window.event;

		if (typeof e.currentTarget == "undefined") {
			e.currentTarget = m;
		}

		args.unshift(jindo.$Event(e));

		var returnValue = f.apply(t, args.$value());
		if(typeof returnValue != "undefined"){
			e.returnValue =  returnValue;
		}
		return returnValue;
	};

	return b;
};

/**
 * attach ¸Þ¼­µå´Â ÇÔ¼ö¸¦ Æ¯Á¤ ¿¤¸®¸ÕÆ®ÀÇ ÀÌº¥Æ® Çîµé·¯·Î µî·ÏÇÑ´Ù.
 * @remark ÀÌº¥Æ® ÀÌ¸§Àº on Á¢µÎ¾î¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
 * @remark ¸¶¿ì½º ÈÙ ½ºÅ©·Ñ ÀÌº¥Æ®´Â mousewheel ·Î »ç¿ëÇÑ´Ù.
 * @param {Element} oElement ÀÌº¥Æ®¸¦ Ãß°¡ÇÒ ¿¤¸®¸ÕÆ®
 * @param {String} sEvent Ãß°¡ÇÒ ÀÌº¥Æ®ÀÇ Á¾·ù
 * @see $Fn#detach
 * @description [Lite]
 */
jindo.$Fn.prototype.attach = function(oElement, sEvent) {
	var fn = null, l, ev = sEvent, el = oElement, ua = navigator.userAgent;

	if ((el instanceof Array) || (jindo.$A && (el instanceof jindo.$A) && (el=el.$value()))) {
		for(var i=0; i < el.length; i++) this.attach(el[i], ev);
		return this;
	}

	if (!el || !ev) return this;
	if (typeof el.$value == "function") el = el.$value();

	el = jindo.$(el);
	ev = ev.toLowerCase();
	
	this._tmpElm = el;
	fn = this.bindForEvent();
	this._tmpElm = null;

	if (typeof el.addEventListener != "undefined") {
		if (ev == "domready") ev = "DOMContentLoaded";
		else if (ev == "mousewheel" && ua.indexOf("WebKit") < 0 && !/Opera/.test(ua)) ev = "DOMMouseScroll";
		else if (ev == "mouseenter"){
			ev = "mouseover";
			fn = jindo.$Fn._fireWhenElementBoundary(el, fn);
		} 
		else if (ev == "mouseleave"){
			ev = "mouseout";
			fn = jindo.$Fn._fireWhenElementBoundary(el, fn);
		} 
		el.addEventListener(ev, fn, false);
	} else if (typeof el.attachEvent != "undefined") {
		if (ev == "domready") {
			jindo.$Fn._domready(el, fn);
			return this;
		} else {
			el.attachEvent("on"+ev, fn);
		}
	}
	
	if (!this._key) {
		this._key = "$"+jindo.$Fn.gc.count++;
		jindo.$Fn.gc.pool[this._key] = this;
	}

	this._events[this._events.length] = {element:el, event:sEvent.toLowerCase(), func:fn};

	return this;
};

/**
 * detach ¸Þ¼­µå´Â ÇÔ¼ö¸¦ Æ¯Á¤ ¿¤¸®¸ÕÆ®ÀÇ ÀÌº¥Æ®¿¡¼­ Á¦°ÅÇÑ´Ù.
 * @remark ÀÌº¥Æ® ÀÌ¸§Àº on Á¢µÎ¾î¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
 * @remark ¸¶¿ì½º ÈÙ ½ºÅ©·Ñ ÀÌº¥Æ®´Â mousewheel ·Î »ç¿ëÇÑ´Ù.
 * @param {Element} oElement ÀÌº¥Æ®¸¦ Á¦°ÅÇÒ ¿¤¸®¸ÕÆ®
 * @param {String} sEvent Á¦°ÅÇÒ ÀÌº¥Æ®ÀÇ ÀÌ¸§
 * @see $Fn#attach
 * @description [Lite]
 */
jindo.$Fn.prototype.detach = function(oElement, sEvent) {
	var fn = null, l, el = oElement, ev = sEvent, ua = navigator.userAgent;
	
	if ((el instanceof Array) || (jindo.$A && (el instanceof jindo.$A) && (el=el.$value()))) {
		for(var i=0; i < el.length; i++) this.detach(el[i], ev);
		return this;
	}

	if (!el || !ev) return this;
	if (jindo.$Element && el instanceof jindo.$Element) el = el.$value();

	el = jindo.$(el);
	ev = ev.toLowerCase();

	var e = this._events;
	for(var i=0; i < e.length; i++) {
		if (e[i].element !== el || e[i].event !== ev) continue;
		
		fn = e[i].func;
		this._events = jindo.$A(this._events).refuse(e[i]).$value();
		break;
	}

	if (typeof el.removeEventListener != "undefined") {
		if (ev == "domready") ev = "DOMContentLoaded";
		else if (ev == "mousewheel" && ua.indexOf("WebKit") < 0) ev = "DOMMouseScroll";
		else if (ev == "mouseenter") ev = "mouseover";
		else if (ev == "mouseleave") ev = "mouseout";
		el.removeEventListener(ev, fn, false);
	} else if (typeof el.detachEvent != "undefined") {
		if (ev == "domready") {
			jindo.$Fn._domready.list = jindo.$Fn._domready.list.refuse(fn);
			return this;
		} else {
			el.detachEvent("on"+ev, fn);
		}
	}

	return this;
};

/**
 * delay ¸Þ¼­µå´Â ÁöÁ¤ÇÑ ½Ã°£ ÀÌÈÄ¿¡ ÁöÁ¤ÇÑ ÀÎ¼ö·Î ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
 * @param {Number} nSec ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§±îÁö ±â´Ù¸± ½Ã°£.
 * @param {Array} args ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ »ç¿ëÇÒ ÀÎ¼ö. ¿©·¯ °³ÀÇ ÀÎ¼ö¸¦ Àü´ÞÇØ±â À§ÇØ ¹è¿­À» »ç¿ëÇÑ´Ù.
 * @see $Fn#bind
 * @see $Fn#repeat
 * @description [Lite]
 * @example
function popup_sum(a, b) {
    alert(a + b);
}

$Fn(popup_sum).delay(5, [3, 5]);
 */
jindo.$Fn.prototype.delay = function(nSec, args) {
	if (typeof args == "undefined") args = [];
	setTimeout(this.bind.apply(this, args), nSec*1000);

	return this;
};

/**
 * repeat ¸Þ¼­µå´Â ÁöÁ¤ÇÑ ½Ã°£ °£°Ý¸¶´Ù ÁöÁ¤ÇÑ ÀÎ¼ö·Î ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
 * @param {Number} nSec ÇÔ¼ö¸¦ È£Ãâ°£ °£°Ý.
 * @param {Array} args ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ »ç¿ëÇÒ ÀÎ¼ö. ¿©·¯ °³ÀÇ ÀÎ¼ö¸¦ Àü´ÞÇØ±â À§ÇØ ¹è¿­À» »ç¿ëÇÑ´Ù.
 * @return {Object} setInterval·Î »ý¼ºµÈ °´Ã¼
 * @see $Fn#bind
 * @see $Fn#delay 
 * @description [Lite]
 * @example
function popup_sum(a, b) {
    alert(a + b);
}

$Fn(popup_sum).repeat(5, [3, 5]);
 */
jindo.$Fn.prototype.setInterval = function(nSec, args) {
	if (typeof args == "undefined") args = [];
	return setInterval(this.bind.apply(this, args), nSec*1000);
};

/**
 * ¸Þ¸ð¸®¿¡¼­ ÀÌ °´Ã¼¸¦ »ç¿ëÇÑ ÂüÁ¶¸¦ ¸ðµÎ ÇØÁ¦ÇÑ´Ù(Á÷Á¢ È£Ãâ ±ÝÁö).
 * @param {Element} ÇØ´ç ¿ä¼ÒÀÇ ÀÌº¥Æ® ÇÚµé·¯¸¸ ÇØÁ¦.
 * @ignore
 */
jindo.$Fn.prototype.free = function(oElement) {
	var len = this._events.length;
	while(len > 0) {
		var el = this._events[--len].element;
		if (oElement && el!=oElement)
			continue;
			
		this.detach(el, this._events[len].event);
		delete this._events[len];
	}
	
	if(this._events.length==0)	
		try { delete jindo.$Fn.gc.pool[this._key]; }catch(e){};
};

/**
 * IE¿¡¼­ domready(=DOMContentLoaded) ÀÌº¥Æ®¸¦ ¿¡¹Ä·¹ÀÌ¼ÇÇÑ´Ù.
 * @ignore
 */
jindo.$Fn._domready = function(doc, func) {
	if (typeof jindo.$Fn._domready.list == "undefined") {
		var f = null, l  = jindo.$Fn._domready.list = jindo.$A([func]);
		
		// use the trick by Diego Perini
		// http://javascript.nwbox.com/IEContentLoaded/
		var done = false, execFuncs = function(){
			if(!done) {
				done = true;
				var evt = {
					type : "domready",
					target : doc,
					currentTarget : doc
				};

				while(f = l.shift()) f(evt);
			}
		};

		(function (){
			try {
				doc.documentElement.doScroll("left");
			} catch(e) {
				setTimeout(arguments.callee, 50);
				return;
			}
		})();

		// trying to always fire before onload
		doc.onreadystatechange = function() {
			if (doc.readyState == 'complete') {
				doc.onreadystatechange = null;
				execFuncs();
			}
		};

	} else {
		jindo.$Fn._domready.list.push(func);
	}
};

/**
 * ºñ IE¿¡¼­ mouseenter/mouseleave ÀÌº¥Æ®¸¦ ¿¡¹Ä·¹ÀÌ¼ÇÇÏ±â À§ÇÑ ¿ä¼Ò ¿µ¿ªÀ» ¹þ¾î³ª´Â °æ¿ì¿¡¸¸ ½ÇÇàÇÏ´Â ÇÔ¼ö ÇÊÅÍ
 * @ignore
 */
jindo.$Fn._fireWhenElementBoundary = function(doc, func) {
	return function(evt){
		var oEvent = jindo.$Event(evt);
		var relatedElement = jindo.$Element(oEvent.relatedElement);
		if(relatedElement && (relatedElement.isEqual(this) || relatedElement.isChildOf(this))) return;
		
		func.call(this,evt);
	}
};

/**
 * gc ¸Þ¼­µå´Â Window¿¡¼­ ¹þ¾î³¯ ¶§, DOM Element¿¡ ÇÒ´çµÈ ÀÌº¥Æ® ÇÚµé·¯¸¦ Á¦°ÅÇÑ´Ù. ??
 * @see $Fn#free
 */
jindo.$Fn.gc = function() {
	var p = jindo.$Fn.gc.pool;

	for(var key in p) {
		try { p[key].free(); }catch(e){ };
	}

	// delete all missing references
	jindo.$Fn.gc.pool = p = {};
};

/**
 * Æ¯Á¤ ¿ä¼Ò¿¡ ÇÒ´çµÈ ÀÌº¥Æ®¸¦ ¸ðµÎ Á¦°ÅÇÑ´Ù.
 * @since 1.3.5
 * @see $Fn#gc 
 */
jindo.$Fn.freeElement = function(oElement){
	var p = jindo.$Fn.gc.pool;

	for(var key in p) {
		try { p[key].free(oElement); }catch(e){ };
	}	
}

jindo.$Fn.gc.count = 0;

jindo.$Fn.gc.pool = {};
if (typeof window != "undefined") {
	jindo.$Fn(jindo.$Fn.gc).attach(window, "unload");
}
/**
 * @fileOverview $EventÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name event.js
 */

/**
 * $Event Å¬·¡½º´Â Event °´Ã¼ÀÇ ·¹ÆÛ(Wrapper) Å¬·¡½ºÀÌ´Ù.
 * »ç¿ëÀÚ´Â $Event.element ¸Þ¼­µå¸¦ »ç¿ëÇÏ¿© ÀÌº¥Æ®°¡ ½ÇÇàµÈ °´Ã¼¸¦ ¾Ë ¼ö ÀÖ´Ù.
 * @class JavaScript Core ÀÌº¥Æ® °´Ã¼·ÎºÎÅÍ $Event °´Ã¼¸¦ »ý¼ºÇÑ´Ù.
 * @param {Event} e	DOM Event °´Ã¼
 * @constructor
 * @description [Lite]
 * @author Kim, Taegon
 */
jindo.$Event = function(e) {
	var cl = arguments.callee;
	if (e instanceof cl) return e;
	if (!(this instanceof cl)) return new cl(e);

	if (typeof e == "undefined") e = window.event;
	if (e === window.event && document.createEventObject) e = document.createEventObject(e);

	this._event = e;
	this._globalEvent = window.event;

	/** ÀÌº¥Æ®ÀÇ Á¾·ù */
	this.type = e.type.toLowerCase();
	if (this.type == "dommousescroll") {
		this.type = "mousewheel";
	} else if (this.type == "DOMContentLoaded") {
		this.type = "domready";
	}

	this.canceled = false;

	/** ÀÌº¥Æ®°¡ ¹ß»ýÇÑ ¿¤¸®¸ÕÆ® */
	this.element = e.target || e.srcElement;
	/** ÀÌº¥Æ®°¡ Á¤ÀÇµÈ ¿¤¸®¸ÕÆ® */
	this.currentElement = e.currentTarget;
	/** ÀÌº¥Æ®ÀÇ ¿¬°ü ¿¤¸®¸ÕÆ® */
	this.relatedElement = null;

	if (typeof e.relatedTarget != "undefined") {
		this.relatedElement = e.relatedTarget;
	} else if(e.fromElement && e.toElement) {
		this.relatedElement = e[(this.type=="mouseout")?"toElement":"fromElement"];
	}
}

/**
 * ¸¶¿ì½º ÀÌº¥Æ®ÀÇ ¹öÆ°, ÈÙ Á¤º¸¸¦ ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
function eventHandler(evt) {
   var mouse = evt.mouse();

   mouse.delta;   // Number. ÈÙÀÌ ¿òÁ÷ÀÎ Á¤µµ. ÈÙÀ» À§·Î ±¼¸®¸é ¾ç¼ö, ¾Æ·¡·Î ±¼¸®¸é À½¼ö.
   mouse.left;    // Boolean. ¸¶¿ì½º ¿ÞÂÊ ¹öÆ°À» ´­·ÈÀ¸¸é true, ¾Æ´Ï¸é false
   mouse.middle;  // Boolean. ¸¶¿ì½º Áß°£ ¹öÆ°À» ´­·ÈÀ¸¸é true, ¾Æ´Ï¸é false
   mouse.right;   // Boolean. ¸¶¿ì½º ¿À¸¥ÂÊ ¹öÆ°À» ´­·ÈÀ¸¸é true, ¾Æ´Ï¸é false
}
 * @return {Object} ¸¶¿ì½º Á¤º¸¸¦ °¡Áö´Â °´Ã¼. ¸®ÅÏÇÑ °´Ã¼ÀÇ ¼Ó¼ºÀº ¿¹Á¦¸¦ ÂüÁ¶ÇÑ´Ù.
 */
jindo.$Event.prototype.mouse = function() {
	var e    = this._event;
	var delta = 0;
	var left  = (e.which&&e.button==0)||!!(e.button&1);
	var mid   = (e.which&&e.button==1)||!!(e.button&4);
	var right = (e.which&&e.button==2)||!!(e.button&2);
	var ret   = {};

	if (e.wheelDelta) {
		delta = e.wheelDelta / 120;
	} else if (e.detail) {
		delta = -e.detail / 3;
	}

	ret = {
		delta  : delta,
		left   : left,
		middle : mid,
		right  : right
	};

	// replace method
	this.mouse = function(){ return ret };

	return ret;
};

/**
 * Å°º¸µå ÀÌº¥Æ® Á¤º¸¸¦ ¸®ÅÏÇÑ´Ù.
 * @description [Lite]
 * @example
function eventHandler(evt) {
   var key = evt.key();

   key.keyCode; // Number. ´­¸° Å°º¸µåÀÇ Å°ÄÚµå
   key.alt;     // Boolean. Alt Å°¸¦ ´­·ÈÀ¸¸é true.
   key.ctrl;    // Boolean. Ctrl Å°¸¦ ´­·ÈÀ¸¸é true.
   key.meta;    // Boolean. Meta Å°¸¦ ´­·ÈÀ¸¸é true. MetaÅ°´Â ¸ÆÀÇ Ä¿¸ÇµåÅ°¸¦ °ËÃâÇÒ ¶§ »ç¿ëÇÕ´Ï´Ù.
   key.shift;   // Boolean. Shift Å°¸¦ ´­·ÈÀ¸¸é true.
   key.up;      // Boolean. À§ÂÊ È­»ìÇ¥ Å°¸¦ ´­·ÈÀ¸¸é true.
   key.down;    // Boolean. ¾Æ·¡ÂÊ È­»ìÇ¥ Å°¸¦ ´­·ÈÀ¸¸é true.
   key.left;    // Boolean. ¿ÞÂÊ È­»ìÇ¥ Å°¸¦ ´­·ÈÀ¸¸é true.
   key.right;   // Boolean. ¿À¸¥ÂÊ È­»ìÇ¥ Å°¸¦ ´­·ÈÀ¸¸é true.
   key.enter;   // Boolean. ¸®ÅÏÅ°¸¦ ´­·¶À¸¸é true
   key.esc;   // Boolean. ESCÅ°¸¦ ´­·¶À¸¸é true
   }
}
 * @return {Object} Å°º¸µå ÀÌº¥Æ®ÀÇ ´­¸° Å°°ª. °´Ã¼ÀÇ ¼Ó¼ºÀº ¿¹Á¦¸¦ ÂüÁ¶ÇÑ´Ù.
 */
jindo.$Event.prototype.key = function() {
	var e     = this._event;
	var k     = e.keyCode || e.charCode;
	var ret   = {
		keyCode : k,
		alt     : e.altKey,
		ctrl    : e.ctrlKey,
		meta    : e.metaKey,
		shift   : e.shiftKey,
		up      : (k == 38),
		down    : (k == 40),
		left    : (k == 37),
		right   : (k == 39),
		enter   : (k == 13),		
		esc   : (k == 27)
	};

	this.key = function(){ return ret };

	return ret;
};

/**
 * ¸¶¿ì½º Ä¿¼­ÀÇ À§Ä¡ Á¤º¸¸¦ ¸®ÅÏÇÑ´Ù.
 * @param {Boolean} bGetOffset ÇöÀç ¿¤¸®¸ÕÆ®¿¡ ´ëÇÑ ¸¶¿ì½º Ä¿¼­ÀÇ »ó´ëÀ§Ä¡ÀÎ offsetX, offsetY¸¦ ±¸ÇÒ °ÍÀÎÁöÀÇ ¿©ºÎ. true¸é °ªÀ» ±¸ÇÑ´Ù(offsetX, offsetY´Â 1.2.0¹öÀüºÎÅÍ Ãß°¡). $Element °¡ Æ÷ÇÔµÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
 * @description [Lite]
 * @example
function eventHandler(evt) {
   var pos = evt.pos();

   pos.clientX;  // Number. ÇöÀç È­¸é¿¡ ´ëÇÑ X ÁÂÇ¥
   pos.clientY;  // Number. ÇöÀç È­¸é¿¡ ´ëÇÑ Y ÁÂÇ¥
   pos.pageX;    // Number. ¹®¼­ ÀüÃ¼¿¡ ´ëÇÑ X ÁÂÇ¥
   pos.pageY;    // Number. ¹®¼­ ÀüÃ¼¿¡ ´ëÇÑ Y ÁÂÇ¥
   pos.layerX;   // Number. <b>deprecated.</b> ÀÌº¥Æ®°¡ ¹ß»ýÇÑ °´Ã¼·ÎºÎÅÍÀÇ »ó´ëÀûÀÎ X ÁÂÇ¥
   pos.layerY;   // Number. <b>deprecated.</b> ÀÌº¥Æ®°¡ ¹ß»ýÇÑ °´Ã¼·ÎºÎÅÍÀÇ »ó´ëÀûÀÎ Y ÁÂÇ¥
   pos.offsetX;  // Number. ÇöÀç ¿¤¸®¸ÕÆ®¿¡ ´ëÇÑ ¸¶¿ì½º Ä¿¼­ÀÇ »ó´ëÀûÀÎ XÁÂÇ¥ (1.2.0 ÀÌ»ó)
   pos.offsetY;  // Number. ÇöÀç ¿¤¸®¸ÕÆ®¿¡ ´ëÇÑ ¸¶¿ì½º Ä¿¼­ÀÇ »ó´ëÀûÀÎ YÁÂÇ¥ (1.2.0 ÀÌ»ó)

}
 * @return {Object} ¸¶¿ì½º Ä¿¼­ÀÇ À§Ä¡ Á¤º¸. °´Ã¼ÀÇ ¼Ó¼ºÀº ¿¹Á¦¸¦ ÂüÁ¶ÇÑ´Ù.
 * @remark layerX, layerY´Â Â÷ÈÄ Áö¿øÇÏÁö ¾ÊÀ»(deprecated) ¿¹Á¤ÀÔ´Ï´Ù.
 */
jindo.$Event.prototype.pos = function(bGetOffset) {
	var e   = this._event;
	var b   = (this.element.ownerDocument||document).body;
	var de  = (this.element.ownerDocument||document).documentElement;
	var pos = [b.scrollLeft || de.scrollLeft, b.scrollTop || de.scrollTop];
	var ret = {
		clientX : e.clientX,
		clientY : e.clientY,
		pageX   : 'pageX' in e ? e.pageX : e.clientX+pos[0]-b.clientLeft,
		pageY   : 'pageY' in e ? e.pageY : e.clientY+pos[1]-b.clientTop,
		layerX  : 'offsetX' in e ? e.offsetX : e.layerX - 1,
		layerY  : 'offsetY' in e ? e.offsetY : e.layerY - 1
	};

	// ¿ÀÇÁ¼ÂÀ» ±¸ÇÏ´Â ¸Þ¼ÒµåÀÇ ºñ¿ëÀÌ Å©¹Ç·Î, ¿äÃ»½Ã¿¡¸¸ ±¸ÇÏµµ·Ï ÇÑ´Ù.
	if (bGetOffset && jindo.$Element) {
		var offset = jindo.$Element(this.element).offset();
		ret.offsetX = ret.pageX - offset.left;
		ret.offsetY = ret.pageY - offset.top;
	}

	return ret;
};

/**
 * ÀÌº¥Æ®¸¦ Á¾·áÇÑ´Ù.
 * @remark ¹öºí¸µÀº Æ¯Á¤ DOM ¿¤¸®¸ÕÆ®¿¡¼­ ÀÌº¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ ÀÌº¥Æ®°¡ »óÀ§ ³ëµå·Î ÀüÆÄµÇ´Â Çö»óÀÌ´Ù. ¿¹¸¦ µé¾î, div °´Ã¼¸¦ Å¬¸¯ÇÒ ¶§ div¿Í ÇÔ²² »óÀ§ ¿¤¸®¸ÕÆ®ÀÎ document¿¡µµ onclick ÀÌº¥Æ®°¡ ¹ß»ýÇÑ´Ù. stop() ¸Þ¼Òµå´Â ÁöÁ¤ÇÑ °´Ã¼¿¡¼­¸¸ ÀÌº¥Æ®°¡ ¹ß»ýÇÏµµ·Ï ¹öºí¸µÀ» Â÷´ÜÇÑ´Ù.
 * @description [Lite]
 * @example
function eventHandler(evt) {
   someCode();
   evt.stop();
}
 * @example
// µðÆúÆ® ÀÌº¥Æ®¸¸ ÁßÁö½ÃÅ°°í ½ÍÀ» ¶§ (1.1.3¹öÀü ÀÌ»ó)
function stopDefaultOnly(evt) {
	// Here is some code to execute

	// Stop default event only
	evt.stop($Event.CANCEL_DEFAULT);
}
 * @return {$Event} ÀÌº¥Æ® °´Ã¼.
 * @param {Number} nCancel ÀÌº¥Æ®¸¦ Á¤ÁöÇÒ ¶§ ¹öºí¸µ, µðÆúÆ® ¾×¼Ç Áß Á¤Áö½ÃÅ³ °ªÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº $Event.CANCEL_ALL ÀÌ´Ù(1.1.3 ¹öÀü ÀÌ»ó).
 */
jindo.$Event.prototype.stop = function(nCancel) {
	nCancel = nCancel || jindo.$Event.CANCEL_ALL;

	var e = (window.event && window.event == this._globalEvent)?this._globalEvent:this._event;
	var b = !!(nCancel & jindo.$Event.CANCEL_BUBBLE); // stop bubbling
	var d = !!(nCancel & jindo.$Event.CANCEL_DEFAULT); // stop default event

	this.canceled = true;

	if (typeof e.preventDefault != "undefined" && d) e.preventDefault();
	if (typeof e.stopPropagation != "undefined" && b) e.stopPropagation();

	if(d) e.returnValue = false;
	if(b) e.cancelBubble = true;

	return this;
};

/**
 * default ÀÌº¥Æ®¸¦ Á¾·áÇÑ´Ù.
 * @return {$Event} ÀÌº¥Æ® °´Ã¼.
 * @see $Event#stop
 * @description [Lite]
 */
jindo.$Event.prototype.stopDefault = function(){
	return this.stop(jindo.$Event.CANCEL_DEFAULT);
}

/**
 * bubble ÀÌº¥Æ®¸¦ Á¾·áÇÑ´Ù.
 * @return {$Event} ÀÌº¥Æ® °´Ã¼.
 * @see $Event#stop
 * @description [Lite]
 */
jindo.$Event.prototype.stopBubble = function(){
	return this.stop(jindo.$Event.CANCEL_BUBBLE);
}

/**
 * $Event#stop ¸Þ¼­µå¿¡¼­ ¹öºí¸µÀ» ÁßÁö½ÃÅ²´Ù.
 * @final
 */
jindo.$Event.CANCEL_BUBBLE = 1;

/**
 * $Event#stop ¸Þ¼­µå¿¡¼­ µðÆúÆ® ¾×¼ÇÀ» ÁßÁö½ÃÅ²´Ù.
 * @final
 */
jindo.$Event.CANCEL_DEFAULT = 2;

/**
 * $Event#stop ¸Þ¼­µå¿¡¼­ ¹öºí¸®°ú µðÆúÆ® ¾×¼Ç ¸ðµÎ ÁßÁö½ÃÅ²´Ù.
 * @final
 */
jindo.$Event.CANCEL_ALL = 3;

/**
 * @fileOverview $ElementListÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name elementlist.js
 */

/**
 * $ElementList °´Ã¼¸¦ »ý¼º ¹× ¸®ÅÏÇÑ´Ù.
 * @class $ElementList Å¬·¡½º´Â id ¹è¿­, È¤Àº CSS Äõ¸® µîÀ» »ç¿ëÇÏ¿© DOM ¿¤¸®¸ÕÆ®ÀÇ ¹è¿­À» ¸¸µç´Ù. 
 * @param {String | Array} els ¹®¼­¿¡¼­ DOM ¿¤¸®¸ÕÆ®¸¦ Ã£±â À§ÇÑ CSS ¼±ÅÃÀÚ È¤Àº id, HTMLElement, $ElementÀÇ ¹è¿­
 * @constructor
 * @borrows $Element#show as this.show
 * @borrows $Element#hide as this.hide
 * @borrows $Element#toggle as this.toggle
 * @borrows $Element#addClass as this.addClass
 * @borrows $Element#removeClass as this.removeClass
 * @borrows $Element#toggleClass as this.toggleClass
 * @borrows $Element#fireEvent as this.fireEvent
 * @borrows $Element#leave as this.leave
 * @borrows $Element#empty as this.empty
 * @borrows $Element#appear as this.appear
 * @borrows $Element#disappear as this.disappear
 * @borrows $Element#className as this.className
 * @borrows $Element#width as this.width
 * @borrows $Element#height as this.height
 * @borrows $Element#text as this.text
 * @borrows $Element#html as this.html
 * @borrows $Element#css as this.css
 * @borrows $Element#attr as this.attr
 * @author Kim, Taegon
 */
jindo.$ElementList = function (els) {
	var cl = arguments.callee;
	if (els instanceof cl) return els;
	if (!(this instanceof cl)) return new cl(els);
	
	if (els instanceof Array || (jindo.$A && els instanceof jindo.$A)) {
		els = jindo.$A(els);
	} else if (typeof els == "string" && cssquery) {
		els = jindo.$A(cssquery(els));
	} else {
		els = jindo.$A();
	}

	this._elements = els.map(function(v,i,a){ return jindo.$Element(v) });
}

/**
 * get ¸Þ¼­µå´Â $ElementList¿¡¼­ ÀÎµ¦½º¿¡ ÇØ´çÇÏ´Â ¿¤¸®¸ÕÆ®¸¦ °¡Á®¿Â´Ù. 
 * @param {Number} idx °¡Á®¿Ã ¿¤¸®¸ÕÆ®ÀÇ ÀÎµ¦½º. ÀÎµ¦½º´Â 0¿¡¼­ ºÎÅÍ ½ÃÀÛÇÑ´Ù.
 * @return {$Element} ÀÎµ¦½º¿¡ ÇØ´çÇÏ´Â ¿¤¸®¸ÕÆ®
*/
jindo.$ElementList.prototype.get = function(idx) {
	return this._elements.$value()[idx];
};

/**
 * getFirst ¸Þ¼­µå´Â $ElementListÀÇ Ã¹¹øÂ° ¿¤¸®¸ÕÆ®¸¦ °¡Á®¿Â´Ù.
 * @remark getFirst ¸Þ¼­µåÀÇ ¸®ÅÏ°ªÀº $ElementList.get(0)ÀÇ ¸®ÅÏ°ª°ú µ¿ÀÏÇÏ´Ù.
 * @return {$Element} Ã¹¹øÂ° ¿¤¸®¸ÕÆ®
*/
jindo.$ElementList.prototype.getFirst = function() {
	return this.get(0);
};

/**
 * getLast ¸Þ¼­µå´Â $ElementListÀÇ ¸¶Áö¸· ¿¤¸®¸ÕÆ®¸¦ °¡Á®¿Â´Ù.
 * @return {$Element} ¸¶Áö¸· ¿¤¸®¸ÕÆ®
*/
jindo.$ElementList.prototype.getLast = function() {
	return this.get(Math.Max(this._elements.length-1,0));
};

(function(proto){
	var setters = 'show,hide,toggle,addClass,removeClass,toggleClass,fireEvent,leave,';
	setters += 'empty,appear,disappear,className,width,height,text,html,css,attr';
	
	jindo.$A(setters.split(',')).forEach(function(name){
		proto[name] = function() {
			var args = jindo.$A(arguments).$value();
			this._elements.forEach(function(el){
				el[name].apply(el, args);
			});
			
			return this;
		}
	});
	
	jindo.$A(['appear','disappear']).forEach(function(name){
		proto[name] = function(duration, callback) {
			var len  = this._elements.length;
			var self = this;
			this._elements.forEach(function(el,idx){
				if(idx == len-1) el[name](duration, function(){callback(self)});
				else el[name](duration);
			});
			
			return this;
		}
	});
})(jindo.$ElementList.prototype);
/**
 * @fileOverview $JsonÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name json.js
 */

/**
 * ÀÎ¼ö·Î ÁöÁ¤ÇÑ ¹®ÀÚ¿­À» »ç¿ëÇÏ¿© $S Å¬·¡½º¸¦ »ý¼ºÇÑ´Ù.
 * @class $S Å¬·¡½º´Â¹®ÀÚ¿­À» Ã³¸®ÇÏ±â À§ÇÑ ·¹ÆÛ(Wrapper) Å¬·¡½ºÀÌ´Ù.
 * @constructor
 * @author Kim, Taegon
 */
jindo.$S = function(str) {
	var cl = arguments.callee;

	if (typeof str == "undefined") str = "";
	if (str instanceof cl) return str;
	if (!(this instanceof cl)) return new cl(str);

	this._str = str+"";
}

/**
 * $value ¸Þ¼­µå´Â ¹®ÀÚ¿­À» ¸®ÅÏÇÑ´Ù.
 * @return {String} $SÀÇ ³»ºÎ ¹®ÀÚ¿­
 * @see $S#toString
 */
jindo.$S.prototype.$value = function() {
	return this._str;
};

/**
 * toString ¸Þ¼­µå´Â ¹®ÀÚ¿­À» ¸®ÅÏÇÑ´Ù.
 * @return {String} $SÀÇ ³»ºÎ ¹®ÀÚ¿­
 * @remark ³»ºÎÀûÀ¸·Î $value¸¦ »ç¿ëÇÑ´Ù.
 */
jindo.$S.prototype.toString = jindo.$S.prototype.$value;

/**
 * trim ¸Þ¼­µå´Â ¹®ÀÚ¿­ÀÇ ¾ç ³¡ °ø¹éÀ» Á¦°ÅÇÑ´Ù.
 * @return {$S} ¹®ÀÚ¿­ÀÇ ¾ç ³¡À» Á¦°ÅÇÑ »õ·Î¿î $S °´Ã¼
 * @example
 * var str = "   I have many spaces.   ";
 * document.write ( $S(str).trim() );
 *
 * // °á°ú :
 * // I have many spaces.
 */
jindo.$S.prototype.trim = function() {
	return jindo.$S(this._str.replace(/^\s+|\s+$/g, ""));
};

/**
 * escapeHTML ¸Þ¼­µå´Â HTML Æ¯¼ö ¹®ÀÚ¸¦ HTML ¿£Æ¼Æ¼ Çü½ÄÀ¸·Î º¯È¯ÇÑ´Ù.
 * @return {$S} HTML Æ¯¼ö ¹®ÀÚ¸¦ ¿£Æ¼Æ¼ Çü½ÄÀ¸·Î º¯È¯ÇÑ »õ·Î¿î $S °´Ã¼
 * @see $S#unescapeHTML
 * @remark  ", &, <, > ¸¦ °¢°¢ &quot;, &amp;, &lt;, &gt; ·Î º¯°æÇÑ´Ù.
 * @example
 * var str = ">_<;;";
 * document.write( $S(str).escapeHTML() );
 *
 * // °á°ú :
 * // &amp;gt;_&amp;lt;;;
 */
jindo.$S.prototype.escapeHTML = function() {
	var entities = {'"':'quot','&':'amp','<':'lt','>':'gt'};
	var s = this._str.replace(/[<>&"]/g, function(m0){
		return entities[m0]?'&'+entities[m0]+';':m0;
	});
	return jindo.$S(s);
};

/**
 * stripTags ¸Þ¼­µå´Â ¹®ÀÚ¿­¿¡¼­ XML È¤Àº HTML ÅÂ±×¸¦ Á¦°ÅÇÑ´Ù.
 * @return {$S} XML È¤Àº HTML ÅÂ±×¸¦ Á¦°ÅÇÑ »õ·Î¿î $S °´Ã¼
 * @example
 * var str = "Meeting <b>people</b> is easy.";
 * document.write( $S(str).stripTags() );
 *
 * // °á°ú :
 * // Meeting people is easy.
 */
jindo.$S.prototype.stripTags = function() {
	return jindo.$S(this._str.replace(/<\/?(?:h[1-5]|[a-z]+(?:\:[a-z]+)?)[^>]*>/ig, ''));
};

/**
 * times ¸Þ¼­µå´Â ¹®ÀÚ¿­À» ÀÎ¼ö·Î ÁöÁ¤ÇÑ ¼ýÀÚ¸¸Å­ ¹Ýº¹ÇÑ´Ù.
 * @param {Number} nTimes ¹Ýº¹ÇÒ È½¼ö
 * @return {$S} ¹®ÀÚ¿­À» ÁöÁ¤ÇÑ ¼ýÀÚ¸¸Å­ ¹Ýº¹ÇÑ »õ·Î¿î $S °´Ã¼
 * @example
 * document.write ( $S("Abc").times(3) );
 *
 * // °á°ú : AbcAbcAbc
 */
jindo.$S.prototype.times = function(nTimes) {
	var buf = [];
	for(var i=0; i < nTimes; i++) {
		buf[buf.length] = this._str;
	}

	return jindo.$S(buf.join(''));
};

/**
 * unescapeHTML ¸Þ¼­µå´Â ÀÌ½ºÄÉÀÌÇÁµÈ HTMLÀ» ¿ø·¡ÀÇ HTML·Î º¯È¯ÇÑ´Ù.
 * @return {$S} ÀÌ½ºÄÉÀÌÇÁµÈ HTMLÀ» ¿ø·¡ÀÇ HTML·Î º¯È¯ÇÑ »õ·Î¿î $S °´Ã¼
 * @remark  &quot;, &amp;, &lt;, &gt;¸¦ °¢°¢ ", &, <, > À¸·Î º¯°æÇÑ´Ù.
 * @see $S#escapeHTML
 * @example
 * var str = "&lt;a href=&quot;http://naver.com&quot;&gt;Naver&lt;/a&gt;";
 * document.write( $S(str).unescapeHTML() );
 *
 * // °á°ú :
 * // <a href="http://naver.com">Naver</a>
 */
jindo.$S.prototype.unescapeHTML = function() {
	var entities = {'quot':'"','amp':'&','lt':'<','gt':'>'};
	var s = this._str.replace(/&([a-z]+);/g, function(m0,m1){
		return entities[m1]?entities[m1]:m0;
	});
	return jindo.$S(s);
};

/**
 * escape ¸Þ¼­µå´Â ¹®ÀÚ¿­À» °ãµû¿ÈÇ¥¿¡ Æ÷ÇÔµÉ ¼ö ÀÖ´Â ASCI ¹®ÀÚ¿­·Î ÀÌ½ºÄÉÀÌÇÁ Ã³¸®ÇÑ´Ù.
 * @remark \r, \n, \t, ', ", non-ASCII ¹®ÀÚ¸¦ ÀÌ½ºÄÉÀÌÇÁ Ã³¸®ÇÑ´Ù.
 * @return {$S} ¹®ÀÚ¿­À» ÀÌ½ºÄÉÀÌÇÁ Ã³¸®ÇÑ »õ·Î¿î $S °´Ã¼
 * @see $S#escapeHTML
 * @example
 * var str = '°¡"\'³ª\\';
 * document.write( $S(str).escape() );
 *
 * // °á°ú :
 * \uAC00\"\'\uB098\\
 */
jindo.$S.prototype.escape = function() {
	var s = this._str.replace(/([\u0080-\uFFFF]+)|[\n\r\t"'\\]/g, function(m0,m1,_){
		if(m1) return escape(m1).replace(/%/g,'\\');
		return (_={"\n":"\\n","\r":"\\r","\t":"\\t"})[m0]?_[m0]:"\\"+m0;
	});

	return jindo.$S(s);
};

/**
 * bytes ¸Þ¼­µå´Â ¹®ÀÚ¿­ÀÇ ½ÇÁ¦ ¹ÙÀÌÆ®(byte) ¼ö¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return ¹®ÀÚ¿­ÀÇ ¹ÙÀÌÆ® ¼ö. ´Ü, Ã¹¹øÂ° ÆÄ¶ó¹ÌÅÍ¸¦ ¼³Á¤ÇÏ¸é ÀÚ±â °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @param {Number} nBytes ¸ÂÃâ ±ÛÀÚ ¼ö
 * @remark ¹®¼­ÀÇ charsetÀ» ÇØ¼®ÇØ¼­ ÀÎÄÚµù ¹æ½Ä¿¡ µû¶ó ÇÑ±ÛÀ» ºñ·ÔÇÑ À¯´ÏÄÚµå ¹®ÀÚ¿­ÀÇ ¹ÙÀÌÆ® ¼ö¸¦ °¡º¯ÀûÀ¸·Î °è»êÇÑ´Ù. À¯´ÏÄÚµå ¹®¼­°¡ ¾Æ´Ï¶ó¸é, À¯´ÏÄÚµå ¹®ÀÚ¿­Àº Ç×»ó 2byte·Î °è»êÇÑ´Ù.
 * @example
 * // ¹®¼­°¡ euc-kr È¯°æÀÓÀ» °¡Á¤ÇÕ´Ï´Ù.
 * var str = "ÇÑ±Û°ú English°¡ ¼¯ÀÎ ¹®Àå...";
 * document.write( $S(str).bytes() );
 *
 * // °á°ú : 29
 */
jindo.$S.prototype.bytes = function(nBytes) {
	var code = 0, bytes = 0, i = 0, len = this._str.length;
	var charset = ((document.charset || document.characterSet || document.defaultCharset)+"").toLowerCase();
	var cut = (typeof nBytes == "number");

	if (charset == "utf-8") {
		// À¯´ÏÄÚµå ¹®ÀÚ¿­ÀÇ ¹ÙÀÌÆ® ¼ö´Â À§Å°ÇÇµð¾Æ¸¦ Âü°íÇß´Ù(http://ko.wikipedia.org/wiki/UTF-8).
		for(i=0; i < len; i++) {
			code = this._str.charCodeAt(i);
			if (code < 128) bytes += 1;
			else if (code < 2048) bytes += 2;
			else if (code < 65536) bytes += 3;
			else bytes += 4;
			
			if (cut && bytes > nBytes) {
				this._str = this._str.substr(0,i);
				break;
			}
		}
	} else {
		for(i=0; i < len; i++) {
			bytes += (this._str.charCodeAt(i) > 128)?2:1;
			
			if (cut && bytes > nBytes) {
				this._str = this._str.substr(0,i);
				break;
			}
		}
	}

	return cut?this:bytes;
};

/**
 * parseString ¸Þ¼­µå´Â URL Äõ¸® ½ºÆ®¸µÀ» °´Ã¼·Î ÆÄ½ÌÇÑ´Ù.
 * @return {Object} ¹®ÀÚ¿­À» ÆÄ½ÌÇÑ °´Ã¼
 * @example
 * var str = "aa=first&bb=second";
 * var obj = $S(str).parseString();
 *
 * // obj => { aa : "first", bb : "second" }
 */
jindo.$S.prototype.parseString = function() {
	var str = this._str.split(/&/g), pos, key, val, buf = {};

	for(var i=0; i < str.length; i++) {
		key = str[i].substring(0, pos=str[i].indexOf("="));
		val = decodeURIComponent(str[i].substring(pos+1));

		if (key.substr(key.length-2,2) == "[]") {
			key = key.substring(0, key.length-2);
			if (typeof buf[key] == "undefined") buf[key] = [];
			buf[key][buf[key].length] = val;
		} else {
			buf[key] = val;
		}
	}

	return buf;
};

/**
 * Á¤±Ô½Ä¿¡ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ¹®ÀÚ¿­À» ÀÌ½ºÄÉÀÌÇÁ ÇÑ´Ù.
 * @since 1.2.0
 * @return {String} ÀÌ½ºÄÉÀÌÇÁµÈ ¹®ÀÚ¿­
 * @example
 * var str = "Slash / is very important. Backslash \ is more important. +_+";
 * document.write( $S(str).escapeRegex() );
 * 
 * // °á°ú :
 * // Slash \/ is very important\. Backslash \\ is more important\. \+_\+
 */
jindo.$S.prototype.escapeRegex = function() {
	var s = this._str;
	var r = /([\?\.\*\+\-\/\(\)\{\}\[\]\:\!\^\$\\\|])/g;

	return jindo.$S(s.replace(r, "\\$1"));
};

/**
 * format ¸Þ¼­µå´Â ¹®ÀÚ¿­À» Çü½Ä ¹®ÀÚ¿­¿¡ ´ëÀÔÇÑ »õ·Î¿î ¹®ÀÚ¿­À» ¸¸µç´Ù. Çü½Ä ¹®ÀÚ¿­Àº %·Î ½ÃÀÛÇÏ¸ç, Çü½Ä ¹®ÀÚ¿­ÀÇ Á¾·ù´Â <a href="http://www.php.net/manual/en/function.sprintf.php">PHP</a>¿Í µ¿ÀÏÇÏ´Ù.
 * @param {String} formatString Çü½Ä ¹®ÀÚ¿­
 * @return {String} ¹®ÀÚ¿­À» Çü½Ä ¹®ÀÚ¿­¿¡ ´ëÀÔÇÏ¿© ¸¸µç »õ·Î¿î ¹®ÀÚ¿­.
 * @example
var str = $S("%4d³â %02d¿ù %02dÀÏ").format(2008, 2, 13);
// str == "2008³â 02¿ù 13ÀÏ"

var str = $S("ÆÐµù %5s ºó°ø¹é").format("°ª");
// str == "ÆÐµù     °ª ºó°ø¹é"

var str = $S("%b").format(10);
// str == "1010"

var str = $S("%x").format(10);
// str == "a"

var str = $S("%X").format(10);
// str == "A"
 * @see $S#times
 */
jindo.$S.prototype.format = function() {
	var args = arguments;
	var idx  = 0;
	var s = this._str.replace(/%([ 0])?(-)?([1-9][0-9]*)?([bcdsoxX])/g, function(m0,m1,m2,m3,m4){
		var a = args[idx++];
		var ret = "", pad = "";

		m3 = m3?+m3:0;

		if (m4 == "s") {
			ret = a+"";
		} else if (" bcdoxX".indexOf(m4) > 0) {
			if (typeof a != "number") return "";
			ret = (m4 == "c")?String.fromCharCode(a):a.toString(({b:2,d:10,o:8,x:16,X:16})[m4]);
			if (" X".indexOf(m4) > 0) ret = ret.toUpperCase();
		}

		if (ret.length < m3) pad = jindo.$S(m1||" ").times(m3 - ret.length).toString();
		(m2 == '-')?(ret+=pad):(ret=pad+ret);

		return ret;
	});

	return jindo.$S(s);
};

/**
 * @fileOverview $Document »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name document.js
 */

/**
 * $Document °´Ã¼¸¦ »ý¼º ¹× ¸®ÅÏÇÑ´Ù.
 * @class $Document Å¬·¡½º´Â ¹®¼­¿Í °ü·ÃµÈ ¿©·¯°¡Áö ±â´ÉÀÇ ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù 
 * @param {Document} doc	±â´É¿¡ »ç¿ëµÈ document °´Ã¼, ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ±âº»ÀûÀ¸·Î ÇöÀç ¹®¼­ÀÇ document °¡ ÁöÁ¤µÈ´Ù.
 * @constructor
 * @author Hooriza
 */
jindo.$Document = function (el) {
	var cl = arguments.callee;
	if (el instanceof cl) return el;
	if (!(this instanceof cl)) return new cl(el);
	
	this._doc = el || document;
	
	this._docKey = this.renderingMode() == 'Standards' ? 'documentElement' : 'body';	
};

/**
 * $value ¸Þ¼­µå´Â ·¡ÇÎµÈ ¿ø·¡ÀÇ document °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.
 * @return {HTMLDocument} document °´Ã¼
 */
jindo.$Document.prototype.$value = function() {
	return this._doc;
};

/**
 * scrollSize ¸Þ¼­µå´Â ¹®¼­ÀÇ ½ÇÁ¦ °¡·Î, ¼¼·Î Å©±â¸¦ ±¸ÇÑ´Ù
 * @return {Object} °¡·ÎÅ©±â´Â width, ¼¼·ÎÅ©±â´Â height ¶ó´Â Å°°ªÀ¸·Î ¸®ÅÏµÈ´Ù.
 * @example
var size = $Document().scrollSize();
alert('°¡·Î : ' + size.width + ' / ¼¼·Î : ' + size.height); 
 */
jindo.$Document.prototype.scrollSize = function() {

	// webkit °è¿­¿¡¼­´Â Standard ¸ðµå¶óµµ body¸¦ »ç¿ëÇØ¾ß Á¤»óÀûÀÎ scroll Size¸¦ ¾ò¾î¿Â´Ù.
	var isWebkit = navigator.userAgent.indexOf("WebKit")>-1;
	var oDoc = this._doc[isWebkit?'body':this._docKey];
	
	return {
		width : Math.max(oDoc.scrollWidth, oDoc.clientWidth),
		height : Math.max(oDoc.scrollHeight, oDoc.clientHeight)
	};

};

/**
 * scrollPosition ¸Þ¼­µå´Â ¹®¼­ÀÇ ½ºÅ©·Ñ¹Ù À§Ä¡¸¦ ±¸ÇÑ´Ù
 * @return {Object} °¡·Î À§Ä¡´Â left, ¼¼·ÎÀ§Ä¡´Â top ¶ó´Â Å°°ªÀ¸·Î ¸®ÅÏµÈ´Ù.
 * @example
var size = $Document().scrollPosition();
alert('°¡·Î : ' + size.left + ' / ¼¼·Î : ' + size.top); 
* @since 1.3.5
 */
jindo.$Document.prototype.scrollPosition = function() {

	// webkit °è¿­¿¡¼­´Â Standard ¸ðµå¶óµµ body¸¦ »ç¿ëÇØ¾ß Á¤»óÀûÀÎ scroll Size¸¦ ¾ò¾î¿Â´Ù.
	var isWebkit = navigator.userAgent.indexOf("WebKit")>-1;
	var oDoc = this._doc[isWebkit?'body':this._docKey];
	return {
		left : oDoc.scrollLeft||window.pageXOffset||window.scrollX||0,
		top : oDoc.scrollTop||window.pageYOffset||window.scrollY||0
	};

};

/**
 * clientSize ¸Þ¼­µå´Â ½ºÅ©·Ñ¹Ù·Î ÀÎÇØ °¡·ÁÁø ºÎºÐÀ» Á¦¿ÜÇÑ ¹®¼­ Áß º¸ÀÌ´Â ºÎºÐÀÇ °¡·Î, ¼¼·Î Å©±â¸¦ ±¸ÇÑ´Ù
 * @return {Object} °¡·ÎÅ©±â´Â width, ¼¼·ÎÅ©±â´Â height ¶ó´Â Å°°ªÀ¸·Î ¸®ÅÏµÈ´Ù
 * @example
var size = $Document(document).clientSize();
alert('°¡·Î : ' + size.width + ' / ¼¼·Î : ' + size.height); 
 */
jindo.$Document.prototype.clientSize = function() {
	
	var oDoc = this._doc[this._docKey];
	
	var isSafari = navigator.userAgent.indexOf("WebKit")>-1 && navigator.userAgent.indexOf("Chrome")==-1;

	// »çÆÄ¸®ÀÇ °æ¿ì À©µµ¿ì ¸®»çÀÌÁî½Ã¿¡ clientWidth,clientHeight°ªÀÌ Á¤»óÀûÀ¸·Î ³ª¿ÀÁö ¾Ê¾Æ¼­ window.innerWidth,innerHeight·Î ´ëÃ¼
	return (isSafari)?{
					width : window.innerWidth,
					height : window.innerHeight
				}:{
					width : oDoc.clientWidth,
					height : oDoc.clientHeight
				};
};

/**
 * renderingMode ¸Þ¼­µå´Â ¹®¼­ÀÇ ·»´õ¸µ ¹æ½ÄÀ» ¾ò´Â´Ù
 * @return {String} ·»´õ¸µ ¸ðµå
 * <dl>
 *	<dt>Standards</dt>
 *	<dd>Ç¥ÁØ ·»´õ¸µ ¸ðµå</dd>
 *	<dt>Almost</dt>
 *	<dd>À¯»ç Ç¥ÁØ ·»´õ¸µ ¸ðµå (IE ¿ÜÀÇ ºê¶ó¿ìÀú¿¡¼­ DTD À» ¿Ã¹Ù¸£°Ô ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ»¶§ ¸®ÅÏ)</dd>
 *	<dt>Quirks</dt>
 *	<dd>ºñÇ¥ÁØ ·»´õ¸µ ¸ðµå</dd>
 * </dl>
 * @example
var mode = $Document().renderingMode();
alert('·»´õ¸µ ¹æ½Ä : ' + mode);
 */
jindo.$Document.prototype.renderingMode = function() {

	var isIe = (typeof window.opera=="undefined" && navigator.userAgent.indexOf("MSIE")>-1);
	var isSafari = (navigator.userAgent.indexOf("WebKit")>-1 && navigator.userAgent.indexOf("Chrome")<0 && navigator.vendor.indexOf("Apple")>-1);
	var sRet;

	if ('compatMode' in this._doc)
		sRet = this._doc.compatMode == 'CSS1Compat' ? 'Standards' : (isIe ? 'Quirks' : 'Almost');
	else
		sRet = isSafari ? 'Standards' : 'Quirks';

	return sRet;

};

/**
 * ¹®¼­¿¡¼­ ÁÖ¾îÁø selector¸¦ ¸¸Á·½ÃÅ°´Â ¿ä¼ÒÀÇ ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù. ¸¸Á·ÇÏ´Â ¿ä¼Ò°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ºó ¹è¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sSelector
 * @return {Array} Á¶°ÇÀ» ¸¸Á·ÇÏ´Â ¿ä¼ÒÀÇ ¹è¿­
 */
jindo.$Document.prototype.queryAll = function(sSelector) { 
	return jindo.$$(sSelector, this._doc); 
};

/**
 * ¹®¼­¿¡¼­ ÁÖ¾îÁø selector¸¦ ¸¸Á·½ÃÅ°´Â ¿ä¼ÒÁß Ã¹ ¹øÂ° ¿ä¼Ò¸¦ ¹ÝÈ¯ÇÑ´Ù. ¸¸Á·ÇÏ´Â ¿ä¼Ò°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é nullÀ» ¹ÝÈ¯ÇÑ´Ù.
 * @param {String} sSelector
 * @return {Element} Á¶°ÇÀ» ¸¸Á·ÇÏ´Â ¿ä¼ÒÁß Ã¹¹øÂ° ¿ä¼Ò
 */
jindo.$Document.prototype.query = function(sSelector) { 
	return jindo.$$.getSingle(sSelector, this._doc); 
};

/**
 * ¹®¼­¿¡¼­  XPath ¹®¹ýÀ» »ç¿ëÇÏ¿© ¿¤¸®¸ÕÆ®¸¦ ¾ò¾î¿Â´Ù.
 * @remark Áö¿øÇÏ´Â ¹®¹ýÀÌ ¹«Ã´ Á¦ÇÑÀûÀ¸·Î Æ¯¼öÇÑ °æ¿ì¿¡¼­¸¸ »ç¿ëÇÏ´Â °ÍÀ» ±ÇÀåÇÑ´Ù.
 * @param {String} sXPath
 * @return {Array} path¿¡ ÇØ´çÇÏ´Â ¿ä¼Ò
 */
jindo.$Document.prototype.xpathAll = function(sXPath) { 
	return jindo.$$.xpath(sSelector, this._doc); 
};
/**
 * @fileOverview $Form »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name form.js
 */

/**
 * $Form °´Ã¼¸¦ »ý¼º ¹× ¸®ÅÏÇÑ´Ù.
 * @class $Form Å¬·¡½º´Â <form> ¿¤¸®¸ÕÆ®¿Í ÇÏÀ§ ÀÔ·Â¿ä¼ÒµéÀ» ´Ù·ç±â À§ÇÑ ¿©·¯ °¡Áö ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù. 
 * @param {Element | String} el	$Form¸¦ »ç¿ëÇÒ <form> ¿¤¸®¸ÕÆ®, È¤Àº <form> ¿¤¸®¸ÕÆ®ÀÇ °íÀ¯ÇÑ id. ¸¸¾à °íÀ¯ÇÏÁö ¾ÊÀº id¸¦ ÁöÁ¤ÇÏ¸é °¡Àå ¸ÕÀú ³ª¿À´Â ¿¤¸®¸ÕÆ®¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @constructor
 * @author Hooriza
 */
jindo.$Form = function (el) {
	var cl = arguments.callee;
	if (el instanceof cl) return el;
	if (!(this instanceof cl)) return new cl(el);
	
	el = jindo.$(el);
	
	if (!el.tagName || el.tagName.toUpperCase() != 'FORM') throw new Error('The element should be a FORM element');
	this._form = el;
}

/**
 * $value ¸Þ¼­µå´Â ·¦ÇÎµÈ ¿ø·¡ <form> ¿¤¸®¸ÕÆ®¸¦ ¸®ÅÏÇÑ´Ù
 * @return {HTMLElement} <form> ¿¤¸®¸ÕÆ®
 * @example

var el = $('<form>');
var form = $Form(el);

alert(form.$value() === el); // true
 
 */
jindo.$Form.prototype.$value = function() {
	return this._form;
};

/**
 * serialize ¸Þ¼­µå´Â Æ¯Á¤ ¶Ç´Â ÀüÃ¼ ¿¤¸®¸àÆ®  ÀÔ·Â¿ä¼Ò¸¦ ¹®ÀÚ¿­ ÇüÅÂ·Î ¸®ÅÏÇÑ´Ù.
 * @param {Mixed} Mixed ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê°Å³ª ÀÎ¼ö¸¦ ÇÏ³ª ÀÌ»ó ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. 
 * <dl>
 *	<dt>ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀ» °æ¿ì</dt>
 *	<dd>ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é Äõ¸® ÇüÅÂÀÇ ¹®ÀÚ¿­À» ¸®ÅÏÇÑ´Ù.</dd>
 *	<dt>{String} one_element_name</dt>
 *	<dd>ÀÎ¼ö·Î ÇÏ³ªÀÇ ¹®ÀÚ¿­¸¸ ÁöÁ¤ÇÏ¸é ¹®ÀÚ¿­°ú µ¿ÀÏÇÑ name ¼Ó¼ºÀ» °¡Áö´Â ¿¤¸®¸ÕÆ®¿Í ±× °ªÀ» ¸®ÅÏÇÑ´Ù.</dd>
 *	<dt>{String, String... } element_names</dt>
 *	<dd>µÎ °³ ÀÌ»óÀÇ ¿¤¸®¸ÕÆ®¿Í ±× °ªÀ» ¸®ÅÏÇÑ´Ù. </dd>
 * </dl>
 * @return {String} Äõ¸® ¹®ÀÚ¿­ ÇüÅÂ·Î º¯È¯ÇÑ ¿¤¸®¸ÕÆ®¿Í ±× °ª.
 * @example

<form id="TEST">
	<input name="ONE" value="1" type="text" />
	<input name="TWO" value="2" checked="checked" type="checkbox" />
	<input name="THREE" value="3_1" type="radio" />
	<input name="THREE" value="3_2" checked="checked" type="radio" />
	<input name="THREE" value="3_3" type="radio" />
	<select name="FOUR">
		<option value="4_1">..</option>
		<option value="4_2">..</option>
		<option value="4_3" selected="selected">..</option>
	</select>
</form>
<script type="text/javascript">
	var form = $Form('TEST');

	var allstr = form.serialize();
	alert(allstr == 'ONE=1&TWO=2&THREE=3_2&FOUR=4_3'); // true

	var str = form.serialize('ONE', 'THREE');
	alert(str == 'ONE=1&THREE=3_2'); // true
</script>

 */
jindo.$Form.prototype.serialize = function() {

 	var self = this;
 	var oRet = {};
 	
 	var nLen = arguments.length;
 	var fpInsert = function(sKey) {
 		var sVal = self.value(sKey);
 		if (typeof sVal != 'undefined') oRet[sKey] = sVal;
 	};
 	
 	if (nLen == 0) 
	 	jindo.$A(this.element()).forEach(function(o) { if (o.name) fpInsert(o.name); });
 	else
 		for (var i = 0; i < nLen; i++) fpInsert(arguments[i]);
 	
	return jindo.$H(oRet).toQueryString();
	
};

/**
 * element ¸Þ¼­µå´Â Æ¯Á¤ ¶Ç´Â ÀüÃ¼ ÀÔ·Â¿ä¼Ò¸¦ ¸®ÅÏÇÑ´Ù.
 * @param {String} sKey ¾ò°íÀÚ ÇÏ´Â ÀÔ·Â¿ä¼Ò ¿¤¸®¸ÕÆ®ÀÇ name ¹®ÀÚ¿­, »ý·«½Ã¿¡´Â ¸ðµç ÀÔ·Â¿ä¼ÒµéÀ» ¹è¿­·Î ¸®ÅÏÇÑ´Ù.
 * @return {HTMLElement | Array} ÀÔ·Â ¿ä¼Ò ¿¤¸®¸ÕÆ®
 */
jindo.$Form.prototype.element = function(sKey) {

	if (arguments.length > 0)
		return this._form[sKey];
	
	return this._form.elements;
	
};

/**
 * enable ¸Þ¼­µå´Â ÀÔ·Â ¿ä¼ÒÀÇ È°¼ºÈ­ ¿©ºÎ¸¦ ¾ò°Å³ª ¼³Á¤ÇÑ´Ù.
 * @param {Mixed} mixed Á¤È®ÇÑ ÀÎ¼ö´Â ´ÙÀ½°ú °°´Ù. 
 * <dl>
 *	<dt>{String}fieldName</dt>
 *	<dd>ÀÎ¼ö·Î ÀÔ·Â¿ä¼ÒÀÇ ÀÌ¸§¸¸ ³Ö¾îÁÖ¸é ÇØ´ç ÀÔ·Â¿ä¼ÒÀÇ È°¼ºÈ­ ¿©ºÎ¸¦ true, false ·Î ¹ÝÈ¯ÇÑ´Ù</dd>
 *	<dt>{String}fieldName, {Boolean}flag</dt>
 *	<dd>ÀÔ·Â¿ä¼Ò¿Í Boolean ÇüÀÇ »óÅÂ°ªÀ» ÇÔ²² ³Ö¾îÁÖ¸é ÇØ´ç ÀÔ·Â¿ä¼Ò¸¦ ÁöÁ¤ÇÑ »óÅÂ·Î È°¼ºÈ­ ¿©ºÎ¸¦ º¯°æÇÑ´Ù</dd>
 *	<dt>{Object}objectProperties</dt>
 *	<dd>µ¿½Ã¿¡ ¿©·¯°³ÀÇ ÀÔ·Â¿ä¼Ò¿¡ ´ëÇØ È°¼ºÈ­ ¿©ºÎ¸¦ ÁöÁ¤ÇÏ°í ½ÍÀ»¶§ »ç¿ëÇÑ´Ù</dd>
 * </dl>
 * @return {Boolean|$Form} ¿¤¸®¸ÕÆ®ÀÇ È°¼ºÈ­ ¿©ºÎ¸¦ °¡Á®¿À°Å³ª ¿¤¸®¸ÕÆ®ÀÇ È°¼ºÈ­ ¿©ºÎ¸¦ ¼³Á¤ÇÑ $Form °´Ã¼. 
 * @example

<form id="TEST">
	<input name="ONE" disabled="disabled" type="text" />
	<input name="TWO" type="checkbox" />
</form>
<script type="text/javascript">
	var form = $Form('TEST');

	var one_enabled = form.enable('ONE');
	alert(one_enabled === false); // true

	form.enable('TWO', false);

	form.enable({
		'ONE' : true,
		'TWO' : false
	});
</script>

 */
jindo.$Form.prototype.enable = function() {
	
	var sKey = arguments[0];

	if (typeof sKey == 'object') {
		
		var self = this;
		jindo.$H(sKey).forEach(function(bFlag, sKey) { self.enable(sKey, bFlag); });
		return this;
		
	}
	
	var aEls = this.element(sKey);
	if (!aEls) return this;
	aEls = aEls.nodeType == 1 ? [ aEls ] : aEls;
	
	if (arguments.length < 2) {
		
		var bEnabled = true;
		jindo.$A(aEls).forEach(function(o) { if (o.disabled) {
			bEnabled = false;
			jindo.$A.Break();
		}});
		return bEnabled;
		
	} else { // setter
		
		var sFlag = arguments[1];
		jindo.$A(aEls).forEach(function(o) { o.disabled = !sFlag; });
		
		return this;
		
	}
	
};

/**
 * value ¸Þ¼­µå´Â Æû ¿¤¸®¸ÕÆ®ÀÇ °ªÀ» ¾ò°Å³ª ¼³Á¤ÇÑ´Ù.
 * @param {Mixed} Mixed Á¤È®¾È ÀÎ¼ö Á¤º¸´Â ´ÙÀ½°ú °°´Ù. 
 * <dl>
 *	<dt>{String}fieldName</dt>
 *	<dd>ÀÎ¼ö·Î ¿¤¸®¸ÕÆ®ÀÇ ÀÌ¸§¸¸ ÁöÁ¤ÇÏ¸é ¿¤¸®¸ÕÆ®ÀÇ °ªÀ» ¸®ÅÏÇÑ´Ù</dd>
 *	<dt>{String}fieldName, {String}value</dt>
 *	<dd>¿¤¸®¸ÕÆ®ÀÇ ÀÌ¸§°ú ¿¤¸®¸ÕÆ®¿¡ ¼³Á¤ÇÒ °ªÀ» ÇÔ²² ÁöÁ¤ÇÏ¸é ¿¤¸®¸ÕÆ®ÀÇ °ªÀ» ÁöÁ¤ÇÑ °ªÀ¸·Î ¹Ù²Û´Ù.</dd>
 *	<dt>{Object}objectProperties</dt>
 *	<dd>µÎ °³ ÀÌ»óÀÇ ¿¤¸®¸ÕÆ® °ªÀ» µ¿½Ã¿¡ ÁöÁ¤ÇÏ°í ½ÍÀ¸¸é '¿¤¸®¸ÕÆ® ÀÌ¸§ : ¿¤¸®¸ÕÆ® °ª'À» ¿ø¼Ò·Î °¡Áö´Â °´Ã¼¸¦ ÁöÁ¤ÇÑ´Ù. </dd>
 * </dl>
 * @return {String|$Form} ÀÎ¼ö·Î ¿¤¸®¸ÕÆ®¸¸ ÁöÁ¤Çß´Ù¸é ÁöÁ¤ÇÑ ¿¤¸®¸ÕÆ®ÀÇ °ªÀ», ÀÎ¼ö·Î Æû ¿¤¸®¸Õ¿Í ¿¤¸®¸ÕÆ®ÀÇ °ªÀ» ÁöÁ¤Çß´Ù¸é $Form °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.    
 * @example

<form id="TEST">
	<input name="ONE" value="1" type="text" />
	<input name="TWO" value="2" type="checkbox" />
</form>
<script type="text/javascript">
	var form = $Form('TEST');

	var one_value = form.value('ONE');
	alert(one_value === '1'); // true

	var two_value = form.value('TWO');
	alert(two_value === undefined); // true

	form.value('TWO', 2);
	alert(two_value === '2'); // true

	form.value({
		'ONE' : '1111',
		'TWO' : '2'
	});	
	// form.value('ONE') -> 1111
	// form.value('ONE') -> 2
</script>

 */
jindo.$Form.prototype.value = function(sKey) {
	
	if (typeof sKey == 'object') {
		
		var self = this;
		jindo.$H(sKey).forEach(function(bFlag, sKey) { self.value(sKey, bFlag); });
		return this;
		
	}
	
	var aEls = this.element(sKey);
	if (!aEls) throw new Error('The element is not exist');
	aEls = aEls.nodeType == 1 ? [ aEls ] : aEls;
	
	if (arguments.length > 1) { // setter
		
		var sVal = arguments[1];
		
		jindo.$A(aEls).forEach(function(o) {
			
			switch (o.type) {
			case 'radio':
			case 'checkbox':
				o.checked = (o.value == sVal);
				break;
				
			case 'select-one':
				var nIndex = -1;
				for (var i = 0, len = o.options.length; i < len; i++)
					if (o.options[i].value == sVal) nIndex = i;
				o.selectedIndex = nIndex;

				break;
				
			default:
				o.value = sVal;
				break;
			}
			
		});
		
		return this;
	}

	// getter
	
	var aRet = [];
	
	jindo.$A(aEls).forEach(function(o) {
		
		switch (o.type) {
		case 'radio':
		case 'checkbox':
			if (o.checked) aRet.push(o.value);
			break;
		
		case 'select-one':
			if (o.selectedIndex != -1) aRet.push(o.options[o.selectedIndex].value);
			break;
			
		default:
			aRet.push(o.value);
			break;
		}
		
	});
	
	return aRet.length > 1 ? aRet : aRet[0];
	
};

/**
 * submit ¸Þ¼­µå´Â ÆûÀÇ µ¥ÀÌÅÍ¸¦ À¥À¸·Î Á¦Ãâ(submit) ÇÑ´Ù.
 * @param {String} sTargetName Á¦ÃâÇÒ ÆûÀÌ ÀÖ´Â À©µµ¿ìÀÇ ÀÌ¸§. sTargetNameÀ» »ý·«ÇÏ¸é ±âº» Å¸°Ù
 * @param {String} fValidation Á¦ÃâÇÒ ÆûÀÇ ¹ë¸®µ¥ÀÌ¼Ç ÇÔ¼ö. form ¿ä¼Ò¸¦ ÀÎÀÚ·Î ¹Þ´Â´Ù.
 * @return {$Form} µ¥ÀÌÅÍ¸¦ Á¦ÃâÇÑ $Form °´Ã¼. 
 * @example
var form = $Form(el);
form.submit();
form.submit('foo');
 */
jindo.$Form.prototype.submit = function(sTargetName, fValidation) {
	
	var sOrgTarget = null;
	
	if (typeof sTargetName == 'string') {
		sOrgTarget = this._form.target;
		this._form.target = sTargetName;
	}
	
	if(typeof sTargetName == 'function') fValidation = sTargetName;
	
	if(typeof fValidation != 'undefined'){
		if(!fValidation(this._form)) return this;	
	}	
	
	this._form.submit();
	
	if (sOrgTarget !== null)
		this._form.target = sOrgTarget;
	
	return this;
	
};

/**
 * reset ¸Þ¼­µå´Â ÆûÀ» ÃÊ±âÈ­(reset)ÇÑ´Ù.
 * @param {String} fValidation Á¦ÃâÇÒ ÆûÀÇ ¹ë¸®µ¥ÀÌ¼Ç ÇÔ¼ö. form ¿ä¼Ò¸¦ ÀÎÀÚ·Î ¹Þ´Â´Ù.
 * @return {$Form} ÃÊ±âÈ­ÇÑ $Form °´Ã¼.
 * @example
var form = $Form(el);
form.reset(); 
 */
jindo.$Form.prototype.reset = function(fValidation) {
	
	if(typeof fValidation != 'undefined'){
		if(!fValidation(this._form)) return this;	
	}	
	
	this._form.reset();
	return this;
	
};

/**
 * @fileOverview $TemplateÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name template.js
 */

/**
 * ÅÛÇÃ¸´À» ½ÇÇàÇÑ´Ù. Ã¹¹øÂ° ÀÎ¼ö·Î ÅÛÇÃ¸´ ¹®ÀÚ¿­ ¶Ç´Â ¹®ÀÚ¿­À» Æ÷ÇÔÇÑ HTML ¿¤¸®¸ÕÆ® È¤Àº ¿¤¸®¸ÕÆ®ÀÇ ¾ÆÀÌµð¸¦ Àü´ÞÇÒ ¼ö ÀÖ´Ù.
 * ¿¤¸®¸ÕÆ®´Â &lt;textarea&gt; ¶Ç´Â &lt;script type="text/template"&gt; ÀÌ °¡´ÉÇÏ´Ù(&lt;script&gt; ÅÂ±×¸¦ »ç¿ëÇÏ·Á¸é ¹Ýµå½Ã type ¼Ó¼ºÀ» ÁöÁ¤ÇØÁÖ¾î¾ß ÇÑ´Ù).
 * @class $Template Å¬·¡½º´Â ÅÛÇÃ¸´ ¹®ÀÚ¿­¿¡ µ¿ÀûÀ¸·Î ¹®ÀÚ¿­À» »ðÀÔÇÑ´Ù.
 * @constructor
 * @author Kim, Taegon
 * @example
 * <script type="text/javascript">
 * // Template ¹®ÀÚ¿­À» Àü´ÞÇÏ´Â °æ¿ì
 * var tpl = $Template("Value : {=test}");
 * </script>
 * @example
 * <textarea id="tpl1">
 * Value : {=test}
 * </textarea>
 *
 * <script type="text/template" id="tpl2">
 Value : {=test}
 * </script>
 *
 * <script type="text/javascript">
 * // Textarea ¿¤¸®¸ÕÆ®¸¦ »ç¿ëÇÏ´Â °æ¿ì
 * var template1 = $Template("tpl1");
 *
 * // Script ¿¤¸®¸ÕÆ®¸¦ »ç¿ëÇÏ´Â °æ¿ì
 * var template2 = $Template("tpl2");
 * </script>
 */
jindo.$Template = function(str) {
    var obj = null, tag = "";
    var cl  = arguments.callee;

    if (str instanceof cl) return str;
    if (!(this instanceof cl)) return new cl(str);

    if(typeof str == "undefined") str = "";
    else if( (obj=document.getElementById(str)||str) && obj.tagName && (tag=obj.tagName.toUpperCase()) && (tag == "TEXTAREA" || (tag == "SCRIPT" && obj.getAttribute("type") == "text/template")) ) {
        str = (obj.value||obj.innerHTML).replace(/^\s+|\s+$/g,"");
    }

    this._str = str+"";
}
jindo.$Template.splitter = /(?!\\)[\{\}]/g;
jindo.$Template.pattern  = /^(?:if (.+)|elseif (.+)|for (?:(.+)\:)?(.+) in (.+)|(else)|\/(if|for)|=(.+)|js (.+)|set (.+))$/;

 /**
 * process ¸Þ¼­µå´Â ÅÛÇÃ¸´À» ÇØ¼®ÇÏ°í ÇØ¼®µÈ °á°ú ¹®ÀÚ¿­À» ¹ÝÈ¯ÇÑ´Ù.
 * @param {Object} data º¯¼ö ¹× ÇÔ¼ö µ¥ÀÌÅÍ
 * @return {String} ÇØ¼®À» ¸¶Ä£ »õ·Î¿î ¹®ÀÚ¿­
 * @example
 * // ´Ü¼ø ¹®ÀÚ¿­ Ä¡È¯
 * var tpl  = $Template("Value1 : {=val1}, Value2 : {=val2}")
 * var data = {val1:"first value", val2:"second value"};
 * document.write( tpl.process(data) );
 *
 * // °á°ú :
 * // Value1 : first value, Value2 : second value
 *
 * @example
 * // Á¶°Ç¹®
 * var tpl= $Template("{if num >= 7}7º¸´Ù Å©°Å³ª °°´Ù.{elseif num =< 5}5º¸´Ù ÀÛ°Å³ª °°´Ù.{else}¾Æ¸¶ 6?{/if}");
 * var data = { num:5 };
 * document.write( tpl.process(data) );
 *
 * // °á°ú :
 * 5º¸´Ù ÀÛ°Å³ª °°´Ù.
 *
 * @example
 * // ¹Ýº¹¹® - ÀÎµ¦½º »ç¿ë¾ÈÇÔ
 * var tpl  = $Template("<h1>Æ÷Å» »çÀÌÆ®</h1>\n<ul> {for site in potals}\n<li><a href="{=site.url}">{=site.name}</a></li>{/for} \n</ul>");
 * var data = {potals:[
 *		{ name : "³×ÀÌ¹ö", url : "http://www.naver.com"  },
 *		{ name : "´ÙÀ½",  url : "http://www.daum.net"  },
 *		{ name : "¾ßÈÄ",  url : "http://www.yahoo.co.kr"  }
 * ]};
 *
 * // °á°ú:
 * <h1>Æ÷Å» »çÀÌÆ® ¸ñ·Ï</h1> <ul> <li>³×ÀÌ¹ö</li><li>´ÙÀ½</li><li>¾ßÈÄ</li>
 * <ul>
 * <li><a href="http://www.naver.com">³×ÀÌ¹ö</a></li>
 * <li><a href="http://www.daum.net">´ÙÀ½</a></li>
 * <li><a href="http://www.yahoo.co.kr">¾ßÈÄ</a></li>
 * </ul>
 * 
 * @example
 * // ¹Ýº¹¹® - ÀÎµ¦½º »ç¿ë
 * var tpl  = $Template("{for num:word in numbers}{=word}({=num}) {/for}");
 * var data = { numbers : ["zero", "one", "two", "three"] };
 * document.write( tpl.process(data) );
 *
 * // °á°ú
 * zero(0) one(1) two(2) three(3) 
 * 
 * @example
 * // ÀÓ½Ãº¯¼ö»ç¿ë. 
 * var tpl  = $Template("{set val3=val1}Value1 : {=val1}, Value2 : {=val2}, Value3 : {=val3}")
 * var data = {val1:"first value", val2:"second value"};
 * document.write( tpl.process(data) );
 *
 * // °á°ú :
 * // Value1 : first value, Value2 : second value, Value3 : first value
 * 
 * @example
 * // javascript»ç¿ë. 
 * var tpl  = $Template("Value1 : {js $S(=val1).bytes()}, Value2 : {=val2}")
 * var data = {val1:"first value", val2:"second value"};
 * document.write( tpl.process(data) );
 *
 * // °á°ú :
 * // Value1 : 11, Value2 : second value
 */
jindo.$Template.prototype.process = function(data) {
	var key = "\x01";
	var leftBrace = "\x02";
	var rightBrace = "\x03";
    var tpl = (" "+this._str+" ").replace(/\\{/g,leftBrace).replace(/\\}/g,rightBrace).replace(/(?!\\)\}\{/g, "}"+key+"{").split(jindo.$Template.splitter), i = tpl.length;
	
    var map = {'"':'\\"','\\':'\\\\','\n':'\\n','\r':'\\r','\t':'\\t','\f':'\\f'};
    var reg = [/(["'](?:(?:\\.)+|[^\\["']+)*["']|[a-zA-Z_][\w\.]*)/g, /[\n\r\t\f"\\]/g, /^\s+/, /\s+$/, /#/g];
    var cb  = [function(m){ return (m.substring(0,1)=='"' || m.substring(0,1)=='\'')?m:"d."+m; }, function(m){return map[m]||m}, "", ""];
    var stm = [];
	var lev = 0;

	// remove " "
	tpl[0] = tpl[0].substr(1);
	tpl[i-1] = tpl[i-1].substr(0, tpl[i-1].length-1);

    // no pattern
    if(i<2) return tpl;

    while(i--) {
        if(i%2) {
            tpl[i] = tpl[i].replace(jindo.$Template.pattern, function(){
                var m = arguments;

				// set
				if (m[10]) {
					return m[10].replace(/(\w+)=(?:([a-zA-Z_][a-zA-Z0-9_]+)|(.+))$/g, function(){
										var mm = arguments;
										var str = "d."+mm[1]+"=";
										if(mm[2]) str+="d."+mm[2];										
										else str += mm[3].replace(   /(=(?:[a-zA-Z_][\w\.]*)+)/g,
                				                                           function(m){ return (m.substring(0,1)=='=')?"d."+m.replace('=','') : m; }
                                				                        );
										return str;
								}) +	";"; 
				}
				// js 
				if(m[9]) return 's[i++]=' + m[9].replace(   /(=(?:[a-zA-Z_][\w\.]*)+)/g,
                				                                           function(m){ return (m.substring(0,1)=='=')?"d."+m.replace('=','') : m; }
                                				                        )+';';
                // variables
                if(m[8]) return 's[i++]= d.'+m[8]+';';

                // if
                if(m[1]) {
                    return 'if('+m[1].replace(reg[0],cb[0]).replace(/d\.(typeof) /,'$1 ').replace(/ d\.(instanceof) d\./,' $1 ')+'){';
                }

                // else if
                if(m[2]) return '}else if('+m[2].replace(reg[0],cb[0]).replace(/d\.(typeof) /,'$1 ').replace(/ d\.(instanceof) d\./,' $1 ')+'){';

                // for loop
                if(m[5]) {
					return ('var t#=d.'+m[5]+'||{},p#=isArray(t#),i#=0;'+
							'for(var x# in t#){'+
							'	if( (p# && isNaN(i#=parseInt(x#))) || (!p# && !t#.propertyIsEnumerable(x#)) ) continue;'+
							'	d.'+m[4]+'=t#[x#];'+
							(m[3]?'d.'+m[3]+'=p#?i#:x#;':'')
						).replace(reg[4], lev++ );
                }

                // else
                if(m[6]) return '}else{';

                // end if, end for
                if(m[7]) {
                    return '};';
                }

                return m[0];
            });
        }else if(tpl[i] == key) {
			tpl[i] = "";
        }else if(tpl[i]){
            tpl[i] = 's[i++]="'+tpl[i].replace(reg[1],cb[1])+'";';
        }
    }
	
	tpl = tpl.join('').replace(new RegExp(leftBrace,'g'),"{").replace(new RegExp(rightBrace,'g'),"}");
		
    tpl = (new Function("d",''+
		'var s=[],i=0;'+
		'function isArray(o){ return Object.prototype.toString.call(o) == "[object Array]" };'+
		tpl+
		'return s.join("");'		
	))(data);
	
    return tpl;
};
/**
 * @fileOverview $DateÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name date.js
 */

/**
 * $Date °´Ã¼¸¦ »ý¼ºÇÏ°í ¸®ÅÏÇÑ´Ù.
 * @extends core
 * @class $Date Å¬·¡½º´Â ³¯Â¥¸¦ Ã³¸®ÇÏ±â À§ÇÑ Date Å¸ÀÔÀÇ ·¹ÆÛ(Wrapper) Å¬·¡½ºÀÌ´Ù. 
 * @constructor
 * @author Kim, Taegon
 * @example
$Date();
$Date(milliseconds);
$Date(dateString);
$Date(year, month, date[, hours, minitues, seconds, milliseconds]);
 */
jindo.$Date = function(src) {
	var a=arguments,t="";
	var cl=arguments.callee;

	if (src && src instanceof cl) return src;
	if (!(this instanceof cl)) return new cl(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);

	if ((t=typeof src) == "string") {
		this._date = cl.parse(src);
	} else if (t == "number") {
		if (typeof a[1] == "undefined") this._date = new Date(src);
		else this._date = new Date(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
	} else if (t == "object" && src.constructor == Date) {
		(this._date = new Date).setTime(src.getTime());
		this._date.setMilliseconds(src.getMilliseconds());
	} else {
		this._date = new Date;
	}
}

/**
 * names ¼Ó¼ºÀº $Date¿¡¼­ »ç¿ëÇÒ ´Þ, ¿äÀÏ, ¿ÀÀü/¿ÀÈÄÀÇ ÀÌ¸§À» ÀúÀåÇÑ ¹®ÀÚ¿­ÀÌ´Ù. s_ ¸¦ Á¢µÎ¾î·Î °¡Áö´Â ÀÌ¸§µéÀº ¾à¾î(abbreviation)ÀÌ´Ù.
 */
jindo.$Date.names = {
	month   : ["January","Febrary","March","April","May","June","July","August","September","October","Novermber","December"],
	s_month : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
	day     : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
	s_day   : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
	ampm    : ["AM", "PM"]
};

/**
 * now ¸Þ¼­µå´Â ÇöÀç ½Ã°£À» ¹Ð¸®ÃÊ ´ÜÀ§ÀÇ Á¤¼ö·Î ¸®ÅÏÇÑ´Ù.
 * @return {Number} ¹Ð¸®ÃÊ ´ÜÀ§ÀÇ Á¤¼öÀÎ ÇöÀç ½Ã°£
 */
jindo.$Date.now = function() {
	return Date.now();
};

/**
 * parse ¸Þ¼­µå´Â ÀÎ¼ö·Î ÁöÁ¤ÇÑ ¹®ÀÚ¿­À» ÆÄ½ÌÇÏ¿© ¹®ÀÚ¿­ÀÇ Çü½Ä¿¡ ¸Â´Â Date °´Ã¼¸¦ »ý¼ºÇÑ´Ù. 
 * @param {String} strDate ³¯Â¥, È¤Àº ½Ã°£ Çü½ÄÀ» ÁöÁ¤ÇÑ ÆÄ½Ì ´ë»ó ¹®ÀÚ¿­
 * @return {Object} Date °´Ã¼. 
 */
jindo.$Date.parse = function(strDate) {
	return new Date(Date.parse(strDate));
};

/**
 * $value ¸Þ¼­µå´Â $Date°¡ °¨½Î°í ÀÖ´ø ¿øº» Date °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @returns {Object} Date °´Ã¼
 */
jindo.$Date.prototype.$value = function(){
	return this._date;
};

/**
 * format ¸Þ¼­µå´Â $Date °´Ã¼°¡ ÀúÀåÇÏ°í ÀÖ´Â ½Ã°£À» ÀÎ¼ö·Î ÁöÁ¤ÇÑ Çü½Ä ¹®ÀÚ¿­¿¡ ¸ÂÃß¾î º¯È¯ÇÑ´Ù. Çü½Ä ¹®ÀÚ¿­Àº PHPÀÇ date ÇÔ¼ö¿Í µ¿ÀÏÇÏ°Ô »ç¿ëÇÑ´Ù. ??
 * @param {Date} strFormat  Çü½Ä ¹®ÀÚ¿­
 * @returns {String} ½Ã°£À» Çü½Ä ¹®ÀÚ¿­¿¡ ¸ÂÃß¾î º¯È¯ÇÑ ¹®ÀÚ¿­.
 */
jindo.$Date.prototype.format = function(strFormat){
	var o = {};
	var d = this._date;
	
	return (strFormat||"").replace(/[a-z]/ig, function callback(m){
		if (typeof o[m] != "undefined") return o[m];

		switch(m) {
			case"d":
			case"j":
				o.j = d.getDate();
				o.d = (o.j>9?"":"0")+o.j;
				return o[m];
			case"l":
			case"D":
			case"w":
			case"N":
				o.w = d.getDay();
				o.N = o.w?o.w:7;
				o.D = jindo.$Date.names.s_day[o.w];
				o.l = jindo.$Date.names.day[o.w];
				return o[m];
			case"S":
				return (!!(o.S=["st","nd","rd"][d.getDate()]))?o.S:(o.S="th");
			case"z":
				o.z = Math.floor((d.getTime() - (new Date(d.getFullYear(),0,1)).getTime())/(3600*24*1000));
				return o.z;
			case"m":
			case"n":
				o.n = d.getMonth()+1;
				o.m = (o.n>9?"":"0")+o.n;
				return o[m];
			case"L":
				o.L = this.isLeapYear();
				return o.L;
			case"o":
			case"Y":
			case"y":
				o.o = o.Y = d.getFullYear();
				o.y = (o.o+"").substr(2);
				return o[m];
			case"a":
			case"A":
			case"g":
			case"G":
			case"h":
			case"H":
				o.G = d.getHours();
				o.g = (o.g=o.G%12)?o.g:12;
				o.A = o.G<12?jindo.$Date.names.ampm[0]:jindo.$Date.names.ampm[1];
				o.a = o.A.toLowerCase();
				o.H = (o.G>9?"":"0")+o.G;
				o.h = (o.g>9?"":"0")+o.g;
				return o[m];
			case"i":
				o.i = (((o.i=d.getMinutes())>9)?"":"0")+o.i;
				return o.i;
			case"s":
				o.s = (((o.s=d.getSeconds())>9)?"":"0")+o.s;
				return o.s;
			case"u":
				o.u = d.getMilliseconds();
				return o.u;
			case"U":
				o.U = this.time();
				return o.U;
			default:
				return m;
		}
	});
};

/**
 * time ¸Þ¼­µå´Â GMT 1970/01/01 00:00:00À» ±âÁØÀ¸·Î °æ°úÇÑ ½Ã°£À» ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nTime ¹Ð¸® ÃÊ ´ÜÀ§ÀÇ ½Ã°£ °ª. 
 * @return {$Date | Number} ÀÎ¼ö¸¦ ÁöÁ¤Çß´Ù¸é GMT 1970/01/01 00:00:00 ¿¡¼­ ºÎÅÍ ÀÎ¼ö¸¸Å­ Áö³­ ½Ã°£À» ¼³Á¤ÇÑ $DAte °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é GMT 1970/01/01 00:00:00¿¡¼­ ºÎÅÍ $Date °´Ã¼¿¡ ÁöÁ¤µÈ ½Ã°¢±îÁö °æ°úÇÑ ½Ã°£(¹Ð¸® ÃÊ).
 */
jindo.$Date.prototype.time = function(nTime) {
	if (typeof nTime == "number") {
		this._date.setTime(nTime);
		return this;
	}

	return this._date.getTime();
};

/**
 * year ¸Þ¼­µå´Â ³âµµ¸¦ ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nYear ¼³Á¤ÇÒ ³âµµ°ª
 * @return {$Date | Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ³âµµ °ªÀ» ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ³âµµ¸¦ ¸®ÅÏÇÑ´Ù.
 */
jindo.$Date.prototype.year = function(nYear) {
	if (typeof nYear == "number") {
		this._date.setFullYear(nYear);
		return this;
	}

	return this._date.getFullYear();
};

/**
 * month ¸Þ¼­µå´Â ´ÞÀ» ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nMon ¼³Á¤ÇÒ ´ÞÀÇ °ª
 * @return {$Date | Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ´ÞÀ» ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ´ÞÀ» ¸®ÅÏÇÑ´Ù.
 * @remark ¸®ÅÏ °ªÀÇ ¹üÀ§´Â 0(1¿ù)¿¡¼­ 11(12¿ù)ÀÌ´Ù.
 */
jindo.$Date.prototype.month = function(nMon) {
	if (typeof nMon == "number") {
		this._date.setMonth(nMon);
		return this;
	}

	return this._date.getMonth();
};

/**
 * date ¸Þ¼­µå´Â ³¯Â¥¸¦ ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {nDate} nDate	¼³Á¤ÇÒ ³¯Â¥ °ª
 * @return {$Date | Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ³¯Â¥¸¦ ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ³¯Â¥¸¦ ¸®ÅÏÇÑ´Ù.
 */
jindo.$Date.prototype.date = function(nDate) {
	if (typeof nDate == "number") {
		this._date.setDate(nDate);
		return this;
	}

	return this._date.getDate();
};

/**
 * day ¸Þ¼­µå´Â ¿äÀÏÀ» °¡Á®¿Â´Ù. 
 * @return {Number} ¿äÀÏ °ª. 0(ÀÏ¿äÀÏ)¿¡¼­ 6(Åä¿äÀÏ)À» ¸®ÅÏÇÑ´Ù. 
 */
jindo.$Date.prototype.day = function() {
	return this._date.getDay();
};

/**
 * hours ¸Þ¼­µå´Â ½Ã(ãÁ)¸¦ ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nHour ¼³Á¤ÇÒ ½Ã °ª
 * @return {$Date | Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ½Ã °ªÀ» ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ½Ã °ª.
 */
jindo.$Date.prototype.hours = function(nHour) {
	if (typeof nHour == "number") {
		this._date.setHours(nHour);
		return this;
	}

	return this._date.getHours();
};

/**
 * seconds ¸Þ¼­µå´Â ÃÊÀ» ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nSec ¼³Á¤ÇÒ ÃÊ °ª
 * @return {Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ÃÊ °ªÀ» ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ÃÊ °ª.
 */
jindo.$Date.prototype.seconds = function(nSec) {
	if (typeof nSec == "number") {
		this._date.setSeconds(nSec);
		return this;
	}

	return this._date.getSeconds();
};

/**
 * minutes ¸Þ¼­µå´Â ºÐÀ» ¼³Á¤ÇÏ°Å³ª °¡Á®¿Â´Ù.
 * @param {Number} nMin ¼³Á¤ÇÒ ºÐ °ª
 * @return {Number} ÀÎ¼ö¸¦ ÁöÁ¤ÇÏ¿´´Ù¸é »õ·Î ºÐ °ªÀ» ¼³Á¤ÇÑ $Date °´Ã¼. ÀÎ¼ö¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é $Date °´Ã¼°¡ ÁöÁ¤ÇÏ°í ÀÖ´Â ½Ã°¢ÀÇ ºÐ °ª.
 */
jindo.$Date.prototype.minutes = function(nMin) {
	if (typeof nMin == "number") {
		this._date.setMinutes(nMin);
		return this;
	}

	return this._date.getMinutes();
};

/**
 * isLeapYear ¸Þ¼­µå´Â ½Ã°¢ÀÇ À±³â ¿©ºÎ¸¦ È®ÀÎÇÑ´Ù.
 * @returns {Boolean} $Date°¡ °¡¸®Å°°í ÀÖ´Â ½Ã°¢ÀÌ À±³âÀÌ¸é True, ±×·¸Áö ¾Ê´Ù¸é False
 */
jindo.$Date.prototype.isLeapYear = function() {
	var y = this._date.getFullYear();

	return !(y%4)&&!!(y%100)||!(y%400);
};
/**
 * @fileOverView $WindowÀÇ »ý¼ºÀÚ ¹× ¸Þ¼­µå¸¦ Á¤ÀÇÇÑ ÆÄÀÏ
 * @name window.js
 */

/**
 * $Window °´Ã¼¸¦ »ý¼ºÇÏ°í »ý¼ºÇÑ °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @class $Window °´Ã¼´Â ÀÚ¹Ù½ºÅ©¸³Æ® ³×ÀÌÆ¼ºê °´Ã¼ÀÎ window °´Ã¼¸¦ ·¡ÇÎÇÏ°í, ÀÌ¸¦ ´Ù·ç±â À§ÇÑ ¿©·¯°¡Áö ¸Þ¼­µå¸¦ Á¦°øÇÑ´Ù.
 * @param {HTMLWidnow} el $Window·Î °¨½Ò window ¿¤¸®¸ÕÆ®.
 * @author gony
 */
jindo.$Window = function(el) {
	var cl = arguments.callee;
	if (el instanceof cl) return el;
	if (!(this instanceof cl)) return new cl(el);

	this._win = el || window;
}

/**
 * $value ¸Þ¼­µå´Â $Window °´Ã¼·Î °¨½Ñ ¿ø·¡ÀÇ window °´Ã¼¸¦ ¹ÝÈ¯ÇÑ´Ù.
 * @return {HTMLWindow} window ¿¤¸®¸ÕÆ®
 */
jindo.$Window.prototype.$value = function() {
	return this._win;
};

/**
 * resizeTo ¸Þ¼­µå´Â window °´Ã¼ÀÇ Å©±â¸¦ ÁÖ¾îÁø Å©±â·Î º¯°æÇÑ´Ù.
 * ÀÌ Å©±â´Â ÇÁ·¹ÀÓÀ» Æ÷ÇÔÇÑ Ã¢ ÀüÃ¼ÀÇ Å©±â¸¦ ³ªÅ¸³»¹Ç·Î ½ÇÁ¦·Î Ç¥ÇöÇÏ´Â ÄÁÅÙÆ® »çÀÌÁî´Â
 * ºê¶ó¿ìÀú Á¾·ù¿Í ¼³Á¤¿¡ µû¶ó ´Þ¶óÁú ¼ö ÀÖ´Ù.
 * @remark ºê¶ó¿ìÀú¿¡ µû¶ó º¸¾È ¹®Á¦ ¶§¹®¿¡, Ã¢ Å©±â°¡ È­¸éÀÇ °¡½Ã ¿µ¿ªÀ» ¹þ¾î³ª¼­ Ä¿ÁöÁö ¸øÇÏµµ·Ï ¸·´Â °æ¿ìµµ ÀÖ´Ù. ÀÌ °æ¿ì¿¡´Â ÁöÁ¤ÇÑ Å©±âº¸´Ù ÀÛ°Ô Ã¢ÀÌ Ä¿Áø´Ù.
 * @param {Number} nWidth Ã¢ÀÇ ³Êºñ
 * @param {Number} nHeight Ã¢ÀÇ ³ôÀÌ
 * @return {$Window} Ã¢ Å©±â°¡ º¯°æµÈ $Window °´Ã¼ this
 * @see $Window#resizeBy
 * @example
 * 	// ÇöÀç Ã¢ÀÇ ³Êºñ¸¦ 400, ³ôÀÌ¸¦ 300À¸·Î º¯°æÇÑ´Ù.
 *  $Window.resizeTo(400, 300);
 */
jindo.$Window.prototype.resizeTo = function(nWidth, nHeight) {
	this._win.resizeTo(nWidth, nHeight);
	return this;
};

/**
 * resizeBy ¸Þ¼­µå´Â window °´Ã¼ÀÇ Å©±â¸¦ ÁÖ¾îÁø Å©±â¸¸Å­ º¯°æÇÑ´Ù.
 * @param {Number} nWidth ´Ã¾î³¯ Ã¢ÀÇ ³Êºñ
 * @param {Number} nHeight ´Ã¾î³¯ Ã¢ÀÇ ³ôÀÌ
 * @see $Window#resizeTo
 * @example
 *   // ÇöÀç Ã¢ÀÇ ³Êºñ¸¦ 100, ³ôÀÌ¸¦ 50 ¸¸Å­ ´Ã¸°´Ù.
 *   $Window().resize(100, 50);
 */
jindo.$Window.prototype.resizeBy = function(nWidth, nHeight) {
	this._win.resizeBy(nWidth, nHeight);
	return this;
};

/**
 * moveTo ¸Þ¼­µå´Â Ã¢À» ÁÖ¾îÁø À§Ä¡·Î ÀÌµ¿½ÃÅ²´Ù. ÁÂÇ¥´Â ÇÁ·¹ÀÓÀ» Æ÷ÇÔ À©µµ¿ìÀÇ ÁÂÃø »ó´ÜÀ» ±âÁØÀ¸·Î ÇÑ´Ù.
 * @param {Number} nLeft ÀÌµ¿ÇÒ xÁÂÇ¥ (pixel ´ÜÀ§)
 * @param {Number} nTop ÀÌµ¿ÇÒ yÁÂÇ¥ (pixel ´ÜÀ§)
 * @see $Window#moveBy
 * @example
 *  // ÇöÀç Ã¢À» (15, 10) À¸·Î ÀÌµ¿½ÃÅ²´Ù.
 *  $Window().moveTo(15, 10);
 */
jindo.$Window.prototype.moveTo = function(nLeft, nTop) {
	this._win.moveTo(nLeft, nTop);
	return this;
};

/**
 * moveTo ¸Þ¼­µå´Â Ã¢À» ÁÖ¾îÁø À§Ä¡¸¸Å­ ÀÌµ¿½ÃÅ²´Ù.
 * @param {Number} nLeft xÁÂÇ¥·Î ÀÌµ¿ÇÒ ¾ç (pixel ´ÜÀ§)
 * @param {Number} nTop yÁÂÇ¥ ÀÌµ¿ÇÒ ¾ç (pixel ´ÜÀ§)
 * @see $Window#moveTo
 * @example
 *  // ÇöÀç Ã¢À» ÁÂÃøÀ¸·Î 15px, ¾Æ·¡·Î 10px¸¸Å­ ÀÌµ¿½ÃÅ²´Ù.
 *  $Window().moveBy(15, 10);
 */
 jindo.$Window.prototype.moveBy = function(nLeft, nTop) {
	this._win.moveBy(nLeft, nTop);
	return this;
};

/**
 * sizeToContent ¸Þ¼­µå´Â ³»ºÎ ¹®¼­ Å©±â¿¡ ¸ÂÃß¾î °´Ã¼ÀÇ Å©±â¸¦ º¯°æÇÑ´Ù.
 * @remark ¸Þ¼­µåÀÇ Æ¯¼º»ó ³»ºÎ ¹®¼­°¡ ¿ÏÀüÈ÷ ·ÎµùµÈ ´ÙÀ½¿¡ ½ÇÇàµÇ¾î¾ß ÇÑ´Ù. ¶ÇÇÑ, Ã¢ÀÌ ³»ºÎ ¹®¼­º¸´Ù Å« °æ¿ì¿¡´Â ³»ºÎ ¹®¼­¸¦ ±¸ÇÒ ¼ö ¾øÀ¸¹Ç·Î, ¹Ýµå½Ã Ã¢ Å©±â¸¦ ³»ºÎ ¹®¼­º¸´Ù ÀÛ°Ô ¸¸µç´Ù.
 * @example
 * // »õ Ã¢À» ¶ç¿ì°í ÀÚµ¿À¸·Î Ã¢ Å©±â¸¦ ÄÁÅÙÆ®¿¡ ¸Â°Ô º¯°æÇÏ´Â ÇÔ¼ö
 * function winopen(url) {	
 *		try {
 *			win = window.open(url, "", "toolbar=0,location=0,status=0,menubar=0,scrollbars=0,resizable=0,width=250,height=300");
 *			win.moveTo(200, 100);
 *			win.focus();
 *		} catch(e){}
 *
 *		setTimeout(function() {
 *			$Window(win).sizeToContent();
 *		}, 1000);
 *		
 *	}
 *
 * winopen('/samples/popup.html');
 */
jindo.$Window.prototype.sizeToContent = function() {
	if (typeof this._win.sizeToContent == "function") {
		this._win.sizeToContent();
	} else {
		var doc = jindo.$Document(this._win.document);
		var clientSize = doc.clientSize();
		var scrollSize = doc.scrollSize();

		this.resizeBy(scrollSize.width - clientSize.width, scrollSize.height - clientSize.height);
	}

	return this;
};
/**
 * @fileOverview	´Ù¸¥ ÇÁ·¹ÀÓ¿÷ ¾øÀÌ jindo¸¸ »ç¿ëÇÒ °æ¿ì ÆíÀÇ¼ºÀ» À§ÇØ jindo °´Ã¼¸¦ window¿¡ ºÙÀÓ
 */
// copy jindo objects to window
if (typeof window != "undefined") {
	for (prop in jindo) window[prop] = jindo[prop];
}

