//======================================================================================
// common.js
//======================================================================================
/*
 * 共通 JavaScript
 *
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */

/**
 * ブラウザ画面領域の幅を取得
 */
function getWidth(win)
{
	var tmp_width;
    
	if (win.document.documentElement) { 
		tmp_width = win.document.documentElement.clientWidth;
		if (tmp_width > 0) {
			return tmp_width;
		}
	}
    if (win.document.all) {
    	tmp_width = win.document.body.clientWidth;
		return tmp_width;
	}
	return win.innerWidth;
}
       
/**
 * ブラウザ画面領域の高さを取得
 */
function getHeight(win)
{
	var tmp_height;
    
	if (win.document.documentElement) {
		tmp_height = win.document.documentElement.clientHeight;
		if (tmp_height > 0) {
			return(tmp_height);
		}
	}
    if (win.document.all) {
		return(win.document.body.clientHeight);
	}
	return(win.innerHeight);
}

/**
 * Windowを中心に移動
 */
function moveWindowToCenter(win) {
	x = (screen.width  - getWidth(win)) / 2;
	y = (screen.height - getHeight(win)) / 2;
	win.moveTo(x,y);
}

/**
 * 常に手前に表示するウィンドウを開く
 */
function openModalWindow(url, name, height, width, scrollbars, resizable, status)
{
	ModalWindow = openWindow(url, name, height, width, scrollbars, resizable, status);
	onfocus = function onFocus(){
		if (null !=ModalWindow && !ModalWindow.closed) {
			try {
				ModalWindow.focus();
			} catch(e) {
				document.onmousemove = null;
			}
		} else {
			document.onmousemove = null;
		}
	}
	
	document.onmousemove = onfocus;
	
	return ModalWindow;
}

/**
 * ウィンドウを開く
 */
function openWindow(url, name, height, width, scrollbars, resizable, status, left, top)
{
	var window_condition = "height=" + height + ",width=" + width + 
					((left) ? ",left=" + left : "") + ((top) ? ",top=" + top : "") +
					",scrollbars=" + scrollbars + ",resizable=" + resizable + ",toolbar=no,status=" + status;

	subWindow = window.open(url, name, window_condition);
	// ポップアップブロッカーなどでブロックされた場合にJavaScriptエラーにならないように
	if (subWindow) {
		subWindow.focus();
	}

	return subWindow;
}

/**
 * ウィンドウを後ろに開く
 */
function openWindowBack(url, name, height, width, scrollbars, resizable, status)
{
	var window_condition = "height=" + height + ",width=" + width + 
					",scrollbars=" + scrollbars + ",resizable=" + resizable + ",toolbar=no,status=" + status +
					",left=" + window.screen.width;
	subWindow = window.open(url, name, window_condition);
	subWindow.blur();
	window.focus();
	subWindow.moveTo(0,0);
	return subWindow;
}

/**
 * Escキーでウィンドウを閉じるイベント
 * 
 * ※サブウィンドウのonloadで
 *   document.body.onkeypress = subwinCloseOnEsc;
 * のように使ってください。
 */
function subwinCloseOnEsc(ev)
{
	ev || (ev = window.event);
	if (ev.keyCode == 27) {
		window.close();
		return false;
	}
	return true;
}



// 2004-06-09 Takanori Ishikawa 
// -----------------------------------------------------------
// htmlAlert(), htmlConfirm() は html をそのまま
// 出力せず、サニタイズするようにした。

// sanitize html message
function sanitize_msg(msg)
{
	msg = msg.replace(/</g, '&lt;');
	msg = msg.replace(/>/g, '&gt;');
	msg = msg.replace(/&lt;br\s*&gt;/g, '<br>');

	return msg;
}
// alert
function htmlAlert(msg, height, width)
{
	height = (null == height) ? 150: height;
	width  = (null == width) ? 300: width;
	msg = sanitize_msg(msg);
	
	if (defined(window.showModalDialog)) {
		showModalDialog("/drecomcms/html/message_box.html", sanitize_msg(msg), "dialogHeight: " + height + "px; dialogWidth: " + width + "px; edge: Raised; center: Yes; help: No; resizable: No; status: No;");
  	} else {
		dialogArguments = msg;
		ModalWindow = open("/drecomcms/html/message_box.html", "sub_alert","height=" + height + ",width=" + width + 
					",scrollbars=no,resizable=no,toolbar=no,status=no,alwaysRaised=yes");
		onfocus = function onFocus(){
			if (null !=ModalWindow && !ModalWindow.closed) {
				ModalWindow.focus();
			}
		}
		document.onmousemove = onfocus;
		return ModalWindow;
	}
}
// confirm
function htmlConfirm(msg, height, width)
{
	height = (null == height) ? 150: height;
	width  = (null == width) ? 300: width;
	if (defined(window.showModalDialog)) {
		var value = showModalDialog("/drecomcms/html/confirm.html", sanitize_msg(msg), "dialogHeight: " + height + "px; dialogWidth: " + width + "px; edge: Raised; center: Yes; help: No; resizable: No; status: No;");
		if (typeof value == "undefined") {
			value = false;
		} 
		return value;
	} else {
		return window.confirm(msg.replace(/<br[^>]*\/?>/, '\n'));
	}
}

/**
  * 曜日を取得する関数
  * year:  年
  * month: 月
  * day:   日
  */
function getDayOfWeek(year, month, day) {

	DateOfWeek	= new Date();
	DateOfWeek.setYear(year);
	DateOfWeek.setMonth(month - 1);
	DateOfWeek.setDate(day);
	day_of_week_number	= DateOfWeek.getDay();

	days = new Array('日','月','火','水','木','金','土');
	return days[day_of_week_number];
}


// -----------------------------------------------------------
// ポータル、ヘッダ
// -----------------------------------------------------------
/**
 * INPUT FORM の背景色変更
 */
function focusForm(obj,flag){
	if (obj == null || obj.style == null) {
		return;	
	}
	obj.style.backgroundColor = flag ? '#FFFFCC' : '#FFFFFF' 
}
function Skinup(fnr){
	win = window.open('/contents/skinpop_'+fnr,'skin','width=455,height=300,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes');
	win.focus();
}
function imgSwap(name,gifPath) {
	document.images[name].src = gifPath ;
}


// -----------------------------------------------------------
// 画像
// -----------------------------------------------------------
/**
 * 画像の表示サイズ調整
 */
function adjustImageSize(imgElementName, widthMax, heightMax) {
	var imgs = document.getElementsByName(imgElementName);
	if (imgs) {
		if (!imgs.length) {
			if (widthMax && imgs.width > widthMax) {
				imgs.height = imgs.height * widthMax / imgs.width;
				imgs.width = widthMax;
			}
			if (heightMax && imgs.height > heightMax) {
				imgs.width = imgs.width * heightMax / imgs.height;
				imgs.height = heightMax;
			}
		} else {
			for (i=0; i<imgs.length; i++) {
				if (widthMax && imgs[i].width > widthMax) {
					imgs[i].height = imgs[i].height * widthMax / imgs[i].width;
					imgs[i].width = widthMax;
				}
				if (heightMax && imgs[i].height > heightMax) {
					imgs[i].width = imgs[i].width * heightMax / imgs[i].height;
					imgs[i].height = heightMax;
				}
			}
		}
	}
}

/**
 * 本文のHTMLソースより外部画像URL("http://〜")をPickUp
 */
function getExternalImageList(orgHtml) {

	var extImageList = new Array();
	var list = new Array();
	var n = 0;	
	var exp;
	
	exp = new RegExp("<img [^>]*src=[\"']?http://[^\"']*[\"']?[^>]*>", 'ig');
	list = orgHtml.match(exp);
	if (list) {
		for (var i = 0; i < list.length; i++) {
			var str = "";
			exp = new RegExp("src=[\"']?");
			list[i].match(exp);
			str = RegExp.rightContext;
			exp = new RegExp("[\"'\\s>]|/>");
			if (str) {
				str.match(exp);
				str = RegExp.leftContext;
				
				var isExist = false;
				for (var j = 0; j < extImageList.length; j++) {
					if (extImageList[j] == str) { isExist = true; break; }
				}
				if (!isExist) { extImageList[n++] = str; }
			}
		}
	}
	return extImageList;
}

/**
 * 本文のHTMLソースより外部FlashURL("http://〜")をPickUp
 */
function getExternalFlashList(orgHtml) {

	var extFlashList = new Array();
	var list = new Array();
	var n = 0;	
	var exp;

	var flashTag = "\\{\\\$CMSInclude [^\\\$\\}]*name=\"flash\"\\s*param=\"[^\"]*Movie=http://[^\"]*\"\\s*\\\$\\}";	
	exp = new RegExp(flashTag, 'ig');	
	list = orgHtml.match(exp);
	if (list) {
		for (var i = 0; i < list.length; i++) {
			var str = "";
			exp = new RegExp("Movie=");
			list[i].match(exp);
			str = RegExp.rightContext;
			exp = new RegExp(";");
			if (str) {
				str.match(exp);
				str = RegExp.leftContext;

				var isExist = false;				
				for (var j = 0; j < extFlashList.length; j++) {
					if (extFlashList[j] == str) { isExist = true; break; }
				}
				if (!isExist) { extFlashList[n++] = str; }
			}
		}
	}
	return extFlashList;
}
 
/**
 * リンクの遷移先を無効にする。
 * （<a>タグのhref属性を"javascript:void(0)"に置換）
 */
function replaceLinkInvalid(html) {
	html = html.replace(/<a [^>]*>/ig, '<a href="javascript:void(0);">');
	html = html.replace(/openPermLink\([^)]*\)/ig, 'void(0)');
	return html;
}

/**
 * URL用のエスケープを行います。
 * '&' -> '&amp;'
 * '>' -> '&gt;'
 * '<' -> '&lt;'
 * '"' -> '&quot;'
 * 両端の空白は Trim
 * ' ' -> '%20'
 * @param src 対象文字列
 */
function /*: String :*/ escapeUrl(/*: String :*/ src) {
	var s = replaceAll(src, '&', '&amp;');
	s = replaceAll(s, '>', '&gt;');
	s = replaceAll(s, '<', '&lt;');
	s = replaceAll(s, '"', '&quot;');
	s = trim(s);
	s = replaceAll(s, ' ', '%20');
	return s;
}
function /*: String :*/ escapeScript(/*: String :*/ src) {
	var s = replaceAll(src, "\\", "\\\\");
	s = replaceAll(s, "'", "\\'");
	s = replaceAll(s, "\"", "\\\"");
	return s;
}
/**
 * 文字列の全置換を行います。
 * @param src 対象文字列
 * @param oldc 旧文字列
 * @param newc 新文字列
 */
function /*: String :*/ replaceAll(/*: String :*/src, /*: String :*/oldc, /*: String :*/newc) {
 var h = "";
 var b = src;
 var index = 0;
 while (true) {
  index = b.indexOf(oldc, 0);
  if (index == -1) {
   break;
  }
  src = b.replace(oldc, newc);
  h += src.substring(0, index + newc.length);
  b = src.substring(index + newc.length, src.length);
 }
 return h + b;
}
/**
 * 両端の半角/全角スペースを取り除きます。
 * @param src 対象文字列
 */
function /*: String :*/ trim(/*: String :*/src ) {
	var s = trimR(src);
	return trimL(s);
}
/**
 * 右端の半角/全角スペースを取り除きます。
 * @param src 対象文字列
 */
function /*: String :*/ trimR(/*: String :*/src) {
	var nLoop = 0;
	var strFinal = src;
	var strTemp = src;
	while (nLoop < strTemp.length) {
		if ((strFinal.substring(strFinal.length - 1, strFinal.length) == " ") || (strFinal.substring(strFinal.length - 1, strFinal.length) == "　")) {
			strFinal = strTemp.substring(0, strTemp.length - (nLoop + 1));
		}
		else {
			break;
		}
		nLoop++;
	}
	return strFinal;
}
/**
 * 左端の半角/全角スペースを取り除きます。
 * @param src 対象文字列
 */
function /*: String :*/ trimL(/*: String :*/src) {
	var nLoop = 0;
	var strFinal = src;
	var strTemp = src;
	while (nLoop < strTemp.length) {
		if ((strFinal.substring(0, 1) == " ") || (strFinal.substring(0, 1) == "　")) {
			strFinal = strTemp.substring(nLoop + 1, strTemp.length );
		}
		else {
			break;
		}
		nLoop++;
	}
	return strFinal;
}

/**
 * 継承
 */
function extend(subClass, superClass) {
    for (var prop in superClass.prototype) {
        subClass.prototype[prop] = superClass.prototype[prop];
    }
}


/**
 * ポップアップブロッカー対策
 * window.onPopupBlocked,window.onPopupNonBlockedをオーバーライドしてください。
 */
window.onPopupBlocked = function(){
	alert('ウィンドウを開けませんでした。ポップアップブロッカーを有効にしている場合は、無効にしてください。');
};

window.onPopupNonBlocked = function(){}

if (typeof window.org_open == 'undefined'){
	window.org_open = window.open;
	window.open = function() {
		var win = (2 == window.open.arguments.length)
					? window.org_open(window.open.arguments[0], window.open.arguments[1])
					: window.org_open(window.open.arguments[0], window.open.arguments[1], window.open.arguments[2]);
		if (null == win) {
			window.onPopupBlocked(window.open.arguments);
		} else {
			window.onPopupNonBlocked(window.open.arguments);
		}
		return win;
	}
}


//======================================================================================
// xbs.js
//======================================================================================
/**
 * XBS (Cross Browser Scripting) Utilities
 *
 * Copyright (c) 2004 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */

//---------------------------------------------------------------------------------
// Debugging 
//---------------------------------------------------------------------------------
/**
 * Assertion に失敗したときにこれを throw
 */
ASSERT_EXCEPTION = '*** Assertion Failur *** ';

/**
 * dprint, dinspect の出力をストップするときは true に設定
 */
BLOCK_DEBUG_PRINT  = true;


/**
 * v が undefined でなければ true
 */
function defined(v) { return (typeof v != 'undefined'); }

/**
 * オブジェクトのすべてのプロパティを dprint 関数で表示
 * 
 * @param オブジェクト
 */
function dinspect(anObj)
{
	if (null == anObj) return;
	for (key in anObj) {
		dprint(key + ": " + anObj[key]);
	}

}

function dprint(obj)
{
	if (BLOCK_DEBUG_PRINT) {
		return;
	}
	if (typeof dprint.window == "undefined") {
		dprint.window = window.open("/drecomcms/js/Console.html", 
			"Console",
			"width=300, height=600, scrollbars, resizable, menubar");
	}
	
	var t = dprint.window.document.getElementById('console');
	
	if (t != null) {
		t.value = t.value + "\n> " + obj.toString();
	}
// Takanori Ishiakwa 04/04/06
// -----------------------------------------
// Safari や Opera でうまく動作しないため
// TextArea バージョンに切り替えた
/*
	if (typeof dprint.window == "undefined") {
		dprint.window = window.open("", 
			"Console",
			"width=300, height=600, scrollbars, resizable, menubar");
		dprint.window.document.open("text/plain");	
	}
	var d = dprint.window.document;
	
	if (d == null) return;

	d.writeln("> " + obj.toString());
	
	// Opera: mime text/plain を指定しても HTML として解釈
	// されているようなので、改行させるためにタグを出力
	if (window.opera) d.writeln("<br>");
*/
}

// ---------------------------------------------------------
// XBSUtil
// ---------------------------------------------------------
// for the purpose of namespace
/**
 * ブラウザ互換を目指して、ユーティリティ群をまとめたオブジェクト
 * 
 * @author  Takanori Ishikawa
 * @version 1.0
 */
XBSUtil = new Object();

/**
 * 要素を含む document オブジェクトを返す。
 * 
 * @param document
 */
XBSUtil.getOwnerDocument = function(anElement) 
{
	if (anElement.document) {
		return anElement.document;
	} else if (anElement.ownerDocument) {
		return anElement.ownerDocument;
	}
	return null;
}


/**
 * Unicode code points collection
 * 
 * プログラム中で使う文字コードを集めたもの
 * 
 * @author Takanori Ishikawa
 * @version 1.0
 */
XBSCType = new Object();

// *** XBSCType 初期化 *** //
// 初期化テーブル
// key: property name
// value: string (length must be 1)
XBSCType.template_ = {
	CR:    '\r',
	LF:    '\n',
	TAB:   '\t',
	SPACE: ' ',
	LT:    '<',
	GT:    '>',
	SLASH: '/',
	COLON: ':',
	AMP:   '&',
	LBRACE:'{',
	RBRACE:'}'
};

for (var key in XBSCType.template_) {
	var c = XBSCType.template_[key];
	
	if (c.length != 1) {
		throw ASSERT_EXCEPTION + 'XBSCType.template_[' + key + '] length must be 1.';
	}
	c = c.charCodeAt(0);
	XBSCType[key] = c;
}
// 削除
delete XBSCType.template_;

/**
 * isspace
 */
XBSCType.isspace = function(c) 
{
	return (c == XBSCType.SPACE || c == XBSCType.TAB || c == XBSCType.CR || c == XBSCType.LF);
}


/**
 * DOM サポート具合によるブラウザ判別
 * 
 * <ul>
 * <li>IE4:   IE4 相当</li>
 * <li>IE5:   IE5 相当</li>
 * <li>NN4:   NN4 相当</li>
 * <li>NN6:   NN6 相当</li>
 * <li>OTHER: 上記以外</li>
 * </ul>
 */
OTHER = 0;
IE4   = 1;
IE5   = 2;
NN4   = 3;
NN6   = 4;
XBSUtil.DOM = document.all 
				? (document.getElementById ? IE5 : IE4)
				: (document.getElementById 
					? NN6
					: (document.layers ? NN4 : OTHER));

/**
 * テキスト操作 API のサポート具合によるブラウザ判別
 */
XBSUtil.Range = null;
if (document.selection != null && defined(document.selection.createRange)) {
	XBSUtil.Range = IE5;
}


// エラー時には 0 を返す parseInt(), 10 進数
XBSUtil.parseIntNoError = function(anObj) {
	var v = 0;	

	try {
		v = parseInt(anObj, 10);
	} catch (e) {

	}
	if ((typeof v != typeof 0) || isNaN(v)) {
		v = 0;
	}

	return v;
}

/**
 * DOM:
 * DocumentImplementation - feature list
 */
if (null == XBSUtil.DOM) {
	throw ASSERT_EXCEPTION + 'XBSUtil.DOM must be not null.';
}
XBSUtil.DOM.HTMLEvent = false;

if (document.implementation) {
	XBSUtil.DOM.HTMLEvent = document.implementation.hasFeature('HTMLEvents', '2.0');
}


/**
 * Mac: AppleWebKit
 * 
 * Apple の WebKit framework の上に構築されたブラウザなら
 * ここで XBSUtil.appleWebKit オブジェクトを生成。
 * 
 * @field major WebKit メジャーバージョン番号 (Number)
 * @field minor WebKit マイナーバージョン番号 (Number)
 */
