﻿//=========================
//JScript Only
var CControl = new CControl();
function CControl()
{
	this.RemoveAllOptions = RemoveAllOptions;
	this.GetParentForm = GetParentForm;
	this.FilterKeyCode = FilterKeyCode;
	this.GetCheckedValue = GetCheckedValue;
	this.SetReadOnly = SetReadOnly;
	this.GetFirstElementHasTagNameType = GetFirstElementHasTagNameType;
	this.GetChildHasTag = GetChildHasTag;
	this.GetParentTable = GetParentTable;
	this.GetParentRow = GetParentRow;
	this.GetParentCol = GetParentCol;
	this.GetFirstChildTable = GetFirstChildTable;
	this.SetTableRowLength = SetTableRowLength;
	this.ScrollBottom = ScrollBottom;
	this.CopyText = CopyText;
	this.ToggleChecked = ToggleChecked;
	this.ResizeImage = ResizeImage;
	this.IfNotArrayControlConvertToArray = IfNotArrayControlConvertToArray;
	this.GetControlToMove = GetControlToMove;
	this.CanFocusable = CanFocusable;
	
	return this;
}


	function RemoveAllOptions(Sel)
	{
		//한번에 제거하는 메쏘드는 없음.
		while (Sel.options.length > 0)
		{
			Sel.options.remove(0);
		}
	}
	
	/*
	--설명
	특정 컨트롤이 속한 폼을 찾아 리턴함.
	runat="server"인 form의 경우 client에서 이름을 알 수 없으므로
	현재 컨트롤을 가진 폼을 찾기 위함.
	*/
	function GetParentForm(Elem)
	{
		while (true)
		{
			Elem = Elem.parentElement;
			if (Elem.tagName == "FORM")
			{
				return Elem;
			}
			else if (Elem == null)
			{
				return null;
			}
			else if (Elem.tagName == "BODY")
			{
				return null;
			}
		}
	}

	/*
	--예제
	//다음은 숫자 입력만 허용함.
	public static function t_keypress()
	{
		event.keyCode = FilterKeyCode(event.keyCode, "0123456789");
	}
	*/
	function FilterKeyCode(KeyCode, KeyList)
	{
		switch (KeyCode)
		{
			case 13: //cr
			case 10: //lf
			case 9: //tab
			case 56: //back
				return KeyCode;
		}
	    
		var sKey = String.fromCharCode(KeyCode);
		if (KeyList.indexOf(sKey) != -1)
		{
			return KeyCode;
		}
	
		return 0;
	}
	
	/*
	--설명
	radio, checkbox 컨트롤의 배열 중 선택된 value 값을 콤마로 구분해서 리턴함.
	*/
	function GetCheckedValue(aRad)
	{
		var ValueList = "";
		for (var i = 0, i2 = aRad.length; i < i2; i++)
		{
			if (aRad[i].checked)
			{
				ValueList += "," + aRad[i].value;
			}
		}
		if (ValueList != "")
		{
			ValueList = ValueList.substring(1);
		}
		
		return ValueList;
	}
	
	/*
	--설명
	컨트롤을 읽기 전용으로 설정하거나 해제함.
	readOnly 속성이 없는 select의 경우는 disabled 속성을 이용하면 되나
	submit할 때 값을 읽을 수 없으므로 그냥 놔둠.
	*/
	function SetReadOnly(Ctl, IsReadOnly, IsChangeBackColor)
	{
		var BackColor = IsReadOnly ? "#dddddd" : "white";
		
		Ctl = IfNotArrayControlConvertToArray(Ctl);
		
		for (var i = 0, i2 = Ctl.length; i < i2; i++)
		{
			switch (Ctl[i].type)
			{
				case "text":
					Ctl[i].readOnly = IsReadOnly;
					
					if (IsChangeBackColor)
					{
						Ctl[i].style.backgroundColor = BackColor;
					}
					break;
				case "textarea":
					Ctl[i].readOnly = IsReadOnly;
					
					if (IsChangeBackColor)
					{
						Ctl[i].style.backgroundColor = BackColor;
					}
					break;
				case "button":
				case "checkbox":
				case "select-one":
					//Ctl[i].disabled = IsReadOnly;
					//disabled 설정하면 회색이 자동으로 됨.
			}
		}
	}

	/*
	--설명
	모든 컨트롤 중 특정 tagName, type을 가진 첫번째 컨트롤을 리턴함.
	--예제
	var Elem = GetFirstElementHasTagNameType("input", "file");
	if (Elem != null)
	{
		alert(Elem.tagName + "," + Elem.type);
	}
	*/
	function GetFirstElementHasTagNameType(TagName, Type)
	{
		for (var i = 0, i2 = document.all.length; i < i2; i++)
		{
			if (document.all[i].tagName.toLowerCase() != TagName.toLowerCase()) continue;
			if (document.all[i].type.toLowerCase() != Type.toLowerCase()) continue;
			
			return document.all[i];
		}
		
		return null;
	}

	/*
	--설명
	NodeParent 안에 지정된 태그이름을 가진 노드를 리턴함.
	*/
	function GetChildHasTag(NodeParent, TagName)
	{
		for (var i = 0, i2 = NodeParent.childNodes.length; i < i2; i++)
		{
			NodeCur = NodeParent.childNodes[i];
			if (NodeCur.tagName)
			{
				if (NodeCur.tagName.toLowerCase() == TagName.toLowerCase())
				{
					return NodeCur;
				}
			}
		}
		
		return null;
	}
	
	/*
	--설명
	Elem을 가지고 있는 TABLE Element를 리턴함.
	*/
	function GetParentTable(Elem)
	{
		while (Elem.parentElement != null)
		{
			Elem = Elem.parentElement;
			if (Elem.tagName == "TABLE")
			{
				return Elem;
			}
		}
		
		return null;
	}
	/*
	--설명
	Elem을 가지고 있는 TR Element를 리턴함.
	*/
	function GetParentRow(Elem)
	{
		while (Elem.parentElement != null)
		{
			Elem = Elem.parentElement;
			if (Elem.tagName == "TR")
			{
				return Elem;
			}
		}
		
		return null;
	}
	/*
	--설명
	Elem을 가지고 있는 TD Element를 리턴함.
	*/
	function GetParentCol(Elem)
	{
		while (Elem.parentElement != null)
		{
			Elem = Elem.parentElement;
			if (Elem.tagName == "TD")
			{
				return Elem;
			}
		}
		
		return null;
	}
	
	/*
	--설명
	Elem을 가지고 있는 TR Element를 리턴함.
	*/
	function GetFirstChildTable(Elem)
	{
		var ElemCur = null;
		
		for (var i = 0, i2 = Elem.childNodes.length; i < i2; i++)
		{
			ElemCur = Elem.childNodes[i];
			
			if (ElemCur.tagName == "TABLE")
			{
				return ElemCur;
			}
		}
	}
	
	/*
	--설명
	제목행을 제외한 행의 개수를 설정함.
	*/
	function SetTableRowLength(tbl, Rows)
	{
		if ((tbl.rows.length - 1) > Rows)
		{
			while ((tbl.rows.length - 1) > Rows)
			{
				tbl.deleteRow(tbl.rows.length - 1);
			}
		}
		else
		{
			var Cols = tbl.rows[0].cells.length;
			for (var rw = 0, rw2 = Rows; rw < rw2; rw++)
			{
				Row = tbl.insertRow();
				for (var cl = 0, cl2 = Cols; cl < cl2; cl++)
				{
					Row.insertCell();
				}
			}
		}
	}
	
	function ScrollBottom(Div)
	{
		if (Div.scrollTop != null)
		{
			Div.scrollTop = Div.scrollHeight - Div.clientHeight;
		}
	}

	function CopyText(Text)
	{
		window.clipboardData.setData("Text", Text);
	}

	/*
	--예제
	<input type=checkbox id=chkAdmin>
	<span id=spnAdmin style="cursor: hand;" onclick="ToggleChecked(document.all('chkAdmin'))">관리자 여부</span>
	*/
	function ToggleChecked(Chk)
	{
		if (Chk.type != "checkbox") return;
		if (Chk.disabled) return;
		
		//Chk.checked != Chk.checked; 코드는 작동 안함.
		if (Chk.checked)
		{
			Chk.checked = false;
		}
		else
		{
			Chk.checked = true;
		}
	}

	/*
	--설명
	img 태그의 이미지 크기가 한계를 넘었다면 한계를 넘지 않도록 조절함.
	*/
	function ResizeImage(Img, WidthLimit, HeightLimit)
	{
		w = Img.width;
		h = Img.height;
	
		if ((w <= WidthLimit) && (h <= HeightLimit))
		{
			return;
		}
		
		if (w > WidthLimit)
		{
			hrate = h / w;
			w = WidthLimit;
			h = w * hrate;
		}
		if (h > HeightLimit)
		{
			wrate = w / h;
			h = HeightLimit;
			w = h * wrate;
		}
		
		Img.width = w;
		Img.height = h;
	}

	function IfNotArrayControlConvertToArray(Ctl)
	{
		if (Ctl[0] == null)
		{
			return new Array(Ctl);
		}
		else if (Ctl[0].tagName == "OPTION")
		{
			//option은 select의 배열처럼 취급되므로
			return new Array(Ctl);
		}
		else
		{
			return Ctl;
		}
	}
	
	function GetControlToMove(Ctl, IsNext)
	{
		for (var i = 0, i2 = document.all.length; i < i2; i++)
		{
			if (Ctl == document.all[i])
			{
				if (IsNext)
				{
					for (var j = (i + 1), j2 = document.all.length; j < j2; j++)
					{
						if (CanFocusable(document.all[j]))
						{
							return document.all[j];
						}
					}
				}
				else
				{
					for (var j = (i - 1), j2 = 0; j >= j2; j--)
					{
						if (CanFocusable(document.all[j]))
						{
							return document.all[j];
						}
					}
				}
			}
		}
	}
	
	function CanFocusable(Ctl)
	{
		if (Ctl.disabled)
		{
			return false;
		}
		
		if ((Ctl.tagName == "INPUT") || (Ctl.tagName == "TEXTAREA"))
		{
			return true;
		}
		
		return false;
	}
	
	
