/*@cc_on _d=document;eval('var document=_d')@*/
/**
 * @fileoverview 基本オブジェクトの拡張とUtilの基本クラスを定義します。
 * 
 * @author Bitstar.jp
 * @version 0.3.0
 */
/**
 * オブジェクト継承を可能にします。
 * @param {Object} dest 継承先ソース
 * @param {Object} source 継承元ソース
 * @return {Object} 継承されたオブジェクト
 */
Object.extend = function(dest, source) {
	for (var property in source) dest[property] = source[property];
	return dest;
};
/**
 * 非ネイティブプロパティのキー一覧を返します。
 * @return {Array} 非ネイティブプロパティのキー一覧
 */
Object.prototype.getProperties = function() {
	var keys = [];
	for (var property in this) if (typeof this[property] !== "function") keys.push(property);
	return keys;
};
/**
 * オブジェクトのクローンを返します。
 * @return {Object} クローンオブジェクト
 */
Object.prototype.clone = function() {
	return Object.extend({}, this);
};

// String 拡張
/**
 * 指定された文字列で始まるかどうかを返します。
 * @param {String} prefix 対象文字列
 * @return {Boolean} prefixで指定した文字列で始まっている場合はtrue
 */
String.prototype.startsWith = function(prefix) {
	if (prefix.length > this.length) return false; 
	return prefix == this.substring(0, prefix.length);
};
/**
 * 指定された文字列で終わるかどうかを返します。
 * @param {String} suffix 対象文字列
 * @return {Boolean} suffixで指定した文字列で終わっている場合はtrue
 */
String.prototype.endsWith = function(suffix) {
	if (suffix.length > this.length) return false;
	return suffix == this.slice(~suffix.length + 1);
};
/**
 * 前後の半角スペース、タブ、改行を取り除いた文字列を返します
 * @return {String} 前後の半角スペース、タブ、改行を取り除いた文字列
 */
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, "");
};
/**
 * trim()した文字列が""(空文字)であるかどうかを返します。
 * @return {Boolean} trim()した文字列が空文字である場合はtrue
 */
String.prototype.isBlank = function() {
	return this.trim() == "";
};
/**
 * 文字列が""(空文字)であるかどうかを返します。
 * @return {Boolean} 文字列が""(空文字)である場合はtrue
 */
String.prototype.isEmpty = function() {
	return this == "";
};
/**
 * 文字列を10進数の数値へ変換します。
 * @return {Number} 文字列を10進数の数値へ変換したもの<br>
 * 変換に失敗した場合は0
 */
String.prototype.toInt = function() {
	try {
		return parseInt(this,10);
	} catch ( ex ) {
		return 0;
	}
};
/**
 * 文字列を10進数の浮動小数点数へ変換します。
 * @return {Number} 文字列を10進数の浮動小数点数へ変換したもの<br>
 * 変換に失敗した場合は0.0
 */
String.prototype.toFloat = function() {
	try {
		return parseFloat(this,10);
	} catch ( ex ) {
		return 0.0;
	}
};
/**
 * 文字列をDateオブジェクトに変換します。
 * @param {Boolean} monthonly 日が無い文字列である場合はtrue
 * @return {Date} 文字列から生成された日付オブジェクト
 */
String.prototype.toDate = function(monthonly) {
	var date = null;
	if (typeof monthonly === "undefined") monthonly = false;
	if (this != "") {
		if (monthonly) {
			if (this.match(/((\d{2})?\d{2})\/(\d{1,2})/) || 
				this.match(/((\d{2})?\d{2})-(\d{1,2})/) ||
				this.match(/((\d{0})?\d{4})(\d{2})/)) {
				var year = RegExp.$1;
				var month = RegExp.$3;
				var day = 1;
				
				if (RegExp.$2 == "" && year.length == 2) { year = "19" + year; }
				year = year - 0; month = month - 1; day = day - 0;
				
				if (year > 1900 && year < 2100 && month >= 0 && month <= 11 && day >= 1 && day <= 31) {
					date = new Date(year, month, day);
					if (!(date.getFullYear() == year && date.getMonth() == month && date.getDate() == day)) { date = null; }
				}
			}
		} else {
			if (this.match(/((\d{2})?\d{2})\/(\d{1,2})\/(\d{1,2})/) || 
				this.match(/((\d{2})?\d{2})-(\d{1,2})-(\d{1,2})/) ||
				this.match(/((\d{0})?\d{4})(\d{2})(\d{2})/)) {
				var year = RegExp.$1;
				var month = RegExp.$3;
				var day = RegExp.$4;
				
				if (RegExp.$2 == "" && year.length == 2) { year = "19" + year; }
				year = year - 0; month = month - 1; day = day - 0;
				
				if (year > 1900 && year < 2100 && month >= 0 && month <= 11 && day >= 1 && day <= 31) {
					date = new Date(year, month, day);
					if (!(date.getFullYear() == year && date.getMonth() == month && date.getDate() == day)) { date = null; }
				}
			}
		}
	}
	return date;
};
/**
 * URLエンコーディングを行い、その結果を返します。
 * @return {String} 文字列をURLエンコーディングしたもの
 */
String.prototype.toQueryString = function() {
	return encodeURIComponent(this);
};
/**
 * 「-」のあとに続く小文字を大文字へ変換します。
 * @return {String} 「-」のあとに続く小文字を大文字へ変換したもの
 */
String.prototype.camelize = function() {
	return this.replace( /-([a-z])/g, function($0, $1) { return $1.toUpperCase(); });
};
/**
 * 大文字を「-」のあとに続く小文字へ変換します。
 * @return {String} 大文字を「-」のあとに続く小文字へ変換したもの
 */
String.prototype.deCamelize = function () {
	return this.replace( /[A-Z]/g, function($0) { return "-" + $0.toLowerCase();});
};

// Number拡張
/**
 * 数値を3桁ごとに「,」を入れた文字列に変換します。
 * @param {Boolean} disp 0を表示する場合はtrue(=false)
 * @return {String} 数値を3桁ごとに「,」を入れた文字列
 */
Number.prototype.format = function(disp) {
	if (typeof disp === "undefined") disp = false;
	var s = "" + this;
	var p = s.indexOf(".");
	if (p < 0) { // 小数点が見つからなかった時
		p = s.length; // 仮想的な小数点の位置とする
	}
	var r = s.substring(p, s.length); // 小数点の桁と小数点より右側の文字列
	for (var i = 0; i < p; i++) {
		var c = s.substring(p - 1 - i, p - 1 - i + 1);
		if (c < "0" || c > "9") {
			r = s.substring(0, p - i) + r;
			break;
		}
		if (i > 0 && i % 3 == 0) r = "," + r;
		r = c + r; // 数字を一桁追加する。
	}
	if (disp && r == "") r = 0;
	return r;
};

//Function拡張
/**
 * イベント登録などで利用できる形に変更したFunctionを返します。<br>
 * 引数は自由に設定可能ですが、第一引数は呼び出す関数内で[this]となるものである必要があります。<br>
 * @return {Function} 生成された関数
 */
Function.prototype.bind = function() {
	var args = new Array();
	for (var i=0; i<arguments.length;i++) {
		args.push(arguments[i]);
	}
	var __method = this, object = args.shift();
	var func = function() {
		try{
			var _args = new Array();
			for (var i=0; i<arguments.length;i++) {
				_args.push(arguments[i]);
			}
			return __method.apply(object, args.concat(_args));
		} catch (e) {
		}
	};
	func.__origin = this;
	return func;
};
/**
 * イベント登録などで利用できる形に変更したFunctionを返します。<br>
 * 引数は自由に設定可能ですが、第一引数は呼び出す関数内で[this]となるものである必要があります。<br>
 * また、呼び出されたFunctionの第一引数にはイベントオブジェクトが設定されます。
 * @return {Function} 生成された関数
 */