XBSUtil.appleWebKit = null;
var _webKitMatch = navigator.userAgent.match(/AppleWebKit\/(\d+)\.?(\d+)?/i);
if (_webKitMatch != null) {
	var o = new Object();
	
	o.major = XBSUtil.parseIntNoError(_webKitMatch[1]);
	o.minor = XBSUtil.parseIntNoError(_webKitMatch[2]);	
	XBSUtil.appleWebKit = o;
}

/**
 * Mac IE
 * 
 * Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC)
 */
/**
 * Mac: IE
 * 
 * IE の Mac 版なら
 * ここで XBSUtil.macIE オブジェクトを生成。
 * 
 * @field major IE メジャーバージョン番号 (Number)
 * @field minor IE マイナーバージョン番号 (Number)
 */
//
// 参考： 
// Mac の食えない野郎ども
// http://www.din.or.jp/~hagi3/JavaScript/JSTips/ProbMac5.htm
// Microsoft
// http://www.microsoft.com/
//
XBSUtil.macIE = null;
if (navigator.userAgent.match(/Mac/i)) {
	var _macIEMatch;
	
	_macIEMatch = navigator.userAgent.match(/MSIE\s+(\d+)\.?(\d+)?/i);
	if (_macIEMatch) {
		var o = new Object();

		o.major = XBSUtil.parseIntNoError(_macIEMatch[1]);
		o.minor = XBSUtil.parseIntNoError(_macIEMatch[2]);	
		XBSUtil.macIE = o;
	}
}
/**
 * Opera
 *
 * Opera ならここで XBSUtil.opera オブジェクトを生成。
 * 
 * @field major opera メジャーバージョン番号 (Number)
 * @field minor opera マイナーバージョン番号 (Number)
 */
XBSUtil.opera = null;
if (window.opera) {
	var o = new Object();
	
	o.major = 6;
	if (document.documentElement)
		o.major = 7;
	
	o.minor = 0;
	XBSUtil.opera = o;
}


// ---------------------------------------------------------
// XBSLayer
// ---------------------------------------------------------
/**
 * div 要素などをレイヤーとして扱うためのオブジェクト
 * 
 * For example:
 * <pre>
 *    var layer = new XBSLayer(anIdOfDivElement);
 *    // some operation...
 * </pre>
 *
 * @author  Takanori Ishikawa
 * @version 1.0
 * @see     document.layer
 * @see     style
 * 
 * @param     uniqId  div 要素の id 属性
 * @param     doc     document オブジェクト（オプション：デフォルトはwindow.document）
 */
function XBSLayer(uniqId, doc)
{
	if (uniqId) {
		this.setLayerImp(XBSLayer.getLayerImpById(uniqId, doc));
	}
}
/**
 * 指定された div 要素がなければ例外を投げる
 * 
 * どうせ、たいした数のレイヤーはないのでキャッシュ
 */
XBSLayer.makeLayer = function(uniqId, doc)
{
	var lyer = null;
	
	if (XBSLayer.makeLayer.$cache == null) {
		XBSLayer.makeLayer.$cache = new Object();
	}
	
	lyer = XBSLayer.makeLayer.$cache[uniqId];
	if (null == lyer || (doc && doc != XBSUtil.getOwnerDocument(lyer.getLayerImp()))) {
		lyer = new XBSLayer(uniqId, doc);
		
		if (null == lyer || null == lyer.getLayerImp()) {
			//b throw ASSERT_EXCEPTION + 'div element (id:' + uniqId + ') is required.';
		}
		XBSLayer.makeLayer.$cache[uniqId] = lyer;
	}
	
	return lyer;
}

/* ---- class properties ---- */

// Visibility constants
/**
 * レイヤーの可視属性を表す定数
 */
XBSLayer.VISIBLE   = 1;
XBSLayer.HIDDEN    = 2;
XBSLayer.INHERIT   = 3;
XBSLayer.UNDEFINED = 4;

/**
 * レイヤーの操作に使う実装オブジェクトを得る
 *
 * @param     anId  div 要素の id 属性
 * @param     doc   document オブジェクト（オプション：デフォルトはwindow.document）
 * @return    DOM: element.style, NN: layer
 */
XBSLayer.getLayerImpById = function(anId, doc) 
{
	var imp = null;
	
	if (null == doc) {
		doc = document;
	}
	if (doc.getElementById || doc.all) {
		imp = doc.getElementById 
				? doc.getElementById(anId)
				: doc.all(anId);
	} else if (doc.layers) {
		imp = doc.layers[anId];
	}
	return imp;
}
XBSLayer.getStyleObjectWithLayerImp = function(imp)
{
	if (document.getElementById || document.all) {
		return imp.style;
	} else {
		return imp;
	}
}

/**
 * 親要素を得る
 *
 * @param     imp  実装オブジェクト
 * @return    親要素
 */
XBSLayer.getParentOfLayerImp = function(imp)
{
	var parent = null;
	
	if (null == imp) {
		;
	} else if (defined(imp.parentElement)) {
		parent = imp.parentElement;
	} else if (defined(imp.offsetParent)) {
		parent = imp.offsetParent;
	}

	return parent;
}


/**
 * レイヤーの操作に使う実装オブジェクトの可視属性を返す。
 *
 * @param     imp  実装オブジェクト
 * @return    可視属性を表す定数
 * <ul>
 * <li>XBSLayer.VISIBLE</li>
 * <li>XBSLayer.HIDDEN</li>
 * <li>XBSLayer.INHERIT</li>
 * <li>XBSLayer.UNDEFINED</li>
 * </ul>
 */
XBSLayer.getVisibilityWithLayerImp = function(imp)
{
	var v;
	
	if (XBSUtil.DOM != NN4) {
		imp = imp.style;
	}
	v = imp.visibility;
	if (document.all) {
		if (v == '') return XBSLayer.INHERIT;
	} else if (!document.getElementById && document.layers) {
		if (v == 'show') return XBSLayer.VISIBLE;
		if (v == 'hide') return XBSLayer.HIDDEN;
	}
	
	if (v == 'visible') return XBSLayer.VISIBLE;
	if (v == 'hidden') return XBSLayer.HIDDEN;
	if (v == 'inherit') return XBSLayer.INHERIT;
		
	return XBSLayer.UNDEFINED;
}
XBSLayer.setVisibilityWithLayerImp = function(imp, anEnum)
{
	var v = '';
	
	if (!document.getElementById && document.layers) {
		if (anEnum == XBSLayer.VISIBLE) v = 'show';
		if (anEnum == XBSLayer.HIDDEN) v = 'hide';
	} else {
		if (anEnum == XBSLayer.VISIBLE) v = 'visible';
		if (anEnum == XBSLayer.HIDDEN) v = 'hidden';
		if (anEnum == XBSLayer.INHERIT) v = 'inherit';
	}
	
	if (XBSUtil.DOM != NN4) {
		imp = imp.style;
	}
	return imp.visibility = v;
}
/**
 * レイヤーの display 属性
 * 
 * @return レイヤーが領域を持つ場合は true
 */
XBSLayer.isBlockWithLayerImp = function(imp)
{
	var b = true;
	
	if (imp.style.display != null) {
		b = (imp.style.display != 'none');
	}
	return b;
}
XBSLayer.setBlockWithLayerImp = function(imp, b)
{
	if (imp.style != null) {
		imp.style.display = b ? 'block' : 'none';
	}
}

// Position & Size


// zIndex
XBSLayer.getZIndexWithLayerImp = function(imp)
{
	if (XBSUtil.DOM != NN4)
		imp = imp.style;
	
	return imp.zIndex;
}
XBSLayer.setZIndexWithLayerImp = function(imp, z)
{
	if (XBSUtil.DOM != NN4)
		imp = imp.style;
	
	imp.zIndex = z;
}


// Position
/**
 * 位置指定に使う定数
 */
XBSLayer.LEFT_TOP     = 1;
XBSLayer.LEFT_BOTTOM  = 2;
XBSLayer.RIGHT_TOP    = 3;
XBSLayer.RIGHT_BOTTOM = 4;

/**
 * ユーティリティ： 指定されたイベントの位置にレイヤーを移動、表示
 * 
 * @param imp div 要素
 * @param theEvent イベントオブジェクト
 * @param axisType 座標を指定する位置
 * <ul>
 * <li>XBSLayer.LEFT_TOP</li>
 * <li>XBSLayer.LEFT_BOTTOM</li>
 * <li>XBSLayer.RIGHT_TOP</li>
 * <li>XBSLayer.RIGHT_BOTTOM</li>
 * </ul>
 *
 * @param offsetX この距離だけイベントの位置から離す (x 座標)
 * @param offsetY この距離だけイベントの位置から離す (y 座標)
 * 
 */
XBSLayer.popUpWithLayerImpAtEventLocation = function(imp, theEvent, axisType, offsetX, offsetY)
{
	var left   = XBSEvent.getMouseX(theEvent) + offsetX;
	var top    = XBSEvent.getMouseY(theEvent) + offsetY;
		
	XBSLayer.initPositionStyle(imp);
	XBSLayer.setPositionWIthLayerImp(imp, left, top, axisType);
	XBSLayer.setVisibilityWithLayerImp(imp, XBSLayer.VISIBLE);
}

/**
 * レイヤーの位置指定
 * 
 * @param imp div 要素
 * @param x x 座標
 * @param y y 座標
 * @param axisType 座標を指定する位置 (default: LEFT_TOP)
 * <ul>
 * <li>XBSLayer.LEFT_TOP</li>
 * <li>XBSLayer.LEFT_BOTTOM</li>
 * <li>XBSLayer.RIGHT_TOP</li>
 * <li>XBSLayer.RIGHT_BOTTOM</li>
 * </ul>
 */
XBSLayer.setPositionWIthLayerImp = function(imp, x, y, axisType)
{
	var left = x;
	var top  = y;
	var w = XBSLayer.getWidthWithLayerImp(imp);
	var h = XBSLayer.getHeightWithLayerImp(imp);
	
	if (XBSLayer.LEFT_BOTTOM == axisType) {
		top -= h;
	} else if (XBSLayer.RIGHT_TOP == axisType) {
		left -= w;
	} else if (XBSLayer.RIGHT_BOTTOM == axisType) {
		top -= h;
		left -= w;
	}
	if (left < 0) left = 0;
	if (top < 0) top = 0;
	
	XBSLayer.setLeftTopPositionWithLayerImp(imp, left, top)
}
/**
 * レイヤーの位置（左上）を指定。
 * 
 * @param imp div 要素
 * @param top 左上 x 座標
 * @param left 左上 y 座標
 */
XBSLayer.setLeftTopPositionWithLayerImp = function(imp, left, top)
{	
	if (XBSUtil.DOM == NN4) {
		imp.moveTo(left, top);
	}else if (imp.style != null) {	
		imp.style.left = left; imp.style.top = top;
	}
}
/**
 * レイヤーの位置情報を初期化。ブラウザによってはこの関数を
 * 他の位置関係関数よりも前に呼ばないと結果が不定になる。
 * 
 * @param imp div
 */
XBSLayer.initPositionStyle = function(imp)
{
	if (document.layers) {
		return;
	} else if (typeof imp.style.left == "string") {
		imp.style.left = imp.offsetLeft + 'px';
		imp.style.top  = imp.offsetTop  + 'px';
	} else if (typeof imp.style.pixelLeft != "undefined") {
		imp.style.pixelLeft = imp.offsetLeft;
		imp.style.pixelTop  = imp.offsetTop;
	}
}

XBSLayer.getLeftWithLayerImp = function(imp)
{
	var x = 0;

	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		x = imp.offsetLeft;
	} else if (XBSUtil.DOM == IE4) {
		x = imp.style.pixelLeft;
	} else if (XBSUtil.DOM == NN4) {
		x = imp.clip.left;
	}
	return x;
}

XBSLayer.getTopWithLayerImp = function(imp)
{
	var y = 0;
	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		y = imp.offsetTop;
	} else if (XBSUtil.DOM == IE4) {
		y = imp.style.pixelTop;
	} else if (XBSUtil.DOM == NN4) {
		y = imp.clip.top;
	}
	return y;
}

// Size
XBSLayer.getWidthWithLayerImp = function(imp) 
{
	var w = 0;
	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		w = imp.offsetWidth;
	} else if (XBSUtil.DOM == IE4) {
		w = imp.style.pixelWidth;
	} else if (XBSUtil.DOM == NN4) {
		w = imp.clip.width;
	}
	return w;
}
XBSLayer.getHeightWithLayerImp = function(imp)
{
	var h = 0;
	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		h = imp.offsetHeight;
	} else if (XBSUtil.DOM == IE4) {
		h = imp.style.pixelHeight;
	} else if (XBSUtil.DOM == NN4) {
		h = imp.clip.height;
	}
	return h;
}
XBSLayer.setWidthWithLayerImp = function(imp, w) 
{
	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		imp.style.width = w;	
	} else if (XBSUtil.DOM == IE4) {
		imp.style.pixelWidth = w;
	} else if (XBSUtil.DOM == NN4) {
		imp.resizeTo(w, imp.clip.height);

	}
}
XBSLayer.setHeightWithLayerImp = function(imp, h)
{
	if (XBSUtil.DOM == NN6 || XBSUtil.DOM == IE5) {
		imp.style.height = h;	
	} else if (XBSUtil.DOM == IE4) {
		imp.style.pixelHeight = h;
	} else if (XBSUtil.DOM == NN4) {
		imp.resizeTo(imp.clip.width, h);
	}
}

// HTML
XBSLayer.getInnerHTMLWithLayerImp = function(imp)
{
	if (defined(imp.innerHTML)) {
		return imp.innerHTML;
	}
	return '';
}
XBSLayer.setInnerHTMLWithLayerImp = function(imp, htmlText)
{
	if (defined(imp.innerHTML)) {
		imp.innerHTML = htmlText;
	} else if (document.layers != null) {
		imp.document.open();
		imp.document.write(htmlText);
		imp.document.close();
	}
}

// Cursor
XBSLayer.setCursorWithLayerImp = function(imp, aName) 
{
	if (imp.style != null && defined(imp.style.cursor)) {
		imp.style.cursor = aName;
	}
}



/* ---- Instance properties ---- */
/**
 * 親要素の XBSLayer を返す
 */
XBSLayer.prototype.getParent = function()
{
	var imp = XBSLayer.getParentOfLayerImp(this.getLayerImp());
	if (null == imp) {
		return null;
	}
	var lyer = new XBSLayer();
	
	lyer.setLayerImp(imp);
	return lyer;
}
XBSLayer.prototype.getID = function() { 
	return this.getLayerImp().id;
}
XBSLayer.prototype.hasID = function() {
	var id = this.getID();
	
	return id != null && id != '';
}
XBSLayer.prototype.isValid = function() {
	return (this.getLayerImp() != null);
}
// Visibility
XBSLayer.prototype.getVisibility = function()
{
	return XBSLayer.getVisibilityWithLayerImp(this.getLayerImp());
}
XBSLayer.prototype.setVisibility = function(aEnum)
{
	XBSLayer.setVisibilityWithLayerImp(this.getLayerImp(), aEnum);
}

/**
 * レイヤーが可視かどうかを返す。
 *
 * @return    boolean
 */
XBSLayer.prototype.isVisible  = function()
{
	return this.getVisibility() == XBSLayer.HIDDEN ? false : true;
}
XBSLayer.prototype.setVisible = function(/* boolean */ flag)
{
	this.setVisibility(flag ? XBSLayer.VISIBLE : XBSLayer.HIDDEN);
}
XBSLayer.prototype.toggleVisibility = function()
{
	this.setVisible(false == this.isVisible())
}
/**
 * レイヤーの display 属性
 * 
 * @return レイヤーが領域を持つ場合は true
 */
XBSLayer.prototype.isBlock  = function()  
{ return XBSLayer.isBlockWithLayerImp(this.getLayerImp()); }
XBSLayer.prototype.setBlock = function(b) 
{ XBSLayer.setBlockWithLayerImp(this.getLayerImp(), b); }


/**
 * レイヤーの z 座標
 */
XBSLayer.prototype.getZIndex = function()
{
	return XBSLayer.getZIndexWithLayerImp(this.getLayerImp());
}
XBSLayer.prototype.setZIndex = function(z)
{
	XBSLayer.setZIndexWithLayerImp(this.getLayerImp(), z);
}


XBSLayer.prototype.getStyleObject = function() 
{
	return XBSLayer.getStyleObjectWithLayerImp(this.imp);
}
XBSLayer.prototype.getLayerImp = function() { return this.imp; }
XBSLayer.prototype.setLayerImp = function(imp) { this.imp = imp; }

// Position & Size
XBSLayer.prototype.popUpAtEventLocation = function(theEvent, axisType, offsetX, offsetY)
{ XBSLayer.popUpWithLayerImpAtEventLocation(this.getLayerImp(), theEvent, axisType, offsetX, offsetY); }

/**
 * レイヤーの位置指定
 * 
 * @param x x 座標
 * @param y y 座標
 * @param axisType 座標を指定する位置
 * <ul>
 * <li>XBSLayer.LEFT_TOP</li>
 * <li>XBSLayer.LEFT_BOTTOM</li>
 * <li>XBSLayer.RIGHT_TOP</li>
 * <li>XBSLayer.RIGHT_BOTTOM</li>
 * </ul>
 */
XBSLayer.prototype.setPosition = function(x, y, axisType)
{ XBSLayer.setPositionWIthLayerImp(this.getLayerImp(), x, y, axisType); }
XBSLayer.prototype.setLeftTopPosition = function(left, top) 
{ 
	XBSLayer.setLeftTopPositionWithLayerImp(this.getLayerImp(), left, top); 
}

XBSLayer.prototype.getX = function() { return XBSLayer.getLeftWithLayerImp(this.getLayerImp()); }
XBSLayer.prototype.getY = function() { return XBSLayer.getTopWithLayerImp(this.getLayerImp()); }
/**
 * 座標を絶対値で取得
 */
XBSLayer.prototype.getAbsolute_ = function(fnName)
{
	var ret = 0;
	var lyer = this;
	
	while (lyer != null && lyer.isValid()) {
		ret += lyer[fnName]();	
		lyer = lyer.getParent();
	}
	return ret;
	
}
XBSLayer.prototype.getAbsoluteX = function()
{
	return this.getAbsolute_("getX");
}
XBSLayer.prototype.getAbsoluteY = function()
{
	return this.getAbsolute_("getY");
}

XBSLayer.prototype.getWidth  = function() { return XBSLayer.getWidthWithLayerImp(this.getLayerImp()); }
XBSLayer.prototype.getHeight = function() { return XBSLayer.getHeightWithLayerImp(this.getLayerImp()); }
XBSLayer.prototype.setWidth  = function(w) { return XBSLayer.setWidthWithLayerImp(this.getLayerImp(), w); }
XBSLayer.prototype.setHeight = function(h) { return XBSLayer.setHeightWithLayerImp(this.getLayerImp(), h); }