//=========================	
var CEvent = new CEvent();
function CEvent()
{
	this.ApplyInstructionToText = ApplyInstructionToText;
	this.ApplyEmailProviderSelection = ApplyEmailProviderSelection;
	this.ApplyWhenMaxMoveToNext = ApplyWhenMaxMoveToNext;
	this.ApplyFilterNumeric = ApplyFilterNumeric;
	
	return this;	
}

	/*
	--설명
	기본적으로 지시사항이 표시되고, focus를 받으면 지시사항이 사라지게 하는 기능 구현.
	*/
	function ApplyInstructionToText(Txt, Instruction)
	{
		if (Txt.value == "")
		{
			Txt.value = Instruction;
		};
		
		Txt.onfocus = 
		function()
		{
			var Value = this.value;
			if (Value == Instruction)
			{
				Value = "";
			}
			this.value = Value;
		};

		Txt.onblur =
		function()
		{
			var Value = this.value;
			if (Value == "")
			{
				Value = Instruction;
			}
			this.value = Value;
		};	
	}
	
	/*
	--설명
	이메일 제공회사를 선택하면 @ 다음 란을 입력할 수 없고,
	직접입력을 선택하면 @ 다음 란을 입력할 수 있는 기능 구현
	*/
	function ApplyEmailProviderSelection(txtEmail1, txtEmail2, selEmailProvider)
	{
		//var txtEmail1Name = txtEmail1.name;
		//var txtEmail2Name = txtEmail2.name;

		selEmailProvider.onchange =
		function()
		{
			var Value = selEmailProvider.value;
			if (Value == "custom")
			{
				txtEmail2.value = "";
				txtEmail2.readOnly = false;
			}
			else
			{
				txtEmail2.value = Value;
				txtEmail2.readOnly = true;;
			}

			txtEmail1.focus();
		};
	}
	
	/*
	--설명
	length 속성만큼 문자열이 찼을 때 다음 컨트롤로 focus를 이동시킬 Text 컨트롤 배열
	*/
	function ApplyWhenMaxMoveToNext(aText)
	{
		var ProcName = "ApplyWhenMaxMoveToNext";
		
		for (var i = 0, i2 = aText.length; i < i2; i++)
		{
			var TextCur = aText[i];
			if (TextCur.tagName != "INPUT")
			{
				alert(ProcName + " aText의 tagName이 INPUT이 아닙니다.");
				return;
			}
			
			if (TextCur.type.toLowerCase() != "text")
			{
				alert(ProcName + " aText의 type이 text가 아닙니다.");
				return
			}
			
			aText[i].onkeyup =
			function()
			{
				//Shift+Tab, Tab 키로 이동할 수 있으므로 Shift(16), Tab(9) 키가 눌러져 있다면 빠져나감.
				if (event.keyCode == 16) return;
				if (event.keyCode == 9) return;
				
				//클릭했을 때도 keyCode가 229가 되므로 빠져나감.
				if (event.keyCode == 229) return;

				var Txt = event.srcElement;
				if (Txt.value.length >= Txt.maxLength)
				{
					var TxtNext = CControl.GetControlToMove(Txt, true);
					if (TxtNext)
					{
						TxtNext.focus();

						//다음 컨트롤에 값이 있다면 전체선택을 할 수 있게 함.
						if (
							((TxtNext.tagName == "INPUT") && (TxtNext.type.toLowerCase() == "text"))
							|| ((TxtNext.tagName == "INPUT") && (TxtNext.type.toLowerCase() == "password"))
							)
						{
							TxtNext.select();
						}
					}
				}
			}
		}
	}
	
	/*
	--설명
	숫자만 입력을 허용함
	*/
	function ApplyFilterNumeric(aText)
	{
		var ProcName = "ApplyFilterNumeric";
		
		for (var i = 0, i2 = aText.length; i < i2; i++)
		{
			var TextCur = aText[i];
			if (TextCur.tagName != "INPUT")
			{
				alert(ProcName + " aText의 tagName이 INPUT이 아닙니다.");
				return;
			}
			
			if (TextCur.type.toLowerCase() != "text")
			{
				alert(ProcName + " aText의 type이 text가 아닙니다.");
				return
			}
			
			aText[i].onkeypress =
			function()
			{
				var IsNumeric = ((event.keyCode >= 48) && (event.keyCode <= 57));
				if (!IsNumeric)
				{
					event.keyCode = 0;
				}
			}
		}	
	}
	