Function.prototype.bindAsEventListener = function(object) {
	var args = new Array();
	for (var i=0; i<arguments.length;i++) {
		args.push(arguments[i]);
	}
	
	var __method = this, object = args.shift();
	
	var func = function(event) {
		try{
			return __method.apply(object, [event || window.event].concat(args));
		} catch (e) {
		}
	};
	func.__origin = this;
	return func;
};

// Date拡張
/**
 * 日付のクローンを返します。
 */
Date.prototype.clone = function() {
	return new Date(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds());
};
/**
 * 日付文字列を取得します。
 * @param {Boolean} monthonly 日を必要としないときにtrue(=false)
 * @param {Boolean} notYear 年を必要としないときにtrue(=false)
 * @param {String} glue 連結文字列(="/")
 * @return {String} 日付文字列
 */
Date.prototype.format = function (monthonly, notYear, glue) {
	if (typeof monthonly === "undefined") monthonly = false;
	if (typeof notYear === "undefined") notYear = false;
	if (typeof glue === "undefined") glue = "/";
	
	var year = this.getFullYear();
	var month = this.getMonth() + 1;
	var day = this.getDate();
	
	if (month.toString().length < 2) { month = "0"+ month; }
	if (day.toString().length < 2) { day = "0"+ day; }
	
	var dates = new Array();
	if (!notYear) dates.push(year);
	dates.push(month);
	if (!monthonly) dates.push(day);
	
	return dates.join(glue);
};
/**
 * 国民の休日かどうかを取得します。
 * @return {Boolean} 国民の休日の場合はtrue
 */
Date.prototype.isHoliday = function () {
	var year = this.getFullYear();
	var month = this.getMonth() + 1;
	var day = this.getDate();
	var formatDate = this.format(false, true);
	var holidays = new Array("01/01", "01/15", "02/11", "04/29", "05/03", "05/04", "05/05", "07/20", "09/15", "10/10", "11/03", "11/23", "12/23");
	var isTransfer = (arguments.length > 0) ? arguments[0] : true;
	var isBetween = (arguments.length > 1) ? arguments[1] : true;
	
	// 法律制定以前と、特別な祝日チェック
	if (year < 1948 && month < 7 && day < 20) { // 祝日法の実施以前は祝日は存在しない
		return false;
	} else if (year == 1989 && formatDate == "02/24") { // 昭和天皇の大喪の礼
		return true;
	} else if (year == 1959 && formatDate == "04/10") { // 皇太子明仁親王の結婚の儀
		return true;
	} else if (year == 1993 && formatDate == "06/09") { // 皇太子徳仁親王の結婚の儀
		return true;
	} else if (year == 1990 && formatDate == "11/12") { // 即位礼正殿の儀
		return true;
	}
	
	// 通常の休日
	for (var i = 0; i < holidays.length; i++) { 
		if (formatDate == holidays[i]) { 
			switch (i) {
				case 1: // 成人の日
					if (year <= 1999 ) return true;
					break;
				case 2: // 建国記念日
					if (year >= 1967) return true;
					break;
				case 5: // みどりの日
					if (year >= 2007) return true;
					break;
				case 7: // 海の日
					if (year >= 1996 && year <= 2002) return true;
					break;
				case 8: // 敬老の日
					if (year >= 1966 && year <= 2002) return true;
					break;
				case 9: // 体育の日
					if (year >= 1966 && year <= 1999) return true;
					break;
				case 12: // 天皇誕生日
					if (year >= 1989) return true;
					break;
				default: // 元日、昭和の日、憲法記念日、こどもの日、文化の日、勤労感謝の日は常に祝日
					return true;
			}
		} 
	}
	
	// 春分、秋分
	switch (year % 4) {
		case 0:
			if ((year >= 1900 && year <= 1956) && formatDate == "03/21") { return true; } else if ((year >= 1960 && year <= 2088) && formatDate == "03/20") { return true; } else if ((year >= 2092 && year <= 2096) && formatDate == "03/19") { return true; }
			if (year == 1900 && formatDate == "09/23") { return true; } else if ((year >= 1904 && year <= 2008) && formatDate == "09/23") { return true; } else if ((year >= 2012 && year <= 2096) && formatDate == "09/22") { return true; }
			break;
		case 1:
			if ((year >= 1901 && year <= 1989) && formatDate == "03/21") { return true; } else if ((year >= 1993 && year <= 2097) && formatDate == "03/20") { return true; }
			if ((year >= 1901 && year <= 1917) && formatDate == "09/24") { return true; } else if ((year >= 1921 && year <= 2041) && formatDate == "09/23") { return true; } else if ((year >= 2045 && year <= 2097) && formatDate == "09/22") { return true; }
			break;
		case 2:
			if ((year >= 1902 && year <= 2022) && formatDate == "03/21") { return true; } else if ((year >= 2026 && year <= 2098) && formatDate == "03/20") { return true; }
			if ((year >= 1902 && year <= 1946) && formatDate == "09/24") { return true; } else if ((year >= 1950 && year <= 2041) && formatDate == "09/23") { return true; } else if ((year >= 2045 && year <= 2097) && formatDate == "09/22") { return true; }
			break;
		case 3:
			if ((year >= 1903 && year <= 1923) && formatDate == "03/22") { return true; } else if ((year >= 1927 && year <= 2055) && formatDate == "03/21") { return true; } else if ((year >= 2059 && year <= 2099) && formatDate == "03/20") { return true; }
			if ((year >= 1903 && year <= 1979) && formatDate == "09/24") { return true; } else if ((year >= 1983 && year <= 2099) && formatDate == "09/23") { return true; }
			break;
	}
	
	// ハッピーマンデー
	var lastweek = null;
	var count = 0;
	if (year >= 2000 && (month == 1 || month == 10) && this.getDay() == 1) {
		lastweek = new Date(this.getFullYear(), this.getMonth(), this.getDate());
		lastweek.setDate(lastweek.getDate() - 7);
		while ((lastweek.getMonth() + 1) == month) { lastweek.setDate(lastweek.getDate() - 7); }
		while (lastweek.format() != this.format()) { lastweek.setDate(lastweek.getDate() + 7); count++; }
		if (count == 2) return true;
	}
	if (year >= 2003 && (month == 7 || month == 9) && this.getDay() == 1) {
		lastweek = new Date(this.getFullYear(), this.getMonth(), this.getDate());
		lastweek.setDate(lastweek.getDate() - 7);
		while ((lastweek.getMonth() + 1) == month) { lastweek.setDate(lastweek.getDate() - 7); }
		while (lastweek.format() != this.format()) { lastweek.setDate(lastweek.getDate() + 7); count++; }
		if (count == 3) return true;
	}
	
	var yesterday = null;
	if (isTransfer) {
		// 振り替え休日
		if (year >= 1973) {
			yesterday = new Date(this.getFullYear(), this.getMonth(), this.getDate());
			yesterday.setDate(yesterday.getDate() - 1);
			if (year > 2006) {
				var holiday = false;
				while (yesterday.isHoliday(false)) {
					if (yesterday.getDay() == 0) { holiday = true; break; }
					yesterday.setDate(yesterday.getDate() - 1);
				}
				if (holiday) return true;
			} else if (yesterday.isHoliday(false, false) && yesterday.getDay() == 0) {
				return true;
			}
		}
	}
	
	if (isBetween) { 
		// 「国民の祝日」
		if (year >= 1988) {
			yesterday = new Date(this.getFullYear(), this.getMonth(), this.getDate());
			yesterday.setDate(yesterday.getDate() - 1);
			var tomorrow = new Date(this.getFullYear(), this.getMonth(), this.getDate());
			tomorrow.setDate(tomorrow.getDate() + 1);
			if (year > 2006) {
				if (yesterday.isHoliday(false, false) && tomorrow.isHoliday(false, false)) return true;
			} else {
				if (yesterday.isHoliday(false, false) && tomorrow.isHoliday(false, false) && yesterday.getDay() != 0) return true;
			}
		}
	}
	return false;
};