// HTML
XBSLayer.prototype.getInnerHTML = function()
{
	return XBSLayer.getInnerHTMLWithLayerImp(this.getLayerImp());
}
XBSLayer.prototype.setInnerHTML= function(htmlText)
{
	XBSLayer.setInnerHTMLWithLayerImp(this.getLayerImp(), htmlText);
}

// Cursor
XBSLayer.prototype.setCursor = function(aName) { XBSLayer.setCursorWithLayerImp(this.getLayerImp(), aName); }

//---------------------------------------------------------
// XBSDocument
//---------------------------------------------------------
// object for namespace purpose
/**
 * ドキュメント情報の取得
 * 
 * @author  Takanori Ishikawa
 * @version 1.0
 */
XBSDocument = new Object();


/**
 * ドキュメント全体の大きさ
 * 
 * @return 幅、高さ
 */
XBSDocument.getWidth = function()
{
	var w = 0;
	
	if (window.innerWidth != null) {
		w = window.innerWidth;
	
	// 2004-04-13  Takanori Ishikawa  
	// ------------------------------------------------------------------------
	// IE: 0 が返ってくる
	/*
	} else if (document.documentElement && document.documentElement.clientWidth != null) {
		w = document.documentElement.clientWidth;
	*/
	} else if (document.body && document.body.clientWidth != null) {
		w = document.body.clientWidth;
	} 
	return w;
}

XBSDocument.getHeight = function()
{
	var h = 0;
	
	if (window.innerHeight != null) {
		h = window.innerHeight;
	// 2004-04-13  Takanori Ishikawa  
	// ------------------------------------------------------------------------
	// IE: 0 が返ってくる
	/*
	} else if (document.documentElement && document.documentElement.clientHeight != null) {
		h = document.documentElement.clientHeight;
	*/
	} else if (document.body && document.body.clientHeight != null) {
		h = document.body.clientHeight;
	} 
	return h;
}

/**
 * ドキュメントの可視領域の左上座標
 * 
 * @return x, y
 */
XBSDocument.getPageOffsetX = function()
{
	var x = 0;
	
	if (document.body && document.body.scrollLeft != null) {
		x = document.body.scrollLeft;
	} else if (document.documentElement && document.documentElement.scrollLeft != null) {
		x = document.documentElement.scrollLeft;
	} else if (window.scrollX != null) {
		x = window.scrollX;
	} else if (window.pageXOffset != null) {
		x = window.pageXOffset;
	}
	
	return x;
}
XBSDocument.getPageOffsetY = function()
{
	var y = 0;
	
	if (document.body && document.body.scrollTop != null) {
		y = document.body.scrollTop;
	} else if (document.documentElement && document.documentElement.scrollTop != null) {
		y = document.documentElement.scrollTop;
	} else if (window.scrollY != null) {
		y = window.scrollY;
	} else if (window.pageYOffset != null) {
		y = window.pageYOffset;
	}
	
	return y;
}

//---------------------------------------------------------
//XBSEvent
//---------------------------------------------------------
// object for namespace purpose
/**
 * イベントオブジェクトの操作
 * 
 * @author  Takanori Ishikawa
 * @version 1.0
 */
XBSEvent = new Object();

// *** Key code *** //
/**
 * Key code (unicode)
 * 
 * @see http://www.unicode.org
 */
// 0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;
XBSEvent.BACKSPACE_KEY = 0x08;
// 0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;
XBSEvent.TAB_KEY = 0x09;
// 000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;
XBSEvent.LINE_FEED_KEY = 0x0A;
// 000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;
XBSEvent.NEW_LINE_KEY = 0x0D;


// Modifier keys
XBSEvent.ALT_KEY_MASK     = 1;
XBSEvent.SHIFT_KEY_MASK   = 1 << 1;
XBSEvent.CONTROL_KEY_MASK = 1 << 2;
XBSEvent.META_KEY_MASK    = 1 << 3;

/**
  * getMouseX(e), getMouseY(e)
  *
  * マウスがイベントを起こした時に
  * X座標、Y座標を返す関数
  * 
  * @param theEvent マウスイベント
  * @return 座標
  */
XBSEvent.getMouseX = function(theEvent)
{
	var x = 0;
	
	if (null == theEvent) {
		theEvent = window.event;
	}
	// Safari は clientX も絶対座標で返してくる
	if (XBSUtil.appleWebKit != null) {
		return theEvent.pageX
	}
	
	if (theEvent.clientX != null) {
		x = XBSDocument.getPageOffsetX() + theEvent.clientX;
	} else if (theEvent.pageX != null) {
		x = theEvent.pageX;
	} else if (window.opera != null) {  // 念のため。動作確認したバージョンではこない
		x = (document.documentElement ? window.pageXOffset : 0) + theEvent.clientX;
	}
	
	return x;
}
XBSEvent.getMouseY = function(theEvent) {
	var y = 0;
	
	if (null == theEvent) {
		theEvent = window.event;
	}
	
	// Safari は clientY も絶対座標で返してくる
	if (XBSUtil.appleWebKit != null) {
		return theEvent.pageY;
	}
	
	if (theEvent.clientY != null) {
		y = XBSDocument.getPageOffsetY() + theEvent.clientY;
	} else if (theEvent.pageY != null) {
		y = theEvent.pageY;
	} else if (window.opera != null) {  // 念のため。動作確認したバージョンではこない
		y = (document.documentElement ? window.pageYOffset : 0) + theEvent.clientY;
	}
	
	return y;
}


/**
 * Key Event の Unicode コードポイントを得る
 * 
 * @return code, なければ null
 */
XBSEvent.getKeyCode = function(theEvent) 
{
	if (theEvent.which != null) {
		return theEvent.which;
	} else if (theEvent.keyCode != null) {
		return theEvent.keyCode;
	}
	return null;
}
XBSEvent.getTarget = function(theEvent) 
{
	if (theEvent.target != null) {
		return theEvent.target;
	} else if (theEvent.srcElement != null) {
		return theEvent.srcElement;
	}
	return null;
}


XBSEvent.getModifierFlags = function(theEvent)
{
	var flags = 0;
	

	if (defined(theEvent.ctrlKey)) {
		if (theEvent.altKey) flags |= XBSEvent.ALT_KEY_MASK;
		if (theEvent.shiftKey) flags |= XBSEvent.SHIFT_KEY_MASK;
		if (theEvent.ctrlKey) flags |= XBSEvent.CONTROL_KEY_MASK;
		if (theEvent.metaKey) flags |= XBSEvent.META_KEY_MASK;
	} else if (defined(theEvent.modifiers)) {
		var m = theEvent.modifiers;
		
		if (Event.ALT_MASK & m) flags |= XBSEvent.ALT_KEY_MASK;
		if (Event.SHIFT_KEY_MASK & m) flags |= XBSEvent.SHIFT_KEY_MASK;
		if (Event.CONTROL_MASK & m) flags |= XBSEvent.CONTROL_KEY_MASK;
		if (Event.META_MASK & m) flags |= XBSEvent.META_KEY_MASK;
	}
	return flags;
}


//---------------------------------------------------------------------------------
// Utilities
//---------------------------------------------------------------------------------
UtilKit = new Object();

/**
 * 指定されたオブジェクトのプロパティに関数を *** 追加 *** する。
 * 以前に別の関数が登録されていればそれを呼び出してから、登録された関数を呼び出す。
 * 
 * NOTE: 渡せる引数はとりあえず 5 つまでとした。これだけあれば十分なので。
 * 
 * @param anObject オブジェクト
 * @param funcName プロパティ名
 * @param func     関数本体
 */
UtilKit.addhook = function(anObject, funcName, func)
{
	var prev = anObject[funcName];
	var fns  = new Array();
	if (typeof prev == typeof UtilKit.addhook) {
		fns[fns.length] = prev;
	}
	fns[fns.length] = func;
	
	// dprint("UtilKit.addhook(" + anObject + ", " + funcName + ") nfunc = " + fns.length);
	anObject[funcName] = function() {
		// dprint("funcName: " + funcName + ": " + this);
		for (var i = 0; i < fns.length; i++) {
			// dprint(fns[i]);
			
			// 2004-04-20  Takanori Ishikawa  
			// -------------------------------------------------------------------
			// 関数内で引数の個数をチェックしている可能性もあるので、本当は引数個数で分岐すべきかも
			// ただ、その場合、引数が足りない場合なども考慮すると面倒くさいので手抜き
			 fns[i](
				arguments[0],
				arguments[1],
				arguments[2],
				arguments[3],
				arguments[4]);
			/*
			var f = fns[i]; var args = arguments;
			
			switch (fns.length) {
			case 0: f(); break;
			case 1: f(args[0]); break;
			case 2: f(args[0], args[1]); break;
			case 3: f(args[0], args[1], args[2]); break;
			default: ;
			}
			*/
		}
	};
}

/**
 * オブジェクトのプロパティを返す。
 * null の場合は例外を投げる
 * 
 * @param obj  object
 * @param name property name
 */
UtilKit.getPropertyNotNull = function(obj, name)
{
	var v = obj[name];
	
	if (null == v) {
		throw ASSERT_EXCEPTION + "object: " + obj + " name: " + name + ' must be nut null.';
	}
	
	return v;	
}

/**
 * オブジェクトを論理値に変換
 */
UtilKit.parseBoolean = function(v)
{
	if (typeof v == typeof true) {
		return v;
	} else if (typeof v == typeof "") {
		if ('true' == v) 
			return true;
		else if ('false' == v) 
			return false;
		else
			return true;
	} else if (null == v) {
		return false;
	} else {
		return true;
	}
}
/**
 * オブジェクトのプロパティから、それの登録されているキーを検索
 * 
 * @param anObject オブジェクト
 * @param aValue   プロパティ値
 */
UtilKit.getKeyForValue = function(anObject, aValue)
{
	for (var key in anObject) {
		if (aValue == anObject[key]) {
			return key;
		}
	}
	return null;
}

UtilKit.getBgColorById = function(anId, doc)
{
	var imp;
	var style;
	
	if (doc == null) {
		doc = document;
	}
	imp = XBSLayer.getLayerImpById(anId, doc);
	style = imp ? XBSLayer.getStyleObjectWithLayerImp(imp) : null;
	
	if (style == null) {
		return null;
	}
	return UtilKit.normalizeRGBColorRep(style.backgroundColor);
}
UtilKit.setBgColorById = function(anId, aColor, doc)
{
	var imp;
	var style;
	
	if (doc == null) {
		doc = document;
	}
		
	imp = XBSLayer.getLayerImpById(anId, doc);
	style = imp ? XBSLayer.getStyleObjectWithLayerImp(imp) : null;
	
	if (style == null) {
		return null;
	}
	style.backgroundColor = aColor;
}

/**
 * NN, Opera は背景色を rgb(r, g, b) という形式で
 * 渡してくるので、それを #RGB に変換
 */
UtilKit.normalizeRGBColorRep = function(aColor)
{
	var m = aColor.match(/rgb\((\d+),\s*(\d+),\s+(\d+)\)/);
	
	if (null == m) {
		return aColor;
	}
	var s = "#";
	
	for (var i = 1; i <= 3; i++) {
		var n = m[i];
		
		n = XBSUtil.parseIntNoError(n);
		n = n.toString(16);
		if (n.length == 1){
			n = '0' + n;
		}
		s += n;
	}
	return s;
}

/**
 * InitialFirstResponder:
 *   ユーザが最初に入力すべきフォーム要素
 * 
 * InitialFirstResponder を設定する関数を返す。
 * この関数は実行されると、window.initialFirstResponder にそのフォーム要素を格納し、
 * そのフォーム要素を focus() する。
 * window.onload で使われることを想定
 * 
 */
UtilKit.makeInitialFirstResponder = function(formName, elementName)
{
	return function() {
		var frm = document.forms[formName];
	
		if (frm == null) return;
		frm = frm[elementName];
		if (frm == null) return;
		
		window.initialFirstResponder = frm;
		setTimeout("window.initialFirstResponder.focus()", 500);
	};
}


//---------------------------------------------------------------------------------
// ContentsChangedListener
//---------------------------------------------------------------------------------
/**
 * 
 * ページの内容が変更されたかどうかを記録
 * 
 * @author Takanori Ishikawa
 * @version 2004/04/20
 */
function ContentsChangedListener(/* Optional */ aName)
{
	this.name = aName;
	if (this.name == null) {
		this.name = '[undefined listener]';
	}
	this.changed = false;
}
ContentsChangedListener.prototype.toString = function()
{ return '[ContentsChangedListener] ' + this.name; }

ContentsChangedListener.prototype.isChanged = function() { return this.changed; }
ContentsChangedListener.prototype.setChanged = function(b) {
	if (this.changed != b) {
		//alert(this + " changed: " + b);
	}
	this.changed = b; 
}

/**
 * イベントを登録し、登録したイベントが発生したときに
 * 変更フラグを true にする。
 * 
 * 主に html 要素の onchange イベントなどを捕捉し、
 * 変更フラグを立てるのに使う。
 */
ContentsChangedListener.prototype.listenEvent = function(anObject, eventName)
{
//	2004-04-20  Takanori Ishikawa  
//	------------------------------------------------------------------------
//	this は関数内部で実行時に解釈されるため、一度変数に入れて
//	静的スコープに束縛する必要がある（解放されない？）
	var me = this
	var callback = function(){ me.setChanged(true); };
	
	UtilKit.addhook(anObject, eventName, callback);
}


//---------------------------------------------------------------------------------
// Common
//---------------------------------------------------------------------------------
/**
 * アプリケーション全体の設定
 * 
 * @author  Takanori Ishikawa
 * @version 1.0
 */
OEMBlogGlobal = new Object();

/**
 * 記事編集で Blog ポータル・カテゴリの選択をクッキーに保存するか
 */
OEMBlogGlobal.saveTbCategoryToCookie = false;

/**
 * 記事編集でタグ編集機能（タグごと削除、移動など）を HTML タグでも有効にするか
 */
OEMBlogGlobal.enableTagEditingOnHTML = false;


/**
 * 項目設定のディスクロージャトライアングルなどでアニメーションを有効にするか
 */
OEMBlogGlobal.enableAnimationFeedback = true;

/**
 * 画像をアップロードするディレクトリのパス
 * jsp 側で適宜更新される。
 */
OEMBlogGlobal.uploadImageDirectory = null;

/**
 * アップロードできる画像ファイル名の形式
 */