//=========================	
var CFindRep = new CFindRep();
function CFindRep()
{
	this.ReplaceSpecialChar = ReplaceSpecialChar;
	this.TrimStart = TrimStart;
	this.TrimEnd = TrimEnd;
	this.Trim = Trim;
	this.Right = Right;
	this.Left = Left;
	this.StartsWith = StartsWith;
	this.EndsWith = EndsWith;
	this.ReplaceAll = ReplaceAll;
	this.GetUniqueId = GetUniqueId;
	this.RemoveInvisible = RemoveInvisible;
	this.RemoveExcept = RemoveExcept;
	this.Repeat = Repeat;
	this.Format = Format;
	this.Escape = Escape;
	this.Unescape = Unescape;
	this.HasValueNotInList = HasValueNotInList;
	this.PadLeft = PadLeft;
	this.PadRight = PadRight;
	
	return this;
}

	/*
	--설명
	클라이언트의 자바스크립트 문자열이 서버로 전송될 때 원래의 문자열 그대로
	도착할 수 있도록 특수문자열은 %로 시작하는 문자열로 인코딩함.
	--예제
	ReplaceSpecialChar("#x@") --> "%23x%40"
	*/
	function ReplaceSpecialChar(value)
	{
		var value2 = "";
		var c = "";
	
		for (var i = 0; i < value.length; i++)
		{
			c = value.substr(i, 1);
			if (c == "!") c = "%21";
			else if (c == "#") c = "%23";
			else if (c == '"') c = "%22";
			else if (c == "$") c = "%24";
			else if (c == "%") c = "%25";
			else if (c == "&") c = "%26";
			else if (c == "(") c = "%28";
			else if (c == ")") c = "%29";
			else if (c == "@") c = "%40";
			else if (c == "+") c = "%2b";
			else if (c == ",") c = "%2c";
			else if (c == "-") c = "%2d";
			else if (c == ".") c = "%2e";
			else if (c == "/") c = "%2f";
			else if (c == ":") c = "%3a";
			else if (c == "<") c = "%3c";
			else if (c == "=") c = "%3d";
			else if (c == ">") c = "%3e";
			else if (c == "?") c = "%3f";
			else if (c == "[") c = "%5b";
			else if (c == "]") c = "%5d";
			else if (c.charCodeAt(0) == 13) c = "%0d";
			else if (c.charCodeAt(0) == 10) c = "%0a";
			else if ((c.charCodeAt(0) >= 0) && (c.charCodeAt(0) <= 5)) c = "%0" + c.charCodeAt(0);
	
			value2 += c;
		}
		
		return value2;
	}
	
	/*
	--설명
	문자열 앞의 스페이스 제거
	*/
	function TrimStart(text)
	{
		var c = "";
		var newText = "";
		
		for(var i = 0; i < text.length; i++)
		{
			c = text.charAt(i);
			if(c != " ")
			{
				newText = text.substr(i, text.length - i);
				break;
			}
		}
		
		return newText;
	}
	/*
	--설명
	문자열 뒤의 스페이스 제거
	*/
	function TrimEnd(text)
	{
		var c = "";
		var newText = "";
	
		for(var i = (text.length - 1); i >= 0; i--)
		{
			c = text.charAt(i);
			if(c != " " )
			{
				newText = text.substr(0, i + 1);
				break;
			}
		}
		
		return newText;
	}
	/*
	--설명
	문자열 앞뒤의 스페이스 제거
	*/
	function Trim(text)
	{
		var c = "";
		var newText = "";
	
		newText = TrimEnd(TrimStart(text));
	
		return newText;
	}
	/*
	설명
	오른쪽에서 num개만큼의 문자열을 리턴함.
	VB의 Right 함수와 같음.
	*/
	function Right(Value, Length)
	{
		return Value.substr(Value.length - Length);
	}
	function Left(Value, Length)
	{
		return Value.substr(0, Length);
	}
	
	function StartsWith(Value, Find)
	{
		return (Value.substr(0, Find.length) == Find);
	}
	function EndsWith(Value, Find)
	{
		return (Value.substr((Value.length - Find.length), Find.length) == Find);
	}
	/*
	--설명
	JScript의 replace는 첫번째 문자열만 변경하므로 만듦.
	--다음의 코드는 Find가 특수문자를 포함할 때 잘못 작동하므로 보류
	eval("var x = Value.replace(/" + Find + "/gi, Replace);");
	return x;
	*/
	function ReplaceAll(Value, Find, Replace)
	{
		//Value가 숫자인 경우, indexOf가 null을 리턴하므로 무한루핑을 하게 됨.
		Value = Value + "";
		
		var aNewValue = new Array();
		var nStart = 999;
		while (nStart != -1)
		{
			nStart = Value.indexOf(Find);
			if (nStart != -1)
			{
				aNewValue[aNewValue.length] = Value.substr(0, nStart) + Replace;
				Value = Value.substr(nStart + Find.length);
			}
			else
			{
				aNewValue[aNewValue.length] = Value;
				break;
			}
		}
		
		return aNewValue.join("");
	}
	
	/*
	--설명
	유일한 문자열을 가져오기 위해 현재 시간을 리턴함.
	*/
	function GetUniqueId()
	{
		var oDate = new Date();
		var ymd = CDateTime.GetYYYYMMDD(oDate);
		var hnsi = CDateTime.GetHHNNSSIII(oDate);
		return "uid" 
			+ ymd.yyyy + ymd.mm + ymd.dd
			+ hnsi.hh + hnsi.nn + hnsi.ss + hnsi.iii;
	}
	/*
	--설명
	아스키코드가 0부터 47인 경우는 눈에 보이지 않는 문자열임.
	(예: 스페이스, 줄바꿈, null, 탭 등...)
	이러한 문자열만으로 구성되었다면 실제로는 DB에 입력되지 않아야 하므로
	이러한 문자열을 삭제한 나머지 문자열의 길이가 있는 경우 DB에 입력될
	수 있다고 볼 수 있음.
	--예제
	alert(RemoveInvisible("안\n\n녕")); //안녕 -> 줄바꿈은 없어지므로 '안'과 '녕'이 붙음.
	alert(RemoveInvisible("\t\n")); //"" -> 탭과 줄바꿈은 없어지므로 빈 문자열을 리턴함.
	*/
	function RemoveInvisible(str)
	{
		var ascii = 0;
		var newStr = "";
		
		if(str == null) return "";
		
		for(var i = 0; i < str.length; i++)
		{
			ascii = str.charCodeAt(i);
			if(ascii < 0 || ascii > 47)
			{
				newStr = newStr + str.charAt(i);
			}
		}
		
		return newStr;
	}
	/*
	--설명
	except 문자열에 없는 문자는 Text에서 삭제한 후 리턴함.
	--예제
	RemoveExcept("1abc234", "0123456789")
	-> "1234"
	*/
	function RemoveExcept(text, except)
	{
		var newText = "";
		var c = "";
		
		
		for(var i = 0; i <= text.length - 1; i++)
		{
			c = text.charAt(i);
			if(except.indexOf(c) != -1)
			{
				newText += c;
			}
		}
	
		return newText;
	}	
	function Repeat(num, text)
	{
		var newText = "";
		
		for(var i = 0; i < num; i++)
		{
			newText += text;
		}
		
		return newText;
	}	
	/*
	--설명
	VB의 Format 함수와 같은 기능을 함.
	현재는 format 인수에 #,##0만 가능함.
	*/
	function Format(text, format)
	{
		var newText = "";
		var fromRightToLeft = 0;
		
		switch(format)
		{
			case "#,##0":
				if(isNaN(text))
				{
					return "";
				}
				
				text = text.toString();
				for (var i = text.length - 1; i >= 0; i--)
				{
					fromRightToLeft++;
					
					if((fromRightToLeft != 1) && (fromRightToLeft % 3 == 0))
					{
						newText = "," + text.charAt(i) + newText;
					}
					else
					{
						newText = text.charAt(i) + newText;
					}
				}
				break;
		}
		
		if (newText.charAt(0) == ",")
		{
			newText = newText.substring(1, newText.length);
		}
		
		return newText;
	}	
	
	/*
	--설명
	System.useCodepage이 true이면 escape 함수가 제대로 작동하지 않음.
	그러므로 useCodepage를 false로 만들어야 함.
	*/
	function Escape(Value)
	{
		var IsUse = System.useCodepage;
		if (IsUse) System.useCodepage = false;
		var Value2 = escape(Value);
		
		System.useCodepage = IsUse;
		
		return Value2;
	}
	
	function Unescape(Value)
	{
		var IsUse = System.useCodepage;
		if (IsUse) System.useCodepage = false;
		var Value2 = unescape(Value);
		
		System.useCodepage = IsUse;
		
		return Value2;
	}

	/*
	--설명
	List의 문자열 중에 없는 문자열이 Value에 있는 지 확인함.
	--예제
	HasValueNotInList("12a", "01234567890") //true
	HasValueNotInList("123", "01234567890") //false
	*/
	function HasValueNotInList(Value, List)
	{
		var IsFound = false;
		for (var i = 0, i2 = Value.length; i < i2; i++)
		{
			var c = Value.charAt(i);
			if (List.indexOf(c) == -1)
			{
				return true;
			}
		}
	}

	function PadLeft(Value, Length, Pad)
	{
		return Right(Repeat(Pad, Length) + Value, Length);
	}
	function PadRight(Value, Length, Pad)
	{
		return Left(Value + Repeat(Pad, Length), Length);
	}

