/* -------------------------------------------------------------------------- */
/**
 *    @fileoverview
 *       bAJL base script.
 *
 *    @version 2.4.20100506
 *    @requires jquery.js
 *
 *    update BAJL.StyleSheets.Wrapper.prototype.insertRule from version 2.9.20111102
 */
/* -------------------------------------------------------------------------- */
(function($) {



// speed-up reference to 'window' object
var window = this;

// supplements 'undefined'
window.undefined = window.undefined;

// set default easing method
$.easing.def = 'easeOutCubic';



/* =============== create BAJL global object and prepartions =============== */
/**
 * BAJL global object.
 * @name BAJL
 * @namespace BAJL global object
 */
window.BAJL = $.extend(window.BAJL, new (function() {
	var d  = document;
	var de = d.documentElement;
	var di = d.implementation;
	var ua = navigator.userAgent;
	
	/**
	 * default setting values of BAJL function/classes
	 * @name BAJL.settings
	 * @namespace default setting values of BAJL function/classes
	 * @property {Object}  common                  common settings
	 * @property {Boolean} common.useBackCompat    use backword compatible mode
	 * @property {Boolean} common.showGeometry     show geometry values in browser's status bar
	 */
	this.settings        = {};
	this.settings.common = { useBackCompat : false, showGeometry : false };
	
	/**
	 * identifier urls of frequently used XML-Namespaces.
	 * @name BAJL.ns
	 * @namespace identifier urls of frequently used XML-Namespaces
	 * @property {String} defaultNS    current default namespace of the docuemnt elmeent
	 * @property {String} xhtml1       XHTML1 namespace
	 * @property {String} xhtml2       XHTML2 namespace
	 * @property {String} bajl         BAJL namespace
	 */
	this.ns              = {};
	this.ns.defaultNS    = (!de) ? '' : de.namespaceURI || de.tagUrn || '';
	this.ns.xhtml1       = 'http://www.w3.org/1999/xhtml';
	this.ns.xhtml2       = 'http://www.w3.org/2002/06/xhtml2';
	this.ns.bajl         = 'http://www.b-architects.com/';
	
	/**
	 * browser distinction results.
	 * @name BAJL.ua
	 * @namespace browser distinction results.
	 * @property {String}  versionText     string form of the browser version number (ex: "1.9.0.2", "528.18.1", "7.0")
	 * @property {Number}  version         float number of the browser version (ex: 1.9, 528.18, 7.0)
	 * @property {Boolean} isGecko         true if the browser is Gecko-based.
	 * @property {Boolean} isSafari        true if the browser is AppleWebKit-based
	 * @property {Boolean} isOpera         true if the browser is Opera
	 * @property {Boolean} isIE            true if the browser is IE-based
	 * @property {Boolean} isWin           true if the browser runs in Windows
	 * @property {Boolean} isMac           true if the browser runs in MacOS(X)
	 * @property {Boolean} isQuirksMode    true if the browser runs under 'quirks mode'
	 * @property {Number}  documentMode    number of documentMode; this avaiable in IE, the value is 0 in other browsers.
	 * @property {Boolean} isDOMReady      true if the browser had DOM feature.
	 */
	this.ua              = {};
	this.ua.versionText  = $.browser.version;
	this.ua.version      = parseFloat($.browser.version);
	this.ua.isGecko      = $.browser.mozilla;
	this.ua.isSafari     = $.browser.safari;
	this.ua.isOpera      = $.browser.opera;
	this.ua.isIE         = $.browser.msie;
	this.ua.isWin        = /Win/.test(ua);
	this.ua.isMac        = /Mac/.test(ua);
	this.ua.isQuirksMode = (d.compatMode == 'BackCompat' || this.ua.isIE && this.ua.version < 6);
	this.ua.documentMode = (!this.ua.isIE        ) ? 0               :
	                       (d.documentMode       ) ? d.documentMode  :
	                       (!this.ua.isQuirksMode) ? this.ua.version :
	                                                 5               ;
	this.ua.isDOMReady   = (di) ? di.hasFeature('HTML', '1.0') : (this.ua.isIE && de)

	/**
	 * geometry properties object; the property values are updated when {@link BAJL.GetGeometry} is called.
	 * @name BAJL.geom
	 * @namespace geometry properties object; return value of {@link BAJL.GetGeometry}
	 * @property {Number} windowW      width of the window viewport.
	 * @property {Number} windowH      height of the window viewport.
	 * @property {Number} pageW        width of the document.
	 * @property {Number} pageH        height of the document.
	 * @property {Number} scrollX      scrollLeft position of the document.
	 * @property {Number} scrollY      scrollTop position of the document.
	 * @property {Number} windowX      mouse position on X-axis (the origin is top left of the window viewport)
	 * @property {Number} windowY      mouse position on Y-axis (the origin is topleft of the window viewport)
	 * @property {Number} pageX        mouse position on X-axis (the origin is topleft of the document)
	 * @property {Number} pageY        mouse position on Y-axis (the origin is topleft of the document)
	 * @property {Number} zoom         window zoom ratio (in WinIE7).
	 * @property {Number} scrollBar    browser's scrollbar width.
	 */
	this.geom            = {};

	/**
	 * misc environment values.
	 * @name BAJL.env
	 * @namespace misc environment values.
	 * @property {Boolean} isOnline      true if the browser is online.
	 * @property {Boolean} isDOMReady    true if the document is ready for DOM manipulation
	 */
	this.env             = {};
	this.env.isOnline    = /^https?\:$/.test(location.protocol);
	this.env.isDOMReady  = false;
}));

// 'Node.XXXX_NODE' constants for IE
if (typeof window.Node == 'undefined') {
	window.Node = {
		  ELEMENT_NODE                : 1
		, ATTRIBUTE_NODE              : 2
		, TEXT_NODE                   : 3
		, CDATA_SECTION_NODE          : 4
		, ENTITY_REFERENCE_NODE       : 5
		, ENTITY_NODE                 : 6
		, PROCESSING_INSTRUCTION_NODE : 7
		, COMMENT_NODE                : 8
		, DOCUMENT_NODE               : 9
		, DOCUMENT_TYPE_NODE          : 10
		, DOCUMENT_FRAGMENT_NODE      : 11
		, NOTATION_NODE               : 12
	};
}

// dummy object of window.console (Firbug etc)
if (typeof window.console != 'object') {
	window.console = {
		  element           : null
		, firebug           : "0"
		, userObjects       : {}
		, assert            : function(){}
		, clear             : function(){}
		, count             : function(){}
		, debug             : function(){}
		, dir               : function(){}
		, dirxml            : function(){}
		, error             : function(){}
		, getFirebugElement : function(){}
		, group             : function(){}
		, groupCollapsed    : function(){}
		, groupEnd          : function(){}
		, log               : function(){}
		, notifyFirebug     : function(){}
		, profile           : function(){}
		, profileEnd        : function(){}
		, time              : function(){}
		, timeEnd           : function(){}
		, trace             : function(){}
		, warn              : function(){}
	};
}



/* =============== regester onload func =============== */

(function() {
	// prevent background image flicker.
	if (BAJL.ua.isIE) try { document.execCommand('BackgroundImageCache', false, true) } catch(err) { }

	$(function() {
		BAJL.env.isDOMReady = true;
		new BAJL.Timeout(function() {
			$(document.body).addClass('bajl-enabled');
			if (BAJL.settings.common.useBackCompat) $(document.body).addClass('dom-enabled');
			if (BAJL.settings.common.showGeometry ) BAJL.GetGeometry.continuously();
		}, 1);  // workaround for IE to avoid speed down
	});
})();



/* =============== custom / shortage methods for built-in objects =============== */

/* ----- Array.indexOf() ----- */

if (!Array.prototype.indexOf) {
	/**
	 * returns the first index of an element within the array equal to the specified value, or -1 if none is found.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Object} aSearchElement    the item to search
	 * @param {Number} [aFromIndex]      index number to start searching
	 * @return index number
	 * @type Number
	 */
	Array.prototype.indexOf = function(aSearchElement, aFromIndex) {
		if (typeof aFromIndex != 'number') {
			aFromIndex = 0;
		} else if (aFromIndex < 0) {
			aFromIndex = this.length + aFromIndex;
		}
		for (var i = aFromIndex, n = this.length; i < n; i++) {
			if (this[i] === aSearchElement) {
				return i;
			}
		}
		return -1;
	}
}

/* ----- Array.lastIndexOf() ----- */

if (!Array.prototype.lastIndexOf) {
	/**
	 * returns the last index of an element within the array equal to the specified value, or -1 if none is found.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Object} aSearchElement    the item to search
	 * @param {Number} [aFromIndex]      index number to start searching
	 * @return index number
	 * @type Number
	 */
	Array.prototype.lastIndexOf = function(aSearchElement, aFromIndex) {
		if (typeof aFromIndex != 'number') {
			aFromIndex = this.length - 1;
		} else if (aFromIndex < 0) {
			aFromIndex = this.length + aFromIndex;
		}
		for (var i = aFromIndex; i >= 0; i--) {
			if (this[i] === aSearchElement) {
				return i;
			}
		}
		return -1;
	}
}

/* ----- Array.forEach() ----- */

if (!Array.prototype.forEach) {
	/**
	 * calls a function for each element in the array.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Array.callback.iterate} aCallback        the function to exec for every element
	 * @param {Object}                 [aThisObject]    the object that will be a global object ('this') in aCallback func.
	 */
	Array.prototype.forEach = function(aCallback, aThisObject) {
		for (var i = 0, n = this.length; i < n; i++) {
			aCallback.call(aThisObject, this[i], i, this);
		}
	}
}

/* ----- Array.map() ----- */

if (!Array.prototype.map) {
	/**
	 * creates a new array with the results of calling a provided function on every element in this array.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Array.callback.iterate} aCallback        the function to exec for every element
	 * @param {Object}                 [aThisObject]    the object that will be a global object ('this') in aCallback func.
	 * @return array that consisted of returned values.
	 * @type Array
	 */
	Array.prototype.map = function(aCallback, aThisObject) {
		var ret = [];
		for (var i = 0, n = this.length; i < n; i++) {
			ret.push(aCallback.call(aThisObject, this[i], i, this));
		}
		return ret;
	}
}

/* ----- Array.filter() ----- */

if (!Array.prototype.filter) {
	/**
	 * creates a new array with all of the elements of this array for which the provided filtering function returns true. 
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Array.callback.test} aCallback        the function to test all elements
	 * @param {Object}              [aThisObject]    the object that will be a global object ('this') in aCallback func.
	 * @return array that consisted of only adapted elements.
	 * @type Array
	 */
	Array.prototype.filter = function(aCallback, aThisObject) {
		var ret = [];
		for (var i = 0, n = this.length; i < n; i++) {
			if (aCallback.call(aThisObject, this[i], i, this)) {
				ret.push(this[i]);
			}
		}
		return ret;
	}
}

/* ----- Array.some() ----- */

if (!Array.prototype.some) {
	/**
	 * returns true if at least one element in this array satisfies the provided testing function.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Array.callback.test} aCallback        the function to test condition of the elements
	 * @param {Object}              [aThisObject]    the object that will be a global object ('this') in aCallback func.
	 * @return did some elements satisfy the condition?
	 * @type Boolean
	 */
	Array.prototype.some = function(aCallback, aThisObject){
		for (var i = 0, n = this.length; i < n; i++) {
			if (aCallback.call(aThisObject, this[i], i, this)) return true;
		}
		return false;
	}
}

/* ----- Array.every() ----- */

if (!Array.prototype.every) {
	/**
	 * returns true if every element in this array satisfies the provided testing function.
	 * (implement emulation of the method defined in JavaScript1.6)
	 * @param {Array.callback.test} aCallback        the function to test condition of the elements
	 * @param {Object}              [aThisObject]    the object that will be a global object ('this') in aCallback func.
	 * @return did all elements satisfy the condition?
	 * @type Boolean
	 */
	Array.prototype.every = function(aCallback, aThisObject){
		for (var i = 0, n = this.length; i < n; i++) {
			if(!aCallback.call(aThisObject, this[i], i, this)) return false;
		}
		return true;
	}
}

/* ----- for JSDoc toolkit output ----- */
/**
 * higher-order functions for member methods of {@link Array}
 * @name Array.callback
 * @namespace higher-order functions for member methods of {@link Array}
 */
/**
 * higher-order function for {@link Array#forEach}, {@link Array#map}
 * @function
 * @name Array.callback.iterate
 * @param {Object} anElement    current processing element of the Array.
 * @param {Number} anIndex      current processing index-num of the Array.
 * @param {Array}  anArray      the Array itself.
 * @returns processing result value (any type) of this function
 * @type Object
 */
/**
 * higher-order function for {@link Array#filter}, {@link Array#some}, {@link Array#every}
 * @function
 * @name Array.callback.test
 * @param {Object} anElement    current processing element of the Array.
 * @param {Number} anIndex      current processing index-num of the Array.
 * @param {Array}  anArray      the Array itself.
 * @returns processing result value (boolean) of this function
 * @type Boolean
 */






/* ============================== BAJL build-in object wrapper classes ============================== */

/* --------------- Class : BAJL.Number --------------- */
/**
 * get number manipulator {@link BAJL.Number.Wrapper}.
 * @namespace number manipulator
 * @param {Number} [value]    number to manipulate.
 * @return BAJL.Number.Wrapper instance
 * @type BAJL.Number.Wrapper
 */
BAJL.Number = function(value) {
	return new BAJL.Number.Wrapper(value);
}

/* ----- Class : BAJL.Number.Wrapper ----- */
/**
 * number manipulator; the instance is available as return value of {@link BAJL.Number}
 * @class number manipulator.
 * @param {Number} [value=0]    number to manipulate.
 * @constructor
 * @see BAJL.Number
 */
BAJL.Number.Wrapper = function(value) {
	/** stored number to manipulate
	    @type Number
	    @private */
	this.value = Number(value) || 0;
}

/**
 * get current number as string
 * @returns get current number as string
 * @type String
 */
BAJL.Number.Wrapper.prototype.toString = function() {
	return String(this.value);
}

/**
 * get current number
 * @returns get current number
 * @type Number
 */
BAJL.Number.Wrapper.prototype.get = function() {
	return this.value;
}

/**
 * simple number formatter.
 * @param {String} format     fomatter string
 * @return string manipulator instance contains result string of this method
 * @type BAJL.String.fn
 * @example
 *  BAJL.Number(     '56'   ).format(      '000'    ).get() ->        '056'
 *  BAJL.Number( '123456'   ).format(      '###'    ).get() ->        '456'
 *  BAJL.Number( '123456.78').format('#,###,###'    ).get() ->    '123,457'
 *  BAJL.Number( '123456.78').format('#,###,###.#'  ).get() ->    '123,456.8'
 *  BAJL.Number('-123456.78').format('0,###,###.000').get() -> '-0,123,456.780'
 */
BAJL.Number.Wrapper.prototype.format = function(format) {
	if (!format || typeof format != 'string') {
		throw new TypeError('BAJL.Number.Wrapper.format: first argument must be a formatting string.');
	} else {
		var ret       = [];
		var num       = parseFloat(this.value) || 0;
		var intFormat = format.split('.')[0].split('');
		var decFormat = format.split('.')[1] || '';
		var value     = (decFormat) ? Math.abs(num) : Math.round(Math.abs(num));
		var sign      = (num < 0) ? '-' : '';
		var intValue  = value.toString().split('.')[0].split('');
		do {
			var _value  = intValue .pop() || '';
			var _format = intFormat.pop() || '';
			switch (_format) {
				case '0' : ret.push(_value  ? _value : '0');                        break;
				case '#' : ret.push(_value  ? _value : '' );                        break;
				case ''  : /* exit do-while loop */          intValue = [];         break;
				default  : ret.push(_format               ); intValue.push(_value); break;
			}
		} while (intValue.length > 0 || intFormat.length > 0);
		ret = ret.reverse().join('').replace(/^\D+/, '');
		if (decFormat) {
			var scale     = Math.pow(10, decFormat.length);
			var rounded   = Math.round(value * scale) / scale;
			if (rounded - ret == 1) {
				ret++;
			}
			var decValue  = rounded.toString().split('.')[1] || '0';
			    decValue  = decValue .split('').reverse().join('');
			    decFormat = decFormat.split('').reverse().join('');
			    ret       = ret + '.' + BAJL.Number(decValue).format(decFormat).split('').reverse().join('');
		}
		if (BAJL.String(decFormat).startsWith('#') && BAJL.String(ret).endsWith('.0')) {
			ret = BAJL.String(ret).getBefore('.0');
		}
		return BAJL.String(sign + ret);
	}
}



/* --------------- Class : BAJL.String --------------- */
/**
 * get string manipulator {@link BAJL.String.Wrapper}.
 * @namespace string manipulator
 * @param {String} [value]    string to manipulate.
 * @returns BAJL.String.Wrapper instance
 * @type BAJL.String.Wrapper
 */
BAJL.String = function(value) {
	return new BAJL.String.Wrapper(value);
}

/* ----- Class : BAJL.String.Wrapper ----- */
/**
 * creates string manipulator; the instance is available as return value of {@link BAJL.String}
 * @class string manipulator.
 * @param {String} [value='']    string to manipulate.
 * @constructor
 * @see BAJL.String
 */
BAJL.String.Wrapper = function(value) {
	/** stored string to manipulate
	    @type String
	    @private */
	this.value  = String(value === undefined ? '' : value);
	/** string length
	    @type Number */
	this.length = this.value.length;
}

/**
 * get current string
 * @returns current string
 * @type String
 */
BAJL.String.Wrapper.prototype.toString = function() {
	return this.value;
}

/**
 * get current string
 * @returns current string
 * @type String
 * @function
 */
BAJL.String.Wrapper.prototype.get = BAJL.String.Wrapper.prototype.toString

/**
 * simple text formatter. (super tiny!)
 * @param {String|String[]|Object}  arg1     a string, an array, or an associative array.
 * @param {String}                 [argN]    a string
 * @return this instance itself
 * @type BAJL.String.Wrapper
 * @example
 *  BAJL.String('${0}HOGE${1}FUGA${2}').format(    'xxx', '  yyy',   'zzz'  ).get()
 *  BAJL.String('${0}HOGE${1}FUGA${2}').format([   'xxx',   'yyy',   'zzz' ]).get()
 *  BAJL.String('${A}HOGE${B}FUGA${C}').format({ A:'xxx', B:'yyy', C:'zzz' }).get()
 *      -> 'xxxHOGEyyyFUGAzzz'
 */
BAJL.String.Wrapper.prototype.format = function(arg1, /* arg2, arg3 ..., */ argN) {
	var arr;
	if (arguments.length == 0) {
		return this;
	} else if (typeof arg1 == 'object') {
		arr = arg1;
	} else {
		arr = $.makeArray(arguments).map(function(a) { return String(a) });
	}

	$.each(arr, BAJL.Delegate(function(i, str) {
		this.value = this.value.replace(new RegExp('\\$\\{' + i + '\\}', 'g'), str);
	}, this));
	this.length = this.value.length;

	return this;
}

/**
 * get string before specified keyword.
 * @param {String}  str          find keyword
 * @param {Boolean} [include]    if true, 'str' is included in manipulating string
 * @return this instance itself
 * @type BAJL.String.Wrapper
 */
BAJL.String.Wrapper.prototype.getBefore = function(str, include) {
	if (typeof str != 'string') {
		throw new TypeError('BAJL.String.Wrapper.getBefore: first argument must be a string.');
	} else if (str) {
		var idx = this.value.indexOf(str);
		this.value  = (idx == -1) ? '' : this.value.substring(0, idx) + (include ? str : '');
		this.length = this.value.length;
	}
	return this;
}

/**
 * get string after specified keyword.
 * @param {String}  str          find keyword
 * @param {Boolean} [include]    if true, 'str' is included in manipulating string
 * @return this instance itself
 * @type BAJL.String.Wrapper
 */
BAJL.String.Wrapper.prototype.getAfter = function(str, include) {
	if (typeof str != 'string') {
		throw new TypeError('String.Wrapper.getAfter: first argument must be a string.');
	} else if (str) {
		var idx = this.value.indexOf(str);
		this.value  =  (idx == -1) ? '' : (include ? str : '') + this.value.substring(idx + str.length, this.value.length);
		this.length = this.value.length;
	}
	return this;
}

/**
 * returns true if the string is started with specified keyword.
 * @param {String}  str    checking keyword
 * @return is the string started with the keyword?
 * @type Boolean
 */
BAJL.String.Wrapper.prototype.startsWith = function(str) {
	return (this.value.indexOf(str) == 0);
}

/**
 * returns true if the string is ended with specified keyword.
 * @param {String} str    checking keyword
 * @return is the string ended with the keyword?
 * @type Boolean
 */
BAJL.String.Wrapper.prototype.endsWith = function(str) {
	var idx = this.value.lastIndexOf(str);
	return (idx > -1 && idx + str.length == this.value.length);
}

/**
 * convert relative path/URL to absolute path/URL.
 * @param {String} base    absolute path/URL as a base.
 * @return this instance itself
 * @type BAJL.String.Wrapper
 * @example
 *  BAJL.String('../target/').rel2abs('/path/to/base/'      ).get() -> '/path/to/target/'
 *  BAJL.String('../target/').rel2abs('http://path/to/base/').get() -> 'http://path/to/target/'
 */
BAJL.String.Wrapper.prototype.rel2abs = function(base) {
	var target = this.value;
	var b      = base  .split('/');
	var t      = target.split('/');
	var ptn = /^(\/|\w+:)/;
	if (!base.match(ptn)) {
		throw new TypeError('BAJL.String.Wrapper.rel2abs: first argument must be an absolute path/URL.');
	} else if (target.match(ptn)) {
		// do nothing
	} else if (target.charAt(0) == '#' || target.charAt(0) == '?') {
		this.value = base + target;
	} else if (t[0] == '.' || t[0] == '..') {
		this.value = BAJL.String(t.slice(1, t.length).join('/')).rel2abs(b.slice(0, b.length - t[0].length).join('/') + '/').get();
	} else {
		this.value = b.slice(0, b.length - 1).join('/') + '/' + target;
	}
	this.length = this.value.length;
	return this;
}

/**
 * convert absolute path/URL to relative path/URL.
 * @param {String} base    absolute path/URL as a base.
 * @return this instance itself
 * @type BAJL.String.Wrapper
 * @example
 *  BAJL.String(      '/path/to/target/').abs2rel('/path/to/base/'      ).get() -> '../target/'
 *  BAJL.String('http://path/to/target/').abs2rel('http://path/to/base/').get() -> '../target/'
 */
BAJL.String.Wrapper.prototype.abs2rel = function(base) {
	var ptn = /^(\/|\w+:)/;
	if (!base.match(ptn)) {
		throw new TypeError('BAJL.String.Wrapper.abs2rel: first argument must be an absolute path/URL.');
	} else if (!this.value.match(ptn)) {
		throw new TypeError('BAJL.String.Wrapper.abs2rel: current string is not an absolute path/URL.');
	} else {
		this.value  =  _compare(base, this.value) || base;
		this.length = this.value.length;
	}
	return this;
	
	function _compare(base, target) {
		var b = base  .split('/');
		var t = target.split('/');
		if (!base) {
			return target;
		} else if (!target) {
			return _goup(base);
		} else if (b[0] != t[0]) {
			return _goup(base) + target;
		} else {
			return arguments.callee(b.slice(1, b.length).join('/'), t.slice(1, t.length).join('/'));
		}
	}
	
	function _goup(path) {
		path = path.split('/');
		path.shift();
		path.forEach(function(elem, idx) { path[idx] = '..' });
		return path.join('/') + '/';
	}
}

/**
 * convert to sanitized string
 * @return this instance itself
 * @type BAJL.String.Wrapper
 */
BAJL.String.Wrapper.prototype.sanitize = function() {
	var pairs = {
		  '&'      : '&amp;'
		, '<'      : '&lt;'
		, '>'      : '&gt;'
		, '\u0022' : '&quot;'
		, '\u0027' : '&apos;'
	};
	for (var key in pairs) {
		this.value  = this.value.replace(new RegExp(key, 'g'), pairs[key]);
		this.length = this.value.length;
	}
	return this;
}



/* --------------- Class : BAJL.StyleSheets --------------- */
/**
 * get styleSheet wrapper instance.
 * @namespace styleSheet manipulator
 * @param {Number|StyleSheet} [arg]    index number in StyleSheet list / StyleSheet object
 * @return styleSheet wrapper instance
 * @type BAJL.StyleSheets.Wrapper
 * @example
 *  BAJL.StyleSheets().insertRule('body { color: red }');          // set font color to red
 *  BAJL.StyleSheets().each(function() { this.disabled = true });  // diable all style
 */
BAJL.StyleSheets = function(arg) {
	var sheets = document.styleSheets;
	
	if (BAJL.ua.isSafari) {
		var $cssNode = $('link').filter(function() { return Boolean(this.sheet) });
		var dataName = 'BAJL.StyleSheets.Sheet.disabled';

		if ($cssNode.length > sheets.length) {
			$cssNode.each(function() {
				$(this).data(dataName, ($.inArray(this.sheet, sheets) == -1));
				this.disabled = true;
				this.disabled = false;
			});
			$.each(sheets, function() {
				this.disabled = $(this.ownerNode).data(dataName);
			});
		}
	}

	if (typeof arg == 'number') {
		sheets = sheets[arg];
	} else if (typeof arg == 'object' && arg.type == 'text/css') {
		sheets = arg;
	}

	return new BAJL.StyleSheets.Wrapper(sheets);
}

/* ----- Class : BAJL.StyleSheets.Wrapper ----- */
/**
 * styleSheet wrapper; the instance is available as return value of {@link BAJL.StyleSheets}
 * @class styleSheet wrapper
 * @param {StyleSheetList} [sheets]    styleSheet list
 * @constructor
 */
BAJL.StyleSheets.Wrapper = function(sheets) {
	/** number of styleSheets owned by this instance.
	    @type Number */
	this.length = 0;

	$.makeArray(sheets).forEach(function(sheet, i) {
		this[i] = sheet;
		this.length++;
	}, this);
}

/**
 * get new instance that has a styleSheet indicated by index number.
 * @param {Number} [index]    index number to get.
 * @return new instance that has a styleSheet indicated by index number.
 * @type BAJL.StyleSheets.Wrapper
 */
BAJL.StyleSheets.Wrapper.prototype.eq = function(index) {
	var sheet = (typeof index == 'number') ? this[index] : null;
	return new this.constructor(sheet);
}

/**
 * get DOM StyleSheet object specified by index number, or an array of StyleSheets
 * @param {Number} [index]    index number to get.
 * @return StyleSheet object specified by index number, or an array of StyleSheets
 * @type StyleSheet|Array
 */
BAJL.StyleSheets.Wrapper.prototype.get = function(index) {
	return (typeof index == 'number') ? this[index] : Array.prototype.slice.call(this);
}

/**
 * get "ownerNode" of a DOM StyleSheet specified by index number, or an array of ownerNodes of the StyleSheets.
 * @param {Number} [index]    index number to get.
 * @return "ownerNode" of a DOM StyleSheet specified by index number, or an array of ownerNodes of the StyleSheets
 * @type Element|Element[]
 */
BAJL.StyleSheets.Wrapper.prototype.getOwnerNode = function(index) {
	if (typeof index == 'number') {
		return this[index].ownerNode || this[index].owingElement;
	} else {
		return Array.prototype.map.call(this, function(e, i) { return this.getOwnerNode(i) }, this);
	}
}

/**
 * get number of styleSheets owned by this instance.
 * @return number of styleSheets owned by this instance.
 * @type Number
 */
BAJL.StyleSheets.Wrapper.prototype.size = function() {
	return this.length;
}

/**
 * calls a function for each styleSheet in this instance; compatible with jQuery.each().
 * @param {BAJL.StyleSheets.Wrapper.callback.test} aCallback    the function to exec for every styleSheet; if the func returns false, it terminates iteration.
 * @return this instance itself
 * @type BAJL.StyleSheets.Wrapper
 */
BAJL.StyleSheets.Wrapper.prototype.each = function(aCallback) {
	$.each(this.get(), aCallback);
	return this;
}

/**
 * filter styleSheets in this instance; compatible with jQuery.filter().
 * @param {BAJL.StyleSheets.Wrapper.callback.test} aCallback    the function to exec for every styleSheet; if the func returns false, the styleSheet is filtered.
 * @return new instance that has filtered styleSheets.
 * @type BAJL.StyleSheets.Wrapper
 */
BAJL.StyleSheets.Wrapper.prototype.filter = function(aCallback) {
	return new this.constructor(this.get().filter(function(s, i) { return aCallback.call(s, i, s) }));
}

/**
 * insert css rule; the rule insert to the first styleSheet in this instance.
 * @param {String} cssText    css rule text to add
 * @return this instance itself
 * @type BAJL.StyleSheets.Wrapper
 */
BAJL.StyleSheets.Wrapper.prototype.insertRule = function(cssText) {
	var expr  = /([^\{]+)(\{.+\})/;
	var sheet = this.get(0);
	if (!sheet) {
		return;
	} else if (!expr.test(cssText)) {
		throw new TypeError('BAJL.StyleSheets.Wrapper.insertRule : first argument must be a style rule text.');
	} else {
		var isOldSafari = (BAJL.ua.isSafari && BAJL.ua.version < 522); /* Safari 2.0.x or ealier */
		if (isOldSafari || (!sheet.insertRule && !sheet.addRule)) {
			var style = document.createElement('style');
			style.type= 'text/css';
			style.appendChild(document.createTextNode(cssText));
			document.getElementsByTagName('head')[0].appendChild(style);
		} else if (sheet.insertRule) {  // Std DOM.
			var pos = sheet.cssRules ? sheet.cssRules.length : 0;  // workaround for Chrome in "file:" protocol.
			sheet.insertRule(cssText, pos);
		} else if (sheet.addRule) {     // IE
			var regex     = expr.exec(cssText);
			var selector  = $.trim(regex[1]);
			var predicate = $.trim(regex[2]);
			if (BAJL.ua.documentMode >= 8) {
				predicate = predicate.slice(1, predicate.length - 1);
			}
			selector.split(',').forEach(function(_selector) {
				sheet.addRule(_selector, predicate);
			});
		}
		return this;
	}
};

/* ----- for JSDoc toolkit output ----- */
/**
 * higher-order functions for member methods of {@link BAJL.StyleSheets.Wrapper}
 * @name BAJL.StyleSheets.Wrapper.callback
 * @namespace higher-order functions for member methods of  {@link BAJL.StyleSheets.Wrapper}
 */
/**
 * higher-order function for {@link BAJL.StyleSheets.Wrapper#each}, {@link BAJL.StyleSheets.Wrapper#filter}
 * @function
 * @name BAJL.StyleSheets.Wrapper.callback.test
 * @param {Number}      anIndex      current processing index-num of the styleSheet.
 * @param {StyleSheet}  anSheet      current styleSheet.
 * @returns processing result value (boolean) of this function
 * @type Boolean
 */



/* --------------- Class : BAJL.OpenWindow --------------- */
/**
 * open new window.
 * @namespace window opener
 * @param {String}  url               url to open in new window
 * @param {String}  [target="_blank"] window target name
 * @param {Number}  [width]           width of new window
 * @param {Number}  [height]          height of new window
 * @param {String}  [options]         window options wo/width,height
 * @param {Boolean} [moveFlag]        if true, the new window moves to left top of the screen
 * @return new window object
 * @type Window
 */
BAJL.OpenWindow = function(url, target, width, height, options, moveFlag) {
	if (typeof url != 'string' || !url) {
		throw new URIError('BAJL.OpenWindow: first argument must be a string (url).');
	} else {
		var _this    = arguments.callee;
		var target   = (typeof target == 'string' && target) ? target : '_blank';
		var preset   = _this.getPreset(target);
		var options  = preset.options  || _this.parseOptions(options);
		var moveFlag = preset.moveFlag || Boolean(moveFlag);

		options.width  = preset.width  || width  || options.width  || undefined;
		options.height = preset.height || height || options.height || undefined;
		if (!(options.width  > 0)) delete options.width;
		if (!(options.height > 0)) delete options.height;

		var optArr = [];
		for (var key in options) optArr.push(key + '=' + options[key]);
		var newWin = window.open(url, target, optArr.join(','));
		newWin.focus();

		if (moveFlag    ) newWin.moveTo(0, 0);
		if (window.event) window.event.returnValue = false;
		return newWin;
	}
}

/**
 * preset data storage.
 * @type Object
 * @private
 */
BAJL.OpenWindow.presets = {};

/**
 * get preset data in associative array format
 * @return preset data (associative array)
 * @type Object
 */
BAJL.OpenWindow.getPreset = function(target) {
	if (typeof target != 'string' || !target) {
		return {};
	} else {
		return this.presets[target] || {};
	}
}

/**
 * add setting data that related to link target name 
 * @param {String}  target         window target name
 * @param {Number}  [width]        width of new window
 * @param {Number}  [height]       height of new window
 * @param {String}  [options]      window options wo/width,height
 * @param {Boolean} [moveFlag]     if true, the new window moves to left top of the screen
 * @return preset data (associative array)
 * @type Object
 */
BAJL.OpenWindow.addPreset = function(target, width, height, options, moveFlag) {
	if (typeof target != 'string' || !target) {
		throw new TypeError('BAJL.OpenWindow,addPreset: first argument (target) must be a string.');
	} else {
		var preset      = this.presets[target] = {};
		var options     = this.parseOptions(options);
		preset.width    = (width  > 0) ? width  : (options.width  > 0) ? options.width  : undefined;
		preset.height   = (height > 0) ? height : (options.height > 0) ? options.height : undefined;
		preset.options  = options;
		preset.moveFlag = Boolean(moveFlag);

		delete preset.options.width;
		delete preset.options.height;

		return preset;
	}
}

/**
 * parse options text, and change into an associative array.
 * @return associative array
 * @type Object
 * @private
 */
BAJL.OpenWindow.parseOptions = function(optionsStr) {
	if (typeof optionsStr != 'string' || !optionsStr) {
		return {};
	} else {
		var options = {};
		optionsStr.replace(/\s/g, '').split(',').forEach(function(pair) {
			var arr = pair.split('=');
			if (arr[0]) options[arr[0]] = arr[1] || '';
		});
		return options;
	}
}

/**
 * open new fullscreen window.
 * @param {String} url                   url to open in new window
 * @param {String} [target="_blank"]     window target name
 * @param {String} [options]             window options wo/width,height
 * @return new window object
 * @type Window
 * @see BAJL.OpenWindow
 */
BAJL.OpenWindow.full = function(url, target, options) {
	options = options || 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no';
	return BAJL.OpenWindow(url, target, screen.availWidth, screen.availHeight, options, true);
}






/* ============================== BAJL classes ============================== */

/* -------------------- Class : BAJL.Observable -------------------- */
/**
 * create observable object
 * @class observable
 * @constructor
 */
BAJL.Observable = function() {
	/** callback function chain, pair of key name and function.
	    @type Object
	    @private */
	this.callbackChains      = null;
	/** callback ignoring level - pairs of callback name and level string; 'all', 'preserved', 'disposable', 'none'.
	    @type Object
	    @private */
	this.callbackIgnoreLevel = {};
}

/**
 * process callback functions.
 * @param {String} name            callback name (preferred to start with 'on')
 * @param {Object} [_arguments]    arguments for callback function
 * @return result value of last one of the callback functions chain.
 * @type Object
 */
BAJL.Observable.prototype.doCallback = function(name, /* arg1, arg2, ... */ _arguments) {
	var chain = this.callbackChains;
	if (!chain || !chain[name]) {
		return undefined;
	} else {
		var ret;
		var args = Array.prototype.slice.call(arguments, 1);

		chain[name]
			.filter(function(delegate) {
				var level = this.callbackIgnoreLevel[name] || 'none';
				switch (level) {
					case 'preserved'  : return  delegate.isDisposable;
					case 'disposable' : return !delegate.isDisposable;
					case 'all'        : return  false;
					case 'none'       : return  true;
					default           : return  true;
				}
			}, this)
			.forEach(function(delegate) {
				ret = delegate.apply(null, args);
			});

		this.removeDisposableCallback(name);
		return ret;
	}
}

/**
 * add callback function.
 * @param {String}   name             callback name (preferred to start with 'on')
 * @param {Function} func             callback function/method
 * @param {Object}   [aThisObject]    object that will be a global object ('this') in func
 * @param {String}   [disposable]     if 'disposable' specified, the callback function is treated as 'disposable'.
 * @return this instance
 * @type BAJL.Observable
 */
BAJL.Observable.prototype.addCallback = function(name, func, aThisObject, disposable) {
	if (typeof name != 'string' || name == '') {
		throw new TypeError('BAJL.Observable.addCallback: argument \'name\' must be a string as callback name.');
	} else if (typeof func != 'function') {
		throw new TypeError('BAJL.Observable.addCallback: argument \'func\' must be a Function object.');
	} else {
		if (!this.callbackChains      ) this.callbackChains       = {};
		if (!this.callbackChains[name]) this.callbackChains[name] = [];

		var delegate = BAJL.Delegate(func, aThisObject);
		delegate.isDisposable = (disposable == 'disposable');
		this.callbackChains[name].push(delegate);
	}
	return this;
}

/**
 * remove callback function.
 * @param {String}   name             callback name (preferred to start with 'on')
 * @param {Function} [func]           callback function/method to remove, if no funcs given, all callback funcs will be removed.
 * @param {Object}   [aThisObject]    object that will be a global object ('this') in func
 * @return this instance
 * @type BAJL.Observable
 */
BAJL.Observable.prototype.removeCallback = function(name, func, aThisObject) {
	var chain = this.callbackChains;
	if (typeof name != 'string' || name == '') {
		throw new TypeError('BAJL.Observable.removeCallback: argument \'name\' must be a string as callback name.');
	} else if (chain && chain[name]) {
		if (typeof func != 'function') {
			delete chain[name];
		} else {
			var obj = (typeof aThisObject == 'object' && aThisObject) ? aThisObject : window;
			chain[name] = chain[name].filter(function(delegate) {
				return (delegate.func !== func || delegate.aThisObject !== obj);
			});
		}
	}
	return this;
}

/**
 * remove 'disposable' callback function.
 * @param {String} name    callback name (preferred to start with 'on')
 * @private
 */
BAJL.Observable.prototype.removeDisposableCallback = function(name) {
	var chain = this.callbackChains;
	if (chain && chain[name]) {
		chain[name] = chain[name].filter(function(delegate) { return !delegate.isDisposable });
	}
}

/**
 * set callback ignoring level.
 * @param {String} name             callback name (preferred to start with 'on')
 * @param {String} [level="all"]    ignoring level - 'all', 'preserved', 'disposable', 'none'
 * @return this instance
 * @type BAJL.Observable
 */
BAJL.Observable.prototype.ignoreCallback = function(name, level) {
	var chain = this.callbackChains;
	if (typeof name != 'string' || name == '') {
		throw new TypeError('BAJL.Observable.ignoreCallback: argument \'name\' must be a string as callback name.');
	} else if (chain && chain[name]) {
		var levels = ['all', 'preserved', 'disposable', 'none'];
		this.callbackIgnoreLevel[name] = (levels.indexOf(level) != -1) ? level : 'all';
	}
	return this;
}

if (BAJL.settings.common.useBackCompat) {
	/** @deprecated use {@link #doCallback} method instead of this method. */
	BAJL.Observable.prototype.doCallBack = function() { return this.doCallback.apply(this, arguments) }
	/** @deprecated use {@link #addCakkback} method instead of this method. */
	BAJL.Observable.prototype.addCallBack = function() { return this.addCallback.apply(this, arguments) }
	/** @deprecated use {@link #removeCallback} method instead of this method. */
	BAJL.Observable.prototype.removeCallBack = function() { return this.removeCallback.apply(this, arguments) }
	/** @deprecated use {@link #removeDisposableCallback} method instead of this method. */
	BAJL.Observable.prototype.removeDisposableCallBacks = function() { return this.removeDisposableCallback.apply(this, arguments) }
}



/* --------------- Class : BAJL.Iterator --------------- */
/**
 * create iterator object
 * @class iterator
 * @param {Object} obj               iterated elements; an associative array, an array, or an object like those.
 * @param {Object} [mode="value"]    element getting mode; 'key', 'value', or 'both'
 */
BAJL.Iterator = function(obj, mode) {
	/** iterated elements; an associative array, an array, or an object like those.
	    @type Object
	    @private
	    @constant */
	this.targets = obj;
	/** an array of keys in iterated elements.
	    @type String[]
	    @private
	    @constant */
	this.keys    = [];
	/** a number of current position of the iterator.
	    @type Number
	    @private */
	this.counter = 0;
	/** element getting mode; "key", "value", or "both".
	    @type String
	    @constant
	    @private */
	this.mode    = mode || 'value';
	
	if (arguments.length > 0) {
		this.init();
	}
}

/**
 * initialize
 * @private
 */
BAJL.Iterator.prototype.init = function() {
	if (!this.targets || typeof this.targets != 'object') {
		throw new TypeError('BAJL.Iterator#init: invalid object type.');
	} else {
		$.each(this.targets, BAJL.Delegate(function(key) { this.keys.push(key) }, this));
	}
}

/**
 * does the iterator has next element?
 * @return true if the iterator has next element.
 * @type Boolean
 */
BAJL.Iterator.prototype.hasNext = function() {
	return (this.counter < this.keys.length);
}

/**
 * get next element in the iteration; the form of an acquired element depends on "element getting mode"
 * @return next element in the iteration
 * @type Object
 */
BAJL.Iterator.prototype.next = function() {
	if (!this.hasNext()) {
		throw new ReferenceError('BAJL.Iterator#next: StopIteration');
	} else {
		var key   = this.keys[this.counter++];
		var value = this.targets[key];
		switch(this.mode) {
			case 'key'   : return key;
			case 'value' : return value;
			case 'both'  : return [key, value];
			default      : return undefined;
		}
	}
}

/*
 * @param {Function} func             callback function
 * @param {Number}   [ms=0]           milliseconds to interval
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the func
 */
BAJL.Iterator.prototype.iterate = function(func, ms, aThisObject) {
	if (typeof func != 'function') {
		throw new TypeError('BAJL.Iterator#iterate: first argument must be a function object.');
	} else {
		var flag = (this.hasNext()) ?
		           	func.apply(aThisObject, $.makeArray(this.next())) :
		           	false;
		if (flag !== false) {
			if (ms > 0) {
				new BAJL.Timeout(function() {
					this.iterate(func, ms, aThisObject);
				}, ms, this);
			} else {
				this.iterate(func, ms, aThisObject);
			}
		}
	}
}



/* --------------- Class : BAJL.Timeout --------------- */
/**
 * a wrapper of 'setTimeout()'.
 * @class timeout timer
 * @param {Function} func             callback function
 * @param {Number}   [ms=0]           milliseconds to timeout
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the func
 * @constructor
 */
BAJL.Timeout = function(func, ms, aThisObject) {
	/** timer ID.
	    @type Number
	    @private */
	this.timer       = 0;
	/** callback function
	    @type Function
	    @private
	    @constant */
	this.func        = func;
	/** milliseconds to timeout
	    @type Function
	    @private
	    @constant */
	this.ms          = Math.max(0, ms) || 0
	/** the object that will be a global object ('this') in the func
	    @type Object
	    @private
	    @constant */
	this.aThisObject = aThisObject || window;
	/** native timer function name; 'setTimeout' or 'setInterval'
	    @type String
	    @private
	    @constant */
	this.timerFunc   = 'setTimeout';

	if (arguments.length) {
		this.init();
	}
}

/**
 * initialize.
 * @private
 */
BAJL.Timeout.prototype.init = function() {
	if (typeof this.func != 'function') {
		throw new ReferenceError('BAJL.Timeout.init: callback function is not given.');
	} else {
		var delegate  = BAJL.Delegate(this.func, this.aThisObject);
		var timerFunc = window[this.timerFunc];
		this.timer    = (BAJL.ua.isIE) ?
		              	timerFunc(delegate, this.ms, 'JScript') : // workaround to the page weaved with vbscript.
		              	timerFunc(delegate, this.ms           ) ;
	}
}

/**
 * clear timer.
 */
BAJL.Timeout.prototype.clear = function() {
	clearTimeout (this.timer);
	clearInterval(this.timer);
}

/** @deprecated use {@link #clear} method instead of this method. */
BAJL.Timeout.prototype.clearTimer = function() { return this.clear.apply(this, arguments) }



/* --------------- Class : BAJL.Interval --------------- */
/**
 * a wrapper of 'setInterval()'.
 * @class interval timer
 * @extends BAJL.Timeout
 * @param {Function} func             callback function
 * @param {Number}   [ms=0]           milliseconds to interval
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the func
 * @constructor
 */
BAJL.Interval = function(func, ms, aThisObject) {
	/** timer ID.
	    @type Number
	    @private */
	this.timer       = 0;
	/** callback function
	    @type Function
	    @private
	    @constant */
	this.func        = func;
	/** milliseconds to timeout
	    @type Function
	    @private
	    @constant */
	this.ms          = Math.max(0, ms) || 0
	/** the object that will be a global object ('this') in the func
	    @type Object
	    @private
	    @constant */
	this.aThisObject = aThisObject || window;
	/** native timer function name; 'setTimeout' or 'setInterval'
	    @type String
	    @private
	    @constant */
	this.timerFunc   = 'setInterval';

	if (arguments.length) {
		this.init();
	}
}
BAJL.Interval.prototype = new BAJL.Timeout;



/* --------------- Class : BAJL.Timer --------------- */
/**
 * construct simple elapsed timer object.
 * @class simple elapsed timer.
 * @constructor
 */
BAJL.Timer = function() {
	/** started time of the timer in 'epoch time'.
	    @type Number
	    @private */
	this.startTime = null;

	this.reset();
}

/**
 * reset timer.
 */
BAJL.Timer.prototype.reset = function() {
	this.startTime = (new Date()).getTime();
}

/**
 * get acquire time progress in milisecond.
 * @return acquire time progress in milisecond.
 * @type Number
 */
BAJL.Timer.prototype.getTime = function() {
	return (new Date()).getTime() - this.startTime;
}

/**
 * get acquire time progress in second.
 * @return acquire time progress in second.
 * @type Number
 */
BAJL.Timer.prototype.getSeconds = function() {
	return this.getTime() / 1000;
}



/* --------------- Class : BAJL.Tag --------------- */
/**
 * create tag string object for document.write().
 * @class tagstring as element object.
 * @constructor
 * @param {String} tagName    element name to create
 * @param {Object} [attrs]    associative array of attributes { name1 : value1, name2 : value2 ... }
 */
BAJL.Tag = function(tagName, attrs) {
	/** tag name (element name) to create
	    @type String
	    @constant */
	this.tagName    = tagName;
	/** associative array of attributes { name1 : value1, name2 : value2 ... }
	    @type Object */
	this.attributes = attrs || {};
	/** array of {@link BAJL.Tag} instances
	    @type BAJL.Tag[] */
	this.childNodes = [];
}

/**
 * get/set attribute value.
 * @param {String} name    attribute name
 * @param {String} [value]    value to set
 */
BAJL.Tag.prototype.attr = function(name, value) {
	if (typeof name != 'string') {
		throw new TypeError('BAJL.Tag.attr: first argument must be a string (name).');
	} else if (value == undefined) {
		return this.attributes[name] || '';
	} else {
		return (this.attributes[name] = String(value));
	}
}

/**
 * append child instance.
 * @param {BAJL.Tag|String} arg     instance to append
 */
BAJL.Tag.prototype.append = function(arg) {
	if (arg == undefined || arg == null) {
		throw new TypeError('BAJL.Tag.append: first argument must be a string or a BAJL.Tag instance.');
	} else {
		if (arg.constructor != this.constructor) {
			arg = String(arg);
		}
		this.childNodes.push(arg);
	}
}

/**
 * output instance data as tag string. typically to use document.write().
 * @param {Boolean} [debug=false]    debug mode - escaped output
 * @return HTML tag string
 * @type String
 */
BAJL.Tag.prototype.toString = function(debug) {
	var tagOpen    = (debug) ? '&lt;' : '<';
	var tagClose   = (debug) ? '&gt;' : '>';
	var tag        = tagOpen + this.tagName;
	var content    = (this.childNodes.length) ? '' : null;
	for (var i = 0, n = this.childNodes.length; i < n; i++) {
		content += this.childNodes[i].toString(debug);
	}
	for (var attr in this.attributes) {
		tag += ' ' + attr + '="' + this.attributes[attr] + '"';
	}
	tag += (content != null) ?
		tagClose + content + tagOpen + '/' + this.tagName + tagClose :
		' /' + tagClose;
	return tag;
}

if (BAJL.settings.common.useBackCompat) {
	/** @deprecated use {@link #append} method instead of this method. */
	BAJL.Tag.prototype.setAttributeBA = function() { return this.attr.apply(this, arguments) }
	/** @deprecated use {@link #append} method instead of this method. */
	BAJL.Tag.prototype.appendChildBA = function() { return this.append.apply(this, arguments) }
}



/* ============================== BAJL static functions ============================== */

/* --------------- Function : BAJL.CreateBackCompat --------------- */
/**
 * create references from old name to new name; for backword compatibility.
 * @param {Object} pairs    associative array of pairs of deprecated old name and it's new object
 * @deprecated this func is available for a limited time.
 */
BAJL.CreateBackCompat = function(pairs) {
	$.each(pairs, function(key, value) { BAJL.SetValue(key, value) });
}



/* --------------- Function : BAJL.SetValue --------------- */
/**
 * set value to deep object directly.
 * @param {String} expr            object expression string to set value
 * @param {Object} [value]         value to set
 * @param {Object} [obj=window]    base object of expr
 * @returns value that set
 * @type Object
 */
BAJL.SetValue = function(expr, value, obj) {
	if (typeof expr != 'string' || !expr) {
		throw new TypeError('BAJL.SetValue: first argument type must be string (expr).');
	} else if (obj !== null) {
		var props = expr.split('.');
		var obj   = (obj === undefined) ? window : obj
		if (props.length == 1) {
			return (obj[expr] = value);
		} else {
			var prop = props.shift();
			if (obj[prop] == undefined) {
				obj[prop] = {};
			}
			return arguments.callee(props.join('.'), value, obj[prop]);
		}
	}
}



/* --------------- Function : BAJL.GetValue --------------- */
/**
 * get value from deep object directly.
 * @param {String} expr            object expression string to get value
 * @param {Object} [obj=window]    base object of expr
 * @returns any type of value
 * @type Object
 */
BAJL.GetValue = function(expr, obj) {
	if (typeof expr != 'string' || !expr) {
		throw new TypeError('BAJL.GetValue: first argument type must be string (expr).');
	} else {
		var props = expr.split('.');
		var obj   = (typeof obj != 'object' || !obj) ? window : obj;
		if (props.length == 1) {
			return obj[expr];
		} else {
			var prop = props.shift();
			return (obj[prop] == undefined) ? undefined : arguments.callee(props.join('.'), obj[prop]);
		}
	}
}



/* --------------- Function : BAJL.Singleton --------------- */
/**
 * create object as single instance. or put existing instance.
 * @param {Function} _constructor    constructor
 * @param {Object}   [_arguments]    arguments for constructor
 * @return single instance.
 * @type Object
 */
BAJL.Singleton = function(_constructor, /* arg1, arg2, ... */ _arguments) {
	if (typeof _constructor != 'function') {
		throw new TypeError('BAJL.Singleton: first argument must be a constructor function.');
	} else {
//		var args = Array.prototype.slice.call(arguments, 1);
		return _constructor.__BAJL_SingleInstance__ || (_constructor.__BAJL_SingleInstance__ = new _constructor());
	}
}



/* --------------- Function : BAJL.Delegate --------------- */
/**
 * create delegate function to change 'this' scope.
 * @param {Function} func             function for delegate
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the function
 * @return delegated function.
 * @type Function
 */
BAJL.Delegate = function(func, aThisObject) {
	if (typeof func != 'function') {
		throw new TypeError('BAJL.Delegate: first argument must be a function object.');
	} else {
		var aThisObj = aThisObject || window;
		var delegate = function(){
			return func.apply(aThisObj, arguments);
		};
		delegate.func        = func;
		delegate.aThisObject = aThisObj;
		return delegate; 
	}
}



/* --------------- Function : BAJL.BarrageShield --------------- */
/**
 * create wrapper function which ignores and unify barraged-function-calls.
 * @param {Function} func             a function which has possibility to be barraged function-calls
 * @param {Number}   [delay=1]        delay time to ignore barraged function-calls
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the function
 * @return wrapper function.
 * @type Function
 */
BAJL.BarrageShield = function(func, delay, aThisObject) {
	if (typeof func != 'function') {
		throw new TypeError('BAJL.BarrageShield: first argument must be a function object.');
	} else {
		return function() {
			var _args  = arguments;
			var _delay = Math.max(delay, 1) || 1;
			clearTimeout(func.__BAJL_BarrageShield_Timer__);
			func.__BAJL_BarrageShield_Timer__ = setTimeout(function() { func.apply(aThisObject || window, _args) }, _delay);
		}
	}
}



/* --------------- Function : BAJL.AlreadyApplied --------------- */
/**
 * return 'true' if the function is already applied.
 * @param {Function} func    typically 'arguments.callee'
 * @return boolean
 * @type Boolean
 */
BAJL.AlreadyApplied = function(func) {
	if (typeof func != 'function') {
		throw new TypeError('BAJL.AlreadyApplied: first argument must be a function object.');
	} else {
		return func.__BAJL_AlreadyApplied__ || !(func.__BAJL_AlreadyApplied__ = true);
	}
}



/* --------------- Function : BAJL.PreloadImage --------------- */
/**
 * create Image object (load image).
 * @param {String} src     image url to load
 * @return image object
 * @type Image
 */
BAJL.PreloadImage = function(src) {
	if (typeof src != 'string' || !src) {
		throw new TypeError('BAJL.PreloadImage: first argument must be a string (img src).');
	} else {
		var img = new Image;
		img.src = src;
		return img;
	}
}



/* --------------- Function : BAJL.GetLinkTarget --------------- */
/**
 * get an element which is linked from given anchor element in same page.
 * @see jQuery.fn.BAJL_LinkTarget
 * @param {Element|jQuery|String}  anchor             anchor element (a, area).
 * @param {String}                [target="_self"]    target name to assume that given anchor is inner-page link.
 * @return jQuery indicating an element which is linked from given anchor element.
 * @type jQuery
 */
BAJL.GetLinkTarget = function(anchor, target) {
	var anchor = $(anchor).filter('a, area').get(0);
	var target = target ? String(target) : '_self';
	if (anchor) {
		var _target = anchor.target || '_self';
		var _hash   = anchor.hash   || '#';
		var _href   = anchor.href.replace(_hash, '').replace(location.href.split('#')[0], '');
		if (_target == target && _hash != '#' && !_href) {
			return $(_hash);
		}
	}
	return $();
}



/* --------------- Function : BAJL.GetGeometry --------------- */
/**
 * get window geometry and mouse position.
 * @param {Event} e    event object - this param exists when this function is called as an event handler.
 * @returns an associative array of geometry properties
 * @type BAJL.geom
 */
BAJL.GetGeometry = function(e) {
	var w = window;
	var d = document.documentElement;
	var b = document.body;
	var g = BAJL.geom;
	var _ = arguments.callee;

	var isWinIEqm = (BAJL.ua.isIE && BAJL.ua.isWin && BAJL.ua.isQuirksMode);
	var isMacIE   = (BAJL.ua.isIE && BAJL.ua.isMac);
	var isSafari2 = (BAJL.ua.isSafari && BAJL.ua.version < 522); /* Safari 2.0.x or ealier */

	g.windowW   = w.innerWidth  || (isMacIE ? b.scrollWidth  : d.offsetWidth );
	g.windowH   = w.innerHeight || (isMacIE ? b.scrollHeight : d.offsetHeight);
	g.pageW     = (isMacIE) ? d.offsetWidth  : (isWinIEqm) ? b.scrollWidth  : d.scrollWidth ;
	g.pageH     = (isMacIE) ? d.offsetHeight : (isWinIEqm) ? b.scrollHeight : d.scrollHeight;
	g.scrollX   = w.scrollX || d.scrollLeft || b.scrollLeft || 0;
	g.scrollY   = w.scrollY || d.scrollTop  || b.scrollTop  || 0;
	g.windowX   = (!e) ? (g.windowX || 0) : e.clientX - (( isSafari2) ? g.scrollX : 0);
	g.windowY   = (!e) ? (g.windowY || 0) : e.clientY - (( isSafari2) ? g.scrollY : 0);
	g.pageX     = (!e) ? (g.pageX   || 0) : e.clientX + ((!isSafari2) ? g.scrollX : 0);
	g.pageY     = (!e) ? (g.pageX   || 0) : e.clientY + ((!isSafari2) ? g.scrollY : 0);
	g.zoom      = _.getZoomRatio();
	g.scrollBar = _.getScrollBarWidth();

	if (BAJL.settings.common.showGeometry) {
		var msg = [
			  ['window'   , '${windowW}x${windowH}']
			, ['page'     , '${pageW}x${pageH}'    ]
			, ['scroll'   , '${scrollX},${scrollY}']
			, ['pos(view)', '${windowX},${windowY}']
			, ['pos(abs)' , '${pageX},${pageY}'    ]
			, ['zoom'     , '${zoom}'              ]
			, ['sbar'     , '${scrollBar}'         ]
		].map(function(a) { return a.join(': ') }).join(' | ');
		window.status = BAJL.String(msg).format(g).get();
	}
	if (BAJL.settings.common.useBackCompat) {
		g.mouseX = g.pageX;
		g.mouseY = g.pageY;
	}

	return g;
}

/**
 * get window zoom ratio for IE7+
 * @returns window zoom ratio on IE7+ / always 1 on other browsers.
 * @type Number
 * @private
 */
BAJL.GetGeometry.getZoomRatio = function() {
	var d = document.documentElement;
	var b = document.body;
	var _ = arguments.callee;
	_._cache_ = _._cache_ || 1;
	if (BAJL.ua.isIE && BAJL.ua.version >= 7.0) {
		if (_._lock_) {
			_._lock_.clear();
			_._lock_ = new BAJL.Timeout(function() { _._lock_ = null }, 500);
		} else {
			_._lock_ = new BAJL.Timeout(function() { _._lock_ = null }, 500);
			if (BAJL.ua.isQuirksMode) {
				_._cache_ = d.offsetWidth / b.offsetWidth;
			} else {
				var id  = 'BAJL_GetGeometry_getZoomRatio_TestNode';
				var css = {
					  'position'   : 'absolute'
					, 'left'       : '0px'
					, 'top'        : '0px'
					, 'width'      : (d.scrollWidth * 10) + 'px'
					, 'height'     : '10px'
					, 'background' : 'red'
				};
				var node = $('#' + id).get(0) || $(document.createElement('ins')).attr('id', id).css(css).appendTo(document.body).get(0);
				$(node).show();
				_._cache_ = d.scrollWidth / node.offsetWidth;
				$(node).hide();
			}
		}
	}
	return _._cache_;
}

/**
 * get scrollbar width
 * @return scrollbar width in px unit
 * @type Number
 * @private
 */
BAJL.GetGeometry.getScrollBarWidth = function() {
	var _ = arguments.callee;
	if (typeof _._cache_ != 'number') {
		var id  = 'BAJL_GetGeometry_getScrollBarWidth_TestNode';
		var css = {
			  'position'   : 'absolute'
			, 'left'       : '-10000px'
			, 'top'        : '-10000px'
			, 'display'    : 'block'
			, 'visibility' : 'hidden'
			, 'overflow'   : 'scroll'
			, 'width'      : '100px'
			, 'height'     : '100px'
			, 'border'     : 'none'
			, 'margin'     : '0'
			, 'padding'    : '0'
		};
		var node = $('#' + id).get(0) || $(document.createElement('ins')).attr('id', id).css(css).appendTo(document.body).get(0);
		_._cache_ = node.offsetWidth - node.clientWidth;
		$(node).remove();
	}
	return _._cache_;
}

/**
 * measuring the geometry continuously
 */
BAJL.GetGeometry.continuously = function() {
	if (!BAJL.AlreadyApplied(arguments.callee)) {
		BAJL.GetGeometry();
		$(document).mousemove(BAJL.GetGeometry);
	}
}



/* --------------- Function : BAJL.GetCommonDir --------------- */
/**
 * get URL of common directory.
 * @param {String} dirName     name of common directory
 * @return absolute URL of common directory.
 * @type String
 */
BAJL.GetCommonDir = function(dirName) {
	if (typeof dirName != 'string' || !dirName) {
		throw new TypeError('BAJL.GetCommonDir: first argument must be a string (directory name to find).');
	} else {
		var path  = './';
		var nodes = document.getElementsByTagName('head')[0].getElementsByTagName('script');
		for (var i = 0, n = nodes.length; i < n; i++) {
			var arr = nodes[i].src.split('/');
			var idx = arr.indexOf(dirName);
			if (idx != -1) {
				path = arr.slice(0, idx + 1).join('/') + '/';
				break;
			}
		}
		if (!path.match(':')) {   // if path is not absolute url (workaround for IE)
			var base = document.getElementsByTagName('base')[0];
			var burl = (base) ? base.href : location.href;
			if (BAJL.String(path).startsWith('/')) {
				path = burl.match(/^\w+:\/*[^\/]+/)[0] + path;
			} else {
				path = BAJL.String(path).rel2abs(burl).get();
			}
		}
		return path;
	}
}






/* =============== additional jQuery plugin methods =============== */

/* -------------------- jQuery.fn : BAJL_LinkTarget -------------------- */
/**
 * get an element which is linked from given anchor element in same page.
 * @see BAJL.GetLinkTarget
 * @param {String} [target="_self"]    target name to assume that given anchor is inner-page link.
 * @return jQuery indicating an element which is linked from given anchor element.
 * @type jQuery
 */
jQuery.fn.BAJL_LinkTarget = function(target) {
	return BAJL.GetLinkTarget(this, target);
}



/* -------------------- jQuery.fn : BAJL_NormalizeTextNode -------------------- */
/**
 * remove text nodes that have only white spaces, and normalize space of each text nodes.
 * @param {Boolean} [deep]    process recursive node tree?
 * @return jQuery current context object
 * @type jQuery
 */
jQuery.fn.BAJL_NormalizeTextNode = function(deep) {
	this.contents().each(function() {
		if (this.nodeType == Node.TEXT_NODE) {
			if ((this.nodeValue = jQuery.trim(this.nodeValue)) == '') {
				this.parentNode.removeChild(this);
			}
		} else if (deep && this.nodeType == Node.ELEMENT_NODE) {
			jQuery(this).BAJL_NormalizeTextNode(deep);
		}
	});
	return this;
}



/* -------------------- jQuery.fn : BAJL_HasElement -------------------- */
/**
 * check if the current context of jQuery objecdt has Element node(s)?
 * @return if the jQuery object has Element node(s).
 * @type Boolean
 */
jQuery.fn.BAJL_HasElement = function() {
	return (this.size() > 0 && this.get(0) && this.get(0).nodeType == Node.ELEMENT_NODE);
}



/* -------------------- jQuery.fn : BAJL_AddBeforeUnload -------------------- */
/**
 * temporary wrapper for adding event listener of "window.onBeforeUnload".
 * @param {Function} listener         an event listener function
 * @param {Object}   [aThisObject]    the object that will be a global object ('this') in the listener func.
 */
jQuery.fn.BAJL_AddBeforeUnload = function(listener, aThisObject) {
	if (this.get(0) === window) {
		if (window.addEventListener) {    // except IE8 and above
			window.addEventListener('beforeunload', BAJL.Delegate(listener, aThisObject), false);
		} else {
			this.bind('beforeunload', function(e) {
				if (e && e.originalEvent) {    // prevent error on IE (since jQuery1.4)
					listener.call(aThisObject, e.originalEvent);
				}
			});
		}
	}
}






/* =============== for backward compatibilities =============== */

if (BAJL.settings.common.useBackCompat) {
	// define old BADOM methods
	var _BADOM = {
		instanceOf : 'BAElement',
		addEventListenerBA : function(type, func, aThis) {
			$(this).bind(type, function(e) {
				$(e.target       )._setBADOM();
				$(e.currentTarget)._setBADOM();
				$(e.relatedTarget)._setBADOM();
				func.call(aThis || this, e);
			});
		},
		removeEventListenerBA : function(type, func) {
			$(this).unbind(type, func);
		},
		dispatchEventBA : function(e) {
			$(this).trigger(e.type);
		}
	};
	var _BAWindow   = $.extend(null, _BADOM, {});
	var _BADocument = $.extend(null, _BADOM, {
		getElementsByTagNameBA : function(tagName) {
			return $(tagName, this)._setBADOM().get();
		},
		getElementsByClassNameBA : function(className, tagName) {
			return $([ tagName, className ].join('.'), this)._setBADOM().get();
		},
		getElementsByNameBA : function(n) {
			return $('[name=' + n + ']', this)._setBADOM().get();
		},
		getElementByIdBA : function(id) {
			return $('#' + id)._setBADOM().get(0);
		},
		createElementBA : function(tagName) {
			return $(document.createElement(tagName))._setBADOM().get(0);
		},
		createDocumentFragmentBA : function() {
			var node = $(document.createElement('ins'))._setBADOM().get(0);
			$.data(node, 'BADocument.PseudoDocumentFragmentNode', true);
			return node;
		},
		isAncestorOfBA : function(node) {
			var _this = this;
			return $(node).parents().get().some(function(_node) { return (_node == _this) });
		},
		getStyleSheetsBA : function() {
			return BAJL.StyleSheets().get().map(function(sheet) {
				/** @ignore */
				sheet.addRuleBA = function(cssText) { BAJL.StyleSheets(this).insertRule(cssText) };
				return sheet;
			});
		}
	});
	var _BAElement = $.extend(null, _BADocument, {
		getAncestorsByTagNameBA : function(tagName) {
			return $(this).parents(tagName)._setBADOM().get();
		},
		getAncestorsByClassNameBA : function(className, tagName) {
			return $(this).parents([ tagName, className ].join('.'))._setBADOM().get();
		},
		getParentNodeBA : function() {
			return $(this).parent()._setBADOM().get(0);
		},
		getChildNodesBA : function() {
			return $(this).contents()._setBADOM().get();
		},
		appendChildBA : function(content, forceAsHTML) {
			if (typeof content == 'string' && !forceAsHTML) {
				return this.appendChild(document.createTextNode(content));
			} else if ($.data(content, 'BADocument.PseudoDocumentFragmentNode')) {
				while (content.hasChildNodes()) this.appendChild(content.firstChild);
				return content;
			} else {
				if (content.constructor == BAJL.Tag) content = content.toString();
				return $($(this).append(content).contents().get().pop())._setBADOM().get(0);
			}
		},
		removeChildBA : function(node) {
			$(node).remove()._setBADOM().get(0);
		},
		removeAllChildrenBA : function() {
			var nodes = $(this).contents()._setBADOM().get();
			$(this).empty();
			return nodes;
		},
		isDescendantOfBA : function(node) {
			return $(node)._setBADOM().get(0).isAncestorOfBA(this);
		},
		getInnerTextBA : function(includeAlt) {
			return $(this).text().replace(/\s+/g, ' ');
		},
		getAttributeBA : function(name) {
			return $(this).attr(name);
		},
		setAttributeBA : function(name, value) {
			$(this).attr(name, value);
		},
		hasClassNameBA : function(className) {
			return $(this).hasClass(className);
		},
		appendClassNameBA : function(className) {
			$(this).addClass(className);
		},
		removeClassNameBA : function(className) {
			$(this).removeClass(className);
		},
		normalizeTextNodeBA : function(deep) {
			$(this).BAJL_NormalizeText(deep);
		},
		getAbsoluteOffsetBA : function() {
			var offset = $(this).offset();
			return { X : offset.left, Y : offset.top };
		},
		getCurrentStyleBA : function(property, pseudo) {
			return $(this).css(property);
		},
		setPositionFixedBA : function(ignoreX, ignoreY, autoHide) {
			// later...
		}
	});
	delete _BAElement.createElementBA;
	delete _BAElement.createDocumentFragmentBA;
	delete _BAElement.getStyleSheetsBA;

	// once called 'BARegisterDOMMethodsTo()'
	var _setBADOM = function(node, deep) {
		var valid;
		try { valid = (node && (node.nodeType == 1 || node.nodeType == 11)) } catch(err) {}
		if (valid && node.instanceOf != 'BAElement') {
			$.each(_BAElement, function(p) { node[p] = _BAElement[p] });
		}
		if (valid && deep === true) {
			for (var i = 0, node = node.childNodes.length; i < n; i++) {
				arguments.callee(node.childNodes[i], true);
			}
		}
		return node;
	};

	// expose 'BARegisterDOMMethodsTo()' as jQuery plugin function
	$.fn._setBADOM = function(deep) { this.each(function() { _setBADOM(this, deep) }); return this };

	// once called 'BARegisterDOMMethods()'
	$.each(_BAWindow  , function(p) { window  [p] = _BAWindow  [p] });
	$.each(_BADocument, function(p) { document[p] = _BADocument[p] });
	$(function() { _setBADOM(document.documentElement); _setBADOM(document.body) });

	// create object references for back compatibility
	var _commonDir = BAJL.GetCommonDir('common') || BAJL.GetCommonDir('shared');
	BAJL.CreateBackCompat({
		// deprecated 'BA' props
		  'BA.url.commonDir' : _commonDir
		, 'BA.url.imgDir'    : _commonDir + 'img/'
		, 'BA.url.cssDir'    : _commonDir + 'css/'
		, 'BA.url.jsDir'     : _commonDir + 'js/'
		, 'BA.ns'            : BAJL.ns
		, 'BA.ns.bA'         : BAJL.ns.bajl
		, 'BA.env'           : BAJL.env
		, 'BA.env.referer'   : document.referrer
		, 'BA.ua'            : BAJL.ua
		, 'BA.ua.revision'   : BAJL.ua.version
		, 'BA.ua.isWinIE'    : BAJL.ua.isWin && BAJL.ua.isIE
		, 'BA.ua.isMacIE'    : BAJL.ua.isMac && BAJL.ua.isIE
		, 'BA.ua.isIE40'     : BAJL.ua.isIE  && BAJL.ua.version == 4.0
		, 'BA.ua.isIE45'     : BAJL.ua.isIE  && BAJL.ua.version == 4.5
		, 'BA.ua.isIE50'     : BAJL.ua.isIE  && BAJL.ua.version == 5.0
		, 'BA.ua.isIE55'     : BAJL.ua.isIE  && BAJL.ua.version == 5.5
		, 'BA.ua.isIE60'     : BAJL.ua.isIE  && BAJL.ua.version == 6.0
		, 'BA.ua.isIE70'     : BAJL.ua.isIE  && BAJL.ua.version == 7.0
		, 'BA.ua.isIE80'     : BAJL.ua.isIE  && BAJL.ua.version == 8.0
		, 'BA.ua.isWinIEQM'  : BAJL.ua.isQuirksMode
		, 'BA.ua.IEDocMode'  : BAJL.ua.documentMode

		// depracated 'BA'-suffixed methods in build-in object
		, 'Number.prototype.formatNumberBA' : function(format) { return BAJL.Number(this).format (format).get() }
		, 'String.prototype.formatNumberBA' : function(format) { return BAJL.Number(this).format (format).get() }
		, 'String.prototype.formatNumberBA' : function(format) { return BAJL.Number(this).format (format).get() }
		, 'String.prototype.formatTextBA'   : function(arr)    { return BAJL.String(this).format    (arr).get() }
		, 'String.prototype.getBeforeBA'    : function(str)    { return BAJL.String(this).getBefore (str).get() }
		, 'String.prototype.getAfterBA'     : function(str)    { return BAJL.String(this).getAfter  (str).get() }
		, 'String.prototype.startsWithBA'   : function(str)    { return BAJL.String(this).startsWith(str)       }
		, 'String.prototype.endsWithBA'     : function(str)    { return BAJL.String(this).endsWith  (str)       }
		, 'String.prototype.relToAbsBA'     : function(base)   { return BAJL.String(this).rel2abs  (base).get() }
		, 'String.prototype.absToRelBA'     : function(base)   { return BAJL.String(this).abs2rel  (base).get() }
		, 'String.prototype.getSanitizedStringBA' : function() { return BAJL.String(this).sanitize     ().get() }

		// deprecated 'BA'-prefixed global functions
		, 'BASingleton'            : BAJL.Singleton
		, 'BACreateDelegate'       : BAJL.Delegate
		, 'BAAlreadyApplied'       : BAJL.AlreadyApplied
		, 'BAPreloadImage'         : BAJL.PreloadImage
		, 'BAOpenWindow'           : BAJL.OpenWindow
		, 'BAOpenFullscreenWindow' : BAJL.OpenWindow.full
		, 'BAGetGeometry'          : BAJL.GetGeometry
		, 'BAGetCommonDir'         : BAJL.GetCommonDir
		, 'BAGetStyleSheets'       : _BADocument.getStyleSheetsBA

		// deprecated 'BA'-prefixed constructors
		, 'BAObservable'  : BAJL.Observable
		, 'BASetTimeout'  : BAJL.Timeout
		, 'BASetInterval' : BAJL.Interval
		, 'BATimer'       : BAJL.Timer
		, 'BATag'         : BAJL.Tag

		// deprecated BADOM-related functions
		, 'BARegisterDOMMethodsTo' : _setBADOM
		, 'BAAddOnload'            : function(func, aThis) { $(BAJL.Delegate(func, aThis)) }
		, 'BAAddOnunload'          : function(func, aThis) { $(window).unload(BAJL.Delegate(func, aThis)) }
		, 'BAAppendStateClassName' : function(className) { $(document.body).addClass(className) }
		, 'BARemoveStateClassName' : function(className) { $(document.body).removeClass(className) }
		, 'BAConcatNodeList'       : function() { var arr = []; $.makeArray(arguments).forEach(function(arg) { arr.concat($.makeArray(arg)) }); return arr }
		, 'BAStartGeometryMeasure' : BAJL.GetGeometry.continuously

		// deprecated ImportJS functions and properies
		, 'BAImportJS'  : BAJL.ImportJS
		, 'BAImportCSS' : BAJL.ImportCSS
	});
}



/* =============== for JSDoc toolkit output =============== */
/**
 * jQuery object, contains jQuery static methods.
 * @name jQuery
 * @namespace contains jQuery methods.
 */
/**
 * jQuery instance methods.
 * @name jQuery.fn
 * @fieldOf jQuery
 * @namespace jQuery instance methods.
 */



})(jQuery);