OEMBlogGlobal.IMAGE_FILE_PATTERN = /{(左:|右:)?([a-zA-Z0-9-_.!~'()]+\.[a-zA-Z]+)}/;

/**
 * サイドバー：配置できる項目の最大数
 * 
 * @see sidefunc_order.js BoxConfig.maxNBoxes
 */
OEMBlogGlobal.PANEL_DISABLE_MAX_NBOXES	= 50;	// 「使用しない機能」
OEMBlogGlobal.PANEL_LEFT_MAX_NBOXES		= 50;	// 「使用する機能」左
OEMBlogGlobal.PANEL_RIGHT_MAX_NBOXES	= 50;	// 「使用する機能」右


/**
 * 
 * 記事編集、新規作成では以下の文字列を含むリンクをクリックした場合、
 * まだ変更が保存されていなければ確認ダイアログを出す。
 * 
 * @see entry_write_edit.js, entry_save_confirm.jsp
 * @see OEMBlogGlobal.watchOtherLinks
 */
OEMBlogGlobal.DOCUMENT_EDITED_WARNING = "変更は保存されていません。<br>次のページへ移ってもよろしいですか？"
OEMBlogGlobal.WATCH_OTHER_LINK_LIST = [
					/* 上 */
					'MyPage',			/* マイページ */
					'EntryWrite',		/* 記事新規作成 */
					'EntryList',		/* 記事一覧 */
					'TopicList',		/* リンクリスト */
					'SidefuncOrder',	/* サイドバー */
					'DesignChange',		/* デザイン */
					'BlogSetup',		/* 設定 */
					
					/* 左 */
					'SidefuncOrder',	/* 機能選択・並び替え */
					'SidefuncSetup',	/* 表示名変更 */
					'SidefuncEditList',		/* 機能追加 */
					'LinksList',		/* リンク集  編集 */
					'CategoryList'		/* カテゴリ  編集 */
					];


/**
 * テキストの置換などで使用する改行コード
 */
/** TODO: 仕様にしたがって、判別コードを書くこと。とりあえず、CRLF にしておく */
OEMBlogGlobal.lineSeparator = "\r\n";


OEMBlogGlobal.makeWatchOtherLinkFunction = function(aListener, prevFunc)
{
	return function(e) {
		var ret = true;
			
		if (prevFunc != null) {
			ret = prevFunc(e);
		}
		if (aListener.isChanged() == false)
			return ret;
			
		return (htmlConfirm(OEMBlogGlobal.DOCUMENT_EDITED_WARNING))
	};
}
OEMBlogGlobal.watchOtherLinks = function(aDocument, aListener)
{
	var linkArray = aDocument.links;
	var nms = OEMBlogGlobal.WATCH_OTHER_LINK_LIST;
	var link;
	var count = 0;
	
	for (var i = 0; i < linkArray.length; i++) {
		
		link = linkArray[i];
		if (null == link) continue;
		
		for (var j = 0; j < nms.length; j++) {
			if (link.href.indexOf(nms[j]) != -1) {
				var prevFunc = link.onclick;
				
				if (typeof prevFunc != 'function') {
					prevFunc = null;
				}
				link.onclick = OEMBlogGlobal.makeWatchOtherLinkFunction(aListener, prevFunc);
				
				count++;
				break;
			}
		}
		if (count == nms.length) {
			break;
		}
	}
}

//======================================================================================
// cookie_util.js
//======================================================================================
/*
 * クッキー操作 JavaScript
 *
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */
 
/**
 * Cookieの値設定
 */
function setCookie(name,value,expire){
  document.cookie
    = name + '=' + escape(value)
    + ((expire==null)?'; path=/; expires=Thu, 1-Jan-2030 00:00:00 GMT':('; expires='+expire.toGMTString()));
}

/**
 * Cookie 取得関数
 */
function getCookie(name){
  var search = name + '=';
  if (document.cookie.length>0) {
    offset = document.cookie.indexOf(search);
    if (offset != -1){
      offset += search.length;
      end     = document.cookie.indexOf(';',offset);
      if(end == -1)
        end = document.cookie.length;
      return unescape(document.cookie.substring(offset,end));
    }
  }
  return null;
}


/**
 * Cookie 制御オブジェクト
 * 
 * @param aDocument クッキーを格納する document オブジェクト（必須）
 * @param aName     クッキーの名前（必須）
 * @param hours     有効期限。単位は時間。
 * @param path      path 
 * @param domain    domain
 * @param secure    secure
 * 
 * @author David Flanagan
 * @author http://examples.oreilly.com/jscript3/text/18-1.txt
 */
function Cookie(aDocument, aName, hours, path, domain, secure)
{
	// 2004-04-20  Takanori Ishikawa  
	// ------------------------------------------------------------------------
	// cookie に保存するプロパティと区別するため、
	// Cookie オブジェクトのプロパティには prefix として '$' をつける
	this.$document = aDocument;
	this.$name     = aName;
	
	this.$expiration = hours ? new Date((new Date()).getTime() + hours*3600000) : null;
	this.$path = path ? path : null;
	this.$domain = domain ? domain : null;
	this.$secure = secure ? secure : false;
}

/**
 * クッキーを保存
 */

Cookie.prototype.store = function()
{
	// First, loop through the properties of the Cookie object and
	// put together the value of the cookie. Since cookies use the
	// equals sign and semicolons as separators, we'll use colons
	// and ampersands for the individual state variables we store 
	// within a single cookie value. Note that we escape the value
	// of each state variable, in case it contains punctuation or other
	// illegal characters.
	var cookieval = "";
	for(var prop in this) {
		// Ignore properties with names that begin with '$' and also methods.
		if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function')) 
			continue;
		if (cookieval != "") cookieval += '&';
		cookieval += prop + ':' + escape(this[prop]);
	}

	// Now that we have the value of the cookie, put together the 
	// complete cookie string, which includes the name and the various
	// attributes specified when the Cookie object was created.
	var cookie = this.$name + '=' + cookieval;
	if (this.$expiration)
		cookie += '; expires=' + this.$expiration.toGMTString();
	if (this.$path) cookie += '; path=' + this.$path;
	if (this.$domain) cookie += '; domain=' + this.$domain;
	if (this.$secure) cookie += '; secure';

	// Now store the cookie by setting the magic Document.cookie property.
	this.$document.cookie = cookie;
}

/**
 * クッキーを読み込む
 */
Cookie.prototype.load = function()
{
	// First, get a list of all cookies that pertain to this document.
	// We do this by reading the magic Document.cookie property.
	var allcookies = this.$document.cookie;
	if (allcookies == "") return false;

	// Now extract just the named cookie from that list.
	var start = allcookies.indexOf(this.$name + '=');
	if (start == -1) return false;   // Cookie not defined for this page.
	start += this.$name.length + 1;  // Skip name and equals sign.
	var end = allcookies.indexOf(';', start);
	if (end == -1) end = allcookies.length;
	var cookieval = allcookies.substring(start, end);

	// Now that we've extracted the value of the named cookie, we've
	// got to break that value down into individual state variable 
	// names and values. The name/value pairs are separated from each
	// other by ampersands, and the individual names and values are
	// separated from each other by colons. We use the split method
	// to parse everything.
	var a = cookieval.split('&');    // Break it into array of name/value pairs.
	for(var i=0; i < a.length; i++)  // Break each pair into an array.
		a[i] = a[i].split(':');

	// Now that we've parsed the cookie value, set all the names and values
	// of the state variables in this Cookie object. Note that we unescape()
	// the property value, because we called escape() when we stored it.
	for(var i = 0; i < a.length; i++) {
		this[a[i][0]] = unescape(a[i][1]);
	}

	// We're done, so return the success code.
	return true;
}

/**
 * クッキーを取り除く
 */
Cookie.prototype.remove = function()
{
	var cookie;
	cookie = this.$name + '=';
	if (this.$path) cookie += '; path=' + this.$path;
	if (this.$domain) cookie += '; domain=' + this.$domain;
	cookie += '; expires=Fri, 02-Jan-1970 00:00:00 GMT';

	this.$document.cookie = cookie;
}

Cookie.prototype.toString = function()
{
	var cookieval = "";
	for(var prop in this) {
		// Ignore properties with names that begin with '$' and also methods.
		if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function')) 
			continue;

		cookieval += prop + ':' + (this[prop]) + "\n";
	}
	return cookieval;
}
/**

//===================================================================
//	The code above is the definition of the Cookie class.
//	The code below is a sample use of that class.
//===================================================================

// Create the cookie we'll use to save state for this web page.
// Since we're using the default path, this cookie will be accessible
// to all web pages in the same directory as this file or "below" it.
// Therefore, it should have a name that is unique among those pages.
// Note that we set the expiration to 10 days in the future.
var visitordata = new Cookie(document, "name_color_count_state", 240);

// First, try to read data stored in the cookie. If the cookie is not
// defined, or if it doesn't contain the data we need, then query the
// user for that data.
if (!visitordata.load() || !visitordata.name || !visitordata.color) {
	visitordata.name = prompt("What is your name:", "");
	visitordata.color = prompt("What is your favorite color:", "");
}

// Keep track of how many times this user has visited the page:
if (visitordata.visits == null) visitordata.visits = 0;
visitordata.visits++;

// Store the cookie values, even if they were already stored, so that the 
// expiration date will be reset to 10 days from this most recent visit.
// Also, store them again to save the updated visits state variable.
visitordata.store();

// Now we can use the state variables we read:
document.write('<FONT SIZE=7 COLOR="' + visitordata.color + '">' +
			   'Welcome, ' + visitordata.name + '!' +
			   '</FONT>' +
			   '<P>You have visited ' + visitordata.visits + ' times.');

*/

//======================================================================================
// popup.js
//======================================================================================
/*
 * PopUp for tooltip
 *
 *
 * Copyright (c) 2003-2004 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */

var POPUP_ID       = 'popup';
var POPUP_HTML     = '<div id="'+POPUP_ID+'" class="popup" align="left"></div>';

var POPUP_OFFSET   = 15;
// div の大きさが可変のため、XBSLayer.LEFT_TOP しか指定できません
var POPUP_POSITION = XBSLayer.LEFT_TOP; // ポップアップの左上がマウス位置

var gPopUpLayer = null;


/**
 * ポップアップを表示する関数
 * 
 * @param theEvent イベントオブジェクト（必須）
 * @param text ポップアップに表示する内容（必須）
 *
 * @param offsetX X方向にこの距離だけイベントの位置から離す（オプション）
 * @param offsetY Y方向にこの距離だけイベントの位置から離す（オプション）
 * @param axisType ポップアップ領域の頂点のうち、どれを基準に表示するか。（オプション）
 * <ul>
 * <li>XBSLayer.LEFT_TOP     左上頂点を基準</li>
 * <li>XBSLayer.LEFT_BOTTOM  左下頂点を基準</li>
 * <li>XBSLayer.RIGHT_TOP    右上頂点を基準</li>
 * <li>XBSLayer.RIGHT_BOTTOM 右下頂点を基準</li>
 * </ul>
 * 
 */
function showPopup(theEvent, text, axisType, offsetX, offsetY)
{
	var position;
	var x, y;
	
	if (null == gPopUpLayer) {
		gPopUpLayer = XBSLayer.makeLayer(POPUP_ID);
	}
	gPopUpLayer.setInnerHTML(text);
	
	if (axisType == null) {
		axisType = POPUP_POSITION;
	}
	if (offsetX == null) {
		offsetX = POPUP_OFFSET;
	}
	if (offsetY == null) {
		offsetY = POPUP_OFFSET;
	}
	
	gPopUpLayer.popUpAtEventLocation(theEvent, axisType, offsetX, offsetY);
}

/**
  * hidePopup()
  * 
  * レイヤーでポップアップを表示する関数
  */
function hidePopup(e) 
{
	if (gPopUpLayer != null) {
		gPopUpLayer.setVisible(false);
	}
}
// ポップアップ用 html を出力しておく
document.write(POPUP_HTML);

//======================================================================================
// tags.js
//======================================================================================
/*
 * タグ JavaScript
 *
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */


/**
 * String scanner
 * 
 * @param aString     文字列
 * @param packNewline getc() で改行 (CR, CRLF, LF) をすべて LF に変換するか
 */
function StringPointer(aString, packNewline)
{
	this.string = aString;
	this.location = 0;
	
	if (this.string == null) {
		this.string = '';
	}
	
	this.packNewline = packNewline;
}
StringPointer.prototype.getString = function() { return this.string; }
StringPointer.prototype.getLocation = function() { return this.location; }
StringPointer.prototype.setLocation = function(anIndex)
{
	if (anIndex > this.string.length) {
		throw ASSERT_EXCEPTION + 'attempt to set bounding over location.';
	}
	this.location = anIndex;
}
StringPointer.prototype.isAtEnd = function() { return this.string.length <= this.location; }

StringPointer.prototype._getc = function() 
{
	return this.isAtEnd() ? null : this.string.charCodeAt(this.location++);
}
StringPointer.prototype.getc = function() 
{
	var c = this._getc();
	
	if (c == null) {
		return null;
	}
	
	if (this.packNewline && c == XBSCType.CR) {
		var nextc = this._getc();
		
		if (nextc != XBSCType.LF && nextc != null) {
			this.pushback();
		}
		c = XBSCType.LF;
	}
	return c;
}
StringPointer.prototype.pushback = function()
{
	this.location--;
	if (this.location < 0) this.location = 0;
}

StringPointer.prototype.readSpaces = function()
{
	var ret = false;
	var c;
	
	while (c = this.getc()) {
		if (!XBSCType.isspace(c)) {
			this.pushback();
			break;
		}
		ret = true;
	}
	return ret;
}
StringPointer.prototype.readUpToString = function(/* String */ stopString)
{
	var i = this.string.indexOf(stopString, this.location);
	if (i == -1) {
		return false;
	}
	this.location = i + stopString.length;
	return true;
}
StringPointer.prototype.readChar = function(aCharacter)
{
	if (this.isAtEnd()) {
		return false;
	}
	var c = this.getc();
	
	if (c == aCharacter) {
		return true;
	} else {
		this.pushback();
		return false;
	}
	return false;
}
XBSUtil.indexOfCharacter = function(aString, c)
{
	var i;
	var len = aString.length;
	
	for (i = 0; i < len; i++) {
		if (c == aString.charCodeAt(i)) {
			return i;
		}
	}
	return -1;
}
StringPointer.prototype.scanUpToCharactersIn = function(/* String */ stopChars)
{	
	var fromIndex = this.getLocation();
	var toIndex   = fromIndex;
	
	if (stopChars == null) {
		stopChars = '';
	}
	while (c = this.getc()) {
		if (XBSUtil.indexOfCharacter(stopChars, c) != -1) {
			this.pushback();
			break;
		}
		toIndex++;
	}
	// end 
	if (toIndex == this.string.length) {
		this.location = fromIndex;
		return null;
	}
	
	if (fromIndex == toIndex) {
		return '';
	}
	
	return this.string.substring(fromIndex, toIndex);
}
// substring stuffs
StringPointer.prototype.substring = function(/* Integer */ fromIndex, toIndex)
{
	return this.string.substring(fromIndex, toIndex);
}
StringPointer.prototype.substringFrom = function(/* Integer */ fromIndex)
{
	return this.substring(fromIndex, this.location);
}

//---------------------------------------------------------------------------------
// Tag
//---------------------------------------------------------------------------------
/**
 * Tag:
 * タグオブジェクト。<A hoge="foo"> と </A> は別々のインスタンスになる。
 * オブジェクト自体にはタグ関連の機能をまとめてある
 * 
 * @param aTagName タグ名
 * @param aSource テキスト
 * @param isEndTag 閉じタグか
 * @author  Takanori Ishikawa
 * @version 1.0
 */
Tag = function(aTagName, aSource, isEndTag) 
{
	this.name = aTagName;
	this.source = aSource;
	this.value = '';
	this.isEnd = !(!isEndTag);
	this.isComment = false;
}
Tag.prototype.getName   = function() { return this.name; }
Tag.prototype.getSource = function() { return this.source; }
Tag.prototype.getValue  = function() { return this.value; }

// タグ定義
TagDefs = new Object();
TagDefs['斜'] 		= ['span', 'style="font-style: italic;"'];
TagDefs['太'] 		= ['span', 'style="font-weight: bold;"'];
TagDefs['大']   	= ['span', 'style="font-size: 125%;"'];
TagDefs['特大']		= ['span', 'style="font-size: 150%;"'];
TagDefs['小']     	= ['span', 'style="font-size: 75%;"'];
TagDefs['下線']   	= ['span', 'style="text-decoration: underline;"'];
TagDefs['打消線'] 	= ['span', 'style="text-decoration: line-through;"'];
TagDefs['左']		= ['div', 'style="text-align: left;"'];
TagDefs['中']		= ['div', 'style="text-align: center;"'];
TagDefs['右']		= ['div', 'style="text-align: right;"'];
TagDefs['リンク']		= ['a', 'href="', '" target="_blank"'];
TagDefs['色']		= ['span', 'style="color: ', ';"'];

/**
 * 絵文字
 */
Tag.emojiTable = new Object();
Tag.emojiTable['00'] = '笑顔';
Tag.emojiTable['01'] = '笑い';
Tag.emojiTable['02'] = '怒り';
Tag.emojiTable['03'] = '悲しい';
Tag.emojiTable['04'] = 'ラブ';
Tag.emojiTable['05'] = '落ち込み';
Tag.emojiTable['06'] = '困った';
Tag.emojiTable['07'] = 'ウインク';
Tag.emojiTable['08'] = 'びっくり';
Tag.emojiTable['09'] = 'はてな';
Tag.emojiTable['10'] = '音符';
Tag.emojiTable['11'] = 'ハート';
Tag.emojiTable['12'] = 'ハート割れ';
Tag.emojiTable['13'] = '料理';
Tag.emojiTable['14'] = 'ドクロ';
Tag.emojiTable['15'] = 'うんち';
Tag.emojiTable['16'] = '月';
Tag.emojiTable['17'] = '星';
Tag.emojiTable['18'] = '雲';
Tag.emojiTable['19'] = '太陽';
Tag.emojiTable['20'] = '雨';
Tag.emojiTable['21'] = '雪';
Tag.emojiTable['22'] = '木';
Tag.emojiTable['23'] = '山';
Tag.emojiTable['24'] = '携帯';
Tag.emojiTable['25'] = 'メール';
Tag.emojiTable['26'] = 'グラス';
Tag.emojiTable['27'] = 'ジョッキ';
Tag.emojiTable['28'] = 'パソコン';
Tag.emojiTable['29'] = 'プレゼント';
Tag.emojiTable['30'] = 'テレビ';
Tag.emojiTable['31'] = '本';
Tag.emojiTable['32'] = '花';
Tag.emojiTable['33'] = 'お金';
Tag.emojiTable['34'] = 'トイレ';
Tag.emojiTable['35'] = '家';
Tag.emojiTable['36'] = 'ビル';
Tag.emojiTable['37'] = '学校';
Tag.emojiTable['38'] = '温泉';
Tag.emojiTable['39'] = '幽霊';
Tag.emojiTable['40'] = '犬';
Tag.emojiTable['41'] = '猫';
Tag.emojiTable['42'] = '鳥';
Tag.emojiTable['43'] = '馬';
Tag.emojiTable['44'] = 'ネズミ';
Tag.emojiTable['45'] = '魚';
Tag.emojiTable['46'] = 'クジラ';
Tag.emojiTable['47'] = 'ペンギン';
Tag.emojiTable['48'] = '車';
Tag.emojiTable['49'] = '電車';
Tag.emojiTable['50'] = '船';
Tag.emojiTable['51'] = '飛行機';
Tag.emojiTable['52'] = '自転車';
Tag.emojiTable['53'] = '観覧車';
Tag.emojiTable['54'] = '新幹線';
Tag.emojiTable['55'] = 'ロケット';
Tag.emojiTable['56'] = '野球';
Tag.emojiTable['57'] = 'サッカー';
Tag.emojiTable['58'] = 'スキー';
Tag.emojiTable['59'] = 'テニス';
Tag.emojiTable['60'] = 'ゴルフ';
Tag.emojiTable['61'] = 'スノボー';
Tag.emojiTable['62'] = '走る';
Tag.emojiTable['63'] = '泳ぐ';
Tag.emojiTable['64'] = '乾杯';
Tag.emojiTable['65'] = '熱燗';
Tag.emojiTable['66'] = '食パン';
Tag.emojiTable['67'] = 'アイス';
Tag.emojiTable['68'] = 'ごはん';
Tag.emojiTable['69'] = 'ラーメン';
Tag.emojiTable['70'] = 'おにぎり';
Tag.emojiTable['71'] = 'おでん';
Tag.emojiTable['72'] = 'りんご';
Tag.emojiTable['73'] = 'みかん';
Tag.emojiTable['74'] = 'いちご';
Tag.emojiTable['75'] = 'OK';
Tag.emojiTable['76'] = 'アウト';
Tag.emojiTable['77'] = 'クラッカー';
Tag.emojiTable['78'] = '音量';
Tag.emojiTable['79'] = '鐘';
Tag.emojiTable['80'] = 'ダメ';
Tag.emojiTable['81'] = 'まる';
Tag.emojiTable['82'] = 'すいません';
Tag.emojiTable['83'] = 'バニー';
Tag.emojiTable['84'] = '赤ちゃん';
Tag.emojiTable['85'] = '拍手';
Tag.emojiTable['86'] = '足跡';
Tag.emojiTable['87'] = '熱帯魚';
Tag.emojiTable['88'] = 'ヒヨコ';
Tag.emojiTable['89'] = 'ウサギ';
Tag.emojiTable['90'] = 'ニワトリ';
Tag.emojiTable['91'] = 'カエル';
Tag.emojiTable['92'] = 'サル';
Tag.emojiTable['93'] = 'ブタ';
Tag.emojiTable['94'] = '宇宙人';
Tag.emojiTable['95'] = '力こぶ';
Tag.emojiTable['96'] = '自動車';
Tag.emojiTable['97'] = 'ボート';
Tag.emojiTable['98'] = 'バス';
Tag.emojiTable['99'] = '信号';
Tag.emojiTable['100'] = 'チューリップ';
Tag.emojiTable['101'] = 'ひまわり';
Tag.emojiTable['102'] = 'サボテン';
Tag.emojiTable['103'] = 'クローバー';
Tag.emojiTable['104'] = 'ハイビスカス';
Tag.emojiTable['105'] = 'ドキドキ小';
Tag.emojiTable['106'] = 'ドキドキ大';
Tag.emojiTable['107'] = 'ハート矢';
Tag.emojiTable['108'] = 'キラキラ';
Tag.emojiTable['109'] = '電球';
Tag.emojiTable['110'] = '炎';
Tag.emojiTable['111'] = 'VS';
Tag.emojiTable['112'] = '祝';
Tag.emojiTable['113'] = '汗';
Tag.emojiTable['114'] = '怒';
Tag.emojiTable['115'] = 'ZZZ';
Tag.emojiTable['116'] = 'はさみ';
Tag.emojiTable['117'] = 'メモ';
Tag.emojiTable['118'] = 'タバコ';
Tag.emojiTable['119'] = '帽子';
Tag.emojiTable['120'] = '服';
Tag.emojiTable['121'] = 'カバン';
Tag.emojiTable['122'] = '冠';
Tag.emojiTable['123'] = '注射';
Tag.emojiTable['124'] = 'メガホン';
Tag.emojiTable['125'] = 'カギ';
Tag.emojiTable['126'] = 'ランドセル';
Tag.emojiTable['127'] = '傘';
Tag.emojiTable['128'] = '注意';
Tag.emojiTable['129'] = '初心者';
Tag.emojiTable['130'] = '18禁';
Tag.emojiTable['131'] = '手紙';
Tag.emojiTable['132'] = '国旗';
Tag.emojiTable['133'] = '祝日';
Tag.emojiTable['134'] = '朝日';
Tag.emojiTable['135'] = 'リボン';
Tag.emojiTable['136'] = 'ダッシュ';
Tag.emojiTable['137'] = '男の子';
Tag.emojiTable['138'] = '女の子';
Tag.emojiTable['139'] = '雷';
Tag.emojiTable['140'] = '電波';
Tag.emojiTable['141'] = '病院';


Tag.EmojiNameTable = new Object();
for (key in Tag.emojiTable) {
	Tag.EmojiNameTable[Tag.emojiTable[key]] = key;
}

//タグの種類
Tag.TYPE_CSS = 0;
Tag.TYPE_DEPRECATED_HTML = 1;
Tag.TYPE_JP = 2;
Tag.getDefaultType = function() { return Tag.TYPE_JP; }

// shortcut
gTagType = Tag.getDefaultType();

// 絵文字のURLパス
Tag.VIEW_EMOJI_PATH = '/drecomcms/image/emoji/';
Tag.MEMBERS_EMOJI_PATH = '/drecomcms/image/emoji/';





/**
 * 改行をタグに変換するときのテキスト
 */
Tag.BR_TEXT  = '<br>' + OEMBlogGlobal.lineSeparator;
Tag.LT_TEXT  = '&lt;';
Tag.GT_TEXT  = '&gt;';
Tag.AMP_TEXT = '&amp;';

/**
 * 検索オプションを指定するための定数
 * 
 * <ul>
 * <li>BackwardSearch - 後方検索</li>
 * <li>AnchoredSearch - 文字列の先頭、または終端のみで一致</li>
 */
Tag.BackwardSearch = 1;
Tag.AnchoredSearch = 1 << 1;


Tag.findCustomTag = function(aText, option, start)
{
	var tag = Tag.findTag(aText, option, start);
	
	return (tag == null || tag.isCustomTag() == false) ? null : tag;
}

/**
 * text の中からタグを検索する。
 * 
 * @param aText 　検索対象の文字列
 * @param option 検索オプション定数を OR したもの
 * @param start　 検索開始位置（オプション）
 * @return 　　　　　Tag オブジェクト
 */
Tag.findTag = function(aText, option, start)
{
	var anchor  = null;    // AnchoredSearch 設定時の開始文字
	var sp      = null;
	
	if (null == aText || 0 == aText.length) {
		return null;
	}
	sp = new StringPointer(aText);
	
	if (start == null) {
		start = (option & Tag.BackwardSearch) ? aText.length -1 : 0;
	}
	
	//
	// Anchor オプションの処理
	// 検索開始位置 == タグ開始位置
	//
	if (option & Tag.AnchoredSearch) {
		var LR1 = (option & Tag.BackwardSearch) ? XBSCType.GT : XBSCType.LT;
		var LR2 = (option & Tag.BackwardSearch) ? XBSCType.RBRACE : XBSCType.LBRACE;
		c = aText.charCodeAt(start);
		
		switch (c) {
		case LR1:
			anchor = '<';
			break;
		case LR2:
			anchor = '{';
			break;
		default:
			return null;
			break;
		}
	}
	
	var idx    = -1;
	var fnName = (option & Tag.BackwardSearch) ? "lastIndexOf" : "indexOf";
	
	if (anchor != null) {
		// 前方検索なら start が使えるが、
		// 後方検索の場合、改めて検索する必要がある。
		// 面倒なのでどちらの場合でも検索
		idx = aText[fnName](anchor, start);
		
		// 以下のケースに対応
		// <B>hogehoge>hoge
		if (idx != -1 && option & Tag.BackwardSearch) {
			if (idx < aText.lastIndexOf('>', start-1)) {
				return null;
			}
		}
	} else {
		idx = aText[fnName]('<', start);
		if (-1 == idx) {
			idx = aText[fnName]('{', start);
		}
	}
	if (-1 == idx) {
		return null;
	}
	
	// StringPointer の位置をタグの先頭位置にして
	// scanTag() に委譲
	sp.setLocation(idx);
	return this.scanTag(sp);
}

Tag.TAG_NAME_STOP_CHARACTER = "/\"<{:";


/**
 * 空白文字を含まないテキストをスキャン
 * 
 * @param aStrPtr     StringPointer
 * @param stopChars   この文字列に含まれる文字でとまる
 * @param tagStopChar この文字でとまる
 */
Tag.scanText = function(aStrPtr, stopChars, tagStopChar)
{
	var fromIndex = aStrPtr.getLocation();
	var toIndex   = fromIndex;
	
	if (stopChars == null) {
		stopChars = '';
	}
	while (c = aStrPtr.getc()) {
		if (c == tagStopChar || 
			XBSUtil.indexOfCharacter("\r\n\t ", c) != -1 ||
			XBSUtil.indexOfCharacter(stopChars, c) != -1 ) 
		{
			aStrPtr.pushback();
			break;
		}
		toIndex++;
	}
	// end 
	if (toIndex == aStrPtr.string.length) {
		aStrPtr.location = fromIndex;
		return null;
	}
	
	if (fromIndex == toIndex) {
		return '';
	}
	
	return aStrPtr.string.substring(fromIndex, toIndex);
}
Tag.scanParameter = function(aStrPtr, tagStopChar)
{
	var idx = aStrPtr.getLocation();

	// 2004-05-06  Takanori Ishikawa 
	// ------------------------------------------------------------------------
	// ':' の周囲に空白を許す場合はふたつの readSpaces() の
	// コメントアウトを外してください。
	
	// aStrPtr.readSpaces();
	if (false == aStrPtr.readChar(XBSCType.COLON)) {
		aStrPtr.setLocation(idx);
		return "";
	}
	// aStrPtr.readSpaces();
	return Tag.scanText(aStrPtr, "", tagStopChar);
}

/**
 * タグをスキャン。
 * 
 * @param aStrPtr      タグの先頭位置を指す StringPointer
 * @return Tag オブジェクト、
 */
Tag.scanTag = function(aStrPtr)
{
	var sp = aStrPtr;
	var i, c;
	var tagName     = '';
	var isCustomTag = false;
	var tag         = null;
	var isEndTag    = false;
	var param       = null;
	
	if (null == sp || sp.isAtEnd()) {
		return null;
	}
	i = sp.getLocation();
	c = sp.getc();  // 先頭文字
	
	if (null == c) {
		return null;
	}
	
	//
	// <...> タグの場合、閉じタグも考慮する。
	// タグ名とタグの開始文字からカスタムタグかどうかを判別
	//
	var tagStopChar = (c == XBSCType.LT) ? XBSCType.GT : XBSCType.RBRACE;
	
	isEndTag    = (c == XBSCType.LT) ? sp.readChar(XBSCType.SLASH) : false;
	tagName     = Tag.scanText(sp, Tag.TAG_NAME_STOP_CHARACTER, tagStopChar);
	isCustomTag = (TagDefs[tagName] != null || c == XBSCType.LBRACE);
	
	if (tagName == null || tagName.length == 0) {
		return null;
	}
	if (!isEndTag && isCustomTag) {
		param = Tag.scanParameter(sp, tagStopChar);
		if (param == null) param = '';
	}
	
	if (isCustomTag) {
		var ch = sp.getc();
		var stop = (c == XBSCType.LT) ? XBSCType.GT : XBSCType.RBRACE;
		
		if (ch != stop) {
			return null;
		}
	} else {
		var QT1 = '\''.charCodeAt(0);
		var QT2 = '"'.charCodeAt(0);
		
		var ch   = -1;
		var quot = -1;
	
		while (ch = sp.getc()) {
			if (ch == QT1 || ch == QT2) {
				if (quot == ch) {
					quot = -1;
				} else if (quot != -1) {
					;
				} else {
					quot = c;
				}
			} else if (c == XBSCType.LT && quot == -1) {
				// nested tag: invalid
				return null;
			}
			if (ch == XBSCType.GT) {
				break;
			}
		}
	}

	tag = sp.substringFrom(i);
	tag = new Tag(tagName, tag, isEndTag);
	tag.value = param;
	
	return tag;
}



Tag.prototype.charCodeAt = function(idx)
{
	var s = this.source;
	return (s == null || s.length <= idx) ? null : s.charCodeAt(idx);
}

/**
 * 拡張タグかどうか
 */
Tag.prototype.isCustomTag = function() 
{
	return (this.isCustomTag1() || this.isCustomTag2());
}
Tag.prototype.isCustomTag1 = function()
{
	return (this.charCodeAt(0) == XBSCType.LT && TagDefs[this.name] != null);
}
Tag.prototype.isCustomTag2 = function() 
{
	return (this.charCodeAt(0) == XBSCType.LBRACE);
}

/**
 * HTML 表現の文字列
 */
Tag.prototype.toHTMLString = function()
{
	return this.isCustomTag1() ? this.toHTMLString1() : this.toHTMLString2();
}
Tag.prototype.toHTMLString1 = function()
{
	if (this.isComment && (this.name == "大" || this.name == "特大")) {
		var ret = "&lt;";
		
		if (this.isEnd) {
			ret += "/";
		}
		
		return ret + this.name + "&gt;";
	}
	
	var defs = TagDefs[this.name];
	if (defs == null || 0 == defs.length) {
		return this.source;
	}
	
	if (this.isEnd) {
		return '</' + defs[0] + '>';
	}
	
	if (defs.length == 2) {
		return '<' + defs[0] + ' ' + defs[1] + '>';
	} else if (defs.length == 3) {
		var v = this.value;
		if (v == '' || v == null) {
			return '';
		}
		// 念のためサニタイジング
		v = v.replace(/</g, Tag.LT_TEXT);
		v = v.replace(/>/g, Tag.GT_TEXT);			
		return '<' + defs[0] + ' ' + defs[1] + v + defs[2] + '>';
	}

	return this.source;
}
Tag.prototype.toHTMLString2 = function()
{
	if (!this.isCustomTag2()) {
		return this.source;
	}
	
	var code = Tag.EmojiNameTable[this.name];
	var text = '';
	
	if (code != null) {	// 絵文字
		text = Tag.buildEmojiImageTag(code, this.isComment);
	} else {	// 画像
		text = this.buildUploadImageTag();
		if (null == text) {
			text = this.source;
		}
	}
	return text;
}

/**
 * インスタンスの説明的な文字列
 */
Tag.prototype.toString = function()
{
	return '[Tag:'+this.name+'] ' + this.value + '\n' + this.source;
}



 
// 絵文字タグ種類
var EMOJI_HTML 		= 0;
var EMOJI_REF_JP	= 1;
var emoji_type = EMOJI_REF_JP;

// アップ画像タグ種類
var UPIMAGE_HTML 		= 0;
var UPIMAGE_REF			= 1;
var upimage_type = UPIMAGE_REF;



// ---------------------------------------------------------------------------------
// Interface
// ---------------------------------------------------------------------------------
/**
 * 絵文字のコード （e.g. '01', '64'） から名前を得る。
 * 
 * @param aCode コード文字列
 */
function getEmojiNameFromCode(aCode)
{
	var code = '';
	var name = '';
	
	if (aCode != null) {
		// 空文字に連結することで無理やり文字列に変換する
		code += aCode;
	}
	name = Tag.emojiTable[aCode];
	if (name == null) {
		name = '';
	}
	return name;
}

/**
 * 絵文字タグ生成
 * 
 * @param code 絵文字 id
 */
Tag.buildEmojiImageTag = function(code, isComment)
{
	var srcPath;

	if (!isComment) {
		srcPath = Tag.MEMBERS_EMOJI_PATH;
	} else {
		srcPath = Tag.VIEW_EMOJI_PATH;
	}

	return '<img src="' + srcPath + code + '.gif" border="0">';
}

/**
 * アップロード画像へのパスを含む img タグ文字列を生成
 * 
 * @param filename      ファイル名
 * @param optional_attr 追加属性
 * @param dir           ディレクトリ
 * 
 * @return img タグ文字列
 */
Tag.buildUploadImageTag = function(filename, optional_attr, dir)
{
	var path = dir ? dir : OEMBlogGlobal.uploadImageDirectory;
	
	if (null == path || filename == '') {
		return null;
	}
	if (optional_attr == null) {
		optional_attr = '';
	}
	path = path + escape(filename);
	path = '<img src="' + path + '" border="0" ' + optional_attr +'>';
	return path;
}

Tag.buildUploadImageTagFromText = function(tagText)
{
	var r;
	
	r = tagText.match(OEMBlogGlobal.IMAGE_FILE_PATTERN)
	if (null == r || 0 == r.length) {
		return null;
	}
	
	var fileName = r[r.length-1]
	var option   = '';
	
	if (r.length == 3 && r[1] != null && r[1].length != 0) {
		option = (r[1] == '左:') ? 'align="left"' : 'align="right"';
	}
	return Tag.buildUploadImageTag(fileName, option);
}
Tag.prototype.buildUploadImageTag = function()
{
	return Tag.buildUploadImageTagFromText(this.source);
}

//======================================================================================
// render.js
//======================================================================================

/**
 * 
 * HTML 変換
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */

//---------------------------------------------------------------------------------
// Renderer
//---------------------------------------------------------------------------------
/**
 * 本文、追記、コメントなどのプレビュー
 * 
 * @author Takanori Ishikawa
 * @version 1.0
 */
Renderer = new Object();


/**
 * 表示テキストがないときに表示する説明文
 */
Renderer.DEFAULT_EMPTY_MESSAGE = '<div style="color:#999999">（ここにプレビューが表示されます）</div>';


/**
 * プレビューを実行するかどうか
 */
Renderer.enabled = true;

/**
 * HTMLを有効にするかどうか
 * - HTMLを有効
 * -- サニタイジングなし
 * -- HTML タグはそのまま
 * -- 改行もそのまま
 * - HTMLを無効
 * -- サニタイジングあり
 * -- HTML タグはサニタイジングしたものを出力
 * -- 改行は <br> に変換 
 */
Renderer.enableHTML = true;

/**
 * 画像をアップロードするディレクトリのパス
 * jsp 側で適宜更新される。
 */
Renderer.uploadImageDirectory = null;

/**
 * コメントで使用されているかどうかをあらわすフラグ。
 */
Renderer.isComment = false; 



//---------------------------------------------------------------------------------
// Preview
//---------------------------------------------------------------------------------
Renderer.setEnabled = function(flag)
{
	flag = UtilKit.parseBoolean(flag);
	Renderer.enabled = flag;
	
	if (flag) {
		renderPreviewAll(gWriteEntryForm);
	}
}
Renderer.setEnableHTML = function(flag)
{
	flag = UtilKit.parseBoolean(flag);
	Renderer.enableHTML = flag;
	renderPreviewAll(gWriteEntryForm);
}

/**
 * すべてレンダリング
 * 
 * @param form レンダリングする内容をもつ textarea の親 Form 要素
 */

function renderPreviewAll(form)
{
	if (null == form) {
		return;
	}
	
	//	2004-04-08  Takanori Ishikawa  
	//	------------------------------------------------------------
	// 複数の jsp ファイルから呼ばれるため、実際にどのテキストエリアがあるかわからない。
	// とりあえずすべて試す	
	var layerIDs    = ['body_preview', 'comment_preview'];
	var textareaIDs = ['body', 'comment'];
	
	for (var i = 0; i < layerIDs.length; i++) {
		renderPreview(form[textareaIDs[i]], layerIDs[i]);
	}
}



/**
 * key イベントを受け取り、ブラウザごと適切なときに renderPreview() を呼び出す。
 * 
 * @param element value プロパティを持つ Element
 * @param layer_id id
 * @param show_empty_msg 空文字列の場合、説明文を代わりに表示する場合は true
 */
function renderPreviewOnKeyEvent(theEvent, element, layer_id, show_empty_msg)
{	
	if (null == theEvent || null == element) {
		return;
	}
	//	2004-04-08  Takanori Ishikawa  
	//	------------------------------------------------------------
	//	[Bug:OB106] (日本語変換が中断される)
	//	Mac IE5, Opera6 などでは IME で変換中に textArea.value を参照、変更すると
	//	変換が途中で確定してしまうので、keyEvent handler からはこの関数を呼び、ブラウザごと
	//	で処理をわける。
	//	
	//	具体的には、それらのブラウザで Return キーが押された場合のみプレビューを実行するようにした。
	//	（Enter キーは Form 自体の action 起動）
	
	if (XBSUtil.macIE && XBSUtil.macIE.major < 6 ||
	    XBSUtil.opera && XBSUtil.opera.major < 7 )
	{
		var code = XBSEvent.getKeyCode(theEvent);
	
		if (code != XBSEvent.NEW_LINE_KEY) {
			return;
		}
	} 
	renderPreview(element, layer_id, show_empty_msg);
	
}


/**
 * layer_id のレイヤに element.value を html 変換した
 * 内容を表示する
 * 
 * @param element value プロパティを持つ Element
 * @param layer_id id
 * @param show_empty_msg 空文字列の場合、説明文を代わりに表示する場合は true
 * @param is_comment コメントの場合は、true
 */
function renderPreview(element, layer_id, show_empty_msg, is_comment)
{
	if (false == Renderer.enabled || null == element || null == layer_id) {
		return;
	}
	
	var lyer = new XBSLayer(layer_id);
	var htmlText;
	
	if (null == lyer || null == lyer.getLayerImp()) {
		return;
	}
	
	htmlText = element.value;
	htmlText = Renderer.convertTextToHTML(htmlText);
	if (htmlText == '' && (!defined(show_empty_msg) || show_empty_msg == true)) {
		htmlText = Renderer.DEFAULT_EMPTY_MESSAGE;
	}
	
	lyer.setInnerHTML(htmlText);
}



//---------------------------------------------------------------------------------
// Parser
//---------------------------------------------------------------------------------
function Parser(sourceText, options) 
{
	this.src = sourceText;
	this.options = options;
	
	/* StringPointer: CRLF, CR --> LF */
	this.sp = new StringPointer(this.src, true);
	
	this.buffer = '';
	this.markedIndex = 0;
}
/**
 * Option masks (use bit OR)
 * 
 */
Parser.NEWLINE_TO_BR = 1;
Parser.SANITIZE      = 1 << 1;



Parser.prototype.newline2BRIfNeeded = function(v)
{
	if (this.options & Parser.NEWLINE_TO_BR) {
		v = v.replace(/\r\n|\r|\n/g, Tag.BR_TEXT);
	}
	return v;
}
Parser.prototype.sanitizeIfNeeded = function(v, amp)
{
	if (this.options & Parser.SANITIZE) {
		// サニタイジング
		v = v.replace(/</g, Tag.LT_TEXT);
		v = v.replace(/>/g, Tag.GT_TEXT);
		if (amp) {
			v = v.replace(/&/g, Tag.AMP_TEXT);
		}
	}
	return v;
}
Parser.prototype.flush = function(toIndex)
{
	if (toIndex == null)
		toIndex = this.sp.getLocation();
	
	var t = this.sp.substring(this.markedIndex, toIndex);
	
	t = this.sanitizeIfNeeded(t);
	t = this.newline2BRIfNeeded(t);
	this.buffer += t;
}
Parser.prototype.parse = function()
{
	// data variable
	var sp = this.sp;
	var c;
	var idx;
	var tag = '';
	
	this.markedIndex = idx = sp.getLocation();
	while ( (c = sp.getc()) != null ) {
		// Tag
		if (c == XBSCType.LBRACE || c == XBSCType.LT) {
			
			tag = Tag.findTag(this.src, Tag.AnchoredSearch, idx);
			if (tag != null) {
				this.flush(idx);
				tag.isComment = Renderer.isComment;
				
				var html = tag.toHTMLString();
				if (!tag.isCustomTag() && !tag.isCustomTag2()) {
					html = this.sanitizeIfNeeded(html, false);
				}
				this.buffer += html;
				sp.readUpToString(c == XBSCType.LBRACE ? '}' : '>');
				this.markedIndex = sp.getLocation();
			}
		}
		idx = sp.getLocation();
	}
	this.flush();
	
	return this.buffer;
}



/**
 * 文字列を html に変換
 * 
 * @param 文字列
 * @return html
 */
Renderer.convertTextToHTML = function(aText)
{
	var options   = 0;
	var parser    = null;
	var htmlText  = '';
	
	// HTML が有効でなければ改行を<br>に置換
	if (!Renderer.enableHTML) {
		options |= Parser.NEWLINE_TO_BR;
		options |= Parser.SANITIZE;
	}
	parser   = new Parser(aText, options);
	htmlText = parser.parse();
	
	/* JUST A DEBUG */
	window.LAST_HTML = htmlText;
	
	return htmlText;
}
/* JUST A DEBUG */
function ptag() { alert(window.LAST_HTML) }

//======================================================================================
// select.js
//======================================================================================
/*
 * 選択テキストオブジェクト
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */



// 選択範囲の開始点と終了点の順序が逆転したことを示すフラグ
var reversalFlag = false;
/*
	選択範囲に逆順を設定することがIE/NN共にできない。終了点を開始点よりも左に設定しようとした場合、
	開始点も動いてしまい、終了点と同じ位置に来てしまう。
	このため、逆転したことを選択範囲と進む方向、SHIFTキーが押されているかから取得し、この場合には
	現在のキャレットの位置を終了点ではなく開始点から取得するようにしている。
*/


// 強制的に選択を解除することを示すフラグ
var nonSelectedFlag = false;
/*
	NNだと、onkeydownイベントのキャンセルが行えないため、キャレットをプログラムで動かす場合には、
	動かしたいキャレットの数から、実際に押されたキーによって動いてしまう数を減らした分だけ動かす必要がある。
	ただしこの方法だと、開始点と終了点の順序を逆転することができないため、選択範囲を解除することができない。
	(プログラム上で選択範囲を指定した場合、実際に押されたキーによってキャレットが動くのは終了点のためである）
	上記理由より、nonSelectedFlagがtrueの場合は、実際に押されたキーによる範囲選択が終わったあとに送られるイベント内で、
	選択範囲を解除する処理を行う必要がある。
*/


// 右端の範囲を選択することを示すフラグ
var selectingRightEdgeFlag = false;
/*
	nonSelectedFlagと同様に、右端を選択することができないため。
*/


/**
 * 選択テキストオブジェクト
 * 
 */
function SelectedText(selected)
{
	this.srcElement = selected;
	
	// メソッド呼出しごとの null チェックが煩わしいので
	// false で初期化
	if (selected == null) {
		this.srcElement = false;
	} else {
		if (document.selection) {  // document.selection -- IE 
			this.selected = document.selection.createRange();
		} else {
			this.selected   = null;
			this.srcElement = selected;
		}
	}
}
/**
 * HTML タグでタグ編集（タグ削除や移動）を有効にしない場合は
 * カスタムタグだけを検索。
 */
SelectedText.prototype.findTag = function(aText, option, start)
{
	return OEMBlogGlobal.enableTagEditingOnHTML
				? Tag.findTag(aText, option, start)
				: Tag.findCustomTag(aText, option, start);
}

SelectedText.prototype.isSelected = function()
{
	var selected = false;
	
	if (this.selected != null) {	// IE	
		selected = (this.selected.text != '');
	} else if (defined(this.srcElement.selectionStart)) {	// NN 7
		selected = (this.srcElement.selectionStart != this.srcElement.selectionEnd);
	}
	return selected;
}

SelectedText.prototype.move = function(length, isEnd)
{
	var result = 0;
	
	if (this.selected != null) {	// IE
		var lenExp = (isEnd) ? (length > 0) : (length < 0);
		if (lenExp && this.getTextBetweenCaret(isEnd, isEnd).length == 0)
			return 0;
		
		result = this.selected[isEnd ? 'moveEnd' : 'moveStart']('character', length);
		this.selected.select();	
	} else if (defined(this.srcElement.selectionStart)) {
		var ex = this.srcElement[isEnd ? 'selectionEnd' : 'selectionStart'];
		
		if (isEnd) {
			this.srcElement.setSelectionRange(this.srcElement.selectionStart, this.srcElement.selectionEnd + length);					
			result = this.srcElement.selectionEnd - ex;
		} else {
			this.srcElement.setSelectionRange(this.srcElement.selectionStart + length, this.srcElement.selectionEnd);	
			result = this.srcElement.selectionStart - ex;
		}
	}
	return result;
}

SelectedText.prototype.moveStart = function(length)
{
	return this.move(length, false);
}
SelectedText.prototype.moveEnd = function(length)
{
	return this.move(length, true);
}


SelectedText.prototype.moveStartOnEnd = function()
{
	if (this.selected != null) {	// IE
		this.selected.collapse(false);
		this.selected.select();
	} else if (defined(this.srcElement.selectionStart)) {
		this.srcElement.selectionStart = this.srcElement.selectionEnd;
	}
}
SelectedText.prototype.moveEndOnStart = function()
{
	if (this.selected != null) {	// IE	
		this.selected.collapse();
		this.selected.select();
	} else if (defined(this.srcElement.selectionStart)) {
		this.srcElement.selectionEnd = this.srcElement.selectionStart;
	}
}

SelectedText.prototype.getTextBetweenCaret = function(after, isSelectionEnd)
{
	var result = '';
	
	if (this.selected != null) {	// IE	
		result = this.getTextBetweenCaret_IE(after, isSelectionEnd);
	} else if (defined(this.srcElement.selectionStart)) {
		var v = this.srcElement[isSelectionEnd ? 'selectionEnd' : 'selectionStart'];
		if (!after) {
			startPos = 0;
			endPos = v;
		} else {
			startPos = v;
			endPos = this.srcElement.value.length;
		}
		result = this.srcElement.value.substring(startPos, endPos);
	}
	return result;
}
SelectedText.prototype.getTextBetweenCaret_IE = function(after, isSelectionEnd)
{
	// TextRange.textは、最後に改行があるとこれを削除してしまう。
	// そのため、先頭からキャレットまでの文字列がほしい場合は、
	// まずキャレットから最後までの文字列を取得し、エレメントの文字列からこの部分を除いたものを返す
	var rightArea = this._getRangeBetweenCaret_IE(true, isSelectionEnd);
	var parentValue = this.selected.parentElement().value;
	var rightText = rightArea.text;

	// 最後尾に改行があると、現在のキャレットの位置を文字列からでは取得できない。
	// そのため、現在座標を利用して位置を取得する。
			
	var lastCrLf = parentValue.search('(\\r\\n)+$');
	if (lastCrLf >= 0) {
		lastCrLf = parentValue.length - lastCrLf;
				
		// 末尾の座標を取得し、現在末尾から何行目かを判断。
		// また、1行の高さはboundingHeightを利用して算出を行うと、
		// 実際よりも小さな値になってしまう。そのため、
		// 最初の行と最後の行のboundingTopの差を出し、
		// 総行数（テキストエリアに含まれる改行の総数＋1)で割ったものを利用する。
			
		var bottomArea = document.body.createTextRange(); 
		bottomArea.moveToElementText(this.selected.parentElement());
		var topArea = bottomArea.duplicate();
		topArea.collapse(true);
		bottomArea.collapse(false);	
			
		var curRowFromBottom = (bottomArea.boundingTop - this.selected.boundingTop) * parentValue.match(new RegExp('\\r\\n', 'g')).length 
								/ (bottomArea.boundingTop - topArea.boundingTop);
		for (i = 0; i < curRowFromBottom && i < lastCrLf / 2; i++) {
			rightText += '\r\n'; 
		}
	}
	if (after) {
		return rightText;
	} else {
		if (parentValue != null) {
			return parentValue.substring(0, parentValue.length - rightText.length);
		}
	}
	return '';
}

SelectedText.prototype.deleteNeighborTextFromCaret = function(after, target, original, exceptLength)
{
	if (this.selected != null) {	// IE	
		this.deleteNeighborTextFromCaret_IE(after, target, original, exceptLength);
	} else if (defined(this.srcElement.selectionStart)) {
		this.deleteNeighborTextFromCaret_NN(after, target, original, exceptLength);
	}
}
SelectedText.prototype.deleteNeighborTextFromCaret_NN = function(after, target, original, exceptLength)
{
	with (this.srcElement) {
		var startPos = selectionStart;
		var endPos = selectionEnd;
		var nestCnt=0;
		var targetTags = '';
		var tags = null;
		var leftContext = '', rightContext = '';
		var reselectMode;
		var NO_RESELECT_RANGE = 0;
		var MOVE_RANGE = 1;
		var SHRINK_RANGE = -1;
		var i;

		rightSide = this.getTextBetweenCaret(true, false);
		leftSide = this.getTextBetweenCaret(false, false);
		if (after) {
			except = rightSide.substring(0, exceptLength);
			rightSide = rightSide.substring(exceptLength, rightSide.length);
	
			if ((tags = rightSide.match(new RegExp(target + '|' + original, 'g'))) == null)
				return;
	
			for (i = 0; i < tags.length; i++) {
				if (tags[i].charAt(1) != '/') {
					nestCnt++;
				} else {
					nestCnt--;	
					targetTags += tags[i] + ',';
				}	
				if (nestCnt < 0)
					break;
			}
	
			tags = targetTags.split(',');
			if (tags == null)
				return;
	
			var pos = 0;
			var ex_pos = 0;
			i = 0;
			while (true) {
				pos = rightSide.indexOf(tags[i], ex_pos);
	
				leftContext += rightSide.substring(ex_pos, pos);
				ex_pos = pos + tags.length;
				
				if (i >= tags.length - 2) {
					leftContext = rightSide.substring(0, pos);
					target = tags[i];
					break;
				}
										
				leftContext += tags[i];
					
				i++;
			}
			rightContext = rightSide.substring(pos + target.length, rightSide.length);
			value = leftSide + except + leftContext + rightContext;
			
			if (endPos < leftSide.length + exceptLength + leftContext.length)
				reselectMode = NO_RESELECT_RANGE;
			else if (startPos <= leftSide.length + exceptLength + leftContext.length)
				reselectMode = SHRINK_RANGE;
			else
				reselectMode = MOVE_RANGE;
	
	
		} else {
			except = leftSide.substring(leftSide.length - exceptLength, leftSide.length);
			leftSide = leftSide.substring(0, leftSide.length - exceptLength);
			if ((tags = leftSide.match(new RegExp(target + '|' + original, 'g'))) == null)
				return;
	
			for (i = tags.length-1; i >= 0; i--) {
				if (tags[i].charAt(1) == '/') {
					nestCnt++;
				} else {
					nestCnt--;
					targetTags += tags[i] + ',';
				}
				if (nestCnt < 0)
					break;
			}
	
			tags = targetTags.split(',');
			if (tags == null) return;

			var pos = leftSide.length;
			var ex_pos = pos;
			i = 0;
			while (true) {
				pos = leftSide.lastIndexOf(tags[i], ex_pos);
				ex_pos = pos - tags[i].length;
				
				if (i >= tags.length - 2) {
					rightContext = leftSide.substring(pos + tags[i].length, leftSide.length);
					target = tags[i];
					break;
				}
					
				i++;
			}
			leftContext = leftSide.substring(0, pos);

			value = leftContext + rightContext + except + rightSide;

			reselectMode = MOVE_RANGE;
		}

		switch (reselectMode) {
		case SHRINK_RANGE:
			setSelectionRange(startPos, endPos - target.length);
			break;
		case MOVE_RANGE:
			setSelectionRange(startPos - target.length, endPos - target.length);
			break;
		default:
			setSelectionRange(startPos, endPos);
			break;
		}
	}
}

SelectedText.prototype.deleteNeighborTextFromCaret_IE = function(after, target, original, exceptLength)
{
	var nestCnt=0;
	var targetTags = '';
			
	var targetRange = this._getRangeBetweenCaret_IE(after, false);

	if (after)
		targetRange.moveStart('character', exceptLength);
	else
		targetRange.moveEnd('character', -exceptLength);
				

	var originalRange = targetRange.duplicate();
			
	var tags = null;

	if ((tags = targetRange.text.match(new RegExp(target + '|' + original, 'g'))) == null)
		return;
	if (after) { 
		for (i = 0; i < tags.length; i++) {
			if (tags[i].charAt(1) != '/') {
				nestCnt++;
			} else {
				nestCnt--;	
				targetTags += tags[i] + ',';
			}	
			if (nestCnt < 0)
				break;
		}
	} else {
		for (i = tags.length-1; i >= 0; i--) {
			if (tags[i].charAt(1) == '/') {
				nestCnt++;
			} else {
				nestCnt--;
				targetTags += tags[i] + ',';
			}
			if (nestCnt < 0)
				break;
		}
	}

	i = 0;
	tags = targetTags.split(',');
	if ((tags = targetTags.split(',')) == null)
		return;
	while (true)
	{
		if (tags[i] != '') {
			
			if (!targetRange.findText(tags[i], (after) ? 9999999 : -9999999)) 
				return;
						
			if (i >= tags.length - 2) {
				targetRange.text = '';
				break;
			}
						
			if (after) {
				targetRange.setEndPoint('EndToEnd', originalRange);
				targetRange.moveStart('character', tags[i].length);
			} else {
				targetRange.setEndPoint('StartToStart', originalRange);
				targetRange.moveEnd('character', -tags[i].length);
			}					
		}
		i++;
	}
}
SelectedText.prototype._getRangeBetweenCaret_IE = function(after, isSelectionEnd)
{			
	if (this.selected != null) {	// IE	
		targetRange = document.body.createTextRange();
		targetRange.moveToElementText(this.selected.parentElement());
	
		selectedRange = this.selected.duplicate();
		if (!isSelectionEnd)
			selectedRange.collapse();
	
		targetRange.setEndPoint(after ? 'StartToEnd' : 'EndToEnd', selectedRange);
				
		return targetRange;
	}
	return false;
}

SelectedText.prototype.insertTextOnBothSides = function(front, back)
{
	if (this.selected != null) {
		var text_length = this.selected.text.length;
		
		this.selected.text = front + this.selected.text + back;
		this.selected.move('character', - (text_length+back.length) );
		this.selected.moveEnd('character', text_length);
		this.selected.select();
		this.focus();
		
	} else if (defined(this.srcElement.selectionStart)) {
		var sstart = this.srcElement.selectionStart;
		var send   = this.srcElement.selectionEnd;
		var t      = this.srcElement.value;

		t = t.substring(0, sstart) +  front + this.getText() + back +  t.substr(send, t.length);
		this.srcElement.value = t;
		this.srcElement.setSelectionRange(sstart + front.length, send + front.length);
		this.focus();
	} else if (this.srcElement.value != null){
		this.srcElement.value += front + back;
		this.focus();
	}
}
SelectedText.prototype.insertText = function(aText)
{
	if (this.selected) {
		this.selected.text = aText + this.selected.text;
		this.selected.select();
	} else if (defined(this.srcElement.selectionStart)) {
		with (this.srcElement) {
			selectPos = value.substring(0, selectionStart).length +  aText.length;
			value = value.substring(0, selectionStart) +  aText + this.getText() + value.substr(selectionEnd, textLength);
			setSelectionRange(selectPos, selectPos);
			this.focus();
		}
	} else if (this.srcElement.value != null){
		this.srcElement.value += aText;
		this.focus();
	}
}

SelectedText.prototype.focus = function()
{
	if (this.srcElement != null && this.srcElement.focus != null) {
		this.srcElement.focus();
	}
}
SelectedText.prototype.getText = function()
{
	var t = '';
	
	if (this.selected) {
		t = this.selected.text;
	} else if (defined(this.srcElement.selectionStart)) {
		with (this.srcElement) {
			t = value.substring(selectionStart, selectionEnd);
		}
	} 
	return t;
}



/**
 * 
 * 削除しようとしているタグのもう一方のタグを削除する
 *	
 * @param tag	タグ
 * @param isDeleteKey 	
 *   DELETEキーが押された場合はtrue
 *   BackSpaceキーが押された場合はfalse
 * @param isSelected   選択されているか
 * @param exceptLength 選択された状態の場合に、除外したい選択範囲の左端からの位置
 */
SelectedText.prototype.deleteOtherTag = function(tag, isDeleteKey, isSelected, exceptLength)
{
	var tagText = tag.getSource();
	var originalTag = '';
	var targetTag   = '';
	var isEndTag;
	
	if (tagText.match('^</([^>]*)>$') != null) {
		// 削除対象が開始タグの場合
		originalTag = '</' + RegExp.$1 + '>';
		targetTag = tagText.replace(new RegExp('^</([^>]*)>$'), '<$1:[^>]*>|<$1>');
		isEndTag = false;
		if (isSelected)
			exceptLength = 0;
		else if (!isDeleteKey)
			exceptLength += tagText.length;
		
	} else if (tagText.match('^<([^:>]*)>$|^<([^>:]*):[^>]*>$') != null) {
		// 削除対象が終了タグの場合
		originalTag = RegExp.$1 != '' ? tagText : '<' + RegExp.$2 + ':[^>]*>';
		targetTag = tagText.replace(new RegExp('^<([^:>]*)>$'), '</$1>');
		targetTag = targetTag.replace(new RegExp('^<([^>:]*):[^>]*>$'), '</$1>');
		isEndTag = true;
		if (isSelected)
			exceptLength += tagText.length;
		else if (isDeleteKey)
			exceptLength += tagText.length;
			
	} else {
		return;
	}
	
	this.deleteNeighborTextFromCaret(isEndTag, targetTag, originalTag, exceptLength);

}

/**
 * タグの上にキャレットがこないようにする
 *	after:	右側にキャレットが移動しているかどうか
 *  shiftKey:
 *	 		SHIFTキーが押されているかどうか
 * @return 成功時には true
 */
SelectedText.prototype.moveCaretOutOfTag = function(isMoveRight, shiftKey)
{
	var text = ''; ;
	
	if (this.isNull()) {
		return false;
	} 
	if (!isMoveRight && shiftKey && !this.isSelected())
		reversalFlag = true;
	else if (!shiftKey || (isMoveRight && !this.isSelected()))
		reversalFlag = false;
	
	if (this.isSelected() && !shiftKey) {
		return false;
	}
		
	
	if (this.isSelected() && ((isMoveRight && reversalFlag) || (!isMoveRight && !reversalFlag))) {
		text = this.getText();
	} else {
		text = this.getTextBetweenCaret(isMoveRight, !reversalFlag);
	}
	
	var searchOption = 0;
	var tag = null;
	var tagText = '';
	var result = false;

	searchOption |= Tag.AnchoredSearch;
	if (!isMoveRight) {
		searchOption |= Tag.BackwardSearch;
	}
	
	tag = this.findTag(text, searchOption);
	tagText = tag != null ? tag.getSource() : '';

	// 実際に移動したい数より、1少ない（あるいは1多い)数を指定する。
	// 理由は、reversalFlagの宣言部に記述
	if (isMoveRight) {
		if (!reversalFlag) {
			if (tagText != '') {			
				this.moveEnd(tagText.length - 1);
				if (!shiftKey) 
					this.moveStartOnEnd();
			}
		} else {
			this.moveStart(tagText.length != 0 ? tagText.length : 1);
			if (!this.isSelected()) {

				if (this.getTextBetweenCaret(true, true).length != 0)
					nonSelectedFlag = true;

				reversalFlag = false;

				result = true;
			} else {
				this.moveEnd(-1);
			}
		}			

	} else {
		if (!reversalFlag) {
			
			if (tagText != '') {
				var expectedLength = (tagText.length * -1) +1;
				var movedLength    = 0;
				
				movedLength = this.moveEnd(expectedLength)
				if (!shiftKey) {
					this.moveEndOnStart();
				}
			}
		} else {
			var moveLength;
			
			if (this.moveEnd(1) != 1) {
				selectingRightEdgeFlag = true;
				result = true;
			}
			moveLength = tagText.length != 0 ? (tagText.length *-1) : -1;
			this.moveStart(moveLength);
		}
	}
	return result;
}
//alert(1)
/**
 * 
 * 削除しようとしているタグに対応する、もう一方のタグを削除する
 * そのあとで削除しようとしているタグを選択状態にする
 * 削除しようとしているタグの削除は、実際に押されたキー(DEL/BS)が行う
 * 
 * @param isDeleteKey true:DELETE false:BackSpace
 */
SelectedText.prototype.deleteTagOnCaret = function(isDeleteKey)
{
	var selectedText = this.getText();
	var tag          = null;
	
	if (this.isNull())
		return;
	
	if (selectedText == null || selectedText == '') {
		selectedText = this.getTextBetweenCaret(isDeleteKey, false);
		
		var searchOption = isDeleteKey ? 0 : Tag.BackwardSearch;

		searchOption |= Tag.AnchoredSearch;
		tag = this.findTag(selectedText, searchOption);
		if (tag != null) {
			var moveLength = 0;
			
			this.deleteOtherTag(tag, isDeleteKey, false, 0);
			
			moveLength = tag.getSource().length * (isDeleteKey ? 1 : -1);
			this[isDeleteKey ? "moveEnd" : "moveStart"](moveLength);
		}
	} else {
		var exceptLength = 0;
		
		while (1) {
			tag = this.findTag(selectedText, 0);
			if (null == tag)
				break;
			
			var tagText = tag.getSource();
			this.deleteOtherTag(tag, isDeleteKey, true, exceptLength);
			
			selectedText = this.getText();
			exceptLength = selectedText.indexOf(tagText, exceptLength) + tagText.length;
			
			selectedText = selectedText.substring(exceptLength, selectedText.length);
			
		}
	} 
}


SelectedText.prototype.isNull = function()
{
	return (this.srcElement == null || this.srcElement.value == null || this.srcElement.focus == null);
}

//======================================================================================
// insert_tags.js
//======================================================================================
/*
 * タグ編集
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */


/**
 * NullObject idiom
 */
var NullSelectedText = new SelectedText(null);

//---------------------------------------------------------
// Global variables
//---------------------------------------------------------
var gSelectedTextObj   = NullSelectedText;

/**
 * 利用する HTML 要素の id 属性
 */
var gColorPaletteID      = 'palette';
var gEmojiPaletteID      = 'emoji'

var gSampleTextColorID   = 'paletteSampleTextColor';
var gPaletteColorWellID  = 'paletteColorWell';
var gPaletteColorFieldID = 'paletteColorField';

var gPaletteIDs = [gColorPaletteID, gEmojiPaletteID];


/**
 * 背景色を変更できるプレビュー領域
 * 
 * gSelectedPreviewID
 *   null   : 背景色を変更しない
 *   string : 指定された id の背景色変更
 *   array  : 各プレビュー領域の背景色変更
 */
var gSelectedPreviewID   = null;
var gSelectedColorWellID = null;

var gPreviewBgColorWellID = 'preview_colorWell';
var gPreviewIDs = ['body_preview'];

//---------------------------------------------------------
// Palette
//---------------------------------------------------------
/**
 * パレットを指定されたレイヤーの位置で Y 座標を決定。
 * 
 * @param theEvent event
 * @param paletteName 
 * @param layerID
 */
function showPaletteAroundLayer(theEvent, paletteName, layerID)
{
	var lyer = XBSLayer.makeLayer(paletteName);
	var dist = XBSLayer.makeLayer(layerID);
	
	if (theEvent == null) {
		theEvent = window.event;
	}
	setUpColorPalette(paletteName);
	if (lyer.isVisible()) return;
	
	var dx = XBSEvent.getMouseX(theEvent);
	var dy = dist.getY();
	var dw = dist.getWidth();
	var dh = dist.getHeight();
	
	// 2004-05-07  Takanori Ishikawa 
	// ------------------------------------------------------------------------		
	// ウインドウからはみ出そうな場合は調整
	var w = XBSDocument.getWidth() + XBSDocument.getPageOffsetX();
	var h = XBSDocument.getHeight() + XBSDocument.getPageOffsetY();
	
	dx -= lyer.getWidth()/2;
	var x = dx + lyer.getWidth()/2;
	var y = dy  + lyer.getHeight();
	
	if (x > w) {
		dx -= x - w;
	}
	if (y > h) {
		dy -= y - h;
	}
	XBSLayer.initPositionStyle(lyer.getLayerImp());
	lyer.setPosition(dx, dy);
	lyer.setVisible(true);
	
}

/**
 * パレットを非表示にする
 */
function hideAllPalette()
{
	for (var i = 0; i < gPaletteIDs.length; i++) {
		var lyer = XBSLayer.makeLayer(gPaletteIDs[i]);
		
		if (lyer != null && lyer.isValid()) {
			lyer.setVisible(false);
		}
	}
	synchronize_preview_bgcolors();
	gSelectedPreviewID = null;
	gSelectedColorWellID = null;
}

function savePaletteEventHandler()
{
	document.onmouseup = null;
}
function restorePaletteEventHandler()
{
	document.onmouseup = hideAllPalette;
}
//---------------------------------------------------------
// 編集
//---------------------------------------------------------

function initializeSelectedText(element, fromAnotherElement)
{
	if (null == element) {
		return;
	}
	if (fromAnotherElement != null && fromAnotherElement) {
		element.focus();
	}


	// 2004/03/31 Takanori Ishikawa 
	// ------------------------------------------------------
	// Opera 7, Mac IE: createTextRange）() の有無で判定
	
	// キャレットを末尾に移動させる。
	if (element.createTextRange && gSelectedTextObj.isNull()) {
		var text_range;
		
		text_range = element.createTextRange();
		text_range.move("character", element.value.length );
		text_range.select();
	}
	gSelectedTextObj = new SelectedText(element);
	
	gSelectedPreviewID = null;
	gSelectedColorWellID = null;
}


// image_select_place.jsp, entry_write_edit.jsp
function focusSelectedText()
{
	gSelectedTextObj.focus();
}

/**
 * insertText(front)
 * front: 選択部分前部に挿入するテキスト
 *
 * テキスト(エリア)フォームにテキストを挿入する関数
 * 選択文字列の前に挿入される
 * 選択されていない場合、カーソル位置に挿入される
 */
function insertText(front)
{
	gSelectedTextObj.insertText(front);
}

//---------------------------------------------------------------------------------
// Edit
//---------------------------------------------------------------------------------

/**
 * 選択範囲の端がタグの内部にある場合、タグの外に選択範囲を移動させる
 */
function cutOutTagFragmentOnSelectionArea()
{
	if (false == gSelectedTextObj.isSelected()) 
		return;
	
	var nonSelectionArea = '';
	var tagText          = '';
	var targetArea       = '';
	var tagFragment      = '';
	
	var tag = null;
	
	// 選択範囲の左端の処理
	var tags = gSelectedTextObj.getText().match('^[^<]*>|^[^{]*}');
	if (tags != null) {
		tagFragment = tags[0];

		nonSelectionArea = gSelectedTextObj.getTextBetweenCaret(false, false);
	
		targetArea = nonSelectionArea + tagFragment;
		tag = Tag.findTag(targetArea, Tag.BackwardSearch);
		tagText = tag ? tag.getSource() : '';
		if (tagText != '' && nonSelectionArea.length < targetArea.lastIndexOf(tagText) + tagText.length) {
			gSelectedTextObj.moveStart(tagFragment.length);
		}
	}

	// 選択範囲の右端の処理
	tags = gSelectedTextObj.getText().match(new RegExp('</?[^>]*$|{[^}]*$', 'g'));
	if (tags != null) {
		tagFragment = tags[tags.length - 1];

		nonSelectionArea = gSelectedTextObj.getTextBetweenCaret(true, true);
	
		targetArea = tagFragment + nonSelectionArea;
		tag = Tag.findTag(targetArea, 0);
		tagText = tag ? tag.getSource() : '';
		if (tagText != '' && nonSelectionArea.length < targetArea.length - targetArea.indexOf(tagText)) {
			gSelectedTextObj.moveEnd(-tagFragment.length);
		}
	}
}

/**
 * SelectedTextの終了処理
 */
function finalizeSelectedText()
{
	// 下記処理は、NNの場合に行われる
	// IEでは、onkeydownでキャンセルされるため不必要
	
	// IEで、この関数をonselectから呼び出すとアクセスバイオレーションが発生し、IEごと落ちてしまう。
	// そのためこの処理をNNとIEで分けている


	if (document.all != null) 
		return;

	if (nonSelectedFlag) {
		nonSelectedFlag = false;
		gSelectedTextObj.moveEnd(-1);
		gSelectedTextObj.moveStartOnEnd();
	}

	if (selectingRightEdgeFlag) {
		selectingRightEdgeFlag = false;
		gSelectedTextObj.moveEnd(1);
	}
}

//---------------------------------------------------------------------------------
// Color
//---------------------------------------------------------------------------------
/**
 * マウスがのっている色パレットの色を RGB 文字列 (#XXXXXX) で
 * 取得する。
 * 
 * @param event mousemove イベント
 * @return RGB 文字列
 */
getBgColor.prev           = null;	/* 前回取得した値 */
// div - id
getBgColor.colorPaletteID = gColorPaletteID;
getBgColor.childPaletteID = 'colors';
getBgColor.width          = 10;			/* 各色パレットの一辺の長さ */
getBgColor.cols           = 32;			/* 色パレット、カラム数 */

function getBgColor(event)
{
	var color = null;
	
	// イベントから色を取得
	if (event.srcElement && event.srcElement.style) {
		color = event.srcElement.style.backgroundColor;
	} else if (event.target && event.target.style){
		color = event.target.style.backgroundColor;
	}
	
	// イベントから取得できなければマウスの位置から計算する
	if (color == null || (typeof color == 'string' && color.length == 0)) {
		var mouseX = XBSEvent.getMouseX(event);
		var mouseY = XBSEvent.getMouseY(event);
		
		var parent = new XBSLayer(getBgColor.colorPaletteID);	/* 色パレット */
		var lyer   = new XBSLayer(getBgColor.childPaletteID);	/* 各色パレットを格納したレイヤー */
		
		// パレット内部での相対的な位置に変換
		mouseX -= (parent.getX() + lyer.getX());
		mouseY -= (parent.getY() + lyer.getY());
		try {
			var nodes;
			var target = null;
			
			// すべての色パレットを調べる
			nodes = document.getElementById(getBgColor.childPaletteID);
			nodes = nodes.getElementsByTagName("td");
			for (var i = 0; i < nodes.length; i++) {
				var item = nodes.item(i);
				
				// Safari では offsetHeight = 0 になっている
				if (item.offsetLeft <= mouseX && item.offsetLeft + getBgColor.width >= mouseX) {
					// Mac IE では offsetTop = 0 になっている
					var offsetTop = Math.floor((i+1)/getBgColor.cols) * getBgColor.width;
					if (offsetTop <= mouseY && offsetTop + getBgColor.width >= mouseY) {
						target = item;
						break;
					}
				}
			}
			if (target && target.style) {
				color = target.style.backgroundColor;
			}
		} catch (e) {
			//alert("Exception: " + e);
		}
	}
	
	/*
	  NN6だと、色レイヤーが押されたときにevent.targetがnullの場合がある。 
	  この場合は、前回取得した値を返すようにすることで、
	  NN6にも対応する。
	*/
	if (typeof color == 'string' && color.length != 0)
		getBgColor.prev = color;
	else
		color = getBgColor.prev;
	
	return UtilKit.normalizeRGBColorRep(color);	
}
/**
 * 背景色選択の開始。
 * 
 * @param previewID 変更するプレビュー領域の背景色
 * すべてのプレビュー領域を変更するときは null を渡す
 */
function startChoosePreviewBgColor(theEvent, previewID, colorWellID, distLayer)
{
	gSelectedTextObj     = NullSelectedText;
	gSelectedPreviewID   = previewID;
	gSelectedColorWellID = colorWellID;
	if (null == gSelectedPreviewID || typeof gSelectedPreviewID != typeof '') {
		gSelectedPreviewID = gPreviewIDs;
	}
	showPaletteAroundLayer(theEvent, gColorPaletteID, distLayer);
}

/**
 * 色パレット準備
 */
function setUpColorPalette(paletteName)
{
	if (paletteName == gEmojiPaletteID)
		return;
	
	if (gSelectedColorWellID && gSelectedPreviewID){
		// プレビュー背景色
		colorPaletteDidFocusColor(
			UtilKit.getBgColorById(gSelectedColorWellID));
	} else {
		colorPaletteDidFocusColor("#000000");
	}
}



/**
 * 色パレットの色にマウスが載った。
 */
function colorPaletteDidFocusColor(aColor)
{
	var lyer = XBSLayer.makeLayer(gSampleTextColorID);
	var style = null;
	var impFn = null;
	
	if (gSelectedPreviewID != null) {
		// 背景色
	}
	
	lyer.getStyleObject().color = aColor;
	UtilKit.setBgColorById(gPaletteColorWellID, aColor);
	textFieldSetValueById(gPaletteColorFieldID, aColor)
}

function colorPaletteDidSelectColor(aColor)
{
	if (false == gSelectedTextObj.isNull()) {
		insert_tag_color(aColor);
	} else if (gSelectedPreviewID != null) {
		updatePreviewBgcolor(gSelectedPreviewID, aColor);
	}
}

function synchronize_preview_bgcolors()
{
	for (var i = 0; i < gPreviewIDs.length; i++) {
		var preId   = gPreviewIDs[i];
		var bgcolor = UtilKit.getBgColorById(preId);
		
		UtilKit.setBgColorById(gPreviewBgColorWellID, bgcolor);
	}
}

/**
 * プレビュー領域の背景色を変更
 * 
 * @param previewID string or array
 */
function updatePreviewBgcolor(previewID, aColor)
{
	update_preview_bgcolor(previewID, aColor);
	// 背景色を変更したら、すぐにクッキーに保存する
	EntryFormManager ? EntryFormManager.savePreferences() : void(0);
}
function update_preview_bgcolor(previewID, aColor)
{
	if (previewID == null || previewID.length == 0) {
		return;
	}
	if (previewID.substring != null) {
		previewID = new Array(previewID);
	}
	
	for (var i = 0; i < previewID.length; i++) {
		UtilKit.setBgColorById(previewID[i], aColor);
	}
	UtilKit.setBgColorById(gPreviewBgColorWellID, aColor);
}

function textFieldSetValueById(layerID, aValue)
{
	var lyer  = new XBSLayer(layerID);
	var imp = null;
	
	if (false == lyer.isValid()) {
		return;
	}
	
	imp = lyer.getLayerImp();
	if (imp != null && imp.value != aValue) {
		imp.value = aValue;
	}
}
function validateColor(aColor)
{
	var i = 0;
	var a = 'a'.charCodeAt(0);
	var f = 'f'.charCodeAt(0);
	var A = 'A'.charCodeAt(0);
	var F = 'F'.charCodeAt(0);
	var c0 = '0'.charCodeAt(0);
	var c9 = '9'.charCodeAt(0);
	
	if (aColor == null || aColor.substring == null || aColor.length < 6) {
		return false;
	}
	if (aColor.charCodeAt(0) == '#'.charCodeAt(0)) {
		i = 1;
		if (aColor.length != 7) {
			return false;
		}
	}
	
	for (; i < aColor.length; i++) {
		var c = aColor.charCodeAt(i);
		
		if ((a <= c && c <= f) ||
		(A <= c && c <= F) ||
		(c0 <= c && c <= c9))
		{ continue; }
		
		return false;
	}
	return true;
}

function colorPaletteFieldValueDidChange(aField)
{
	var color = aField.value
	var preview_id;
	
	if (false == validateColor(color)) {
		return null;
	}
	if (color.charCodeAt(0) != '#'.charCodeAt(0)) {
		color = '#' + color;
	}
	colorPaletteDidFocusColor(color);
	
	return color;
}
function colorPaletteFieldValueDidAction()
{
	var t;
	var color;
	
	t = document.all 
			? document.all(gPaletteColorFieldID)
			: document.getElementById(gPaletteColorFieldID);
	
	color = colorPaletteFieldValueDidChange(t);
	if (color != null) {
		colorPaletteDidSelectColor(color);
	}
	hideAllPalette();
}



//---------------------------------------------------------------------------------
//タグ
//---------------------------------------------------------------------------------


// 絵文字挿入
function insert_emoji(code)
{
	switch(emoji_type){
		case EMOJI_HTML:
			insertText(Tag.buildEmojiImageTag(code));
			break;
		case EMOJI_REF_JP:
			insertText('{' + getEmojiNameFromCode(code) + '}');
			break;
	}
}

function insert_tag_color(color)
{
	switch (gTagType) {
		case Tag.TYPE_CSS:
			_setSpanTag('color: ' + color + ';');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<font color="' + color + '">', '</font>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<色:' + color + '>', '</色>');
			break;
	}
}

function _setSpanTag(style)
{
	gSelectedTextObj.insertTextOnBothSides('<span style="' + style + '">','</span>');
}

function _setDivTag(style)
{
	gSelectedTextObj.insertTextOnBothSides('<div style="' + style + '">','</div>');
}



function insert_tag_align_left()
{
	switch (gTagType) {
		case Tag.TYPE_CSS:
			_setDivTag('text-align: left;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<div align="left">', '</div>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<左>', '</左>');
			break;
	}
}
function insert_tag_align_center()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setDivTag('text-align: center;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<center>', '</center>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<中>', '</中>');
			break;
	}
}
function insert_tag_align_right()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setDivTag('text-align: right;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<div align="right">', '</div>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<右>', '</右>');
			break;
	}
}
function insert_tag_style_italic()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('font-style: italic;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<i>', '</i>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<斜>', '</斜>');
			break;
	}
}
function insert_tag_strong()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			gSelectedTextObj.insertTextOnBothSides('<strong>', '</strong>');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<strong>', '</strong>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<太>', '</太>');
			break;
	}
}
function insert_tag_size_large()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('font-size: large;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<big>', '</big>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<大>', '</大>');
			break;
	}
}
function insert_tag_size_xlarge()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('font-size: x-large;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<big><big>', '</big></big>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<特大>', '</特大>');
			break;
	}
}
function insert_tag_size_small()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('font-size: small;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<small>', '</small>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<小>', '</小>');
			break;
	}
}
function insert_tag_decoration_underline()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('text-decoration: underline;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<u>', '</u>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<下線>', '</下線>');
			break;
	}
}
function insert_tag_decoration_line_through()
{
	switch(gTagType){
		case Tag.TYPE_CSS:
			_setSpanTag('text-decoration: line-through;');
			break;
		case Tag.TYPE_DEPRECATED_HTML:
			gSelectedTextObj.insertTextOnBothSides('<s>', '</s>');
			break;
		case Tag.TYPE_JP:
			gSelectedTextObj.insertTextOnBothSides('<打消線>', '</打消線>');
			break;
	}
}
function insert_tag_link()
{
	var url = window.prompt('リンク先URLを入力してください', 'http://');

	if (url != null) {

		switch(gTagType){
			case Tag.TYPE_CSS:
				gSelectedTextObj.insertTextOnBothSides('<a href=&quot;' + url + '&quot; target=&quot;_blank&quot;>','</a>');
				break;
			case Tag.TYPE_JP:
				gSelectedTextObj.insertTextOnBothSides('<リンク:' + url + '>','</リンク>');
				break;
		}
	}
}