//=========================
var CFile = new CFile();
function CFile()
{
	this.GetPathName = GetPathName;
	this.GetFileName = GetFileName;
	this.GetFileFromFileExt = GetFileFromFileExt;
	this.GetExtFromFileExt = GetExtFromFileExt;
	this.GetLastPath = GetLastPath;
	this.GetServerUrl = GetServerUrl;
	this.GetParameter = GetParameter;
	this.GetParamFromUrlParam = GetParamFromUrlParam;
	this.GetUrlFromUrlParam = GetUrlFromUrlParam;
	this.GetCookie = GetCookie;
	this.SetCookie = SetCookie;
	return this;
}

	/*
	--설명
	경로와 파일 이름 중에서 경로 이름만 리턴함.
	*/
	function GetPathName(PathFile, PathSep)
	{
		if (PathSep == null) PathSep = "/";
	
		//오른쪽에서 왼쪽으로 첫번째 / 기호를 찾음.
		//그 앞의 모든 문자열은 경로이므로 그것을 리턴함.
		var Pos = PathFile.lastIndexOf(PathSep);
		if (Pos == -1)
		{
			return PathFile;
		}
		else
		{
			return PathFile.substr(0, Pos);
		}
	}
	/*
	--설명
	경로와 파일 이름 중에서 파일 이름만 리턴함.
	*/
	function GetFileName(PathFile, PathSep)
	{
		if (PathSep == null) PathSep = "/";
		
		var Pos = PathFile.lastIndexOf(PathSep);
		if (Pos == -1)
		{
	        	return PathFile;
	        }
		else
		{
			return PathFile.substr(Pos + 1);
		}
	}
	/*
	--설명
	확장자가 포함된 파일 이름에서 파일 이름만을 리턴함.
	*/
	function GetFileFromFileExt(FileExt)
	{
		var PosDot = FileExt.lastIndexOf(".");
		if (PosDot == -1)
		{
			return FileExt;
		}
		else
		{
			return FileExt.substr(0, PosDot);
		}
	}
	/*
	--설명
	확장자가 포함된 파일 이름에서 확장자를 리턴함.
	*/
	function GetExtFromFileExt(FileExt)
	{
		var PosDot = FileExt.lastIndexOf(".");
		if (PosDot == -1)
		{
			return "";
		}
		else
		{
			return FileExt.substr(PosDot + 1);
		}
	}
	/*
	--설명
	C:\Temp\Sub 폴더가 있을 때 가장 마지막 폴더 이름인 'Sub'를 리턴함.
	--예제
	GetLastPath("C:\Temp\1234")
	--> 1234
	*/
	function GetLastPath(PathFile, PathSep)
	{
		if (PathSep == null) PathSep = "/";
	
		if (PathFile.substr(PathFile.length - 1, 1) == PathSep)
			PathFile = PathFile.substr(0, PathFile.length - 1);
		
		var PosStart = PathFile.lastIndexOf(PathSep) + 1;
		if (PosStart == 0)
		{
			return "";
		}
		
		return PathFile.substr(PosStart);
	}
	/*
	--설명
	Url에서 서버의 주소만을 가져오기 위함.
	--예제
	GetServerURL("http://www.microsoft.com/vbasic/ado/")
	-> http://www.microsoft.com
	*/
	function GetServerUrl(Url)
	{
	    //http://에 있는 //의 위치를 알아냄
	    var SlashPos = Url.indexOf("//");
		
	    var SlashPos = Url.indexOf("/", SlashPos + 2);
	    if (SlashPos != -1)
		{
	        return Url.substr(0, SlashPos);
		}
		else
		{
			return Url;
	    }
	}
	/*
	--설명
	'name=박&age=30'이란 문자열이 있을 때
	key 인수에 name을 넘기면 '박'이 리턴됨.
	*/
	function GetParameter(UrlParam, Key)
	{
		if (UrlParam == "") return "";
		
		var Param = GetParamFromUrlParam(UrlParam);
		
		var aParam = Param.split("&");
		for (var i = 0, i2 = aParam.length; i < i2; i++)
		{
			var aKeyValue = aParam[i].split("=");
			if (aKeyValue[0] == Key)
			{
				if (aKeyValue.length == 2)
				{
					return aKeyValue[1];
				}
			}
		}
		
		return "";
	}
	function GetParamFromUrlParam(UrlParam)
	{
		var Pos = UrlParam.indexOf("?");
		if (Pos == -1) return "";
		
		return UrlParam.substr(Pos + 1);
	}
	function GetUrlFromUrlParam(UrlParam)
	{
		var Pos = UrlParam.indexOf("?");
		if (Pos == -1) return UrlParam;
		
		return UrlParam.substr(0, Pos);
	}

	/*
	--설명
	쿠키의 값을 읽어옴.
	예를 들어 'name=박;age=30'이란 문자열이 있을 때
	key 인수에 name을 넘기면 '박'이 리턴됨.
	*/
	function GetCookie(Key)
	{
		var dc = document.cookie;
		
		var prefix = Key + "=";
		var begin = dc.indexOf("; " + prefix);
		if (begin == -1)
		{
			begin = dc.indexOf(prefix);
			if (begin != 0) return "";
		}
		else
		{
			begin += 2;
		}
		
		var end = document.cookie.indexOf(";", begin);
		if (end == -1)
		{
			end = dc.length;
		}
		
		return unescape(dc.substring(begin + prefix.length, end));
	}
	/*
	--설명
	쿠키의 값을 설정함. expiredays는 현재로부터 며칠 후에 쿠키 값이 사라지는 지를 지정함.
	*/
	function SetCookie(key, value, expiredays, domain)
	{
		var todayDate = new Date();
		todayDate.setDate(todayDate.getDate() + expiredays);
		
		var cookie = key + "=" + value + "; path=/; expires=" + todayDate.toGMTString() + ";";
		if (domain)
		{
			cookie += " domain=" + domain + "; ";
		}
		
		document.cookie = cookie;
	}

