// Cookie Funcs
/*
Cookies have specific size limits:

     1. A cookie may be no larger than 4k.
     2. There may be no more than 20 cookies per domain.
     3. There may be no more than 300 cookies total from
        all sources for Netscape. IE allows up to the
        number of bytes allocated for "Temporary
        Internet Files" (e.g. 30Mb), however this space
        is also being used by other temporary internet
        files (512 cookies for 2Mb, 256 for 1Mb assuming
        cookies are all 4k).

(Note that browsers are not required to conform to those
limits. They may allow more or larger cookies. However,
responsible programming requires respect for the
specifications.)


If your server asks a browser for cookies it may have
accepted while at your site and none are available, either
     ~~ the visitor has never been at your site,
     ~~ the browser did not accept cookies your server
        offered,
     ~~ in order to stay within the 300 cookie limit,
        the browser deleted your domain's cookie(s) from
        the hard drive when accepting cookies from other
        sites, or
     ~~ the visitor manually deleted your server's
        cookie(s) from the hard drive.

What It Is:

Cookies are a plain text data record of 5 variable-length
fields:

     1. expires=_______: The date the cookie will expire.
        If this is blank, the cookie will expire when the
        visitor quits the browser.
     2. domain=_______: The domain name of your site.
     3. path=_______: The path to the directory or web page
        that set the cookie. This may be blank if you want
        to retrieve the cookie from any directory or page.
     4. secure: If this field contains the word "secure"
        then the cookie may only be retrieved with a
        secure server. If this field is blank, no such
        restriction exists.
     5. name=value: You or your programmer determine what
        name to call this field and what data it contains.
        The name and data may be any visible plain text
        characters except semi-colons and commas. (To
        store those restricted characters or spaces,
        a plain text encoding method is used.) For example,
        "%20" (without the quotes) would represent a space
        in the generally accepted hexidecimal URL encoding
        system. No particular encoding method is required,
        except it must be plain text and the program
        decoding it must know the method used.
*/

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();


// This function looks for a cookie with a specific name on the visitor's hard drive.
function ncGetCookie(name) {
  // Start by assuming no cookie exists.
  var cookiecontent = null;
  // The browser's cookies can hold data we're not interested in, all in one
  //     long string of characters. Thus, we need to find out where our specific
  //     cookie begins and ends (provided the one we want actually exists).
  //
  // If any cookies are available ...
  if(document.cookie.length > 0) {
    // Determine begin position of the cookie with the specified name.
    var cookiename = name + '=';
    var cookiebegin = document.cookie.indexOf(cookiename);
    // Initialize the end position at zero.
    var cookieend = 0;
    // If a cookie with the specified name is actually available ...
    if(cookiebegin > -1) {
      // Offset the begin position of the cookie by the lengh of the cookie name.
      cookiebegin += cookiename.length;
      // Determine the end position of the cookie.
      cookieend = document.cookie.indexOf(";",cookiebegin);
      if(cookieend < cookiebegin) { cookieend = document.cookie.length; }
      // Put the cookie into our own variable "cookiecontent".
      cookiecontent = document.cookie.substring(cookiebegin,cookieend);
    }
  }
  return cookiecontent;
}

// This function puts the cookie on the visitor's hard drive.
// set ncDaysToLive to a value larger than 0 to make the cookie last longer
// than the browser session (note leave commented to make browser session)
//var ncDaysToLive = 1;
function ncPutCookie(name,value) {
  // Begin by assuming no expiration date is applicable.
  var exp = '';
  // If an expiration date is applicable, determine the future date
  //      and store the date in variable "exp" in the correct format.
  if(typeof(ncDaysToLive) != "undefined"){
    if(ncDaysToLive > 0) {
      var now = new Date();
      then = now.getTime() + (ncDaysToLive * 24 * 60 * 60 * 1000);
      now.setTime(then);
      exp = '; expires=' + now.toGMTString();
    }
  } else {
    exp = '; expires=';
  }
  // Put the cookie on the user's hard drive with path set to root
  //     and with any applicable expiration date.
  document.cookie = name + "=" + value + '; path=/' + exp;
}

// Author: Justin Stenning
// Date: 4th May 2003
// Shows a netcat Modal or Modeless window
// REQUIRES chMW_PleaseWaitMsg to be included in the page that
//          requests this function.
var ncShowModalWindow_aWindowIsOpen=false;
var ncBPModalWindow = null;

/*
Comments:
- Function used to keep window in front, yet not stop form entry
*/
var ncBPModalWindow = null; /* Cross Browser 14/04/2007 */