//---------------------------------------------------------------------------------
// KeyBinding
//---------------------------------------------------------------------------------
/**
 *  「本文」・「追記」のtextareaのキー入力操作
 * 
 * @param theEvent key event
 */
function controlKeystroke(theEvent)
{
	var VK_RIGHT = 39;
	var VK_LEFT  = 37;
	var VK_BS    = 8;
	var VK_DEL   = 46;
	
	keyCode = XBSEvent.getKeyCode(theEvent);
	isIe = (theEvent.which == null);

	switch (keyCode) {
	case VK_RIGHT:
		if (gSelectedTextObj.moveCaretOutOfTag(true, theEvent.shiftKey) && isIe) 
			theEvent.returnValue = false;
		
		break;
	case VK_LEFT:
		if (gSelectedTextObj.moveCaretOutOfTag(false, theEvent.shiftKey) && isIe) 
			theEvent.returnValue = false;
		break;
	case VK_BS:
		gSelectedTextObj.deleteTagOnCaret(false);
		break;
	case VK_DEL:
		gSelectedTextObj.deleteTagOnCaret(true);
		break;
		
	default:
		break;
	}
	return false;
}

//======================================================================================
// comment_edit.js
//======================================================================================
/*
 * コメント編集
 *
 * Copyright (c) 2003 DRECOM CO.,LTD. All rights reserved.
 * 
 * info@drecom.co.jp
 * http://www.drecom.co.jp/
 */