//=========================
var CValid = new CValid();
function CValid()
{
	this.IsId = IsId;
	this.IsPassword = IsPassword;
	this.IsDate = IsDate;
	this.IsTime = IsTime;
	this.IsJumin1 = IsJumin1;
	this.IsJumin2 = IsJumin2;
	this.IsZip = IsZip;
	this.IsCharOnly = IsCharOnly;
	this.IsNumberOnly = IsNumberOnly;
	this.IsMoreThan0 = IsMoreThan0;
	this.IsPhone = IsPhone;
	this.IsHandPhone = IsHandPhone;
	this.IsEmail = IsEmail;
	this.IsDomain = IsDomain;
	this.IsCreditCardNo = IsCreditCardNo;
	this.IsNumberFixedLength = IsNumberFixedLength;
	return this;
}

	/*
	--설명
	다음 규칙에 맞는 유효한 아이디인 지 확인함.
	길이는 MinLength부터 MaxLength까지, 영어와 숫자만 가능, 첫자는 영어만 가능.
	*/
	function IsId(Id, MinLength, MaxLength, IsAllowHangul, oRet) {
		var AlphaList = "abcdefghijklmnopqrstuvwxyz";
		var NumList = "1234567890";
		var AlphaNumList = AlphaList + NumList;
		
		if (!Id)
		{
			oRet.ErrMsg = "아이디를 입력하지 않았습니다.";
			return false;
		}
		
		Id = Id.toLowerCase();
		
		var Len = CTwoByte.LenH(Id);
		
		if (Len < MinLength || Len > MaxLength)
		{
			oRet.ErrMsg = "아이디는 " + MinLength + " ~ " + MaxLength + "자 사이만 가능합니다";
			return false;
		}
		
		if (IsAllowHangul)
		{
			var IsHangul = CTwoByte.IsHangul(Id.charAt(0));
			var IsAlpha = (AlphaList.indexOf(Id.charAt(0)) != -1);
			if (!IsHangul && !IsAlpha)
			{
				oRet.ErrMsg = "아이디의 첫번째는 영어와 한글만 가능합니다.";
				return false;
			}
			
			for(var i = 0, i2 = Id.length; i < i2; i++)
			{
				var c = Id.charAt(i);
				
				var IsHangul = CTwoByte.IsHangul(c);
				var IsAlphaOrNum = (AlphaNumList.indexOf(c) != -1);
				
				if (!IsHangul && !IsAlphaOrNum)
				{
					oRet.ErrMsg = "아이디는 한글, 영문, 숫자만 가능합니다.";
					return false;
				}
			}
		}
		else
		{
			var c = Id.charAt(0);
			if(AlphaList.indexOf(c) == -1) {
				oRet.ErrMsg = "아이디의 첫번째는 영어만 가능합니다";
				return false;
			}
			
			for(var i = 0, i2 = Id.length; i < i2; i++) {
				c = Id.charAt(i);
				if(AlphaNumList.indexOf(c) == -1) {
					oRet.ErrMsg = "아이디는 영어와 숫자만 가능합니다";
					return false;
				}
			}
		}
			
		switch (Id)
		{
			case "sys":
			case "system":
			case "admin":
			case "administrator":
			case "master":
			case "webmaster":
				oRet.ErrMsg = Id + "는 시스템에서 사용되므로 허용되지 않는 아이디입니다.";
				return false;
		}
		
		return true;
	}
	
	/*
	--설명
	다음 규칙에 맞는 유효한 패스워드인 지 확인함.
	길이는 MinLength부터 MaxLength까지, 영어와 숫자만 가능
	*/
	function IsPassword(Password, MinLength, MaxLength, oRet) {
		var alphaList = "abcdefghijklmnopqrstuvwxyz";
		var numList = "1234567890";
		var allowedList = alphaList + numList;
		
	
		Password = Password.toLowerCase();
		
		if(Password.length < MinLength || Password.length > MaxLength) {
			oRet.ErrMsg = "※ 비밀번호는 " + MinLength + " ~ " + MaxLength + "자의 영문, 숫자 혼합만 가능합니다. \n \n";
			return false;
		}
		
		for(var i = 0; i <= Password.length - 1; i++) {
			var c = Password.charAt(i);
			if(allowedList.indexOf(c) == -1) {
				oRet.ErrMsg = "비밀번호는 영어와 숫자만 가능합니다";
				return false;
			}
		}
		
		//같은 번호의 반복 여부
		var c0 = Password.charAt(0);
		var IsAllSame = true;
		for (var i = 1, i2 = Password.length; i < i2; i++)
		{
			var c = Password.charAt(i);
			if (c != c0)
			{
				IsAllSame = false;
				break;
			}
		}
		if (IsAllSame)
		{
			oRet.ErrMsg = "비밀번호에 모두 같은 값이 사용되었습니다.(예: 1111)";
			return false;
		}
		
		//순서대로 증가되는 번호의 여부
		var n0 = Password.charCodeAt(0);
		var IsIncremental = true;
		for (var i = 1, i2 = Password.length; i < i2; i++)
		{
			var n = Password.charCodeAt(i);
			if ((n - i) != n0)
			{
				IsIncremental = false;
				break;
			}
		}
		if (IsIncremental)
		{
			oRet.ErrMsg = "비밀번호에 순서대로 증가되는 값이 사용되었습니다.(예: 1234)";
			return false;
		}
		
		return true;
	}
	/*
	--설명
	해당 년, 월, 일이 날짜 형식인 지 확인함
	--예제
	var Year = 2000, Month = 2, Day = 30;
	alert(IsDate(Year, Month, Day, 1900, 2999)); //false
	*/
	function IsDate(Year, Month, Day, FromYear, ToYear, oRet) {
		var d = new Date();
	
		if (isNaN(Year))
		{
			oRet.ErrMsg = "연도가 숫자 형식이 아닙니다";
			return false;
		}
		
		if (FromYear)
		{
			if (Year < FromYear)
			{
				oRet.ErrMsg = "연도는 " + FromYear + "년부터 가능합니다";
				return false;
			}
		}
		
		if (ToYear)
		{
			if (Year > ToYear)
			{
				oRet.ErrMsg = "연도는 " + ToYear + "년까지 가능합니다";
				return false;
			}
		}
		
		if (isNaN(Month))
		{
			oRet.ErrMsg = "월이 숫자 형식이 아닙니다";
			return false;
		}
		if ((Month < 1) || (Month > 12))
		{
			oRet.ErrMsg = "월은 1부터 12까지만 가능합니다";
			return false;
		}
	
		if (isNaN(Day))
		{
			oRet.ErrMsg = "일이 숫자 형식이 아닙니다";
			return false;
		}
		var LastDay = CDateTime.GetLastDay(Year, Month)
		if (Day < 1 || Day > LastDay)
		{
			oRet.ErrMsg = "일은 1부터 " + LastDay + "까지만 가능합니다";
			return false;
		}
	
		return true;
	}
	
	/*
	--설명
	해당 시, 분, 초가 시간 형식인 지 확인함
	--예제
	var hour = 13, minute = 25, second = 30;
	alert(isTime(hour, minute, second, true)); //false
	*/
	function IsTime(hour, minute, second, Is24, oRet) {
		var minHour = 1;
		var maxHour = 12;
		
		//24시가 기준이면 0시부터 23시가 한계값이 됨.
		if(Is24) {
			minHour = 0;
			maxHour = 23;
		}
		
		if(isNaN(hour)) {
			oRet.ErrMsg = "시간이 숫자 형식이 아닙니다";
			return false;
		}
		if(hour < minHour || hour > maxHour) {
			oRet.ErrMsg = "시간은 " + minHour + "부터 " + maxHour + "까지만 가능합니다";
			return false;
		}
		
		if(isNaN(minute)) {
			oRet.ErrMsg = "분이 숫자 형식이 아닙니다";
			return false;
		}
		if(minute < 0 || minute > 59) {
			oRet.ErrMsg = "분은 0부터 59까지만 가능합니다";
			return false;
		}
	
		if(isNaN(second)) {
			oRet.ErrMsg = "초가 숫자 형식이 아닙니다";
			return false;
		}
		if(second < 0 || second > 59) {
			oRet.ErrMsg = "초는 0부터 59까지만 가능합니다";
			return false;
		}
	
		return true;
	}
	/*
	--설명
	주민등록번호의 첫번째 자리가 제대로 입력되었는 지 확인하기 위함.
	--예제
	alert(IsJumin1("710131")); //true
	alert(IsJumin1("710132")); //false -> 1월 32일은 없으므로.
	*/
	function IsJumin1(value, oRet) {
		if (!value)
		{
			oRet.ErrMsg = "주민등록번호의 첫번째 자리를 입력하지 않았습니다.";
			return false;
		}
		
		//주민등록번호 전체가 숫자인 지 확인
		if(isNaN(value)) {
			oRet.ErrMsg = "주민등록번호는 숫자만 허용됩니다";
			return false;
		}
		
	    //주민등록번호가 6자리인 지 확인
	    if(value.length != 6) {
			oRet.ErrMsg = "주민등록번호의 첫번째 자리는 6자리여야 합니다";
			return false;
	    }
	    
	    //첫번째 부분은 생년월일이므로 날짜 형식인 지 확인
	    var year = "20" + value.substr(0, 2);
	    var month = value.substr(2, 2);
	    var day = value.substr(4, 2);
	    if(!IsDate(year, month, day, 0, 0, oRet))
	    {
			oRet.ErrMsg = "주민등록번호의 첫번째 자리의 " + oRet.ErrMsg;
	    	return false;
	    }
	    
	    return true;
	}
	/*
	--설명
	주민등록번호의 두번째 자리가 제대로 입력되었는 지 확인하기 위함.
	--예제
	alert(IsJumin2("1121513")); //true
	alert(IsJumin2("5121513")); //false -> 첫번째 자리는 1부터 4까지만 있으므로.
	*/
	function IsJumin2(value, oRet) {
		if (!value)
		{
			oRet.ErrMsg = "주민등록번호의 두번째 자리를 입력하지 않았습니다.";
			return false;
		}
		
		//주민등록번호 전체가 숫자인 지 확인
		if(isNaN(value)) {
			oRet.ErrMsg = "주민등록번호는 숫자만 허용됩니다";
			return false;
		}
		
	    //주민등록번호가 7자리인 지 확인
	    if(value.length != 7) {
			oRet.ErrMsg = "주민등록번호의 두번째 자리는 7자리여야 합니다";
			return false;
	    }
	
		//첫째 자리는 성별(1, 3: 남, 2, 4: 여)임.
		if(value.charAt(0) < 1 || value.charAt(0) > 4) {
			oRet.ErrMsg = "주민등록번호의 두번째 부분의 첫번째 자리는 성별을 나타내므로 1부터 4까지만 가능합니다."
			return false;
		}
		
		return true;
	}	
	/*
	--설명
	우편번호의 첫번째, 두번째 자리가 제대로 입력되었는 지 확인하기 위함.
	--예제
	alert(isZip("435")); //true -> 3자리이면서 숫자이므로 맞음.
	alert(isZip("43")); //false -> 3자리가 아니므로 틀림.
	*/
	function IsZip(value, oRet) {
		//우편번호 전체가 숫자인 지 확인
		if(isNaN(value)) {
			oRet.ErrMsg = "우편번호는 숫자만 허용됩니다";
			return false;
		}
		
	    //우편번호가 3자리인 지 확인
	    if(value.length != 3) {
			oRet.ErrMsg = "우편번호는 3자리여야 합니다";
			return false;
	    }
	
		return true;
	}
	
	/*
	--설명
	value 안에 숫자값이 들어있는 지 확인하기 위함.
	--예제
	alert(IsCharOnly("하이")); //true
	alert(IsCharOnly("하2")); //false -> 숫자 2가 들어갔으므로.
	*/
	function IsCharOnly(value, oRet) {
		var c;
		var numLists = "0123456789";
		
		for(var i = 0; i < value.length; i++) {
			c = value.charAt(i);
			if(numLists.indexOf(c) != -1) {
				oRet.ErrMsg = "숫자는 허용되지 않습니다";
				return false;
			}
		}
		
		return true;
	}
	
	function IsNumberOnly(Value)
	{
		if ((!Value) || isNaN(Value))
		{
			return false;
		}
		
		return true;
	}
	
	function IsMoreThan0(Value)
	{
		if (!IsNumberOnly(Value))
		{
			return false;
		}
		
		var n = parseInt(Value, 10);
		if (n <= 0)
		{
			return false;
		}
		
		return true;
	}
	
	/*
	--설명
	전화번호가 형식에 맞게 제대로 입력되었는 지 확인하기 위함.
	--예제
	alert(isPhone("016-731-0343")); //true -> 숫자와 대시만으로 이뤄졌으므로 맞음.
	alert(isPhone("02d7310343")); //false -> 전화번호에 허용되지 않는 알파벳이 들어갔으므로 틀림.
	--추가코드
	RemoveExcept() 함수
	*/
	function IsPhone(value, oRet) {
		var textAllowed = "0123456789-)";
		for(var i = 0; i <= value.length - 1; i++) {
			var c = value.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				oRet.ErrMsg = "전화번호는 다음 문자열만 허용됩니다\n" + textAllowed;
				return false;
			}
		}
	
		value = CFindRep.RemoveExcept(value, "0123456789");
		if(value.length < 6) {
			oRet.ErrMsg = "전화번호는 최소한 6자리 이상의 숫자로 구성되어야 합니다";
			return false;
		}
		
		return true;
	}
	/*
	--설명
	핸드폰 번호가 형식에 맞게 제대로 입력되었는 지 확인하기 위함.
	--추가코드
	RemoveExcept() 함수
	*/
	function IsHandPhone(value, oRet) {
		var textAllowed = "0123456789-)";
		for(var i = 0; i <= value.length - 1; i++) {
			var c = value.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				oRet.ErrMsg = "핸드폰 번호는 다음 문자열만 허용됩니다\n" + textAllowed;
				return false;
			}
		}
	
		value = CFindRep.RemoveExcept(value, "0123456789");
		if(value.length < 10) {
			oRet.ErrMsg = "핸드폰 번호는 최소한 10자리 이상의 숫자로 구성되어야 합니다";
			return false;
		}
		
		var companyNum = "010,011,016,017,018,019";
		if(companyNum.indexOf(value.substr(0, 3)) == -1) {
			oRet.ErrMsg = "핸드폰 번호는 " + companyNum + "으로 시작해야 합니다";
			return false;
		}
		
		return true;
	}
	/*
	--설명
	이메일 주소가 형식에 맞는 지 확인함.
	다음의 규칙에 따라 E-Mail 주소를 얻음.
	
	단어는 알파벳, 숫자, 밑줄(_), 대시(-)만 허용함.
	
	@를 찾음.
	@ 왼쪽의 단어를 찾음.
	@ 오른쪽으로 점으로 끝나는 단어를 찾음.
	점 오른쪽의 단어를 찾음.
	
	각 단어의 길이는 1 이상이어야 함.
	1, 2번째 단어의 시작은 점으로 시작할 수 없음.
	1, 2번째 단어의 시작 다음부터는 허용된 문자열이어야 함.
	3번째 단어는 영어와 숫자와 점(.)만 허용함.
	--예제
	var errMsg = "";
	
	if(!isEmail("kk1965@mail.cc2.cau.ac.kr")) {
		alert(errMsg);
	}
	else {
		alert("yes");
	}
	*/
	function IsEmail(Email, oRet)
	{
		var textAllowed = "abcdefghijklmnopqrstuvwxyz"
						+ "1234567890_-";
		var textAlpha = "abcdefghijklmnopqrstuvwxyz";
		var textNumeric = "1234567890";
		
		if (!Email)
		{
			oRet.ErrMsg = "이메일을 입력하지 않았습니다.";
			return false;
		}
		
		//www.daum.net에서는 Email id가 _-로 시작할 수 있으므로 .만 허용하지 않음.
		//var textNotInFirst = "._-";
		var textNotInFirst = ".";
		
		var posApos = 0, leftOne = "", c = "";
		
		Email = Email.toLowerCase();
		
		var pos1st = 0;	
	
		var posApos = Email.indexOf("@", pos1st + 1);
		if(posApos == -1) {
			oRet.ErrMsg = "이메일에 @ 기호가 없으므로 잘못된 이메일 형식입니다";
			return false;
		}
		var pos2nd = posApos + 1;
		
		var posDot = Email.indexOf(".", pos2nd + 1);
		if(posDot == -1) {
			oRet.ErrMsg = "이메일의 '아이디@서버주소.도메인형식'의 서버주소와 도메인형식 사이에는"
						+ " 점(.)이 있어야 합니다";
			return false;
		}
		var pos3rd = posDot + 1;
		
		var word1st = Email.substring(pos1st, pos2nd - 1);
		var word2nd = Email.substring(pos2nd, pos3rd - 1);
		var word3rd = Email.substring(pos3rd, Email.length);
		
		if(textNotInFirst.indexOf(word1st.charAt(0)) != -1) {
			oRet.ErrMsg = "이메일의 '아이디@서버주소.도메인형식'의 아이디 첫번째 부분에는 '._-' 기호가 허용되지 않습니다";
			return false;
		}
		if(textNotInFirst.indexOf(word2nd.charAt(0)) != -1) {
			oRet.ErrMsg = "이메일의 '아이디@서버주소.도메인형식'의 서버주소 첫번째 부분에는 '._-' 기호가 허용되지 않습니다";
			return false;
		}
		
		/*
		아이디 부분에는 어떤 문자열이든 모두 허용되므로 체크하지 않음.
		for(var i = 0; i <= word1st.length - 1; i++) {
			c = word1st.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				errMsg = "이메일의 '아이디@서버주소.도메인형식'의 아이디 부분에는 다음 문자열만 허용됩니다\n"
						+ textAllowed;
				return false;
			}
		}
		*/
		for(var i = 0; i <= word2nd.length - 1; i++) {
			var c = word2nd.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				oRet.ErrMsg = "이메일의 '아이디@서버주소.도메인형식'의 서버주소 부분에는 다음 문자열만 허용됩니다\n"
						+ textAllowed;
				return false;
			}
		}
	
		var text = textAlpha + textNumeric + ".";
		for(var i = 0; i <= word3rd.length - 1; i++) {
			var c = word3rd.charAt(i);
			if(text.indexOf(c) == -1) {
				oRet.ErrMsg = "이메일의 '아이디@서버주소.도메인형식'의"
							+ " 도메인형식 부분에는 알파벳 기호와 점(.)만 허용됩니다"
				return false;
			}
		}
		
	    var regMust = /\w+([-+.'])|\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
	    var CheckVal = Email.search(regMust);
	    if(CheckVal != 0)
	    {
            oRet.ErrMsg ="정확한 메일주소를 적어주세요";
            return false;
	    }
		
		return true;
	}	
	/*
	--설명
	다음 규칙에 따라 검사함.
	2자 이상 63자 이하
	도메인 네임의 마지막은 대시로 끝날 수 없음.
	*/
	function IsDomain(domain, oRet) {
		var textAllowed = "abcdefghijklmnopqrstuvwxyz"
						+ "1234567890_-";
		var textAlpha = "abcdefghijklmnopqrstuvwxyz";
		var textNotInFirst = "._-";
		//var textNotInLast = "-";
		
		var posDot = 0, leftOne = "", c = "";
		
		domain = domain.toLowerCase();
		if(domain.substr(0, 7) == "http://") {
			domain = domain.substr(7);
		}
		
		var pos1st = 0;	
	
		var posDot = domain.indexOf(".", pos1st + 1);
		if(posDot == -1) {
			oRet.ErrMsg = "점(.)이 없으므로 잘못된 도메인 형식입니다";
			return false;
		}
		var pos2nd = posDot + 1;
		
		var posDot = domain.indexOf(".", pos2nd + 1);
		if(posDot == -1) {
			oRet.ErrMsg = "도메인은 최소한 2개 이상의 점(.)으로 이루어져야 합니다";
			return false;
		}
		var pos3rd = posDot + 1;
		
		var word1st = domain.substring(pos1st, pos2nd - 1);
		var word2nd = domain.substring(pos2nd, pos3rd - 1);
		var word3rd = domain.substring(pos3rd, domain.length);
		
		if(textNotInFirst.indexOf(word1st.charAt(0)) != -1) {
			oRet.ErrMsg = "도메인의 첫번째 부분의 앞자리에는 '._-' 기호가 허용되지 않습니다";
			return false;
		}
		if(textNotInFirst.indexOf(word2nd.charAt(0)) != -1) {
			oRet.ErrMsg = "도메인의 두번째 부분의 앞자리에는 '._-' 기호가 허용되지 않습니다";
			return false;
		}
		if(textNotInFirst.indexOf(word3rd.charAt(0)) != -1) {
			oRet.ErrMsg = "도메인의 세번째 부분의 앞자리에는 '._-' 기호가 허용되지 않습니다";
			return false;
		}
		
		for(var i = 0; i <= word1st.length - 1; i++) {
			var c = word1st.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				oRet.ErrMsg = "도메인 이름의 첫번째 부분은 다음 문자열만 허용됩니다\n"
							+ textAllowed;
				return false;
			}
		}
		for(var i = 0; i <= word2nd.length - 1; i++) {
			var c = word2nd.charAt(i);
			if(textAllowed.indexOf(c) == -1) {
				oRet.ErrMsg = "도메인 이름의 두번째 부분은 다음 문자열만 허용됩니다\n"
						+ textAllowed;
				return false;
			}
		}
		var text = textAllowed + "./";
		for(var i = 0; i <= word3rd.length - 1; i++) {
			var c = word3rd.charAt(i);
			if(text.indexOf(c) == -1) {
				oRet.ErrMsg = "도메인 이름의 세번째 부분은 다음 문자열만 허용됩니다\n"
						+ text;
				return false;
			}
		}
	
		return true;
	}
	
	/*
	--설명
	카드번호가 맞는 지 여부를 검사함.
	*/
	function IsCreditCardNo(No1, No2, No3, No4, oRet)
	{
		var aNo = new Array(No1, No2, No3, No4);
		for (var i = 0; i < aNo.length; i++)
		{
			if (!aNo[i])
			{
				oRet.ErrMsg = "카드번호의 " + (i + 1) + "번째를 입력하지 않았습니다.";
				return false;
			}
			
			if (isNaN(aNo[i]))
			{
				oRet.ErrMsg = "카드번호의 " + (i + 1) + "번째가 숫자 형식이 아닙니다.";
				return false;
			}
			
			if (aNo[i].length != 4)
			{
				oRet.ErrMsg = "카드번호의 " + (i + 1) + "번째가 4자리가 아닙니다.";
				return false;
			}
		}
		
		return true;
	}
	
	function IsNumberFixedLength(Value, Length)
	{
		if (!Value)
		{
			return false;
		}
		if (isNaN(Value))
		{
			return false;
		}
		if (Value.toString().length != Length)
		{
			return false;
		}
		
		return true;
	}