function ncShowModalWindow_v2(modal, name, data, urlStem, additionalURLValue, callBackFunction, rnd, width, height,
                              stickyPos, stickySize, stickyOpen, onloadScript, oncloseScript, resizeable, maximize, minimize) {
	
  if (ncShowModalWindow_aWindowIsOpen){
    alert('Only one dialog can be open at a time.\nFirst close the other open dialog.');
    return false;
  };

  
  //var gDebugModalWindow = true;

  // To ensure that minimize is not undefined
  if (minimize) {var minimize=true;} else {var minimize=false;}

  var x,y,w,h,c,m,r,min;
  var oncloseStr = "";
  var onloadStr = "";
  ncShowPleaseWaitMsg("<br>Loading...<br>&nbsp;");

  c = "yes"; // default to centering the window
  w = parseInt(width);
  h = parseInt(height);
  x=y="";
  m = (maximize)?'yes':'no';
  r = (resizeable)?'yes':'no';
  min = (minimize)?'yes':'no';

  if (stickyPos || stickySize) {
    var aCookieValue = ncGetCookie("ncMWPositions");
    var aValue = null;
    if (aCookieValue) {
      var aValueList = SplitQStrTrim(aCookieValue, "^", false);
      var aValue = ParamValueByName(aValueList, name, "|");
      if (stickyPos) {
        c = "no";
        x = "dialogLeft:"+(parseInt(leftString(aValue, "-"))-3)+"px;";
        y = "dialogTop:"+(parseInt(leftString(rightString(aValue, "-"), "-"))-29)+"px;";
      }
      // Only get width and height from cookie if not a modal window
      if (stickySize) {
        w = leftString(rightString(rightString(aValue, "-"), "-"), "-");
        h = rightString(rightString(rightString(aValue, "-"), "-"), "-");
      }
    }
    if (aValue == null || aValue == "") {
      c = "yes";
      x = y = "";
      // setting the w and h here again fixes a bug when the cookie exists but not
      // a value for the specified window.
      w = parseInt(width);
      h = parseInt(height);
    };
  };

  // Set up the onLoad and onClose scripts
  onloadStr = "dialogArguments.ParentWindow.ncHidePleaseWaitMsg();";
  onloadStr += onloadScript+";";
  oncloseStr = "ncSaveMWPosition(\""+name+"\",parseInt(self.screenLeft)+\"-\"+parseInt(self.screenTop)+\"-\"+parseInt(self.dialogWidth)+\"-\"+parseInt(self.dialogHeight));dialogArguments.ParentWindow.ncShowModalWindow_aWindowIsOpen=false;";
  oncloseStr += (!modal&&stickyOpen)?'ncSaveMWOpenState(\''+name+'\');':'';
  oncloseStr += oncloseScript+";";

  // Setup the Dialog Arguments
  var dialogArgs = {ParentWindow: self, onLoad: onloadStr, onClose: oncloseStr, data: data};

  // Build the URL
  var url = urlStem+name+","+additionalURLValue+",";
  if (rnd) {
    url += Math.random();
  }
  var gDebugModalWindow = false;
  ncShowModalWindow_aWindowIsOpen=true;
  if (modal) {
    if (gDebugModalWindow) {
      if (gDebugModalWindow == true) {
        var gDebugModalWindowArgs = dialogArgs;
        window.open(url, 'DebugDialog', 'addressbar=1,toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width='+ w +',height= ' + h + ',left = 100,top = 100');        
        ncHidePleaseWaitMsg();
        ncShowModalWindow_aWindowIsOpen = false;
      }
    }
    else {
		var o_ncBPFramework = ncBPFramework.DOM;
		var o_ncWindow = new ncNetcatCOM.ncWindows.ncWindow(name,"dialog",name,url, width, height ,dialogArgs);
		o_ncWindow.callBackFunction = callBackFunction;
		o_ncNetcat.windows.Add( o_ncWindow );
		
		//if (window.showModalDialog) {
		if (BrowserDetect.browser == "Explorer") {	//if (window.showModalDialog) {
			var result = window.showModalDialog(url, dialogArgs, "status:no; center:"+c+"; help:no; minimize:"+min+"; maximize:"+m+"; resizable:"+r+"; border:thin; statusbar:no; scroll:no; dialogWidth:"+w+"px; dialogHeight:"+h+"px;"+x+y);
			/* Call this again just in case it didn't close or the user closed the window first */
			ncShowModalWindow_aWindowIsOpen = false;
			try { o_ncWindow.callBackFunction( result ); } catch(e) { window.alert(e.message);}
			ncHidePleaseWaitMsg();
			return null;
		} else {
			o_ncWindow.draw();
			top.o_ncWindows.Add( o_ncWindow );
			ncShowModalWindow_aWindowIsOpen = false;
			ncHidePleaseWaitMsg();
			return null;
		}

    }
  } 
  else {

    /* set global var (with name of window included) */
    if (eval("typeof(ncModalWindowOpen"+name+")") == "undefined") {
      eval("ncModalWindowOpen"+name+"=false");
    }
    if (eval("typeof(ncModalWindowOpen"+name+"Object)") == "undefined") {
      eval("ncModalWindowOpen"+name+"Object=null");
    }
    if (eval("ncModalWindowOpen"+name+"==false")) {
      
      if (gDebugModalWindow) {
        if (gDebugModalWindow == true) {
        
          var gDebugModalWindowArgs = dialogArgs;
          window.open(url, 'DebugDialog', 'addressbar=1,toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width='+ w +',height= ' + h + ',left = 100,top = 100');
          ncHidePleaseWaitMsg();
          ncShowModalWindow_aWindowIsOpen = false;
        }
      }
      else {
	  	//if (window.showModalDialog) {
		if (BrowserDetect.browser == "Explorer") {	//if (window.showModalDialog) {
			var aWindowObj = window.showModelessDialog(url, dialogArgs, "status:no; center:"+c+"; help:no; minimize:"+min+"; maximize:"+m+"; resizable:"+r+"; border:thin; statusbar:yes; scroll:no; dialogWidth:"+w+"px; dialogHeight:"+h+"px;"+x+y);
		  eval("ncModalWindowOpen"+name+"Object=aWindowObj");
		  eval("ncModalWindowOpen"+name+"=true");
		} else { /* Cross browser */
			var o_ncBPFramework = ncBPFramework.DOM;
			var o_ncWindow = new ncNetcatCOM.ncWindows.ncWindow(name,"dialog",name,url, width, height ,dialogArgs);
			o_ncWindow.callBackFunction = callBackFunction;
			o_ncNetcat.windows.Add( o_ncWindow );
			o_ncWindow.draw();
			top.o_ncWindows.Add( o_ncWindow );
			ncShowModalWindow_aWindowIsOpen = false;
			ncHidePleaseWaitMsg();
		}
      }
    } else {
      if (eval("(ncModalWindowOpen"+name+"Object)")) {
        eval("ncModalWindowOpen"+name+"Object.focus()");
      }
    }
  }
  return false;
}