//Array拡張
/**
 * キー一覧を返します。
 * @return {Array} キー一覧
 */
Array.prototype.getKeys = function() {
	var keys = [];
	for (var property in this) if (typeof this[property] !== "function") keys.push(property);
	return keys;
};
/**
 * 指定した内容が含まれるかどうかを返します。
 * @param {any} value 対象となる値
 * @return {Boolean} 含まれる場合はtrue
 */
Array.prototype.contains = function(value) {
	var keys = this.getKeys();
	for (var i=0;i<keys.length;i++) if (this[keys[i]] == value) return true;
	return false;
};
/**
 * 値がvalueである最初のキーを取得します。
 * @param {any} value チェックする値
 * @return {any} 存在した場合はその最初のキー。存在しない場合はnull
 */
Array.prototype.findKey = function(value) {
	var keys = this.getKeys();
	for (var i=0;i<keys.length;i++) if (this[keys[i]] == value) return keys[i];
	return null;
};
/**
 * 値がvalueであるキーの一覧を取得します。
 * @param {any} value チェックする値
 * @return {Array} 値がvalueである配列
 */
Array.prototype.findKeys = function(value) {
	var keys = this.getKeys();
	var ret = [];
	for (var i=0;i<keys.length;i++) if (this[keys[i]] == value) ret.push(keys[i]);
	return ret;
};
/**
 * 配列の内容をシャッフルします。<br>
 * 連想配列の場合は正常に動きません。
 */
Array.prototype.shuffle = function() {
	var i = this.length;
	while(i){
		var j = Math.floor(Math.random()*i);
		var t = this[--i];
		this[i] = this[j];
		this[j] = t;
	}
};
/**
 * 配列の中身をシャッフルした配列を返します。<br>
 * 連想配列の場合は正常に動作しません。
 * @return {Array} 中身をシャッフルした配列
 */
 Array.prototype.shuffleclone = function() {
	var len = this.length;
	var ary = this.concat();
	var res = [];
	while(len) res.push(ary.splice(Math.floor(Math.random()*len--),1));
	return res;
};
 /**
  * Iteratorを返します。<br>
  * Iteratorは以下のメソッドを持ちます。<br>
  * hasNext() - 次の要素がある場合はtrue<br>
  * next() - 次の要素を取得する<br>
  * 連想配列の場合は正常に動作しません。
  * @return {Iterator} 生成されたIterator
  */
 Array.prototype.iterator = function(){
	var len = this.length;
	var ary = this.concat();
	return {
		/**
		 * 次の要素があるかどうかを返します。
		 * @return {Boolean} 次の要素がある場合はtrue
		 */
		hasNext: function(){
			return len ? true : false;
		},
		/**
		 * 次の要素を取得します。
		 * @return {any} 次の要素
		 */
		next: function(){
			if(!len--) return null;
			return ary.splice(0,1);
		}
	};
};
 
 /**
  * ランダムに生成されたIteratorを返します。<br>
  * Iteratorは以下のメソッドを持ちます。<br>
  * hasNext() - 次の要素がある場合はtrue<br>
  * next() - 次の要素を取得する<br>
  * 連想配列の場合は正常に動作しません。
  * @return {Iterator} 生成されたIterator
  */
Array.prototype.randomIterator = function(){
	var len = this.length;
	var ary = this.concat();
	return {
		/**
		 * 次の要素があるかどうかを返します。
		 * @return {Boolean} 次の要素がある場合はtrue
		 */
		hasNext: function(){
			return len ? true : false;
		},
		/**
		 * 次の要素を取得します。
		 * @return {any} 次の要素
		 */
		next: function(){
			if(!len) return null;
			var i = Math.floor(Math.random() * len--);
			return ary.splice(i,1);
		}
	};
};
/**
 * 配列からクエリストリングを作成します。<br>
 * string,number,null,undefinedが値として入っている項目に対してのみ作成を行います。
 * @return {String} クエリストリング
 */
Array.prototype.toQueryString = function() {
	var keys = this.getKeys();
	var queries = [];
	for (var i=0; i<keys.length; i++) {
		var key = keys[i];
		switch (typeof this[key]) {
			case "string":
				queries.push(key+"="+this[key].toQueryString());
				break;
			case "number":
				queries.push(key+"="+this[key]);
				break;
			case "null":
			case "undefined":
				queries.push(key+"=");
				break;
		}
	}
	return queries.join("&");
};

/**
 * window.document.getElementByIdへのショートカットです。
 * @param string id HTMLElementのID
 * @return id に対応したHTMLElement
 */
function $(id) { return window.document.getElementById(id); };

/**
 * window.promptを拡張します。
 * @param {String} mes - メッセージ
 * @param {String} def - デフォルト
 * @return {String} 入力された文字列
 */
var nativePrompt = window.prompt;
window.prompt = function(mes, def) {
	var res = window.nativePrompt(mes, def);
	if (res != null) {
		if (document.all){
			res_b = escape(res);
			pos = res_b.indexOf("%00");
			if (pos != -1) res_b = res_b.substr(0,pos);
			res = unescape(res_b);
		}
	}
	return res;
};

/**
 * 基本クラスです。
 * @class Util基本クラス
 * @return {BitstarUtil} 基本クラス
 */
var BitstarUtil = function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.ClassName = "BitstarUtil"; 
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Version = "0.3.0";
/**
 * ブラウザ管理オブジェクトです。
 * @return {BitstarUtil.Browser} ブラウザ管理オブジェクト
 */
BitstarUtil.prototype.Browser = null;
/**
 * ページ管理オブジェクトです。
 * @return {BitstarUtil.PageControl} ページ管理オブジェクト
 */
BitstarUtil.prototype.PageControl = null;
/**
 * イベント拡張オブジェクトです。
 * @return {BitstarUtil.Event} イベント拡張オブジェクト
 */
BitstarUtil.prototype.Event = null;
/**
 * エレメント管理オブジェクトです。
 * @return {BitstarUtil.Element} エレメント管理オブジェクト
 */
BitstarUtil.prototype.Element = null;
/**
 * コンストラクタです。
 */
BitstarUtil.prototype.initialize = function() {
	// 各種管理オブジェクトを作成します。
	this.Browser = new BitstarUtil.Browser(this);
	this.PageControl = new BitstarUtil.PageControl(this);
	this.Event = new BitstarUtil.Event(this);
	this.Element = new BitstarUtil.Element(this);
	
	// 現在のマウス位置を設定するイベントを登録します。
	this.Event.observe(document, "mousemove", this.Event.setPosition.bind(this.Event), false);
	// 画面破棄時にイベントを削除する(IEメモリリーク対策)
	this.Event.observe(window, "unload", this.Event.clearEvent.bind(this), false);
};

/**
 * ブラウザ情報クラスです。
 * @class ブラウザ情報クラス
 * @return {BitstarUtil.Browser} ブラウザ情報クラス
 */
BitstarUtil.Browser =  function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.Browser.ClassName = "BitstarUtil.Browser";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Browser.Version = "0.3.0";
/**
 * 親オブジェクトです。
 * @return {BitstarUtil} 親オブジェクト
 */
BitstarUtil.Browser.prototype.parent = null;
/**
 * ブラウザがIEかどうかを返します。
 * @return {Boolean} ブラウザがIEの場合はtrue
 */
BitstarUtil.Browser.prototype.IE = !!(window.attachEvent && !window.opera);
/**
 * ブラウザがOperaかどうかを返します。
 * @return {Boolean} ブラウザがOperaの場合はtrue
 */