//=========================		
var CDateTime = new CDateTime();
function CDateTime()
{
	this.GetHHNNSSBySeconds = GetHHNNSSBySeconds;
	this.GetHHNNSSIIIByMilliSeconds = GetHHNNSSIIIByMilliSeconds;
	this.GetHHNNSSIII = GetHHNNSSIII;
	this.GetDateAdd = GetDateAdd;
	this.GetDateDiff = GetDateDiff;
	this.GetLastDay = GetLastDay;
	this.GetDateFromYYYYMMDD = GetDateFromYYYYMMDD;
	this.GetYYYYMMDD = GetYYYYMMDD;
	this.GetDateTimeFormat = GetDateTimeFormat;
	this.GetDateValue = GetDateValue;
	return this;
}

	function GetHHNNSSBySeconds(Seconds)
	{
	    var h = parseInt((Seconds / 3600) + "", 10);
		var n = parseInt(((Seconds - (h * 3600)) / 60) + "", 10);
	    var s = Seconds % 60;
		var hh = (h < 10) ? "0" + h : h;
		var nn = (n < 10) ? "0" + n : n;
		var ss = (s < 10) ? "0" + s : s;
	    
	    var o = new Object();
		o.h = h;
		o.n = n;
		o.s = s;
		o.hh = hh;
		o.nn = nn;
		o.ss = ss;
		o.hhnnss = hh + ":" + nn + ":" + ss;
		
		return o;
	}
	function GetHHNNSSIIIByMilliSeconds(MilliSeconds)
	{
		var i = MilliSeconds % 1000;
		var s = Math.floor(MilliSeconds / 1000) % 60;
		var n = Math.floor(MilliSeconds / 1000 / 60) % 60;
		var h = Math.floor(MilliSeconds / 1000 / 60 / 60) % 24;
		
		var hh = (h < 10) ? "0" + h : h;
		var nn = (n < 10) ? "0" + n : n;
		var ss = (s < 10) ? "0" + s : s;
		var iii = "";
		if (i < 10)
			iii = "00" + i;
		else if (i < 100)
			iii = "0" + i;
		else
			iii = i;
		
		var o = new Object();
		o.h = h;
		o.n = n;
		o.s = s;
		o.i = i;
		o.hh = hh;
		o.nn = nn;
		o.ss = ss;
		o.iii = iii;
		o.hhnnss = hh + ":" + nn + ":" + ss;
		o.hhnnssiii = hh + ":" + nn + ":" + ss + ":" + iii;
		
		return o;
	}
	function GetHHNNSSIII(DateValue)
	{
		var d = ((DateValue == null) || (DateValue <= 0)) ? new Date() : DateValue;
		
		var h = d.getHours();
		if (h > 12) h = h - 12;
		if (h == 0) h = 12;
	
		var hh = (h < 10) ? "0" + h : h;
			
		
		var n = d.getMinutes();
		var nn = (n < 10) ? "0" + n : n;
		
		var s = d.getSeconds();
		var ss = (s < 10) ? "0" + s : s;
		
		
		var i = d.getMilliseconds();
		
		var iii = "";
		if (i < 10)
			iii = "00" + i;
		else if (i < 100)
			iii = "0" + i;
		else
			iii = i;
	
	
		var o = new Object();
		o.h = h;
		o.n = n;
		o.s = s;
		o.i = i;
		o.hh = hh;
		o.nn = nn;
		o.ss = ss;
		o.iii = iii;
		o.hhnnss = hh + ":" + nn + ":" + ss;
		o.hhnnssiii = hh + ":" + nn + ":" + ss + ":" + iii;
		
		return o;
	}
	/*
	--설명
	날짜 형식인 oldDate 개체에 number 개월(년)수 만큼 더한
	날짜 개체를 리턴함.
	interval은 다음의 문자열을 가짐.
	yyyy: 년
	m: 월
	d: 일
	h: 시
	n: 분
	s: 초
	
	getFullYear(): 실제년도
	getMonth(): 0-11
	getDate(): 1-31
	getHours(): 0-23
	getMinutes(): 0-59
	getSeconds(): 0-59
	getMilliseconds(): 0-999
	
	getDay(): 0-6
	
	--예제
	var d = new Date(2000, 0, 31);
	var s = d.getFullYear() + "." + parseInt(d.getMonth() + 1, 10) + "." + d.getDate();
	alert(s); //2000.1.31
	
	var d = GetDateAdd("m", 1, d);
	var s = d.getFullYear() + "." + parseInt(d.getMonth() + 1, 10) + "." + d.getDate();
	alert(s); //2000.2.29
	*/
	function GetDateAdd(Interval, Number, OldDate) {
		with (OldDate)
		{
			var OldYear = getFullYear();
			var OldMonth = getMonth();
			var OldDay = getDate();
			var OldHours = getHours();
			var OldMinutes = getMinutes();
			var OldSeconds = getSeconds();
		}
		
		var NewDate = null;
	
		switch(Interval) {
		case "yyyy" :
			NewDate = new Date(OldYear + Number, OldMonth, OldDay);
			break;
		case "m" :
			NewDate = new Date(OldYear, OldMonth + Number, OldDay);
			break;
		case "d" :
			NewDate = new Date(OldYear, OldMonth, OldDay + Number);
			break;
		case "h" :
			NewDate = new Date(OldYear, OldMonth, OldDay, OldHours + Number, OldMinutes, OldSeconds);
			break;
		case "n" :
			NewDate = new Date(OldYear, OldMonth, OldDay, OldHours, OldMinutes + Number, OldSeconds);
			break;
		case "s" :
			NewDate = new Date(OldYear, OldMonth, OldDay, OldHours, OldMinutes, OldSeconds + Number);
			break;
		}
	
		//월을 가감했을 때 OldDate의 일수가 가감 후의 일수보다 더 큰 경우엔
		//해당 월 다음 월이 리턴되므로, 이런 경우엔 해당 월의 마지막 월로 결정함.
		//예: 2005-1-31의 월에 +1을 하면 2005-2-28일에 3을 더한 2005-3-3일이 되지만
		//2005-2-28일로 결정함.
		switch(Interval) {
		case "yyyy" :
		case "m" :
			if (NewDate.getDate() < OldDate.getDate())
			{
				var DatePrevM = new Date(NewDate.getFullYear(), NewDate.getMonth() - 1, 1);
				NewDate = new Date(DatePrevM.getFullYear(), DatePrevM.getMonth(), GetLastDay(DatePrevM.getFullYear(), DatePrevM.getMonth() + 1));
			}
			break;
		}
	
		return NewDate;
	}
	
	/*
	--설명
	VB의 DateDiff 함수와 동일.
	interval은 다음의 문자열을 가짐.
	yyyy: 년
	m: 월
	d: 일
	h: 시
	n: 분
	s: 초
	
	getFullYear(): 실제년도
	getMonth(): 0-11
	getDate(): 1-31
	getHours(): 0-23
	getMinutes(): 0-59
	getSeconds(): 0-59
	getMilliseconds(): 0-999
	
	getDay(): 0-6
	*/
	function GetDateDiff(interval, date1, date2) {
	//	alert(interval);
		switch(interval) {
		case "yyyy":
			var yearFrom = date1.getFullYear();
			var yearTo = date2.getFullYear();
			var yearNew = yearTo - yearFrom;
			
			return yearNew;
			
			break;
		case "m":
			var cntMonth = 0;
			
			var yearFrom = date1.getFullYear();
			var yearTo = date2.getFullYear();
	
			var monthFrom = date1.getMonth();
			var monthTo = date2.getMonth();
			
			while(yearFrom < yearTo) {
				cntMonth += 11 - monthFrom;
				monthFrom = -1;
				yearFrom++;
			}
			cntMonth += monthTo - monthFrom;
			
			return cntMonth;
			
			break;
		case "d":
			//시, 분, 초, 밀리초가 없이 생성해야 일자 계산이 제대로 됨.
			var date1_ = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
			var date2_ = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
			
			var dateNew = (date2_ - date1_) / 1000 / 60 / 60 / 24;
	
			return dateNew;
			
			break;
		case "h":
			//분, 초, 밀리초가 없이 생성해야 시간 계산이 제대로 됨.
			var date1_ = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate(), date1.getHours());
			var date2_ = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), date2.getHours());
			
			var dateNew = (date2_ - date1_) / 1000 / 60 / 60;
			
			return dateNew;
		
			break;
		case "n":
			//초, 밀리초가 없이 생성해야 시간 계산이 제대로 됨.
			var date1_ = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate(), date1.getHours(), date1.getMinutes());
			var date2_ = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), date2.getHours(), date2.getMinutes());
			
			var dateNew = (date2_ - date1_) / 1000 / 60;
			
			return dateNew;
		
			break;
		case "s":
			//밀리초가 없이 생성해야 시간 계산이 제대로 됨.
			var date1_ = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate(), date1.getHours(), date1.getMinutes(), date1.getSeconds());
			var date2_ = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), date2.getHours(), date2.getMinutes(), date2.getSeconds());
			
			var dateNew = (date2_ - date1_) / 1000;
			
			return dateNew;
		
			break;
		}
	}
	
	/*
	--설명
	해당년, 월의 마지막 일을 리턴함.
	--예제
	var year = 2000, month = 2;
	alert(GetLastDay(year, month); //29
	*/
	function GetLastDay(year, month) {
	    if(month == 4 || month == 6 || month == 9 || month == 11) {
	    	return 30;
		}
	    else if(month == 2) {
		    if((year % 4) == 0) {
		        if((year % 100) == 0) {
		            if((year % 400) == 0) {
		                return 29;
		            }
		            else {
		                return 28;
		            }
		        }
		        else {
		            return 29;
		        }
		    }
		    else {
		        return 28;
		    }
	    	
	    }
	    else {
	        return 31;
	    }
	}
	function GetDateFromYYYYMMDD(YYYYMMDD)
	{
		var YYYY = YYYYMMDD.substr(0, 4);
		var MM = YYYYMMDD.substr(4, 2);
		var DD = YYYYMMDD.substr(6, 2);
		
		var Y = parseInt(YYYY);
		var M = (MM.substr(0, 1) == "0") ? parseInt(MM.substr(1, 1)) : parseInt(MM);
		var D = (DD.substr(0, 1) == "0") ? parseInt(DD.substr(1, 1)) : parseInt(DD);
		
		var d = new Date(Y, M - 1, D);
		return d;
	}
	
	function GetYYYYMMDD(DateValue)
	{
		var date_ = (DateValue == null) ? new Date() : DateValue;
	
		var y = date_.getFullYear();
		var m = date_.getMonth() + 1;
		var d = date_.getDate();
	
		var mm = (m < 10) ? "0" + m : m;
		var dd = (d < 10) ? "0" + d : d;
		
		var o = new Object();
		o.y = y;
		o.m = m;
		o.d = d;
		o.yyyy = y;
		o.mm = mm;
		o.dd = dd;
		o.yyyymmdd = "" + o.yyyy + o.mm + o.dd;
		o.yyyy_mm_dd = o.yyyy + "-" + o.mm + "-" + o.dd;
		return o;
	}
	
	function GetDateTimeFormat(DateTimeIn14Char)
	{
		return	DateTimeIn14Char.substr(0, 4) + "-" +
			DateTimeIn14Char.substr(4, 2) + "-" +
			DateTimeIn14Char.substr(6, 2) + " " +
			DateTimeIn14Char.substr(8, 2) + ":" +
			DateTimeIn14Char.substr(10, 2) + ":" +
			DateTimeIn14Char.substr(12, 2);
	}
	/*
	--설명
	날짜 형식이면 Date 개체를 리턴하고 아니면 null을 리턴함.
	--예제
	d = GetDateValue("2002-2-30"); //null
	d = GetDateValue("2002-1-30"); //Date 형식
	*/
	function GetDateValue(p) {
		var year;
		var month;
		var day;
	
		var a = p.split("-");
		if (a.length != 3) {
			a = p.split("/");
		}
		if (a.length != 3) {
			a = p.split(".");
		}
		if (a.length != 3) {
			if ((p.length == 8) && (!isNaN(p))) {
				year = p.substr(0, 4);
				month = p.substr(4, 2);
				day = p.substr(6, 2);
			}
			else {
				return null;
			}
		}
		else {
			year = a[0];
			month = a[1];
			day = a[2];
		}
	
		if ((isNaN(year)) || (year == "")) {
			return null;
		}
		year = parseInt(year,10);
		if ((year < 1900) || (year > 2999)) {
			return null;
		}
		
		if ((isNaN(month)) || (month == "")) {
			return null;
		}
		month = parseInt(month,10);
		if(month < 1 || month > 12) {
			return null;
		}
		
		if ((isNaN(day)) || (day == "")) {
			return null;
		}
		day = parseInt(day,10);
		
		var lastDay = GetLastDay(year, month)
		if(day < 1 || day > lastDay) {
			return null;
		}
	
		return new Date(year, month - 1, day);
	}