function ncShowModalWindow(modal, name, data, urlStem, additionalURLValue, random, width, height,
                              stickyPos, stickySize, stickyOpen, onloadScript, oncloseScript, resizeable, maximize, minimize) {
	if (!window.showModalDialog) { window.alert('This function is not currently available in Firefox.\n' + urlStem + additionalURLValue); return null; }
  if (ncShowModalWindow_aWindowIsOpen){
    alert('Only one dialog can be open at a time.\nFirst close the other open dialog.');
    return false;
  };

  
  //var gDebugModalWindow = true;

  // To ensure that minimize is not undefined
  if (minimize) {var minimize=true;} else {var minimize=false;}

  var x,y,w,h,c,m,r,min;
  var oncloseStr = "";
  var onloadStr = "";
  ncShowPleaseWaitMsg("<br>Loading...<br>&nbsp;");

  c = "yes"; // default to centering the window
  w = parseInt(width);
  h = parseInt(height);
  x=y="";
  m = (maximize)?'yes':'no';
  r = (resizeable)?'yes':'no';
  min = (minimize)?'yes':'no';

  if (stickyPos || stickySize) {
    var aCookieValue = ncGetCookie("ncMWPositions");
    var aValue = null;
    if (aCookieValue) {
      var aValueList = SplitQStrTrim(aCookieValue, "^", false);
      var aValue = ParamValueByName(aValueList, name, "|");
      if (stickyPos) {
        c = "no";
        x = "dialogLeft:"+(parseInt(leftString(aValue, "-"))-3)+"px;";
        y = "dialogTop:"+(parseInt(leftString(rightString(aValue, "-"), "-"))-29)+"px;";
      }
      // Only get width and height from cookie if not a modal window
      if (stickySize) {
        w = leftString(rightString(rightString(aValue, "-"), "-"), "-");
        h = rightString(rightString(rightString(aValue, "-"), "-"), "-");
      }
    }
    if (aValue == null || aValue == "") {
      c = "yes";
      x = y = "";
      // setting the w and h here again fixes a bug when the cookie exists but not
      // a value for the specified window.
      w = parseInt(width);
      h = parseInt(height);
    };
  };

  // Set up the onLoad and onClose scripts
  onloadStr = "dialogArguments.ParentWindow.ncHidePleaseWaitMsg();";
  onloadStr += onloadScript+";";
  oncloseStr = "ncSaveMWPosition(\""+name+"\",parseInt(self.screenLeft)+\"-\"+parseInt(self.screenTop)+\"-\"+parseInt(self.dialogWidth)+\"-\"+parseInt(self.dialogHeight));dialogArguments.ParentWindow.ncShowModalWindow_aWindowIsOpen=false;";
  oncloseStr += (!modal&&stickyOpen)?'ncSaveMWOpenState(\''+name+'\');':'';
  oncloseStr += oncloseScript+";";

  // Setup the Dialog Arguments
  var dialogArgs = {ParentWindow: self, onLoad: onloadStr, onClose: oncloseStr, data: data};

  // Build the URL
  var url = urlStem+name+","+additionalURLValue+",";
  if (random) {
    url += Math.random();
  }
  var gDebugModalWindow = false;
  ncShowModalWindow_aWindowIsOpen=true;
  if (modal) {
    if (gDebugModalWindow) {
      if (gDebugModalWindow == true) {
        var gDebugModalWindowArgs = dialogArgs;
        window.open(url, 'DebugDialog', 'addressbar=1,toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width='+ w +',height= ' + h + ',left = 100,top = 100');        
        ncHidePleaseWaitMsg();
        ncShowModalWindow_aWindowIsOpen = false;
      }
    }
    else {
		//if (window.showModalDialog) {
		if (BrowserDetect.browser == "Explorer") {	//if (window.showModalDialog) {
			var result = window.showModalDialog(url, dialogArgs, "status:no; center:"+c+"; help:no; minimize:"+min+"; maximize:"+m+"; resizable:"+r+"; border:thin; statusbar:no; scroll:no; dialogWidth:"+w+"px; dialogHeight:"+h+"px;"+x+y);
			/* Call this again just in case it didn't close or the user closed the window first */
			ncShowModalWindow_aWindowIsOpen = false;
			ncHidePleaseWaitMsg();
			return result;
		} else {
			var o_ncBPFramework = ncBPFramework.DOM;
			var o_ncWindow = new ncNetcatCOM.ncWindows.ncWindow(name,"dialog",name,url, w, h ,dialogArgs);
			o_ncNetcat.windows.Add( o_ncWindow );
			o_ncWindow.draw();
			ncShowModalWindow_aWindowIsOpen = false;
			ncHidePleaseWaitMsg();
			return null;
		}

    }
  } 
  else {

    /* set global var (with name of window included) */
    if (eval("typeof(ncModalWindowOpen"+name+")") == "undefined") {
      eval("ncModalWindowOpen"+name+"=false");
    }
    if (eval("typeof(ncModalWindowOpen"+name+"Object)") == "undefined") {
      eval("ncModalWindowOpen"+name+"Object=null");
    }
    if (eval("ncModalWindowOpen"+name+"==false")) {
      
      if (gDebugModalWindow) {
        if (gDebugModalWindow == true) {
        
          var gDebugModalWindowArgs = dialogArgs;
          window.open(url, 'DebugDialog', 'addressbar=1,toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width='+ w +',height= ' + h + ',left = 100,top = 100');
          ncHidePleaseWaitMsg();
          ncShowModalWindow_aWindowIsOpen = false;
        }
      }
      else {  
	  	//if (window.showModalDialog) {
		if (BrowserDetect.browser == "Explorer") {	//if (window.showModalDialog) {
			var aWindowObj = window.showModelessDialog(url, dialogArgs, "status:no; center:"+c+"; help:no; minimize:"+min+"; maximize:"+m+"; resizable:"+r+"; border:thin; statusbar:yes; scroll:no; dialogWidth:"+w+"px; dialogHeight:"+h+"px;"+x+y);
		  eval("ncModalWindowOpen"+name+"Object=aWindowObj");
		  eval("ncModalWindowOpen"+name+"=true");
		} else { /* Cross browser */
			var o_ncBPFramework = ncBPFramework.DOM;
			var o_ncWindow = new ncNetcatCOM.ncWindows.ncWindow(name,"dialog",name,url, w, h ,dialogArgs);
			o_ncNetcat.windows.Add( o_ncWindow );
			o_ncWindow.draw();
			ncShowModalWindow_aWindowIsOpen = false;
			ncHidePleaseWaitMsg();
		}
      }
    } else {
      if (eval("(ncModalWindowOpen"+name+"Object)")) {
        eval("ncModalWindowOpen"+name+"Object.focus()");
      }
    }
  }
  return false;
}

// ncShowMessageBox
var ncOkOnly = 0; // Display OK button only. 
var ncOkCancel = 1; // Display OK and Cancel buttons. 
var ncAbortRetryIgnore = 2; // Display Abort, Retry, and Ignore buttons. 
var ncYesNoCancel = 3; // Display Yes, No, and Cancel buttons. 
var ncYesNo = 4; // Display Yes and No buttons. 
var ncRetryCancel = 5; // Display Retry and Cancel buttons. 

// ncShowMessageBox icon values
var ncNone = 0; // Display no icon.
var ncCritical = 1; // Display Critical Message icon.  
var ncQuestion = 2; // Display Warning Query icon. 
var ncExclamation = 3; // Display Warning Message icon. 
var ncInformation = 4; // Display Information Message icon. 

// ncShowMessageBox results
var ncOk = 1;
var ncCancel = 2;
var ncAbort = 3;
var ncRetry = 4;
var ncIgnore = 5;
var ncYes = 6;
var ncNo = 7;

function ncShowMessageBox(message, title, buttons, icon, urlStem, width, height) {
  if (!(width)) {
    width = 300;
  }
  if (!(height)) {
    height = 160;
  }
  if (!(title)) {
    title = '';
  }

  var aObj = {message: message, title: title, buttons: buttons, icon: icon};
  //if (window.showModalDialog) {
  if (BrowserDetect.browser == "Explorer") {	//if (window.showModalDialog) {
  	return ncShowModalWindow(true, 'Confirm', aObj, urlStem, '', false, width, height, false, false, false, '', '', true, false, false);
  } else {
	  message = message.replace(/<br[^>]*>/g, '\n'); /* remove <br />'s for FF, it's in a windows ctl not a popup */
	  if ( buttons == ncOkOnly ) {
		  window.alert(message);
		  ncBPAnswer = ncOk;
	  } else {
		  ncBPAnswer = confirm(message);
	  }
	  // Response is affirmative
	  if ( (buttons==ncYesNo || buttons == ncYesNoCancel) && ncBPAnswer==true) {
	  	return ncYes;
	  }
	  if ( (buttons == ncOkOnly || buttons == ncOkCancel) && ncBPAnswer==true) {
	  	return ncCancel;
	  }
	  if ( (buttons == ncAbortRetryIgnore || buttons == ncRetryCancel) && ncBPAnswer==true) {
	  	return ncRetry;
	  }
	  // Response is NOT affirmative
	  if ( (buttons==ncYesNo || buttons == ncYesNoCancel) && ncBPAnswer==false) {
	  	return ncNo;
	  }
	  if ( (buttons == ncOkOnly || buttons == ncOkCancel) && ncBPAnswer==false) {
	  	return ncOk;
	  }
	  if ( buttons=ncRetryCancel && ncBPAnswer==false) {
	  	return ncCancel;
	  }
	   if ( buttons == ncAbortRetryIgnore && ncBPAnswer==false) {
	  	return ncAbort;
	  }
	  return ncBPAnswer;
  }
}