BitstarUtil.Browser.prototype.Opera = !!window.opera;
/**
 * ブラウザがWebKitかどうかを返します。
 * @return {Boolean} ブラウザがWebKitの場合はtrue
 */
BitstarUtil.Browser.prototype.WebKit = navigator.userAgent.indexOf("AppleWebKit/") > -1;
/**
 * ブラウザがGeckoかどうかを返します。
 * @return {Boolean} ブラウザがGeckoの場合はtrue
 */
BitstarUtil.Browser.prototype.Gecko = (navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") == -1);
/**
 * ブラウザがMobileSafaliかどうかを返します。
 * @return {Boolean} ブラウザがMobileSafaliの場合はtrue
 */
BitstarUtil.Browser.prototype.MobileSafari = !!navigator.userAgent.match(/Apple.*Mobile.*Safari/);
/**
 * コンストラクタです。
 * @param {BitstarUtil} 基本クラス
 */
BitstarUtil.Browser.prototype.initialize = function(parent) {
	this.parent = parent;
};
/**
 * ブラウザタイプを表示します。
 */
BitstarUtil.Browser.prototype.showType = function() {
	window.alert(
		"IE : " + this.IE + "\n"+
		"Opera : " + this.Opera + "\n"+
		"WebKit : " + this.WebKit + "\n"+
		"Gecko : " + this.Gecko + "\n"+
		"MobileSafari : " + this.MobileSafari
	);
};
/**
 * ブラウザの表示領域の高さを返します。
 * @return {Number} ブラウザの表示領域の高さ
 */
BitstarUtil.Browser.prototype.getBrowserHeight = function() {
	if (window.self && self.innerHeight) return self.innerHeight;
	if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
	return document.body.offsetHeight;
};
/**
 * ブラウザの表示領域の幅を返します。
 * @return {Number} ブラウザの表示領域の幅
 */
BitstarUtil.Browser.prototype.getBrowserWidth = function() {
	if (window.self && self.innerWidth) return self.innerWidth;
	if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
	return document.body.offsetWidth;
};

/**
 * ページ情報管理クラスです。
 * @class ページ情報管理クラス
 * @return {BitstarUtil.PageControl} ページ情報管理クラス
 */
BitstarUtil.PageControl =  function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.PageControl.ClassName = "BitstarUtil.PageControl";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.PageControl.Version = "0.3.0";
/**
 * 親オブジェクトです。
 * @return {BitstarUtil} 親オブジェクト
 */
BitstarUtil.PageControl.prototype.parent = null;
/**
 * 子ウィンドウであるかどうかを返します。
 * @return {Boolean}子ウィンドウである場合はtrue
 */
BitstarUtil.PageControl.prototype.isChild = !!window.opener;
/**
 * 初期実行スクリプトの配列です。
 * @return {Array} 初期実行スクリプト配列
 */
BitstarUtil.PageControl.prototype.initScript = new Array();
/**
 * コンストラクタです。
 * @param {BitstarUtil} 基本クラス
 */
BitstarUtil.PageControl.prototype.initialize = function(parent) {
	this.parent = parent;
};
/**
 * 初期スクリプトを追加します。
 * @param {Function} script - 初期実行スクリプト
 */
BitstarUtil.PageControl.prototype.appendInit = function(script) {
	this.initScript.push(script);
};
/**
 * 初期スクリプトを実行します。
 */
BitstarUtil.PageControl.prototype.doInit = function() {
	for (s in this.initScript) this.initScript[s]();
};
/**
 * キャンセル可能なメッセージダイアログを表示します。
 * @param {String} message 表示するメッセージ
 * @param {Number} line_number 一度に表示する行数
 * @return {Boolean} 最後まで表示した場合はtrue
 */
BitstarUtil.PageControl.prototype.dispMessage = function (message, line_number) {
	if (typeof line_number === "undefined") line_number = 20;
	if (typeof message != "undefined") {
		var lines = message.split("\n");
		var m = "";
		for (var i=0; i<lines.length; i++) {
			m += lines[i] + "\n";
			if (i % line_number == line_number -1 || i == lines.length - 1) {
				if (i != lines.length - 1) {
					m+= "\n--------------------------------------------------------------------";
					m+= "\n続きを見ずに閉じる場合は「キャンセル」を選択してください。";
					m+= "\n--------------------------------------------------------------------";
					var ret = window.confirm(m);
					if (!ret) return false;
				} else {
					window.alert(m);
				}
				m="";
			}
		}
		return true;
	}
	return false;
};
/**
 * Bodyの高さを取得します。<br>
 * Bodyの高さとブラウザの表示領域の高さを比較し、大きいほうが返されます。
 * @return {Number} Bodyの高さとブラウザの表示領域の高さのうち大きい値
 */
BitstarUtil.PageControl.prototype.getBodyHeight = function() {
	return (document.body.scrollHeight > this.parent.Browser.getBrowserHeight()) ? document.body.scrollHeight : this.parent.Browser.getBrowserHeight();
};
/**
 * Bodyの幅を取得します。<br>
 * Bodyの幅とブラウザの表示領域の幅を比較し、大きいほうが返されます。
 * @return {Number} Bodyの幅とブラウザの表示領域の幅のうち大きい値
 */
BitstarUtil.PageControl.prototype.getBodyWidth = function() {
	return (document.body.scrollWidth > this.parent.Browser.getBrowserWidth()) ? document.body.scrollWidth : this.parent.Browser.getBrowserWidth();
};
/**
 * Formの内容からクエリストリングを作成します。
 * @param {String} form_id クエリストリングを作成するフォームのID
 * @param {Boolean} do_escape URLエスケープを行う場合はtrue
 * @return {String} 作成されたクエリストリング
 */
BitstarUtil.PageControl.prototype.toQueryString = function(form_id, do_escape) {
	if (typeof(do_escape) === "undefined") do_escape = false;
	var form = $(form_id);
	var query = "";
	var params = new Array();
	
	if (!form) return "";
	for (var i = 0; i < form.elements.length; i++) {
		var elm = form.elements[i];
		if (elm.name != "") {
			var value = elm.value;
			if (typeof(value) === "string" && do_escape) value = value.toQueryString();
			
			switch (elm.type) {
				case "checkbox":
					if (elm.checked) params.push(elm.name+"="+value);
					break;
				case "radio":
					if (elm.checked) params.push(elm.name+"="+value);
					break;
				default:
					params.push(elm.name+"="+value);
			}
		}
	}
	
	if (params.length > 0) query += params.join("&");
	return query;
};

/**
 * イベント拡張クラスです。
 * @class イベントを拡張したクラス
 * @return {BitstarUtil.Event} イベント拡張クラス
 */
BitstarUtil.Event =  function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.Event.ClassName = "BitstarUtil.Event";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Event.Version = "0.3.0";
/**
 * 親オブジェクトです。
 * @return {BitstarUtil} 親オブジェクト
 */
BitstarUtil.Event.prototype.parent = null;
/**
 * マウスのX座標です。
 * @return {Number} マウスのX座標
 */
BitstarUtil.Event.prototype.X = null;
/**
 * マウスのY座標です。
 * @return {Number} マウスのY座標
 */
BitstarUtil.Event.prototype.Y = null;
/**
 * イベント一覧です。
 */
BitstarUtil.Event.prototype.observers = false;
/**
 * コンストラクタです。
 * @param {BitstarUtil} 基本クラス
 */
BitstarUtil.Event.prototype.initialize = function(parent) {
	this.parent = parent;
};
/**
 * マウスのX,Y座標を設定します。
 */
BitstarUtil.Event.prototype.setPosition = function() {
	ev = this.getEvent();
	this.X = (ev.pageX || (ev.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)));
	this.Y = (ev.pageY || (ev.clientY + (document.documentElement.scrollTop || document.body.scrollTop)));
};
/**
 * イベントの発生したX座標を取得します。
 * @return {Number} イベントが発生したX座標
 */