//=========================	
/*
--설명
OK 단추를 클릭했을 때 커서를 모래시계로 바꾸고 단추를 못 클릭하게 하고,
작업이 끝났을 때 커서를 기본으로 바꾸고 단추를 클릭할 수 있게 함.
--예제
var hg = new CHourGlass(document.all("btnTest"));
alert(1);
hg.Dispose();
*/
function CHourGlass(Ctl)
{
	this.Ctl = Ctl;
	//alert(this.Ctl.value);
	if (this.Ctl) this.Ctl.disabled = true;
	
	window.status = "처리 중...";
	
	this.Dispose = CHourGlass_Dispose;

	document.body.style.cursor = "wait";
}
function CHourGlass_Dispose()
{
	if (this.Ctl) this.Ctl.disabled = false;
	
	window.status = "";
	
	document.body.style.cursor = "default";
}

//=========================	
var CTwoByte = new CTwoByte();
function CTwoByte()
{
	this.LenH = LenH;
	this.LeftH = LeftH;
	this.IsHangul = IsHangul;
	
	return this;
}

	/*
	--설명
	2바이트 문자열의 길이를 2로 감안한 길이를 리턴함.
	--예제
	var s = "하a";
	alert(LenH(s)); //3을 리턴함.
	*/
	function LenH(Value)
	{
		var nChar = 0;
		
		for (var i = 0, i2 = Value.length; i < i2; i++)
		{
			nChar += (escape(Value.charCodeAt(i)).length > 4) ? 2 : 1;
		}
	
		return nChar;
	}
	
	/*
	--설명
	2바이트 문자열의 실제 길이를 2로 계산해서 왼쪽에서 Length만큼의 문자열을 리턴함.
	--예제
	LeftH("한a글", 3).Result -> "한a"
	LeftH("한a글", 4).Result -> "한a", 이때 '글'의 왼쪽 부분이 남으므로 LeftH("한a글", 4).Mod는 1이 됨.
	*/
	function LeftH(Value, Length)
	{
		var ModIs = 0;
		
		var LenH = 0;
		for (var i = 0, i2 = Value.length; i < i2; i++)
		{
			LenH += (escape(Value.charCodeAt(i)).length > 4) ? 2 : 1;
	
			if (LenH == Length)
			{
				this.Mod = 0;
				this.Result = Value.substr(0, i + 1);
				return this;
			}
			else if (LenH == (Length + 1))
			{
				this.Mod = 1;
				this.Result = ((Length == 1) ? "" : Value.substr(0, i));
				return this;
			}
		}
	
		//Length가 문자열보다 긴 경우엔 문자열 자체를 리턴함.
		this.Mod = 0;
		this.Result = Value;
		return this;
	}
	
	function IsHangul(Value)
	{
		var CharCodeFrom = "가".charCodeAt(0);
		var CharCodeTo = "힣".charCodeAt(0);
		
		for (var i = 0, i2 = Value.length; i < i2; i++)
		{
			var CharCodeCur = Value.charCodeAt(0);
			if ((CharCodeCur < CharCodeFrom) || (CharCodeCur > CharCodeTo))
			{
				return false;
			}
		}
		
		return true;
	}
	
//=========================	
var CWindow = new CWindow();
function CWindow()
{
	this.CenterWindow = CenterWindow;
	this.GetRootOpener = GetRootOpener;
	
	return this;
}

	function CenterWindow(Width, Height)
	{
		var Pos = GetScreentCenterXY(Width, Height);
		window.resizeTo(Width, Height);
		window.moveTo(Pos.X, Pos.Y);
	}
	
	function GetScreentCenterXY(Width, Height)
	{
		this.X = (screen.availWidth - Width) / 2;
		this.Y = (screen.availHeight - Height) / 2;
	
		return this;
	}
	
	function GetRootOpener()
	{
		try
		{
			if (window.opener.opener) return window.opener.opener;
		}
		catch (e)
		{
		}
		
		try
		{
			if (window.opener) return window.opener;
		}
		catch (e)
		{
		}
		
		return window;
	}	