function Trim(str) {
// Trim all whitespace characters from start and end of str
  return str.replace(/^\s{1,}/i, "").replace(/\s{1,}$/i, "");
}

function ncSelectListFindOptionByValue(obj, value) {
  for (var i=0;i<obj.options.length;i++) {
    if (obj.options[i].value == value) {
      return obj.options[i];
    }
  }
  return null;
}

function leftStr(str, n)
{
  if (n <= 0) {
      return "";
  }
  else if (n > String(str).length) {
      return str;
  }   
  else {
      return String(str).substring(0,n);
  }
}


function rightStr(str, n)
{
    if (n <= 0) {
       return "";
    }
    else if (n > String(str).length) {
       return str;
    }
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function ncSelectListSelectOption(obj, value, multiple) {
// Selects the select list option for value (if it exists).
  if (multiple) {
    var optObj = ncSelectListFindOptionByValue(obj, value);
    if (optObj) {
      optObj.selected = true;
      return optObj;
    }
  } else {
    obj.value = value;
  }
  return null;
}

function SelectListAddOption(obj, value, text) {
// Add select list option to obj if it doesn't already exist
// e.g. used for adding the custom styles from the attached CSS
  var hasValue = false;
  value = Trim(value);
  text = Trim(text);
  for (var i=0; i<obj.options.length; i++) {
    if (value.toUpperCase() == obj.options[i].value.toUpperCase()) {
      hasValue = true;
      break;
    }
  }
  if ((!hasValue) && (text != "")) {
    var oOption = new Option(text, value);
    obj.options[obj.options.length] = oOption;
  }
}

function ncFindPosX(obj)
{
  var curleft = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curleft += obj.offsetLeft;
      obj = obj.offsetParent;
    }
  }
  else if (obj.x) {
    curleft += obj.x;
  }
  return curleft;
}

function ncFindPosY(obj)
{
  var curtop = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
  }
  else if (obj.y) {
    curtop += obj.y;
  }
  return curtop;
}

// Constant Scroll will reposition the object to the offset specified
// To enable ncConstantScroll either:
// 1. setInterval e.g. window.setInterval("ncConstantScroll(someGlobalObjVar,topOffsetVar, leftOffsetVar)",20)
// OR
// 2. Create an event handler for the window.onscroll event that calls ncConstantScroll(....)
function ncConstantScroll(obj, topOffset, leftOffset) {
  if (document.compatMode == 'CSS1Compat') {
    var sTop = document.documentElement.scrollTop;
    var sLeft = document.documentElement.scrollLeft;
  } else {
    var sTop = document.body.scrollTop;
    var sLeft = document.body.scrollLeft;
  }
  var newPos = new ncBPFramework.DOM.Coordinates(sLeft + leftOffset, sTop + topOffset);
  ncBPFramework.DOM.setElementPosition(obj, newPos);
}

// Smooth Scroll the specified object.
// Start the smooth scroll by setting an interval:
//  e.g. window.setInterval("ncSmoothScroll(objToScroll,topOffsetVar, leftOffsetVar)",20)
function ncSmoothScroll(obj, topOffset, leftOffset) {
  if (document.compatMode == 'CSS1Compat') {
    var sTop = document.documentElement.scrollTop;
    var sLeft = document.documentElement.scrollLeft;
  } else {
    var sTop = document.body.scrollTop;
    var sLeft = document.body.scrollLeft;
  }
var pos = ncBPFramework.DOM.elementPosition(obj);
  var TopDif = parseInt((sTop+topOffset-pos.y)*0.1);
  var LeftDif = parseInt((sLeft+leftOffset-pos.x)*0.1);
  
  // Ensure that the number is atleast going to be 0 (not NaN).
  if (isNaN(TopDif)) TopDif=0;
  if (isNaN(LeftDif)) LeftDif=0;
  if (TopDif == 0) {
    ncBPFramework.DOM.setElementPosition(obj, new ncBPFramework.DOM.Coordinates(pos.x+LeftDif, sTop+topOffset));
  } else {
    ncBPFramework.DOM.setElementPosition(obj, new ncBPFramework.DOM.Coordinates(pos.x+LeftDif, pos.y+TopDif));
  }
}

// Improved Drag object

NetcatDrag = {
    _active: false,
	_move: null,
    _down: null,
    _onstop: null,
    start: function(e,id,onstop) {
        try{e.stop();}catch(e){}
        
		if (NetcatDrag._active) {
			// Set _onstop to null as we are about to start again
			NetcatDrag._onstop = null;
			NetcatDrag._stop();
		}
		NetcatDrag._active = true;
        // We need to remember what we're dragging.
        if (id) {
			NetcatDrag._target = document.getElementById(id);
		} else {
			NetcatDrag._target = e.target();
		}
		NetcatDrag._onstop = onstop;
        
        /*
            There's no cross-browser way to get offsetX and offsetY, so we
            have to do it ourselves. For performance, we do this once and
            cache it.
        */
        NetcatDrag._offset = NetcatDrag._diff(
            e.mouse().page,
            ncBPFramework.DOM.elementPosition(NetcatDrag._target));
        
        NetcatDrag._move = ncBPFramework.Signal.connect(document, 'onmousemove', NetcatDrag._drag);
        NetcatDrag._down = ncBPFramework.Signal.connect(document, 'onmouseup', NetcatDrag._stop);
    },

    _offset: null,
    _target: null,
    
    _diff: function(lhs, rhs) {
        return new ncBPFramework.DOM.Coordinates(lhs.x - rhs.x, lhs.y - rhs.y);
    },
        
    _drag: function(e) {
        e.stop();
        ncBPFramework.DOM.setElementPosition(
            NetcatDrag._target,
            NetcatDrag._diff(e.mouse().page, NetcatDrag._offset));
    },
    
    _stop: function(e) {
		NetcatDrag._active = false;
        ncBPFramework.Signal.disconnect(NetcatDrag._move);
        ncBPFramework.Signal.disconnect(NetcatDrag._down);
		if (NetcatDrag._onstop) {
			NetcatDrag._onstop();
		}
    }
};