BitstarUtil.Event.prototype.pointerX = function() {
	return this.X;
};
/**
 * イベントの発生したY座標を取得します。
 * @return {Number} イベントが発生したY座標
 */
BitstarUtil.Event.prototype.pointerY = function() {
	return this.Y;
};
/**
 * 発生したイベントを取得します。
 * @return {Event} 発生したイベント
 */
BitstarUtil.Event.prototype.getEvent = function() {
	var func = arguments.callee;
	while (func) {
		if (func.caller != null) {
			func = func.caller;
		} else {
			break;
		}
	}
	
	return func.arguments[0] || window.event;
};
/**
 * イベント名を取得します。
 * @return {String} イベント名 
 */
BitstarUtil.Event.prototype.getEventType = function() {
	ev = this.getEvent();
	return (ev) ? ev.type : "";
};
/**
 * キーコードを取得します。<br>
 * 現在一部のOSとブラウザの組み合わせでは正常に取得できません。
 * @return {Number} キーコード
 */
BitstarUtil.Event.prototype.getKeyCode = function() {
	ev = this.getEvent();
	if (ev.keyCode != 0) {
		return ev.keyCode;
	} else {
		return ev.charCode;
	}
};
/**
 * イベントが発生したソースを取得します。
 * @return {HTMLElement} イベントが発生したHTMLElement
 */
BitstarUtil.Event.prototype.getElement = function() {
	ev = this.getEvent();
	var src = ev.target || ev.srcElement;
	return src; 
};
/**
 * 領域変更イベントの移動元HTMLElementを取得します。
 * @return {HTMLElement} 領域変更イベントの移動元HTMLElement
 */
BitstarUtil.Event.prototype.getFromElement = function() {
	ev = this.getEvent();
	if (!ev) return null;
	return (this.getEventType() == "mouseout" ? ev.target : ev.relatedTarget) || ev.fromElement;
};
/**
 * 領域変更イベントの移動先HTMLElementを取得します。
 * @return {HTMLElement} 領域変更イベントの移動先HTMLElement
 */
BitstarUtil.Event.prototype.getToElement = function() {
	ev = this.getEvent();
	if (!ev) return null;
	return (this.getEventType() == "mouseout" ? ev.relatedTarget : ev.target) || ev.toElement;
};
/**
 * イベントソースから見て、指定されたタグのエレメントDOMツリー上方向に探します。
 * @param {String} tagName - 検索するタグ名
 * @return {HTMLElement} 指定されたタグの一番最初のエレメント
 */
BitstarUtil.Event.prototype.findElement =  function(tagName) {
	var element = this.getSource();
	while (element && element.parentNode && (!element.tagName ||(element.tagName.toUpperCase() != tagName.toUpperCase()))) element = element.parentNode;
	return element;
};
/**
 * イベントを停止します。
 */
BitstarUtil.Event.prototype.stop = function() {
	ev = this.getEvent();
	if (!ev) return;
	if (ev.preventDefault) {
		ev.stopPropagation();
		ev.preventDefault();
	} else {
		ev.cancelBubble = true;
		ev.returnValue = false;
	}
};
/**
 * 内部用イベント登録メソッドです。
 * @param {HTMLElement} element - 対象のElement
 * @param {String} name - イベント名
 * @param {Function} func - 発生させるメソッド
 * @param {Boolean} useCapture - キャプチャする場合はtrue(FF)
 */
BitstarUtil.Event.prototype.__observe = function(element, name, func, useCapture) {
	if (!this.observers) this.observers = [];
	this.observers.push([element, name, func, useCapture]);
	if (typeof useCapture === "undefined") useCapture = false;
	if (element.addEventListener) {
		element.addEventListener(name, func, useCapture);
	} else if (element.attachEvent) {
		element.attachEvent('on' + name, func);
	}
};
/**
 * イベントを追加します。
 * @param {HTMLElement} element - 対象のElement
 * @param {String} name - イベント名
 * @param {Function} func - 発生させるメソッド
 * @param {Boolean} useCapture - キャプチャする場合はtrue(FF)
 */
BitstarUtil.Event.prototype.observe = function(element, name, func, useCapture) {
	this.__observe(element, name, func, useCapture);
};
/**
 * 内部用イベント削除メソッドです。<br>
 * funcは同一のオブジェクトか、一字一句同一の内容のものであれば削除されます.
 * @param {HTMLElement} element - 対象のElement
 * @param {String} name - イベント名
 * @param {Function} func - 発生させるメソッド
 * @param {Boolean} useCapture - キャプチャする場合はtrue(FF)
 */
BitstarUtil.Event.prototype.__transgress = function(element, name, func, useCapture) {
	if (typeof useCapture === "undefined") useCapture = false;
	if (this.observers) {
		for (var i = this.observers.length - 1; i >= 0; i--) {
			var t = this.observers[i];
			var f = (func.__origin) ? func.__origin : func;
			var _f = (t[2].__origin) ? t[2].__origin : t[2];
			var del = (f == _f) || (f.toString().replace(/(\s|\n)/g,"").toUpperCase() == _f.toString().replace(/(\s|\n)/g,"").toUpperCase());
			if (element == t[0] && name == t[1] && del) {
				if (element.removeEventListener) {
					element.removeEventListener (name, t[2], useCapture);
				} else if (element.detachEvent) {
					try {
						element.detachEvent('on' + name, t[2]);
					} catch (e) {}
				}
				this.observers.splice(i, 1);
				break;
			}
		}
	}
};
/**
 * イベントを削除します。<br>
 * funcは同一のオブジェクトか、一字一句同一の内容のものであれば削除されます。
 * @param {HTMLElement} element - 対象のElement
 * @param {String} name - イベント名
 * @param {Function} func - 発生させるメソッド
 * @param {Boolean} useCapture - キャプチャする場合はtrue(FF)
 */
BitstarUtil.Event.prototype.transgress = function(element, name, func, useCapture) {
	this.__transgress(element, name, func, useCapture);
};
/**
 * イベントをクリアします。
 */
BitstarUtil.Event.prototype.clearEvent = function() {
	if (this.observers) {
		for (var i = this.observers.length - 1; i >= 0; i--) {
			var t = this.observers[i];
			if (el == t[0] && ename == t[1] && del) {
				if (t[0].removeEventListener ) {
					t[0].removeEventListener (t[1], t[2], false);
				} else if (t[0].detachEvent) {
					try {
						t[0].detachEvent('on' + t[1], t[2]);
					} catch (e) {}
				}
			}
		}
		this.observers = false;
	}
};
/**
 * イベントを起動します。
 * @param {HTMLElement} element イベント起動対象HTMLElement
 * @param {String} name イベント名
 */
BitstarUtil.Event.prototype.fire = function(element, name) {
	if (element) {
		if (element.fireEvent) {
			element.fireEvent('on'+name);
		} else {
			// TODO もっと種類をふやそう
			var e = null;
			switch (name) {
				case "change" :
				case "resize":
					e = document.createEvent("HTMLEvents");
					e.initEvent(name, true, true);
					break;
			}
			if (e != null) element.dispatchEvent( e );
		}
	}
};

/**
 * エレメント情報クラスです。
 * @class エレメント情報クラス
 * @return {BitstarUtil.Element} エレメント情報クラス
 */
BitstarUtil.Element =  function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.Element.ClassName = "BitstarUtil.Element";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Element.Version = "0.2.0";
/**
 * 親オブジェクトです。
 * @return {BitstarUtil} 親オブジェクト
 */
BitstarUtil.Element.prototype.parent = null;
/**
 * コンストラクタです。
 * @param {BitstarUtil} 基本クラス
 */