var COMMENT_FORM_NAME               = 'WriteCommentForm';
var COMMENT_TEXTAREA_NAME           = 'comment';
var COMMENT_COOKIE_CHECKBOX_NAME    = 'EatCookie';
var COMMENT_PREVIEW_ID              = 'comment_preview';
var COMMENT_TOOLBAR_POSMARK_ID      = 'comment_toolbar_position_marker';

var COMMENT_AUTHOR_NAME             = 'author';
var COMMENT_EMAIL_NAME              = 'email';
var COMMENT_URL_NAME                = 'url';
var gCommentSaveCookieNames = [COMMENT_AUTHOR_NAME, COMMENT_EMAIL_NAME, COMMENT_URL_NAME];

var gCommentForm               = null;
var gCommentTextArea           = null;
var gCommentSaveCookieCheckbox = null;

// *** Cookie ***//
var COMMENT_COOKIE_NAME         = 'blog.comment.preferences';
var COMMENT_COOKIE_EXPIRE_DAYS  = 30; 

var gCommentCookie = new Cookie(document, COMMENT_COOKIE_NAME, COMMENT_COOKIE_EXPIRE_DAYS * 24);

loadCommentCookie.loaded = false;
function loadCommentCookie()
{
	var loaded = false;
	
	if (null == gCommentForm || null == gCommentSaveCookieCheckbox) {
		return;
	}
	
	loaded = gCommentCookie.load();
	
	// load の結果を反映
	loadCommentCookie.loaded = loaded;
	if (gCommentSaveCookieCheckbox != null) {
		gCommentSaveCookieCheckbox.checked = loaded;
		if (false == loadCommentCookie.loaded) {
			return;
		}
	}
	
	for (var i = 0; i < gCommentSaveCookieNames.length; i++) {
		var nm = gCommentSaveCookieNames[i];
		var t  = null;
		var v  = null;
		
		if (null == nm) continue;
		t = gCommentForm[nm];
		v = gCommentCookie[nm];
		if (null == v || null == t) continue;
		
		t.value = v;
	}
}
function storeCommentCookie()
{
	for (var i = 0; i < gCommentSaveCookieNames.length; i++) {
		var nm = gCommentSaveCookieNames[i];
		var t  = null;
		
		if (null == nm) continue;
		t = gCommentForm[nm];
		if (null == t || null == t.value) continue;
		
		gCommentCookie[nm] = t.value;
	}
	gCommentCookie.store();
	loadCommentCookie.loaded = true;
}
function removeCommentCookie()
{
	if (loadCommentCookie.loaded) {
		gCommentCookie.remove();
	}
}