// Global object to hold drag information.
var ncDragObj = new Object();
ncDragObj.zIndex = 200;
function ncDragStart(event, id, onstop) {
  var el;
  var x, y;
// If an element id was given, find it. Otherwise use the element being
// clicked on.
  if (id)
    ncDragObj.elNode = document.getElementById(id);
  else {
    ncDragObj.elNode = window.event.srcElement;
  }

// If this is a text node, use its parent element.
  if (ncDragObj.elNode.nodeType == 3)
    ncDragObj.elNode = ncDragObj.elNode.parentNode;

  if (onstop) {
    ncDragObj.onstop = onstop;
  } else {
    ncDragObj.onstop = null;
  }

// Get cursor position with respect to the page.

  x = window.event.clientX + document.documentElement.scrollLeft
      + document.body.scrollLeft;
  y = window.event.clientY + document.documentElement.scrollTop
      + document.body.scrollTop;

// Save starting positions of cursor and element.

  ncDragObj.cursorStartX = x;
  ncDragObj.cursorStartY = y;
  ncDragObj.elStartLeft  = parseInt(ncFindPosX(ncDragObj.elNode));   //ncDragObj.elNode.style.left, 10);
  ncDragObj.elStartTop   = parseInt(ncFindPosY(ncDragObj.elNode));   //ncDragObj.elNode.style.top,  10);

  if (isNaN(ncDragObj.elStartLeft)) ncDragObj.elStartLeft = 0;
  if (isNaN(ncDragObj.elStartTop))  ncDragObj.elStartTop  = 0;

// Update element's z-index.

  ncDragObj.elNode.style.zIndex = ++ncDragObj.zIndex;

// Capture mousemove and mouseup events on the page.
  document.attachEvent("onmousemove", ncDragGo);
  document.attachEvent("onmouseup",   ncDragStop);
  window.event.cancelBubble = true;
  window.event.returnValue = false;
}

function ncDragGo(event) {
  var x, y, x1,y1,cw,ch;

// Get cursor position with respect to the page.

  x = window.event.clientX + document.documentElement.scrollLeft
      + document.body.scrollLeft;
  y = window.event.clientY + document.documentElement.scrollTop
      + document.body.scrollTop;

// Move drag element by the same amount the cursor has moved.
  x1 = (ncDragObj.elStartLeft + x - ncDragObj.cursorStartX);
  y1 = (ncDragObj.elStartTop  + y - ncDragObj.cursorStartY);

  if (((x1 < document.body.clientWidth-40)||(x1 < ncFindPosX(ncDragObj.elNode))) && (x1 >= 0)) {
    ncDragObj.elNode.style.left = x1 + "px";
  }
  if (((y1 < (document.documentElement.scrollTop+document.documentElement.clientHeight-60))||(y1 < ncFindPosY(ncDragObj.elNode))) && (y1 >= document.documentElement.scrollTop)) {
    ncDragObj.elNode.style.top  = y1 + "px";
  } else if (y1 < document.documentElement.scrollTop) {
    ncDragObj.elNode.style.top = document.documentElement.scrollTop+"px";
  }
  window.event.cancelBubble = true;
  window.event.returnValue = false;
}

function ncDragStop(event) {
// Stop capturing mousemove and mouseup events.
  document.detachEvent("onmousemove", ncDragGo);
  document.detachEvent("onmouseup",   ncDragStop);
  if (ncDragObj.onstop) {
    ncDragObj.onstop();
  }
}
// EXAMPLE
//<div id="boxB" class="box" style="left:400px;top:150px;">
//  <div class="bar" style="width:12em;"
//       onmousedown="ncDragStart(event, 'boxB')">Drag Box B</div>
//  <div class="content" style="width:12em;">This is Box B, drag it using the bar above.</div>
//</div>

function HideElementByName(id) {
  try {
    document.getElementById(id).style.display = "none";
  } catch (e) {}
}

function ShowElementByName(id, displayType) {
  try {
    if (typeof(displayType) != "undefined") {
      document.getElementById(id).style.display = displayType;
    } else {
      document.getElementById(id).style.display = "block";
    }
  } catch (e) {}
}

function HideElementByIncrementedName(id) {
// Hides a set of elements that have a common name and an incremented number:
// e.g. linkRow1, linkRow2 etc...
  for (var i=1; ; i++) {
    if (document.getElementById(id + i) == null) {
      break;
    }else {
      HideElementByName(id + i);
    }
  }
}

function ShowElementByIncrementedName(id, displayType) {
  for (var i=1; ; i++) {
    if (document.getElementById(id + i) == null) {
      break;
    }else {
      if (typeof(displayType) != "undefined") {
        ShowElementByName(id + i, displayType);
      } else {
        ShowElementByName(id + i);
      }
    }
  }
}

function GetParentNodeByName(element, name) {
// Find the first occurance of the parentNode "name" in the ancestory
// of element.
  while (element != null) {
    try {
      if ((element.tagName != null) &&(element.tagName.toUpperCase() == name)) {
        return element;
      }
      element = element.parentNode;
    } catch (e) {
      break;
    }
  }
  return null;
}

function GetParentNodeByClass(aElement, aClass) {
// Find the first occurance of the parentNode of class "aClass" in the ancestory
// of aElement.
  while (aElement != null) {
     try {
      var classSet = aElement.className + ' ';
      if ((classSet != ' ') && (classSet.indexOf(aClass + ' ', 0) != -1)) {
        return aElement;
      }
      aElement = aElement.parentNode;
    } catch (e) {
      break;
    }
  }
  return null;
}

function GetParentNodeByNameStopOnTag(element, name, stopTag) {
// Find the first occurance of the parentNode "name" in the ancestory
// of element.
  while (element != null) {
    try {
      if ((element.tagName != null) &&(element.tagName.toUpperCase() == name)) {
        return element;
      }
      else if (element.tagName.toUpperCase() == stopTag.toUpperCase()) 
      {
        return null;
      }
      element = element.parentNode;
    } catch (e) 
    {
      break;
    }
  }
  return null;
}

function GetParentNodeByNameStopOnID(element, name, stopID) {
// Find the first occurance of the parentNode "name" in the ancestory
// of element.
  while (element != null) {
    try {
      if ((element.tagName != null) &&(element.tagName.toUpperCase() == name)) {
        return element;
      }
      else if (element.id.toUpperCase() == stopID.toUpperCase()) 
      {
        return null;
      }
      element = element.parentNode;
    }
    catch (e) 
    {
      break;
    }
  }
  return null;
}