BitstarUtil.Element.prototype.initialize = function(parent) {
	this.parent = parent;
};
/**
 * ElementのBody上部からの絶対位置を取得します。
 * @param {HTMLElement} element 対象HTMLElement
 * @return {Number} elementのBody上部からの絶対位置
 */
BitstarUtil.Element.prototype.offsetTop = function(element) {
	var obj = element;
	var value = 0;
	do {
		value += obj.offsetTop  || 0;
		obj = obj.offsetParent;
	} while (obj);
	return value;
};
/**
 * ElementのBody左部からの絶対位置を取得します。
 * @param {HTMLElement} element 対象HTMLElement
 * @return {Number} elementのBody左部からの絶対位置
 */
BitstarUtil.Element.prototype.offsetLeft = function(element) {
	var obj = element;
	var value = 0;
	do {
		value += obj.offsetLeft || 0;
		obj = obj.offsetParent;
	} while (obj);
	return value;
};
/**
 * elementがtargetElementの子要素であるかどうかを取得します。
 * @param {HTMLElement} element 対象HTMLElement
 * @param {HTMLElement} targetElement 比較するHTMLElement
 * @return {Boolean} elementがtargetElementの子要素である場合はtrue
 */
BitstarUtil.Element.prototype.isContainsObject = function(element, targetElement) {
	while (element) {
		if (element == targetElement) return true;
		element = element.parentNode;
	}
	return false;
};
/**
 * elementを中央に配置します。
 * @param {HTMLElement} element 対象HTMLElement
 * @param {Boolean} fullsize trueの場合は、Bodyがブラウザ表示域より大きな場合Bodyの中心に合わせます。そうでない場合はブラウザ表示域の中心に合わせます(=false)
 */
BitstarUtil.Element.prototype.setCenter = function(element, fullsize) {
	if (typeof fullsize === "undefined") fullsize = false;
	if (!element) return;
	
	var targetWidth = (fullsize) ?  this.parent.PageControl.getBodyWidth() : this.parent.Browser.getBrowserWidth();
	var offsetWidth = element.offsetWidth;
	var left = 0;
	if (element.offsetParent) left = this.parent.Element.offsetLeft(element.offsetParent);
	var scrollLeft = (fullsize) ?  0: document.body.scrollLeft;
	var width = (targetWidth - offsetWidth) / 2  - left + scrollLeft;
	if (width > 0) element.style.left = width + "px";
	
	var targetHeight = (fullsize) ?  this.parent.PageControl.getBodyHeight() : this.parent.Browser.getBrowserHeight();
	var offsetHeight = element.offsetHeight;
	var top = 0;
	if (element.offsetParent) top = this.parent.Element.offsetTop(element.offsetParent);
	var scrollTop = (fullsize) ?  0: document.body.scrollTop;
	var height = (targetHeight - offsetHeight) / 2 - top + scrollTop;
	if (height > 0) element.style.top = height + "px";
};
/**
 * エレメントの現在の指定されたスタイルを取得します。
 * @param {HTMLElement} element 対象エレメント
 * @param {String} property CSSプロパティ名またはjavascript.styleで使用するプロパティ名
 * @return {String} エレメントの現在の指定されたスタイル
 */
BitstarUtil.Element.prototype.getStyle = function(element, property) {
	if (!element) return "";
	if (element.currentStyle) { //IE or Opera  
		if (property.indexOf( "-" ) != -1) property = property.camelize(); 
		mt =  element.currentStyle[property];
	} else if ( getComputedStyle ) { //Mozilla or Opera or Safari
		mt = document.defaultView.getComputedStyle(element, '').getPropertyValue(property);  
	} 
	return mt;
};

/**
 * Ajaxクラスです。
 * @class Ajaxクラス
 * @return {BitstarUtil.Ajax} Ajaxクラス
 */
BitstarUtil.Ajax = function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.Ajax.ClassName = "BitstarUtil.Ajax";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Ajax.Version = "0.3.0";

// MINEタイプ
BitstarUtil.Ajax.MIME_TYPE_XML = "text/xml";

/**
 * ノードタイプを表す配列です。
 * @return {Array} ノードタイプ配列
 */
BitstarUtil.Ajax.NODETYPE_MAP = new Array(
	"",
	"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
);
/**
 * HTTPコネクションオブジェクトです。
 * @return {Object} HTTPコネクションオブジェクト
 */
BitstarUtil.Ajax.prototype.http = null;
/**
 * 非同期通信時に利用するコールバック関数です。
 * @return {Function} コールバック関数
 */
BitstarUtil.Ajax.prototype.callback_func = null;
/**
 * 非同期通信時に利用するコールバック関数に渡される引数です。
 * @return {any} コールバック関数に渡される引数
 */
BitstarUtil.Ajax.prototype.callback_args = null;
/**
 * コールバック関数で「this」として扱われるオブジェクトです。
 * @return {Object} コールバック関数で「this」として扱われるオブジェクト
 */
BitstarUtil.Ajax.prototype.callback_obj = null;
/**
 * 通信時にエラーが発生した場合に呼び出されるコールバック関数です。
 * @return {Function} コールバック関数
 */
BitstarUtil.Ajax.prototype.onerror_func = null;
/**
 * コンストラクタです。
 */
BitstarUtil.Ajax.prototype.initialize = function() {
	url = arguments[0];
	query = arguments[1];
	method = arguments[2];
	this.http = new BitstarUtil.Ajax.HTTP(url, query, method, false);
};
/**
 * 非同期関数を設定します。
 * @param {Function} func コールバック関数
 * @param {any} args コールバック関数用引数
 * @param {Object} obj コールバック関数内で「this」で扱われるオブジェクト(=null)
 */
BitstarUtil.Ajax.prototype.async = function(func, args, obj) {
	if (typeof args === "undefined") obj = null;
	this.callback_func = func;
	this.callback_args = args;
	this.callback_obj = obj;
};
/**
 * エラー関数を設定します。
 * @param {Function} func エラー関数
 */
BitstarUtil.Ajax.prototype.onerror = function(func) {
	this.onerror_func = func;
};
/**
 * パース処理を行います。
 */
BitstarUtil.Ajax.prototype.parse = function() {
	// HTTPオブジェクトが設定されていない場合は何もしない
	if (!this.http) return;
	
	// エラー関数を設定
	if (this.onerror_func) this.http.onerror(this.onerror_func);
	
	// 非同期時
	if (this.callback_func) {
		var __this = this;
		var proc = function() {
			if (!__this.http) return;
			var data = __this.parseResponse();
			if (__this.callback_obj != null) {
				__this.callback_func.bind(__this.callback_obj)(data, __this.callback_args);
			} else {
				__this.callback_func(data, __this.callback_args);
			}
		};
		this.http.async(proc);
	}
	// 読み込み
	this.http.load();
	// 同期時
	if (!this.callback_func) return this.parseResponse();
};
/**
 * 強制的に配列として出力させるカラムを設定します。
 * @param {any} column 強制的に配列として出力させるカラム名<br>
 * columnは、文字列が渡された場合はそのカラムを、配列が渡された場合はその配列に含まれる各文字列をカラム名とする結果が配列になります。<br>
 * columnが"*"である、もしくは"*"を含む配列である場合には、全てのカラムが強制的に配列になります。
 */
BitstarUtil.Ajax.prototype.setForceOutputArray = function (column) {
	// 文字列の場合
	if ( typeof(column) == "string" ) column = new Array(column);
	if ( column && typeof(column) == "object" ) {
		if ( column.length < 0 ) {
			column = false; 
		} else {
			var hash = {};
			for (var i=0;i<column.length;i++) hash[column[i]] = true;
			column = hash;
			// アスタリスクが含まれる場合は全ての項目
			if (column["*"]) column = true;
		} 
	} 
	this.forcearray = column;
};
/**
 * レスポンスのパースを行います。
 * @return {Object} パース結果オブジェクト
 */