/**
 * checkbox - onclick
 */
function handleEatCookieCheckBoxOnClick(aCheckBox)
{
	var checked = (true == aCheckBox.checked);
	if (checked) {
		storeCommentCookie();
	} else {
		removeCommentCookie();
	}	
}
/** form.onsubmit */
function comment_form_onsubmit()
{
	var lyer = XBSLayer.makeLayer(gColorPaletteID);
	
	// 2004-05-19  Takanori Ishikawa 
	// -----------------------------------------------------------
	// カラーパレットの　RGB 手入力の完了
	// HTML の構成上、Form にすることができなかったので
	// 苦肉の策
	if (lyer != null && lyer.isVisible()) {
		colorPaletteFieldValueDidAction();
		return false;
	}
	if (comment_form_onsubmit.tooLate) {
		return false;
	}
	comment_form_onsubmit.tooLate = true;
	
	var checked;
	checked = (gCommentSaveCookieCheckbox != null && true == gCommentSaveCookieCheckbox.checked);	
	if (checked) {
		storeCommentCookie();
	} else {
		removeCommentCookie();
	}
	return true;
}
function comment_setUp_textArea(textArea)
{
	// 2004-05-19  Takanori Ishikawa 
	// -----------------------------------------------------------
	// テンプレート編集でユーザに JavaScript を見せたくないので、ここで設定

	textArea.onfocus     = function(e){ };
	textArea.onmouseup   = function(e){ initializeSelectedText(this); cutOutTagFragmentOnSelectionArea(); renderPreview(this, COMMENT_PREVIEW_ID);}; 
	textArea.onchange    = function(e){ renderPreview(this, COMMENT_PREVIEW_ID); };
	textArea.onkeydown   = function(e){ initializeSelectedText(this); controlKeystroke(event); };
	textArea.onkeyup     = function(e){ initializeSelectedText(this); finalizeSelectedText(); renderPreviewOnKeyEvent(event, this, COMMENT_PREVIEW_ID); };
}