function SplStr(s, del1, del2) {
// Used in SplitQStrTrim
  var s1,a1,a2 = "";
  var list = new Array();
  var i = 0;
  var re_trimLeft = /^\s{1,}/i;
  var re2 = RegExp(del2,"g");

// check for a delimiter
  s1 = s;
  do {
    a1 = leftString(s1, del1);
    if (a1 == "") {
      a1 = s1;
    }
    a2 = rightString(s1, del1);
    a1 = a1.replace(re2, del1);
    a1 = a1.replace(re_trimLeft, "");
    list[i] = a1;
    s1 = a2;
    i++;
  } while (s1 != "");

  return list;
}

// Splits a delimited text line into Array of Strings and trimleft any white spaces.
// (Accounts for quoted strings).
function SplitQStrTrim(s, delimiter, removeQuotes) {
  var repChar = "";  // placeholder for delimiter
  var repChar2 = ""; // placeholder for ""
  var i,p,rc,rc2 = 0;
  var found = false;
  var a1 = "";
  // split string ignoring delimiter inside quotes
  // optionally remove quotes from return value
  // this is the same as above but will leftTrim string when split

  // parse string and change embedded delimiters to
  // a character not already appearing in string.
  // then call modified SplitStr then optionally remove "
  // from return vals
  if (s.length == 0) {
    return null;
  }

  // make sure the replacement char does not appear in string
  rc = 130;
  do {
      repChar = String.fromCharCode(rc);
    rc++;
  } while (s.indexOf(repChar) != -1);
  rc2 = rc+1;
  do {
      repChar2 = String.fromCharCode(rc2);
    rc2++;
  } while (s.indexOf(repChar2) != -1);

  found = false;
  a1 = s;
  for (var i = 0; i < s.length;i++) {
      if (s.charAt(i) == "\"") {
      if (found) {
        if (i < s.length-1) {
          if (s.charAt(i+1) == "\"") {
            // replace "" with repChar2
            //delete(s,i+1,1);
            //delete(a1,i+1,1);
            s = s.substring(0, i+1)+s.slice(i+2);
            a1 = a1.substring(0, i)+repChar2+a1.slice(i+2);
            //a1[i] := repChar2;
            continue;
          }
        }
        s = a1;
      }
      found = !found;
    } else if (found && (s.charAt(i) == delimiter)) {
      a1 = a1.substring(0, i)+repChar+a1.slice(i+1);
        //a1[i] := repChar;
    }
  }

  if (removeQuotes) {
    s = s.replace(/\"/g,"");
  }

  // replace repChar2 with a single quote
  s = s.replace(RegExp(repChar2,"g"),"\"");
  //s.split(repChar);
  return SplStr(s, delimiter, repChar);
}

// Splits a Netcat parameter string into a key=value array. 
// Nested { and } are fine providing they are a matching pair
var SecurityPrefix = '@'
function NCGetParams(s) {
  var max,i,start,position,foundEq,foundBr,braceCount;
  max=i=start=position=foundEq=foundBr=braceCount=0;
  max = s.length
  var paramChars = new RegExp('[A-Z0-9_\\-\\(\\)\\/\\.\\'+SecurityPrefix+']', 'i');
  var buffer = new Array(max);
  var foundWhiteSpace = false;
  
  var list = new Array();
  
  while (start < max) {
    position = -1;
    // find next '='
    foundEq = 0;
    for (i=start;i<max;i++){
      if (s.charAt(i)=='=') {
        foundEq = i;
        break;
      }
    }
    if (foundEq==0) {
      break;
    }
    // get param name
    foundWhiteSpace = false; // this allows for comments above the param
    for (i=start;i<foundEq;i++) {
      if (paramChars.test(s.charAt(i))) {
        if (foundWhiteSpace) {
          position = 0;
          foundWhiteSpace = false;
        } else {
          position++;
        }       
          buffer[position] = s.charAt(i); 
      } else {
        foundWhiteSpace = true;
      }
    }
    
    // insert '='
    position++;
    buffer[position]='=';
      // find opening "{"
      foundBr = 0;
      for (i=foundEq+1;i<max;i++) {
        if (s.charAt(i) == '{') {
          foundBr = i;
          break;
        }
    }
      if (foundBr == 0) {break;}

    // copy param to buffer
    i = foundBr;
    braceCount = 1;
    while (i < max) {
        i++;
        if (s.charAt(i) == '}') {
            braceCount--;
            if (braceCount == 0) {
              position++;
              //buffer[position] = #0;
          var addStr = new String();
          for (var j=0;j<position;j++) {
            addStr += buffer[j];
          }
              list[list.length] = addStr;
              break;
            }
        }
        else if (s.charAt(i) == '{') {
            braceCount++;
      }
        position++;
      buffer[position] = s.charAt(i);
    }

      // if not at the end of the string then start again
    start = i;
  }
  return list;
}
// Test for ncGetParams
function ncTestNCGetParams(s) {
    var testParam = '';
  if (s) {
      testParam = s;
    } else {
      testParam = "param1={thevalue} fweaf fe af @param2={fekjanf  adkjnsf fndjf}    ";
    }

    var myList = NCGetParams(testParam);

  ncTestNCGetParamsAlert(myList);
}
function ncTestNCGetParamsAlert(paramList) {
  var str = '';
    for (var i=0;i<paramList.length;i++) {
      str += parseInt(i+1)+': ['+paramList[i]+']\n';
    }
    alert(str);
}

function ParamValueByName(aArray, name, delimiter) {
// ParamValueByName returns the value of a name=value pair
// from within an array of such values
// An array generated by SplitQStrTrim is an example of input for aArray
// This is most useful for translating netcat commandlines, or INI-like data formats
// - 22nd April added delimiter parameter to support formats that cannot make use of an "=" sign (e.g. cookies)
  var delim = "=";
  if (typeof(delimiter) != "undefined") {
    delim = delimiter;
  }
  for (var i=0;i<aArray.length;i++) {
    if (leftString(aArray[i], delim).toUpperCase() == name.toUpperCase()) {
      return rightString(aArray[i], delim);
    }
  }
  return "";
}

function ParamValueByIndex(aArray, index, delimiter) {
  var delim = "=";
  if (typeof(delimiter) != "undefined") {
    delim = delimiter;
  }
  if (index < aArray.length) {
    return rightString(aArray[index], delim);
  }
  return "";
}

function ParamNameByIndex(aArray, index, delimiter) {
  var delim = "=";
  if (typeof(delimiter) != "undefined") {
    delim = delimiter;
  }
  if (index < aArray.length) {
    return leftString(aArray[index], delim);
  }
  return "";
}

function SetParamValueByName(aArray, name, value, delimiter) {
// SetParamValueByName sets the value of a name=value pair from within
// an array of such values.
  var delim = "=";
  var found = false;
  if (typeof(delimiter) != "undefined") {
    delim = delimiter;
  }
  for (var i=0;i<aArray.length;i++) {
    if (leftString(aArray[i], delim).toUpperCase() == name.toUpperCase()) {
      aArray[i] = name + delim + value;
      found = true;
      break;
    }
  }
  if (!found) {
    aArray[aArray.length] = name + delim + value;
  }
}

function rightString(fullString, subString) {
   var fullStringUpper = fullString.toUpperCase();
   var subStringUpper = subString.toUpperCase();
   if (fullStringUpper.indexOf(subStringUpper) == -1) {
      return "";
   } else {
      return (fullString.substring(fullStringUpper.indexOf(subStringUpper)+subStringUpper.length, fullStringUpper.length));
   }
}

function rightBackString(fullString, subString) {
   var fullStringUpper = fullString.toUpperCase();
   var subStringUpper = subString.toUpperCase();
   if (fullStringUpper.lastIndexOf(subStringUpper) == -1) {
      return "";
   } else {
      return fullString.substring(fullStringUpper.lastIndexOf(subStringUpper)+1, fullStringUpper.length);
   }
}

function middleString(fullString, startString, endString) {
   var fullStringUpper = fullString.toUpperCase();
   var startStringUpper = startString.toUpperCase();
   var endStringUpper = endString.toUpperCase();
   if (fullStringUpper.indexOf(startStringUpper) == -1) {
      return "";
   } else {
      var sub = fullString.substring(fullStringUpper.indexOf(startStringUpper)+startStringUpper.length, fullStringUpper.length);
      var subUpper = sub.toUpperCase();
      if (subUpper.indexOf(endStringUpper) == -1) {
         return sub;
      } else {
         return (sub.substring(0, subUpper.indexOf(endStringUpper)));
      }
   }
}

function middleBackString(fullString, startString, endString) {
   var fullStringUpper = fullString.toUpperCase();
   var startStringUpper = startString.toUpperCase();
   var endStringUpper = endString.toUpperCase();
   if (fullStringUpper.lastIndexOf(startStringUpper) == -1) {
      return "";
   } else {
      var sub = fullString.substring(0, fullStringUpper.lastIndexOf(startStringUpper));
      var subUpper = sub.toUpperCase();
      if (subUpper.indexOf(endStringUpper) == -1) {
         return sub;
      } else {
         return (sub.substring(subUpper.indexOf(endStringUpper)+endStringUpper.length, subUpper.length));
      }
   }
}

function leftString(fullString, subString) {
   var fullStringUpper = fullString.toUpperCase();
   var subStringUpper = subString.toUpperCase();
   if (fullStringUpper.indexOf(subStringUpper) == -1) {
      return "";
   } else {
      return (fullString.substring(0, fullStringUpper.indexOf(subStringUpper)));
   }
}

function leftBackString(fullString, subString) {
   var fullStringUpper = fullString.toUpperCase();
   var subStringUpper = subString.toUpperCase();
   if (fullStringUpper.lastIndexOf(subStringUpper) == -1) {
      return "";
   } else {
      return fullString.substring(0, fullStringUpper.lastIndexOf(subStringUpper));
   }
}

/*****************************************

   Base64 encoding / decoding routines

*****************************************/
var BASE64_END_OF_INPUT = -1;

var ncBase64Chars = new Array(
    'A','B','C','D','E','F','G','H',
    'I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X',
    'Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n',
    'o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9','+','/'
);

var ncReverseBase64Chars = new Array();
for (var i=0; i < ncBase64Chars.length; i++){
    ncReverseBase64Chars[ncBase64Chars[i]] = i;
}

var ncBase64Str;
var ncBase64Count;
function ncSetBase64Str(str){
    ncBase64Str = str;
    ncBase64Count = 0;
}
function ncReadBase64(){
    if (!ncBase64Str) return BASE64_END_OF_INPUT;
    if (ncBase64Count >= ncBase64Str.length) return BASE64_END_OF_INPUT;
    var c = ncBase64Str.charCodeAt(ncBase64Count) & 0xff;
    ncBase64Count++;
    return c;
}

/* function ncEncodeBase64(str)
   ----------------------------
   
   Call this function to Base64 encode a string
   
   Returns: Base64 encoded string
*/
function ncEncodeBase64(str){
    ncSetBase64Str(str);
    var result = '';
    var inBuffer = new Array(3);
    var lineCount = 0;
    var done = false;
    while (!done && (inBuffer[0] = ncReadBase64()) != BASE64_END_OF_INPUT){
        inBuffer[1] = ncReadBase64();
        inBuffer[2] = ncReadBase64();
        result += (ncBase64Chars[ inBuffer[0] >> 2 ]);
        if (inBuffer[1] != BASE64_END_OF_INPUT){
            result += (ncBase64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
            if (inBuffer[2] != BASE64_END_OF_INPUT){
                result += (ncBase64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
                result += (ncBase64Chars [inBuffer[2] & 0x3F]);
            } else {
                result += (ncBase64Chars [((inBuffer[1] << 2) & 0x3c)]);
                result += ('=');
                done = true;
            }
        } else {
            result += (ncBase64Chars [(( inBuffer[0] << 4 ) & 0x30)]);
            result += ('=');
            result += ('=');
            done = true;
        }
        lineCount += 4;
        if (lineCount >= 76){
// Note: Commented to prevent &#10; being included in strings returned
// Uncomment this line to re-implement support for splitting a string at the 58th character
//            result += ('\n');
            lineCount = 0;
        }
    }
    return result;
}
function ncReadReverseBase64(){   
    if (!ncBase64Str) return BASE64_END_OF_INPUT;
    while (true){      
        if (ncBase64Count >= ncBase64Str.length) return BASE64_END_OF_INPUT;
        var nextCharacter = ncBase64Str.charAt(ncBase64Count);
        ncBase64Count++;
        if (ncReverseBase64Chars[nextCharacter]){
            return ncReverseBase64Chars[nextCharacter];
        }
        if (nextCharacter == 'A') return 0;
    } 
}

function ncNtoS(n){
    n=n.toString(16);
    if (n.length == 1) n="0"+n;
    n="%"+n;
    return unescape(n);
}

/* function ncDecodeBase64(str)
   ----------------------------
   
   Call this function to decode a Base64 string.
   
   Returns: unencoded string
*/
function ncDecodeBase64(str){
    ncSetBase64Str(str);
    var result = "";
    var inBuffer = new Array(4);
    var done = false;
    while (!done && (inBuffer[0] = ncReadReverseBase64()) != BASE64_END_OF_INPUT
        && (inBuffer[1] = ncReadReverseBase64()) != BASE64_END_OF_INPUT){
        inBuffer[2] = ncReadReverseBase64();
        inBuffer[3] = ncReadReverseBase64();
        result += ncNtoS((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
        if (inBuffer[2] != BASE64_END_OF_INPUT){
            result +=  ncNtoS((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
            if (inBuffer[3] != BASE64_END_OF_INPUT){
                result +=  ncNtoS((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
            } else {
                done = true;
            }
        } 
        else {
            done = true;
        }
    }
    return result;
}

//Set up events for dialogs
function SetUpDlgEvents(collection) {
  //alert('SetUpDlgEvents');
  try {
    for (var i=0; i < collection.length; i++) {
      collection[i].onkeypress = function anonymous() {PropertyChanged()};
      collection[i].onkeyup = function anonymous() {PropertyChanged()};
      if (collection[i].onchange == null) {
        collection[i].onchange = function anonymous() {PropertyChanged();};
      } 
      else {
        eval("collection[i].onchange = function anonymous() {PropertyChanged(); "+collection[i].onchange+"; anonymous();};");
      }
      if (collection[i].type == 'checkbox') {
        if (collection[i].onclick == null) {
          collection[i].onclick = function anonymous() {PropertyChanged();};
        } 
        else {
          eval("collection[i].onclick = function anonymous() {PropertyChanged(); "+collection[i].onclick+"; anonymous();};");
        }
      }
    }
  } 
  catch(e) {
    try {
      collection.onkeypress = function anonymous() {PropertyChanged()};
      if (collection.onchange == null) {
        collection.onchange = function anonymous() {PropertyChanged();};
      }
      else {
        eval("collection.onchange = function anonymous() {PropertyChanged(); "+collection.onchange+"; anonymous();};");
      }
      if (collection.type == 'checkbox') {
        if (collection.onclick == null) {
          collection.onclick = function anonymous() {PropertyChanged();};
        }
        else {
          eval("collection.onclick = function anonymous() {PropertyChanged(); "+collection.onclick+"; anonymous();};");
        }
      }
    } 
    catch(e) {
    }
  }
}

function ProcessDlgEvent(eventObj)
{
    if (eventObj) 
    {
      if (eventObj.type == 'keypress') 
      {
  // Check srcElement for exclusions/inclusions to invalid keys
        var illegal = eventObj.srcElement.getAttribute('IllegalChars');
        var legal = eventObj.srcElement.getAttribute('LegalChars');
        var keyChar = String.fromCharCode(eventObj.keyCode);
        if (keyChar == ' ') {return;}
        if (!illegal) 
        {
          switch(keyChar) 
          {
            case ',':
              if (legal && legal.indexOf(',')!=-1) {break;}
            case '~':
              if (legal && legal.indexOf('=')!=-1) {break;}
            case '[':
        case ']':
            case '"':
              alert('The character: '+keyChar+' is reserved and cannot be used.\n\nThe reserved characters are: []~,\"');
              eventObj.returnValue = false;
              return;
              break;
            default:
          }
        } 
        else 
        {
          if (illegal.indexOf(keyChar)>-1) 
          {
            alert('The character: '+keyChar+' is reserved and cannot be used.\n\nThe reserved characters are: '+illegal);
            eventObj.returnValue = false;
            return;
          }
        }
      }
   }
}

function DlgPropertyChanged(eventObj, buttonName)
{
   ProcessDlgEvent(eventObj);
   document.all[buttonName].disabled = false;
}



//For a given selector, return a Style object
//
function getStyleBySelector(selector)
{
    var sheetList = document.styleSheets;
    var ruleList;
    var i, j;
    /* look through stylesheets in reverse order that
       they appear in the document */
    for (i = sheetList.length-1; i >= 0; i--)
    {
        /* If standards compliant*/
        if (sheetList[i].cssRules) {
          ruleList = sheetList[i].cssRules;
        }
        /* Else IE */
        else {
          ruleList = sheetList[i].rules;
        }
        if (ruleList) {
          for (j=0; j<ruleList.length; j++)
          {
            if(ruleList[j].selectorText == selector)
            {
                return ruleList[j].style;
            }
/* else { if (j < 10) {alert(ruleList[j].selectorText);} }*/
          }
        }
    }
    return null;
}

//Return true if popup blocker is switched on
function blockingPopups()
{
	 
	 var popUpCookie = ncGetCookie('ncPopUps');
	 
  if (popUpCookie){
 	  return false;
  }
 	var probePopup = window.open('','','width=1,height=1,left=-300,top=-300,scrollbars=no');
   
   if(probePopup) {
      probePopup.close();
      ncPutCookie('ncPopUps','Allowed');
      return false;
   }
   else {
     return true;
   }
}


function validateEmailAddress(aStr) {
  var strAt = "@";
  var strDot = ".";
  var posAt = aStr.indexOf(strAt);
  var posDot = aStr.indexOf(strDot);
  var emailLen = aStr.length;

  //@ does not exist or is at beginning or end
  if (posAt == -1 || posAt == 0 || posAt == emailLen-1) {    
     return false
  }
  //. does not exist or is at beginning or end
  else if (posDot == -1 || posDot==0 || posDot == emailLen-1) {
      return false
  }
  //There is a space in the address
  else if (aStr.indexOf(' ') != -1){
     return false
  }  
  //@ and . are in correct relative positions
  else if (aStr.indexOf(strAt,(posAt+1))!=-1){
      return false
  }

  else if (aStr.substring(posAt-1,posAt)==strDot || aStr.substring(posAt+1,posAt+2)==strDot){
      return false
  }

  else if (aStr.indexOf(strDot,(posAt+2))==-1){
      return false
  }
  //Otherwise return true
  else {
    return true          
  }
}

function pausecomp(millis)
{
var date = new Date();
var curDate = null;

do { curDate = new Date(); }
while(curDate-date < millis);
} 

function ncBPfireEvent ( theObject, theEvent ) {
	if( document.createEvent ) {
		var evObj = document.createEvent("HTMLEvents");
		evObj.initEvent("change", true, true); 
		try { theObject.dispatchEvent(evObj); } catch(e) {}
	} else if( document.createEventObject ) {
		theObject.fireEvent('onchange');
	}	
}

function ncBPcancelEvent( theEvent ) {
	if(!theEvent) var theEvent = window.event;
	theEvent.cancelBubble = true;
	theEvent.returnValue = false;

	//e.stopPropagation works only in Firefox.
	if (theEvent.stopPropagation) {
		theEvent.stopPropagation();
		theEvent.preventDefault();
	}
}

function ncBPisEvent(o){
    return o&&"undefined"!=typeof Event&&o.eventPhase;
}

function ncBPWinUnload(e, message){
	ncBPcancelEvent(e);
	/* IE */
	if(document.all) {
		window.event.returnValue = message;
		return false;
	}
	/* FireFox */
	if(document.getElementById){
		e.returnValue = message;
		return false;
	}
	return false;									/* if (!previewCanNavigate) */
} 											/* function ncBPWinUnload() */