BitstarUtil.Ajax.prototype.parseResponse = function () {
	var root = this.http.documentElement();
	var data = this.parseDocument(root);
	return data;
};
/**
 * ドキュメントのパースを行います。
 * @param {Object} root 取得した結果のRoot要素
 * @return {Object} パース結果JSONオブジェクト
 */
BitstarUtil.Ajax.prototype.parseDocument = function (root) {
	// Root要素が存在しない場合は何もしない
	if (!root) return null;
	// エレメントのパース
	var ret = this.parseElement(root);
	// 配列展開方法のチェック
	if (this.forcearray == null) {
		// 設定されていない場合は、項目が単独の場合はそのまま。そうでない場合は配列
	} else if (this.forcearray === true) {
		// setForceOutputArrayに*が渡されている場合は全て配列にする
		ret = [ret];
	} else if (this.forcearray[root.nodeName]) {
		// 指定された項目を強制的に配列にする
		ret = [ret];
	}
	
	var json = {};
	json[root.nodeName] = ret;
	return json;
};
/**
 * エレメントのパースを行います。
 * @param {Object} elem パース対象となるエレメント
 * @return {Object} パース結果
 */
BitstarUtil.Ajax.prototype.parseElement = function (elem) {
	var nodetype = BitstarUtil.Ajax.NODETYPE_MAP[elem.nodeType];
	//  コメントは無視
	if (nodetype == "COMMENT_NODE") return;
	//  テキストかCDATAの場合
	if (nodetype == "TEXT_NODE" || nodetype == "CDATA_SECTION_NODE") {
		// for Safari
		var bool = elem.nodeValue.match( /[^\x00-\x20]/ );
		return elem.nodeValue;
	}
	var retval;
	var cnt = {};
	//  属性のパース
	if (elem.attributes && elem.attributes.length) {
		retval = {};
		for (var i=0; i<elem.attributes.length; i++) {
			var key = elem.attributes[i].nodeName;
			if (typeof(key) != "string") continue;
			var val = elem.attributes[i].nodeValue;
			if (typeof(cnt[key]) == "undefined") cnt[key] = 0;
			cnt[key]++;
			this.addNode(retval, key, cnt[key], val);
		}
	}
	
	//  再帰的に子要素をパースする
	if (elem.childNodes && elem.childNodes.length) {
		// 属性がある場合はテキストモードとして扱わない
		var textonly = (!retval);
		// 子要素があるかどうか
		for (var i=0; i<elem.childNodes.length && textonly; i++) {
			var ntype = BitstarUtil.Ajax.NODETYPE_MAP[elem.childNodes[i].nodeType];
			if (ntype == "TEXT_NODE" || ntype ==  "CDATA_SECTION_NODE") continue;
			textonly = false;
		}
		
		if (textonly) {
			// テキストモードの場合
			if (!retval) retval = "";
			for (var i=0; i<elem.childNodes.length; i++) {
				retval += elem.childNodes[i].nodeValue;
			}
		} else {
			// 子要素がある場合
			if (!retval) retval = {};
			for (var i=0; i<elem.childNodes.length; i++) {
				var key = elem.childNodes[i].nodeName;
				if (typeof(key) != "string") continue;
				var val = this.parseElement(elem.childNodes[i]);
				if (typeof(cnt[key]) == "undefined") cnt[key] = 0;
				cnt[key] ++;
				this.addNode(retval, key, cnt[key], val);
			}
		}
	}
	
	return retval;
};
/**
 * 取得したデータからノードを作成します。
 * @param {Array} hash 現在のノードツリー
 * @param {String} key ノードのキー名
 * @param {Number} cnts カウント
 * @param {Object} val 内容
 */
BitstarUtil.Ajax.prototype.addNode = function (hash, key, cnts, val) {
	if (this.forcearray == null) {
		if (cnts == 1) {
			// 最初の項目
			hash[key] = val;
		} else if ( cnts == 2 ) {
			// 2番目の項目が存在する場合
			hash[key] = [ hash[key], val ];
		} else {
			// 3番目以降の項目
			hash[key][hash[key].length] = val;
		}
	} else if (this.forcearray === true) {
		if ( cnts == 1 ) hash[key] = [];
		hash[key][hash[key].length] = val;
	} else if (this.forcearray[key]) {
		if ( cnts == 1 ) hash[key] = [];
		hash[key][hash[key].length] = val;
	} else {
		if ( cnts == 1 ) hash[key] = val;
	}
};


/**
 * HTTPアクセスオブジェクトです。
 * @return {BitstarUtil.Ajax.HTTP} HTTPアクセスオブジェクト
 */
BitstarUtil.Ajax.HTTP = function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.Ajax.HTTP.ClassName = "BitstarUtil.Ajax.HTTP";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.Ajax.HTTP.Version = "0.3.0";

BitstarUtil.Ajax.HTTP.REQUEST_TYPE  = "application/x-www-form-urlencoded";
BitstarUtil.Ajax.HTTP.ACTIVEX_XMLDOM  = "Microsoft.XMLDOM"; 
BitstarUtil.Ajax.HTTP.ACTIVEX_XMLHTTP = "Microsoft.XMLHTTP";
BitstarUtil.Ajax.HTTP.EPOCH_TIMESTAMP = "Thu, 01 Jun 1970 00:00:00 GMT";
/**
 * 送信先URLです。
 * @return {String} 送信先URL
 */
BitstarUtil.Ajax.HTTP.prototype.url = "";
/**
 * 送信クエリです。
 * @return {String} 送信クエリ
 */
BitstarUtil.Ajax.HTTP.prototype.query = "";
/**
 * 送信メソッドです。
 * @return {String} 送信メソッド
 */
BitstarUtil.Ajax.HTTP.prototype.method = "GET";
/**
 * 非同期通信用コールバック関数です。
 * @return {Function} 非同期通信用コールバック関数
 */
BitstarUtil.Ajax.HTTP.prototype.async_func = null;
/**
 * HTTPリクエスト用オブジェクトです。
 * @return {Object} HTTPリクエスト用オブジェクト
 */
BitstarUtil.Ajax.HTTP.prototype.req = null;

/**
 * コンストラクタです。
 * @param {String} url 接続先URL
 * @param {String} query 送信クエリ
 * @param {String} method 送信メソッド 
 * @param {Boolean} textmode テキストモードフラグ
 */
BitstarUtil.Ajax.HTTP.prototype.initialize = function (url, query, method, textmode) {
	this.url = url;
	if ( typeof(query) == "string" ) {
		this.query = query;
	} else {
		this.query = "";
	}
	if ( method ) {
		this.method = method;
	} else if ( typeof(query) == "string" ) {
		this.method = "POST";
	} else {
		this.method = "GET";
	}
	this.textmode = textmode ? true : false;
	this.req = null;
	this.xmldom_flag = false;
	this.onerror_func  = null;
	this.callback_func = null;
	this.already_done = null;
};
/**
 * 非同期通信用コールバック関数を設定します。
 * @param {Function} func 非同期通信用コールバック関数
 * @return
 */
BitstarUtil.Ajax.HTTP.prototype.async = function(func) {
	this.async_func = func;
};
/**
 * データの読み込みを行います。
 * @return {Object} 読み込んだデータ
 */