/** body.onload */
function comment_body_onload()
{
	/*
	 * HTML を有効にする
	 * @see render.js
	 */
	Renderer.enableHTML = false;
	Renderer.isComment = true;
	
	gCommentForm = document[COMMENT_FORM_NAME];
	if (gCommentForm != null) {
		gCommentTextArea = gCommentForm[COMMENT_TEXTAREA_NAME];

		// null の可能性もあり
		gCommentSaveCookieCheckbox = gCommentForm[COMMENT_COOKIE_CHECKBOX_NAME];
		if (typeof gCommentTextArea != 'undefined') {
			comment_setUp_textArea(gCommentTextArea);
			renderPreviewAll(gCommentForm);
		}
	
		// UtilKit.addhock だと false を返してキャンセルできない
		gCommentForm.onsubmit = comment_form_onsubmit;
		loadCommentCookie();
	}
	
	// window.onload が実行されたあとで、'creating' (生成中フラグ)が
	// false になるように。
	// - now_creating_entry.html
	// - entry_write_edit.jsp
	window.creating=false;
}

/* shortcut for render.js*/
function comment_render()
{
	if (gCommentTextArea != null) {
		renderPreview(gCommentTextArea, COMMENT_PREVIEW_ID);
	}
}


/* onmousedownにすると、onClickが無効になるので、up */
UtilKit.addhook(document, 'onmouseup', hideAllPalette);

// window.onload が実行されたあとで、'creating' (生成中フラグ)が
// false になるように。
// - now_creating_entry.html
// - entry_write_edit.jsp
window.creating=true;
UtilKit.addhook(window, 'onload', comment_body_onload);

//======================================================================================
// site_common.js
//======================================================================================
/**
 * ブラウザ画面領域の幅を取得
 */
function getWidth(win)
{
	var tmp_width;
    
	if (win.document.documentElement) { 
		tmp_width = win.document.documentElement.clientWidth;
		if (tmp_width > 0) {
			return(tmp_width);
		}
	}
    if (win.document.all) {
		return(win.document.body.clientWidth);
	}
	return(win.innerWidth);
}
       
/**
 * ブラウザ画面領域の高さを取得
 */
function getHeight(win)
{
	var tmp_height;
    
	if (win.document.documentElement) {
		tmp_height = win.document.documentElement.clientHeight;
		if (tmp_height > 0) {
			return(tmp_height);
		}
	}
    if (win.document.all) {
		return(win.document.body.clientHeight);
	}
	return(win.innerHeight);
}

/**
 * Windowを中心に移動
 */
function moveWindowToCenter(win) {
	x = (screen.width  - getWidth(win)) / 2;
	y = (screen.height - getHeight(win)) / 2 - 50;
	win.moveTo(x,y);
}
var clicked = false;
function openPermLink(url, isPopup) {
	if (clicked) { return false; }
	
	if (isPopup) {
		nw_width = 620;
		nw_height = 550;
		nw_left = (screen.width  - nw_width) / 2;
		nw_top = (screen.height - nw_height) / 2 - 50;
		openWindow(url, 'subwin', nw_height, nw_width, 'yes', 'yes', 'no', nw_left, nw_top);
	} else {
		location.href = url;
	}
	clicked = true;
	setTimeout('setFalseClicked()', 1000);
	return false;
}

function setFalseClicked() {
	clicked = false;
}

function setWindowSize(width, height)
{
	WINDOW_WIDTH = width;
	WINDOW_HEIGHT = height;
}

function adjustWindow()
{
	if (null == WINDOW_WIDTH || null == WINDOW_HEIGHT) {
		return;
	}
	
	// window.opener.location.hostにアクセスするとエラーが起こる場合があるので･･･
	var ok = false;
	try {
		var test = window.opener.location.host;
		ok = true;
	} catch (e) {}
	
	if (ok && window.opener && window.opener.location.host == window.location.host) {
		resizeTo(WINDOW_WIDTH, WINDOW_HEIGHT);
		moveWindowToCenter(window);
		focus();
	}
}

/**
 * ウィンドウを開く
 */
function openPopup(url, width, height)
{
	if (null == width) {
		width = 550;
	}
	if (null == height) {
		height = 600;
	}
	subWindow = window.open(url, "_popup", "width=" + width + ",height=" + height + ",scrollbars=yes,resizable=yes,toolbar=no,status=no");
	return void(0);
}

function styleChangeOnMouseOver(id, className) {
	var obj, obj_top, obj_middle, obj_bottom, obj_left, obj_right, obj_text;
	if (document.all) {
		obj = document.all(id);
		obj_top = document.all(id + "_top");
		obj_middle = document.all(id + "_middle");
		obj_bottom = document.all(id + "_bottom");
		obj_left = document.all(id + "_left");
		obj_right = document.all(id + "_right");
		obj_text = document.all(id + "_text");
	} else if(document.getElementById) {
		obj = document.getElementById(id);
		obj_top = document.getElementById(id + "_top");
		obj_middle = document.getElementById(id + "_middle");
		obj_bottom = document.getElementById(id + "_bottom");
		obj_left = document.getElementById(id + "_left");
		obj_right = document.getElementById(id + "_right");
		obj_text = document.getElementById(id + "_text");
	}
	if (obj) {
		obj.className = className + "_hover";
	}		
	if (obj_top) {
		obj_top.className = className + "_hover_top";
	}		
	if (obj_middle) {
		obj_middle.className = className + "_hover_middle";
	}		
	if (obj_bottom) {
		obj_bottom.className = className + "_hover_bottom";
	}		
	if (obj_left) {
		obj_left.className = className + "_hover_left";
	}		
	if (obj_right) {
		obj_right.className = className + "_hover_right";
	}		
	if (obj_text) {
		obj_text.className = className + "_hover_text";
	}		
}

function styleChangeOnMouseOut(id, className, isSelected) {
	var obj, obj_top, obj_middle, obj_bottom, obj_left, obj_right, obj_text;
	if (document.all) {
		obj = document.all(id);
		obj_top = document.all(id + "_top");
		obj_middle = document.all(id + "_middle");
		obj_bottom = document.all(id + "_bottom");
		obj_left = document.all(id + "_left");
		obj_right = document.all(id + "_right");
		obj_text = document.all(id + "_text");
	} else if(document.getElementById) {
		obj = document.getElementById(id);
		obj_top = document.getElementById(id + "_top");
		obj_middle = document.getElementById(id + "_middle");
		obj_bottom = document.getElementById(id + "_bottom");
		obj_left = document.getElementById(id + "_left");
		obj_right = document.getElementById(id + "_right");
		obj_text = document.getElementById(id + "_text");
	}
	var onText = isSelected ? "_on" : "";
	if (obj) {
		obj.className = className + onText;
	}		
	if (obj_top) {
		obj_top.className = className + onText + "_top";
	}		
	if (obj_middle) {
		obj_middle.className = className + onText + "_middle";
	}		
	if (obj_bottom) {
		obj_bottom.className = className + onText + "_bottom";
	}		
	if (obj_left) {
		obj_left.className = className + onText + "_left";
	}		
	if (obj_right) {
		obj_right.className = className + onText + "_right";
	}		
	if (obj_text) {
		obj_text.className = className + onText + "_text";
	}		
}

function sidemenuOnMouseOver(id) {
	if (document.all) {
		if (document.all(id + "_table")) document.all(id + "_table").className = "sidemenu_table_hover";
		if (document.all(id + "_top")) document.all(id + "_top").className = "sidemenu_hover_top";
		if (document.all(id + "_mdl")) document.all(id + "_mdl").className = "sidemenu_hover_mdl";
		if (document.all(id + "_btm")) document.all(id + "_btm").className = "sidemenu_hover_btm";
	} else if(document.getElementById) {
		if (document.getElementById(id + "_table")) document.getElementById(id + "_table").className = "sidemenu_table_hover";
		if (document.getElementById(id + "_top")) document.getElementById(id + "_top").className = "sidemenu_hover_top";
		if (document.getElementById(id + "_mdl")) document.getElementById(id + "_mdl").className = "sidemenu_hover_mdl";
		if (document.getElementById(id + "_btm")) document.getElementById(id + "_btm").className = "sidemenu_hover_btm";
	}
}

function sidemenuOnMouseOut(id, isSelected) {
	if (isSelected) {
		if (document.all) {
			if (document.all(id + "_table")) document.all(id + "_table").className = "sidemenu_table_on";
			if (document.all(id + "_top")) document.all(id + "_top").className = "sidemenu_on_top";
			if (document.all(id + "_mdl")) document.all(id + "_mdl").className = "sidemenu_on_mdl";
			if (document.all(id + "_btm")) document.all(id + "_btm").className = "sidemenu_on_btm";
		} else if(document.getElementById) {
			if (document.getElementById(id + "_table")) document.getElementById(id + "_table").className = "sidemenu_table_on";
			if (document.getElementById(id + "_top")) document.getElementById(id + "_top").className = "sidemenu_on_top";
			if (document.getElementById(id + "_mdl")) document.getElementById(id + "_mdl").className = "sidemenu_on_mdl";
			if (document.getElementById(id + "_btm")) document.getElementById(id + "_btm").className = "sidemenu_on_btm";
		}

	} else {
		if (document.all) {
			if (document.all(id + "_table")) document.all(id + "_table").className = "sidemenu_table";
			if (document.all(id + "_top")) document.all(id + "_top").className = "sidemenu_top";
			if (document.all(id + "_mdl")) document.all(id + "_mdl").className = "sidemenu_mdl";
			if (document.all(id + "_btm")) document.all(id + "_btm").className = "sidemenu_btm";
		} else if(document.getElementById) {
			if (document.getElementById(id + "_table")) document.getElementById(id + "_table").className = "sidemenu_table";
			if (document.getElementById(id + "_top")) document.getElementById(id + "_top").className = "sidemenu_top";
			if (document.getElementById(id + "_mdl")) document.getElementById(id + "_mdl").className = "sidemenu_mdl";
			if (document.getElementById(id + "_btm")) document.getElementById(id + "_btm").className = "sidemenu_btm";
		}
	}
}

/**
 * adjustWindow()で使用する、Windowのサイズを変更する定数
 * どちらかがnullの場合は変更しない。
 */
WINDOW_WIDTH = null;
WINDOW_HEIGHT = null;

/**
 * WINDOW_WIDTH,WINDOW_HEIGHTが指定されている場合、
 * onloadでサイズを変更する。
 */
UtilKit.addhook(window, 'onload', adjustWindow);