BitstarUtil.Ajax.HTTP.prototype.load = function() {
	if (window.ActiveXObject) {
		// IEの場合
		var activex = BitstarUtil.Ajax.HTTP.ACTIVEX_XMLHTTP;
		if ( this.method == "GET" && !this.textmode ) {
			// IE6でテキストモードではない場合
			activex = BitstarUtil.Ajax.HTTP.ACTIVEX_XMLDOM;
		}
		this.req = new ActiveXObject(activex);
	} else if ( window.XMLHttpRequest ) {
		// Firefoxなど
		this.req = new XMLHttpRequest();
	}
	
	// 非同期関数がセットされている場合は非同期扱い
	var async_flag = this.async_func ? true : false;
	
	// HTTPリクエストを送信する
	if (typeof(this.req.send) != "undefined") {
		this.req.open(this.method, this.url, async_flag);
	}
	
	// リクエストヘッダの設定
	if (typeof(this.req.setRequestHeader) != "undefined") {
		this.req.setRequestHeader("Content-Type", BitstarUtil.Ajax.HTTP.REQUEST_TYPE);
	}
	
	// コンテントタイプの設定
	if (typeof(this.req.overrideMimeType) != "undefined" && !this.textmode) {
		this.req.overrideMimeType(BitstarUtil.Ajax.MIME_TYPE_XML);
	}
	
	// 非同期処理の場合
	if (async_flag) {
		var __this = this;
		__this.already_done = false;                  // not parsed yet
		var check_func = function () {
			if (__this.req.readyState != 4) return;
			var succeed = __this.checkResponse();
			// 失敗の場合は何もしない
			if (!succeed) return;
			// 実行済みフラグが設定されている場合は何もしない
			if (__this.done) return;
			// 実行済みフラグを設定
			__this.done = true;
			// コールバック関数を呼び出す
			__this.async_func();
		};
		// ステータス変更時のメソッド設定
		this.req.onreadystatechange = check_func;
	}
	
	// クエリの送信
	if (typeof(this.req.send) != "undefined") {
		this.req.send(this.query);
	} else if (typeof(this.req.load) != "undefined") {
		this.req.async = async_flag;
		this.req.load(this.url);
	}
	
	// 非同期の場合はそのまま終了
	if (async_flag) return;
	var succeed = this.checkResponse();
};
/**
 * レスポンスのチェックを行います。
 * @return {Boolean} レスポンスチェック結果
 */
BitstarUtil.Ajax.HTTP.prototype.checkResponse = function() {
	// パースに失敗した場合
	if ( this.req.parseError && this.req.parseError.errorCode != 0 ) {
		// エラー関数が設定されている場合はそれを呼び出す
		if ( this.onerror_func ) this.onerror_func( this.req.parseError.reason );
		// 失敗
		return false;
	}
	
	// HTTPステータスがOK,一部、変更なしのいずれでもない場合
	if (this.req.status-0 > 0 && this.req.status != 200 && this.req.status != 206 && this.req.status != 304) {
		// エラー関数が設定されている場合はそれを呼び出す
		if ( this.onerror_func ) this.onerror_func(this.req.status);
		// 失敗
		return false;
	}
	
	// 成功
	return true;
};
/**
 * ドキュメントエレメントを取得します。
 * @return {Object} ドキュメントエレメント
 */
BitstarUtil.Ajax.HTTP.prototype.documentElement = function() {
	if (!this.req) return;
	if (this.req.responseXML) {
		// XMLHTTPRequest
		return this.req.responseXML.documentElement;
	} else {
		// IXMLDOMDocument
		return this.req.documentElement;
	}
};
/**
 * リクエストテキストを取得します。
 * @return {String} リクエストテキスト
 */
BitstarUtil.Ajax.HTTP.prototype.responseText = function() {
	if (!this.req) return;
	
	//  一部ブラウザ用エンコーディング処理
	if (navigator.appVersion.match("KHTML")) {
		var esc = escape(this.req.responseText);
		if (!esc.match("%u") && esc.match("%")) {
			return decodeURIComponent(esc);
		}
	}
	return this.req.responseText;
};

/**
 * タイマー管理クラスです。
 * @class タイマー管理クラス
 * @return {BitstarUtil.IntervalTimer} タイマー管理クラス
 */
BitstarUtil.IntervalTimer = function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.IntervalTimer.ClassName = "BitstarUtil.IntervalTimer";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.IntervalTimer.Version = "0.3.0";
/**
 * コンストラクタです。
 */
BitstarUtil.IntervalTimer.prototype.initialize = function() {};
/**
 * イベントキューです。
 * @return {Array} イベントキュー
 */
BitstarUtil.IntervalTimer.prototype.queue = new Array();
/**
 * イベント実行最終時刻です。
 * @return {Interger} イベント実行最終時刻
 */
BitstarUtil.IntervalTimer.prototype.lastTime = new Date().getTime();
/**
 * イベントを追加します。
 * @param {Function} process  登録する処理
 * @param {Number} delay  実行インターバル
 * @return {Number} イベントID
 */
BitstarUtil.IntervalTimer.prototype.add = function(process, delay) {
	entry = new BitstarUtil.IntervalTimer.Entry(process, delay);
	var id = this.queue.length;
	this.queue[id] = entry;
	return id;
};

/**
 * タイマーイベントクラスです。
 * @class タイマーイベントクラス
 * @return {BitstarUtil.IntervalTimer.Entry} イベントタイマークラス
 */
BitstarUtil.IntervalTimer.Entry = function() { this.initialize.apply(this, arguments); };
/**
 * クラス名です。
 * @return {String} クラス名
 */
BitstarUtil.IntervalTimer.Entry.ClassName = "BitStarUtil.IntervalTimer.Entry";
/**
 * バージョンです。
 * @return {String} バージョン
 */
BitstarUtil.IntervalTimer.Entry.Version = "0.3.0";
/**
 * 実行する処理です。
 * @return {Function} 実行する処理
 */
BitstarUtil.IntervalTimer.Entry.prototype.process = null;
/**
 * 実行インターバルです。
 * @return {Number} 実行インターバル
 */
BitstarUtil.IntervalTimer.Entry.prototype.deley = null;
/**
 * 起動時間管理タイマーです。
 * @type {Number} 起動時間管理タイマー
 */
BitstarUtil.IntervalTimer.Entry.prototype.time = 0;
/**
 * コンストラクタ.
 */
BitstarUtil.IntervalTimer.Entry.prototype.initialize = function() {
	if (typeof arguments[0] == 'string') {
		this.process = function(){eval(arguments[0]);};
	} else if (typeof arguments[0] == 'function') {
		this.process = arguments[0];
	} else {
		throw Error('第一引数が不正です。');
	}
	this.delay   = arguments[1];
};
/**
 * ループ処理.
 * @param {Number} time - 管理タイマーに追加する時間(ms).
 */
BitstarUtil.IntervalTimer.Entry.prototype.loop = function (time) {
	this.time += time;
	while (this.time >= this.delay) {
		this.process();
		this.time -= this.delay;
	}
};

/**
 * 既存のタイマーを退避します。
 */
var nativeSetInterval = window.setInterval;
/**
 * 既存のタイマー解除を退避します。
 */
var nativeClearInterval = window.clearInterval;
/**
 * タイマーコントロールを作成します。
 */
var TimerControl = new BitstarUtil.IntervalTimer();
/**
 * setIntervalを上書きします。
 * @param {Function} process  実行する処理
 * @param {Number} delay  実行インターバル
 * @return {Number} 追加されたID
 */
window.setInterval = function(process, delay) {
	return TimerControl.add(process, delay);
};
/**
 * タイマーイベントを無効化します。
 * @param {Number} id - タイマーID
 */
window.clearInterval = function(id) {
	if (TimerControl.queue[id]) TimerControl.queue[id].loop = function(){};
};
/**
 * タイマーイベントを実行します。
 */
window.nativeSetInterval(function() {
	var time = new Date().getTime();
	var subTime =  time - TimerControl.lastTime;
	TimerControl.lastTime = time;
	
	for (var i = 0; i < TimerControl.queue.length; i++) {
		TimerControl.queue[i].loop(subTime);
	}
}, 10);

/**
 * 基本クラスのオブジェクトです。
 * @return {BitstarUtil} 基本クラスオブジェクト
 */
var BSU = new BitstarUtil();
