/*		- AjaxRequest		- EmbeddedView		- Common		- Sortable		- View		- Events	*/// ===================================================================// Author: Matt Kruse <matt@ajaxtoolbox.com>// WWW: http://www.AjaxToolbox.com///// NOTICE: You may use this code for any purpose, commercial or// private, without any further permission from the author. You may// remove this notice from your final code if you wish, however it is// appreciated by the author if at least my web site address is kept.//// You may *NOT* re-distribute this code in any way except through its// use. That means, you can include it in your product, or your web// site, or any other form where the code is actually being used. You// may not put the plain javascript up on your site for download or// include it in your javascript libraries for download. // If you wish to share this code with others, please just point them// to the URL instead.// Please DO NOT link directly to my .js files from your site. Copy// the files to your server and use them there. Thank you.// ===================================================================/** * The AjaxRequest class is a wrapper for the XMLHttpRequest objects which  * are available in most modern browsers. It simplifies the interfaces for * making Ajax requests, adds commonly-used convenience methods, and makes  * the process of handling state changes more intuitive. * An object may be instantiated and used, or the Class methods may be used  * which internally create an AjaxRequest object. */function AjaxRequest() {  var req = new Object();    // -------------------  // Instance properties  // -------------------  /**   * Timeout period (in ms) until an async request will be aborted, and   * the onTimeout function will be called   */  req.timeout = null;    /**   *  Since some browsers cache GET requests via XMLHttpRequest, an   * additional parameter called AjaxRequestUniqueId will be added to   * the request URI with a unique numeric value appended so that the requested   * URL will not be cached.   */  req.generateUniqueUrl = true;    /**   * The url that the request will be made to, which defaults to the current    * url of the window   */  req.url = window.location.href;    /**   * The method of the request, either GET (default), POST, or HEAD   */  req.method = "GET";    /**   * Whether or not the request will be asynchronous. In general, synchronous    * requests should not be used so this should rarely be changed from true   */  req.async = true;    /**   * The username used to access the URL   */  req.username = null;    /**   * The password used to access the URL   */  req.password = null;    /**   * The parameters is an object holding name/value pairs which will be    * added to the url for a GET request or the request content for a POST request   */  req.parameters = new Object();    /**   * The sequential index number of this request, updated internally   */  req.requestIndex = AjaxRequest.numAjaxRequests++;    /**   * Indicates whether a response has been received yet from the server   */  req.responseReceived = false;    /**   * The name of the group that this request belongs to, for activity    * monitoring purposes   */  req.groupName = null;    /**   * The query string to be added to the end of a GET request, in proper    * URIEncoded format   */  req.queryString = "";    /**   * After a response has been received, this will hold the text contents of    * the response - even in case of error   */  req.responseText = null;    /**   * After a response has been received, this will hold the XML content   */  req.responseXML = null;    /**   * After a response has been received, this will hold the status code of    * the response as returned by the server.   */  req.status = null;    /**   * After a response has been received, this will hold the text description    * of the response code   */  req.statusText = null;  /**   * An internal flag to indicate whether the request has been aborted   */  req.aborted = false;    /**   * The XMLHttpRequest object used internally   */  req.xmlHttpRequest = null;  // --------------  // Event handlers  // --------------    /**   * If a timeout period is set, and it is reached before a response is    * received, a function reference assigned to onTimeout will be called   */  req.onTimeout = null;     /**   * A function reference assigned will be called when readyState=1   */  req.onLoading = null;  /**   * A function reference assigned will be called when readyState=2   */  req.onLoaded = null;  /**   * A function reference assigned will be called when readyState=3   */  req.onInteractive = null;  /**   * A function reference assigned will be called when readyState=4   */  req.onComplete = null;  /**   * A function reference assigned will be called after onComplete, if    * the statusCode=200   */  req.onSuccess = null;  /**   * A function reference assigned will be called after onComplete, if    * the statusCode != 200   */  req.onError = null;    /**   * If this request has a group name, this function reference will be called    * and passed the group name if this is the first request in the group to    * become active   */  req.onGroupBegin = null;  /**   * If this request has a group name, and this request is the last request    * in the group to complete, this function reference will be called   */  req.onGroupEnd = null;  // Get the XMLHttpRequest object itself  req.xmlHttpRequest = AjaxRequest.getXmlHttpRequest();  if (req.xmlHttpRequest==null) { return null; }    // -------------------------------------------------------  // Attach the event handlers for the XMLHttpRequest object  // -------------------------------------------------------  req.xmlHttpRequest.onreadystatechange =   function() {    if (req==null || req.xmlHttpRequest==null) { return; }    if (req.xmlHttpRequest.readyState==1) { req.onLoadingInternal(req); }    if (req.xmlHttpRequest.readyState==2) { req.onLoadedInternal(req); }    if (req.xmlHttpRequest.readyState==3) { req.onInteractiveInternal(req); }    if (req.xmlHttpRequest.readyState==4) { req.onCompleteInternal(req); }  };    // ---------------------------------------------------------------------------  // Internal event handlers that fire, and in turn fire the user event handlers  // ---------------------------------------------------------------------------  // Flags to keep track if each event has been handled, in case of   // multiple calls (some browsers may call the onreadystatechange   // multiple times for the same state)  req.onLoadingInternalHandled = false;  req.onLoadedInternalHandled = false;  req.onInteractiveInternalHandled = false;  req.onCompleteInternalHandled = false;  req.onLoadingInternal =     function() {      if (req.onLoadingInternalHandled) { return; }      AjaxRequest.numActiveAjaxRequests++;      if (AjaxRequest.numActiveAjaxRequests==1 && typeof(window['AjaxRequestBegin'])=="function") {        AjaxRequestBegin();      }      if (req.groupName!=null) {        if (typeof(AjaxRequest.numActiveAjaxGroupRequests[req.groupName])=="undefined") {          AjaxRequest.numActiveAjaxGroupRequests[req.groupName] = 0;        }        AjaxRequest.numActiveAjaxGroupRequests[req.groupName]++;        if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==1 && typeof(req.onGroupBegin)=="function") {          req.onGroupBegin(req.groupName);        }      }      if (typeof(req.onLoading)=="function") {        req.onLoading(req);      }      req.onLoadingInternalHandled = true;    };  req.onLoadedInternal =     function() {      if (req.onLoadedInternalHandled) { return; }      if (typeof(req.onLoaded)=="function") {        req.onLoaded(req);      }      req.onLoadedInternalHandled = true;    };  req.onInteractiveInternal =     function() {      if (req.onInteractiveInternalHandled) { return; }      if (typeof(req.onInteractive)=="function") {        req.onInteractive(req);      }      req.onInteractiveInternalHandled = true;    };  req.onCompleteInternal =     function() {      if (req.onCompleteInternalHandled || req.aborted) { return; }      req.onCompleteInternalHandled = true;      AjaxRequest.numActiveAjaxRequests--;      if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {        AjaxRequestEnd(req.groupName);      }      if (req.groupName!=null) {        AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;        if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {          req.onGroupEnd(req.groupName);        }      }      req.responseReceived = true;      req.status = req.xmlHttpRequest.status;      req.statusText = req.xmlHttpRequest.statusText;      req.responseText = req.xmlHttpRequest.responseText;      req.responseXML = req.xmlHttpRequest.responseXML;      if (typeof(req.onComplete)=="function") {        req.onComplete(req);      }      if (req.xmlHttpRequest.status==200 && typeof(req.onSuccess)=="function") {        req.onSuccess(req);      }      else if (typeof(req.onError)=="function") {        req.onError(req);      }      // Clean up so IE doesn't leak memory      delete req.xmlHttpRequest['onreadystatechange'];      req.xmlHttpRequest = null;    };  req.onTimeoutInternal =     function() {      if (req!=null && req.xmlHttpRequest!=null && !req.onCompleteInternalHandled) {        req.aborted = true;        req.xmlHttpRequest.abort();        AjaxRequest.numActiveAjaxRequests--;        if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {          AjaxRequestEnd(req.groupName);        }        if (req.groupName!=null) {          AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;          if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {            req.onGroupEnd(req.groupName);          }        }        if (typeof(req.onTimeout)=="function") {          req.onTimeout(req);        }      // Opera won't fire onreadystatechange after abort, but other browsers do.       // So we can't rely on the onreadystate function getting called. Clean up here!      delete req.xmlHttpRequest['onreadystatechange'];      req.xmlHttpRequest = null;      }    };  // ----------------  // Instance methods  // ----------------  /**   * The process method is called to actually make the request. It builds the   * querystring for GET requests (the content for POST requests), sets the   * appropriate headers if necessary, and calls the    * XMLHttpRequest.send() method  */  req.process =     function() {      if (req.xmlHttpRequest!=null) {        // Some logic to get the real request URL        if (req.generateUniqueUrl && req.method=="GET") {          req.parameters["AjaxRequestUniqueId"] = new Date().getTime() + "" + req.requestIndex;        }        var content = null; // For POST requests, to hold query string        for (var i in req.parameters) {          if (req.queryString.length>0) { req.queryString += "&"; }          req.queryString += encodeURIComponent(i) + "=" + encodeURIComponent(req.parameters[i]);        }        if (req.method=="GET") {          if (req.queryString.length>0) {            req.url += ((req.url.indexOf("?")>-1)?"&":"?") + req.queryString;          }        }        req.xmlHttpRequest.open(req.method,req.url,req.async,req.username,req.password);        if (req.method=="POST") {          if (typeof(req.xmlHttpRequest.setRequestHeader)!="undefined") {            req.xmlHttpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');          }          content = req.queryString;        }        if (req.timeout>0) {          setTimeout(req.onTimeoutInternal,req.timeout);        }        req.xmlHttpRequest.send(content);      }    };  /**   * An internal function to handle an Object argument, which may contain   * either AjaxRequest field values or parameter name/values   */  req.handleArguments =     function(args) {      for (var i in args) {        // If the AjaxRequest object doesn't have a property which was passed, treat it as a url parameter        if (typeof(req[i])=="undefined") {          req.parameters[i] = args[i];        }        else {          req[i] = args[i];        }      }    };  /**   * Returns the results of XMLHttpRequest.getAllResponseHeaders().   * Only available after a response has been returned   */  req.getAllResponseHeaders =    function() {      if (req.xmlHttpRequest!=null) {        if (req.responseReceived) {          return req.xmlHttpRequest.getAllResponseHeaders();        }        alert("Cannot getAllResponseHeaders because a response has not yet been received");      }    };  /**   * Returns the the value of a response header as returned by    * XMLHttpRequest,getResponseHeader().   * Only available after a response has been returned   */  req.getResponseHeader =    function(headerName) {      if (req.xmlHttpRequest!=null) {        if (req.responseReceived) {          return req.xmlHttpRequest.getResponseHeader(headerName);        }        alert("Cannot getResponseHeader because a response has not yet been received");      }    };  return req;}// ---------------------------------------// Static methods of the AjaxRequest class// ---------------------------------------/** * Returns an XMLHttpRequest object, either as a core object or an ActiveX  * implementation. If an object cannot be instantiated, it will return null; */AjaxRequest.getXmlHttpRequest = function() {  if (window.XMLHttpRequest) {    return new XMLHttpRequest();  }  else if (window.ActiveXObject) {    // Based on http://jibbering.com/2002/4/httprequest.html    /*@cc_on @*/    /*@if (@_jscript_version >= 5)    try {      return new ActiveXObject("Msxml2.XMLHTTP");    } catch (e) {      try {        return new ActiveXObject("Microsoft.XMLHTTP");      } catch (E) {        return null;      }    }    @end @*/  }  else {    return null;  }};/** * See if any request is active in the background */AjaxRequest.isActive = function() {  return (AjaxRequest.numActiveAjaxRequests>0);};/** * Make a GET request. Pass an object containing parameters and arguments as  * the second argument. * These areguments may be either AjaxRequest properties to set on the request  * object or name/values to set in the request querystring. */AjaxRequest.get = function(args) {  AjaxRequest.doRequest("GET",args);};/** * Make a POST request. Pass an object containing parameters and arguments as  * the second argument. * These areguments may be either AjaxRequest properties to set on the request  * object or name/values to set in the request querystring. */AjaxRequest.post = function(args) {  AjaxRequest.doRequest("POST",args);};/** * The internal method used by the .get() and .post() methods */AjaxRequest.doRequest = function(method,args) {  if (typeof(args)!="undefined" && args!=null) {    var myRequest = new AjaxRequest();    myRequest.method = method;    myRequest.handleArguments(args);    myRequest.process();  }}  ;/** * Submit a form. The requested URL will be the form's ACTION, and the request  * method will be the form's METHOD. * Returns true if the submittal was handled successfully, else false so it  * can easily be used with an onSubmit event for a form, and fallback to  * submitting the form normally. */AjaxRequest.submit = function(theform, args) {  var myRequest = new AjaxRequest();  if (myRequest==null) { return false; }  var serializedForm = AjaxRequest.serializeForm(theform);  myRequest.method = theform.method.toUpperCase();  myRequest.url = theform.action;  myRequest.handleArguments(args);  myRequest.queryString = serializedForm;  myRequest.process();  return true;};/** * Serialize a form into a format which can be sent as a GET string or a POST  * content.It correctly ignores disabled fields, maintains order of the fields  * as in the elements[] array. The 'file' input type is not supported, as  * its content is not available to javascript. This method is used internally * by the submit class method. */AjaxRequest.serializeForm = function(theform) {  var els = theform.elements;  var len = els.length;  var queryString = "";  this.addField =     function(name,value) {       if (queryString.length>0) {         queryString += "&";      }      queryString += encodeURIComponent(name) + "=" + encodeURIComponent(value);    };  for (var i=0; i<len; i++) {    var el = els[i];    if (!el.disabled) {      switch(el.type) {        case 'text': case 'password': case 'hidden': case 'textarea':           this.addField(el.name,el.value);          break;        case 'select-one':          if (el.selectedIndex>=0) {            this.addField(el.name,el.options[el.selectedIndex].value);          }          break;        case 'select-multiple':          for (var j=0; j<el.options.length; j++) {            if (el.options[j].selected) {              this.addField(el.name,el.options[j].value);            }          }          break;        case 'checkbox': case 'radio':          if (el.checked) {            this.addField(el.name,el.value);          }          break;      }    }  }  return queryString;};// -----------------------// Static Class variables// -----------------------/** * The number of total AjaxRequest objects currently active and running */AjaxRequest.numActiveAjaxRequests = 0;/** * An object holding the number of active requests for each group */AjaxRequest.numActiveAjaxGroupRequests = new Object();/** * The total number of AjaxRequest objects instantiated */AjaxRequest.numAjaxRequests = 0;/*	getInnerText function courtesy of Martin Honnen	http://www.thescripts.com/forum/threadedpost582930.html*/function getInnerText (node) {	if (typeof node.textContent != 'undefined') {		return node.textContent;	} else if (typeof node.innerText != 'undefined') {		return node.innerText;	} else if (typeof node.text != 'undefined') {		return node.text;	} else {		switch (node.nodeType) {			case 3:			case 4:				return node.nodeValue;				break;			case 1:			case 11:				var innerText = '';				for (var i = 0; i < node.childNodes.length; i++)				{					innerText += getInnerText(node.childNodes[i]);				}				return innerText;				break;			default:				return '';		}	}}/* returns an array of a given node from a domino view */function xmlToArray( xmlDoc, iCol ) {  var a = new Array();    if( xmlToArray ) {    // open the xml    var root = xmlDoc.documentElement;    results = root.getElementsByTagName("viewentry");    for (i=0; i<results.length; i++) {      a[a.length] = getInnerText(results[i].getElementsByTagName("entrydata")[iCol]);    }  }  return a;}function getUnids( xmlDoc ) {  var a = new Array();  if ( xmlDoc ) {    // open the xml    var root = xmlDoc.documentElement;    results = root.getElementsByTagName("viewentry");    for (i=0; i<results.length; i++) {      a[a.length] = results[i].getAttribute("unid");    }  }  return a;}function $() {	var elements = new Array();	for (var i = 0; i < arguments.length; i++) {		var element = arguments[i];		if (typeof element == 'string')			element = document.getElementById(element);		if (arguments.length == 1)			return element;		elements.push(element);	}	return elements;}//======================================================================/*  EmbeddedView - creates embedded view table in a target element  Vince DiMascio  requires - AjaxRequest.js           - database called _resourcesDb containing images                  msload.gif: progress                  edit.gif: edit                  rm.gif: remove                  vw.gif: view*//*parameters: target - object into which to create the table view - string that defines view (including db) parameters - params passed to ?ReadViewEntries headers - array of headers to show in table controls - array of controls ["a","e","r","v"] = add, edit, remove, view popupParm - window.open parameters for actions form - form to use for "new" action*/ function EmbeddedView(target, view, parameters, headers, controls, popupParms, form ) {    /* constants */  LOADING_HTML = "<img src=\"" + _resourcesDb + "/resources/$master_graphics/$file/msload.gif\" alt=\"loading\">";  popupParms = 'scrollbars=1,resizable=1,status=0,' + popupParms;     function rndNo()  {    var d = new Date();     return '' + d.getMonth() + d.getDate() + d.getYear() + d.getHours() + d.getMinutes() +d.getSeconds() + '';  }  function construct() {    this.target = target;    this.view = view;    this.parameters = parameters;    this.headers = headers;    this.controls = controls;              this.construct = function() {     } // end construct            this.load = function(newParms) {      var o = this;            // allow user to override what's loaded using .load() method      if ( newParms ) p = newParms; else p = parameters;            AjaxRequest.get(      {        'url':  view + '?ReadViewEntries&Preformat' + "&" + p       ,'onSuccess':function(req){            // get xml from the view and create a table out of it           var tableHTML = o.makeHTMLTableFromXML( req.responseXML );                       // place the html in the target element           target.innerHTML = tableHTML;             }           ,'onError':function(req){            alert('Error!\nStatusText='+req.statusText+'\nContents='+req.responseText);        }       ,'onLoading':function(){             target.innerHTML = LOADING_HTML;             }      }) // end AjaxRequest        }        this.reload = function() {      setTimeout( "window.embeddedViews['" + target.id + "'].load()", 300 );    }        this.rm = function( id ) {      if ( confirm("Are you sure you want to remove this record?") ) {        // call agent to erase this doc then execute the refersh functoin        AjaxRequest.get(        {          'url': window._resourcesDb + "/(rm)?Open" + "&vw=" + view + "&docid=" + id + "&rnd=" + rndNo(),          'onSuccess':function(req){                if ( req.responseText.indexOf("OK") == -1 ) {                 alert( req.responseText );               } else {                 eval( "embeddedViews['" + target.id + "']" + ".load()" );               }           }         ,'onError':function(req){ alert('Error!\nStatusText='+req.statusText+'\nContents='+req.responseText);}         ,'onLoading':function(){  target.innerHTML = LOADING_HTML;}        }        );      }    }        this.vw = function( id ) {      var url = view + "/" + id;      window.open( url, '', popupParms );      }    this.ed = function( id ) {      var url = view + "/" + id + "?EditDocument";      window.open( url, '', popupParms );      }        this.addRecord = function() {      var url = view.toLowerCase().split(".nsf")[0] + ".nsf/" + form;      window.open( url, '', popupParms );          }        this.makeHTMLTableFromXML = function( xml ) {              var htm = "<table>";      var root = xml.documentElement;      var rows = root.getElementsByTagName("viewentry");      var i = 0;           // top row      htm += "<tr>"            // blank header over action icons      if ( this.controls.length > 0 ) {        htm += "<th colspan=\"" + this.controls.length + "\">&nbsp;</th>";         i += this.controls.length;      }      // headers      for ( var h = 0; h < headers.length; h++ ) {        htm += "<th>" + this.headers[h] + "</th>";        i++;      }      // data as html table      if ( rows.length > 0 ) {        var cols = rows[0].getElementsByTagName("entrydata");        for ( var i = 0; i < rows.length; i++ ) {          var rowDocId = rows[i].attributes[1].value;                       // new row               htm += "<tr>";                    // cells containing action icons          if( controls.length > 0 ) {            if ( controls.inArray("e") )               htm += "<td width=\"12px\"><img onclick=\"embeddedViews['" + target.id + "'].ed('" + rowDocId + "')\" src=\"" + _resourcesDb + "/edit.gif\" alt=\"Edit\"></td>";                                      if ( controls.inArray("r") )                           htm += "<td width=\"12px\"><img onclick=\"embeddedViews['" + target.id + "'].rm('" + rowDocId + "');\" src=\"" + _resourcesDb + "/rm.gif\" alt=\"Remove\"></td>"                        if ( controls.inArray("v") )                           htm += "<td width=\"12px\"><img onclick=\"embeddedViews['" + target.id  + "'].vw('" + rowDocId + "');\" src=\"" + _resourcesDb + "/vw.gif\" alt=\"View\"></td>"          }                    // cells containing data          for ( var j = 0; j < cols.length; j++ ) {             htm += "<td>" + getInnerText(rows[i].getElementsByTagName("entrydata")[j]) + "</td>";           }                     htm += "</tr>";        }      } else {        // no rows = no data        htm += "<tr><td colspan=\"" + i  + "\">Nothing found</td></tr>";      }      htm += "</table>";      return htm;    }             }    return new construct();} //===================== COMMON =========================================================/*Strip whitespace from the beginning and end of a stringInput : a string*/function trim(str){	return str.replace(/^\s+|\s+$/g,'');}/*Make sure that textBox only contain number*/function checkNumber(textBox){	while (textBox.value.length > 0 && isNaN(textBox.value)) {		textBox.value = textBox.value.substring(0, textBox.value.length - 1)	}		textBox.value = trim(textBox.value);/*	if (textBox.value.length == 0) {		textBox.value = 0;			} else {		textBox.value = parseInt(textBox.value);	}*/}/*	Check if a form element is empty.	If it is display an alert box and focus	on the element*/function isEmpty(formElement, message) {	formElement.value = trim(formElement.value);		_isEmpty = false;	if (formElement.value == '') {		_isEmpty = true;		alert(message);		formElement.focus();	}		return _isEmpty;}/*	Set one value in combo box as the selected value*/function setSelect(listElement, listValue){	for (i=0; i < listElement.options.length; i++) {		if (listElement.options[i].value == listValue)	{			listElement.selectedIndex = i;		}	}	}/** Function for jumping from one site to the other when url is supplied 	*It simply takes the id of the compobox field with	* works out the selected value as a url and options page/url**/function jumpTo(id, userid){	var url = $F(id);	if (url != "") document.location.href=url;}/***Validates the date format entered into a field */function checkDate(id, msg, format){	if(isAvailable(id))	{		var label = getLabelForId(id);		var datevalue = document.getElementById(id).value; 			if(format == undefined)		{			//Check for default formats			if(isDate(datevalue, "M/d/yyyy") || isDate(datevalue, "M/d/yy"))			{				label.className = 'completed';				return true;			}					}		else		{			//Check for specified format			if(isDate(datevalue, format))			{				label.className = 'completed';				return true;			}		}				if(msg != undefined & msg != "")			alert(msg);				//		document.getElementById(id).select();		label.className = 'problem';		return;	}	return true;}function getLabelForId(id) {    var label, labels = document.getElementsByTagName('label');    for (var i = 0; (label = labels[i]); i++) {        if (label.htmlFor == id) {            return label;        }    }    return false;}/***   Tokenizer.js - JavaScript String Tokenizer Function       ***/String.prototype.tokenize = tokenize;function tokenize()  {     var input             = "";     var separator         = " ";     var trim              = "";     var ignoreEmptyTokens = true;     try {       String(this.toLowerCase());     }     catch(e) {       window.alert("Tokenizer Usage: string myTokens[] = myString.tokenize(string separator, string trim, boolean ignoreEmptyTokens);");       return;     }     if(typeof(this) != "undefined")       {          input = String(this);       }     if(typeof(tokenize.arguments[0]) != "undefined")       {          separator = String(tokenize.arguments[0]);       }     if(typeof(tokenize.arguments[1]) != "undefined")       {          trim = String(tokenize.arguments[1]);       }     if(typeof(tokenize.arguments[2]) != "undefined")       {          if(!tokenize.arguments[2])            ignoreEmptyTokens = false;       }     var array = input.split(separator);     if(trim)       for(var i=0; i<array.length; i++)         {           while(array[i].slice(0, trim.length) == trim)             array[i] = array[i].slice(trim.length);           while(array[i].slice(array[i].length-trim.length) == trim)             array[i] = array[i].slice(0, array[i].length-trim.length);         }     var token = new Array();     if(ignoreEmptyTokens)       {          for(var i=0; i<array.length; i++)            if(array[i] != "")              token.push(array[i]);       }     else       {          token = array;       }     return token;  }function isAvailable(item){	var id = document.getElementById(item)	if (id == null)	return false;	else	return true;}// JScript source codefunction popup(tUrl,tLoc,tStatus,tScroll,tWidth,tHeight,p1,p2){popwindow= window.open (tUrl, "ViewWindow",    "location=" + tLoc + ",status=" + tStatus + ",scrollbars=" + tScroll + ",width=" + tWidth + ",height=" + tHeight +"");popwindow.moveTo(p1,p2);return false;}function ScreenResolution(){ var ScrnSize = screen.width + "x" + screen.height    if (navigator.appVersion.indexOf("4.") != -1 &&       navigator.appName.indexOf("Explorer") != -1) {     ScrnSize = screen.width + "x" + screen.height;  }  if (navigator.appVersion.indexOf("4.") != -1 &&       navigator.appName.indexOf("Netscape") != -1) {     ScrnSize = screen.width + "x" + (screen.height + 19); //Netscape sees 19 pixels less on Height  }	return(ScrnSize);}String.prototype.trim = function() {	a = this.replace(/^\s+/, '');	return a.replace(/\s+$/, '');};function getCheckedValues(aField, aType){var v = "";  for (var i=0; i < aField.length; i++){	if (aField[i].checked){  		switch (aType){			case "i": v += i + ","; break;			case "v": v += aField[i].value + ","; break;			case "t": v +=  aField[i].text + ",";break;		}	}  }  return v.substring(0,v.length-1);}function getCheckedValue(aField, aType){  for (var i=0; i < aField.length; i++){	if (aField[i].checked){  		switch (aType){			case "i": return i;			case "v": return aField[i].value;			case "t": return aField[i].text;		}	}  }}function getSelectedValues(aField, aType){var v = "";  for (var i=0; i < aField.length; i++){	if (aField[i].selected){  		switch (aType){			case "i": v += i + ","; break;			case "v": v += aField[i].value + ","; break;			case "t": v += aField[i].text; break;		}	}  }  return v.substring(0,v.length-1);}function getSelectedValue(aField, aType){  for (var i=0; i < aField.length; i++){	if (aField[i].selected){  		switch (aType){			case "i": return i;			case "v": return aField[i].value;			case "t": return aField[i].text;		}	}  }}function doSubmit(){ var objForm = document.forms[0];/* Test for proper completion of fields here */ objForm.submit();}function doSubmitById(id){	if(isAvailable(id)) {	document.getElementById(id).submit(); 	} else {		alert("Failed to submit form, id: '" + id + "'");	}}function KeyPress(){	//alert(window.event.keyCode)	if (window.event.keyCode == 13){		window.event.keyCode =0;		return false;	}	return true;}function doSelect( frm, nam, sel ){  for (var i = 0; i < frm.elements.length; i++) {    if (frm.elements[i].type == "checkbox") {      if (frm.elements[i].name == nam) {		frm.elements[i].checked = sel;      }    }  }  return false;}function doInvertSelection( frm, nam ){  for (var i = 0; i < frm.elements.length; i++) {    if (frm.elements[i].type == "checkbox") {      if (frm.elements[i].name == nam) {		frm.elements[i].checked = (frm.elements[i].checked) ? false:true;      }    }  }  return false;}//For setting locations: Region,Country,City,Town, etcfunction setOptions(chooser,thisElement, label, curval) {    var newElem;    var where = (navigator.appName == "Microsoft Internet Explorer") ? -1 : null;    var tChooser = chooser.form.elements[thisElement];    while (tChooser.options.length) {	tChooser.remove(0);    }    var choice = chooser.options[chooser.selectedIndex].value;    var db = locationdb[choice];    newElem = document.createElement("option");    newElem.text = label + ":";    newElem.value = "";    tChooser.add(newElem, where);    if (choice != "") {        for (var i = 0; i < db.length; i++) {            newElem = document.createElement("option");            newElem.text = db[i].text;            newElem.value = db[i].value;	    if(db[i].value == curval) {	newElem.selected = true; }		            tChooser.add(newElem, where);        }    }}function update(dspid, newvalue){		document.getElementById(dspid).innerHTML = newvalue;	}// ================== CREDIT==========================================// Author: Matt Kruse <matt@mattkruse.com>// WWW: http://www.mattkruse.com/ rest remove to reduce the size of this filevar MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');function LZ(x) {return(x<0||x>9?"":"0")+x}// ------------------------------------------------------------------// isDate ( date_string, format_string )// Returns true if date string matches format of format string and// is a valid date. Else returns false.// It is recommended that you trim whitespace around the value before// passing it to this function, as whitespace is NOT ignored!// ------------------------------------------------------------------function isDate(val,format) {	var date=getDateFromFormat(val,format);	if (date==0) { return false; }	return true;	}// -------------------------------------------------------------------// compareDates(date1,date1format,date2,date2format)//   Compare two date strings to see which is greater.//   Returns://   1 if date1 is greater than date2//   0 if date2 is greater than date1 of if they are the same//  -1 if either of the dates is in an invalid format// -------------------------------------------------------------------function compareDates(date1,dateformat1,date2,dateformat2) {	var d1=getDateFromFormat(date1,dateformat1);	var d2=getDateFromFormat(date2,dateformat2);	if (d1==0 || d2==0) {		return -1;		}	else if (d1 > d2) {		return 1;		}	return 0;	}// ------------------------------------------------------------------// formatDate (date_object, format)// Returns a date in the output format specified.// The format string uses the same abbreviations as in getDateFromFormat()// ------------------------------------------------------------------function formatDate(date,format) {	format=format+"";	var result="";	var i_format=0;	var c="";	var token="";	var y=date.getYear()+"";	var M=date.getMonth()+1;	var d=date.getDate();	var E=date.getDay();	var H=date.getHours();	var m=date.getMinutes();	var s=date.getSeconds();	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;	// Convert real date parts into formatted versions	var value=new Object();	if (y.length < 4) {y=""+(y-0+1900);}	value["y"]=""+y;	value["yyyy"]=y;	value["yy"]=y.substring(2,4);	value["M"]=M;	value["MM"]=LZ(M);	value["MMM"]=MONTH_NAMES[M-1];	value["NNN"]=MONTH_NAMES[M+11];	value["d"]=d;	value["dd"]=LZ(d);	value["E"]=DAY_NAMES[E+7];	value["EE"]=DAY_NAMES[E];	value["H"]=H;	value["HH"]=LZ(H);	if (H==0){value["h"]=12;}	else if (H>12){value["h"]=H-12;}	else {value["h"]=H;}	value["hh"]=LZ(value["h"]);	if (H>11){value["K"]=H-12;} else {value["K"]=H;}	value["k"]=H+1;	value["KK"]=LZ(value["K"]);	value["kk"]=LZ(value["k"]);	if (H > 11) { value["a"]="PM"; }	else { value["a"]="AM"; }	value["m"]=m;	value["mm"]=LZ(m);	value["s"]=s;	value["ss"]=LZ(s);	while (i_format < format.length) {		c=format.charAt(i_format);		token="";		while ((format.charAt(i_format)==c) && (i_format < format.length)) {			token += format.charAt(i_format++);			}		if (value[token] != null) { result=result + value[token]; }		else { result=result + token; }		}	return result;	}	// ------------------------------------------------------------------// Utility functions for parsing in getDateFromFormat()// ------------------------------------------------------------------function _isInteger(val) {	var digits="1234567890";	for (var i=0; i < val.length; i++) {		if (digits.indexOf(val.charAt(i))==-1) { return false; }		}	return true;	}function _getInt(str,i,minlength,maxlength) {	for (var x=maxlength; x>=minlength; x--) {		var token=str.substring(i,i+x);		if (token.length < minlength) { return null; }		if (_isInteger(token)) { return token; }		}	return null;	}	// ------------------------------------------------------------------// getDateFromFormat( date_string , format_string )//// This function takes a date string and a format string. It matches// If the date string matches the format string, it returns the // getTime() of the date. If it does not match, it returns 0.// ------------------------------------------------------------------function getDateFromFormat(val,format) {	val=val+"";	format=format+"";	var i_val=0;	var i_format=0;	var c="";	var token="";	var token2="";	var x,y;	var now=new Date();	var year=now.getYear();	var month=now.getMonth()+1;	var date=1;	var hh=now.getHours();	var mm=now.getMinutes();	var ss=now.getSeconds();	var ampm="";		while (i_format < format.length) {		// Get next token from format string		c=format.charAt(i_format);		token="";		while ((format.charAt(i_format)==c) && (i_format < format.length)) {			token += format.charAt(i_format++);			}		// Extract contents of value based on format token		if (token=="yyyy" || token=="yy" || token=="y") {			if (token=="yyyy") { x=4;y=4; }			if (token=="yy")   { x=2;y=2; }			if (token=="y")    { x=2;y=4; }			year=_getInt(val,i_val,x,y);			if (year==null) { return 0; }			i_val += year.length;			if (year.length==2) {				if (year > 70) { year=1900+(year-0); }				else { year=2000+(year-0); }				}			}		else if (token=="MMM"||token=="NNN"){			month=0;			for (var i=0; i<MONTH_NAMES.length; i++) {				var month_name=MONTH_NAMES[i];				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {					if (token=="MMM"||(token=="NNN"&&i>11)) {						month=i+1;						if (month>12) { month -= 12; }						i_val += month_name.length;						break;						}					}				}			if ((month < 1)||(month>12)){return 0;}			}		else if (token=="EE"||token=="E"){			for (var i=0; i<DAY_NAMES.length; i++) {				var day_name=DAY_NAMES[i];				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {					i_val += day_name.length;					break;					}				}			}		else if (token=="MM"||token=="M") {			month=_getInt(val,i_val,token.length,2);			if(month==null||(month<1)||(month>12)){return 0;}			i_val+=month.length;}		else if (token=="dd"||token=="d") {			date=_getInt(val,i_val,token.length,2);			if(date==null||(date<1)||(date>31)){return 0;}			i_val+=date.length;}		else if (token=="hh"||token=="h") {			hh=_getInt(val,i_val,token.length,2);			if(hh==null||(hh<1)||(hh>12)){return 0;}			i_val+=hh.length;}		else if (token=="HH"||token=="H") {			hh=_getInt(val,i_val,token.length,2);			if(hh==null||(hh<0)||(hh>23)){return 0;}			i_val+=hh.length;}		else if (token=="KK"||token=="K") {			hh=_getInt(val,i_val,token.length,2);			if(hh==null||(hh<0)||(hh>11)){return 0;}			i_val+=hh.length;}		else if (token=="kk"||token=="k") {			hh=_getInt(val,i_val,token.length,2);			if(hh==null||(hh<1)||(hh>24)){return 0;}			i_val+=hh.length;hh--;}		else if (token=="mm"||token=="m") {			mm=_getInt(val,i_val,token.length,2);			if(mm==null||(mm<0)||(mm>59)){return 0;}			i_val+=mm.length;}		else if (token=="ss"||token=="s") {			ss=_getInt(val,i_val,token.length,2);			if(ss==null||(ss<0)||(ss>59)){return 0;}			i_val+=ss.length;}		else if (token=="a") {			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}			else {return 0;}			i_val+=2;}		else {			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}			else {i_val+=token.length;}			}		}	// If there are any trailing characters left in the value, it doesn't match	if (i_val != val.length) { return 0; }	// Is date valid for month?	if (month==2) {		// Check for leap year		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year			if (date > 29){ return 0; }			}		else { if (date > 28) { return 0; } }		}	if ((month==4)||(month==6)||(month==9)||(month==11)) {		if (date > 30) { return 0; }		}	// Correct hours value	if (hh<12 && ampm=="PM") { hh=hh-0+12; }	else if (hh>11 && ampm=="AM") { hh-=12; }	var newdate=new Date(year,month-1,date,hh,mm,ss);	return newdate.getTime();	}// ------------------------------------------------------------------// parseDate( date_string [, prefer_euro_format] )//// This function takes a date string and tries to match it to a// number of possible date formats to get the value. It will try to// match against the following international formats, in this order:// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M// A second argument may be passed to instruct the method to search// for formats like d/M/y (european format) before M/d/y (American).// Returns a Date object or null if no patterns match.// ------------------------------------------------------------------function parseDate(val) {	var preferEuro=(arguments.length==2)?arguments[1]:false;	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');	var d=null;	for (var i=0; i<checkList.length; i++) {		var l=window[checkList[i]];		for (var j=0; j<l.length; j++) {			d=getDateFromFormat(val,l[j]);			if (d!=0) { return new Date(d); }			}		}	return null;	}/************************************************************************************************************(C) www.dhtmlgoodies.com, March 2006This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.	Terms of use:You are free to use this script as long as the copyright message is kept intact. However, you may notredistribute, sell or repost it without our permission.Thank you!www.dhtmlgoodies.comAlf Magne Kalleland************************************************************************************************************/var dynamicContent_ajaxObjects = new Array();function ajax_showContent(divId,ajaxIndex){	document.getElementById(divId).innerHTML = dynamicContent_ajaxObjects[ajaxIndex].response;	dynamicContent_ajaxObjects[ajaxIndex] = false;}function ajax_loadContent(divId,url){		var ajaxIndex = dynamicContent_ajaxObjects.length;	dynamicContent_ajaxObjects[ajaxIndex] = new sack();	dynamicContent_ajaxObjects[ajaxIndex].requestFile = url;	// Specifying which file to get	dynamicContent_ajaxObjects[ajaxIndex].onCompletion = function(){ ajax_showContent(divId,ajaxIndex); };	// Specify function that will be executed after file has been found	dynamicContent_ajaxObjects[ajaxIndex].runAJAX();		// Execute AJAX function			}/************************************************ Dynamic Ajax Content- \u00A9 Dynamic Drive DHTML code library (www.dynamicdrive.com)* This notice MUST stay intact for legal use* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code***********************************************/var loadedobjects=""var rootdomain="http://"+window.location.hostnamefunction ajaxpage(url, containerid){var page_request = falseif (window.XMLHttpRequest) // if Mozilla, Safari etcpage_request = new XMLHttpRequest()else if (window.ActiveXObject){ // if IEtry {page_request = new ActiveXObject("Msxml2.XMLHTTP")} catch (e){try{page_request = new ActiveXObject("Microsoft.XMLHTTP")}catch (e){}}}elsereturn falsepage_request.onreadystatechange=function(){loadpage(page_request, containerid)}page_request.open('GET', url, true)page_request.send(null)}function loadpage(page_request, containerid){if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))document.getElementById(containerid).innerHTML=page_request.responseText}function loadobjs(){if (!document.getElementById)returnfor (i=0; i<arguments.length; i++){var file=arguments[i]var fileref=""if (loadedobjects.indexOf(file)==-1){ //Check to see if this object has not already been added to page before proceedingif (file.indexOf(".js")!=-1){ //If object is a js filefileref=document.createElement('script')fileref.setAttribute("type","text/javascript");fileref.setAttribute("src", file);}else if (file.indexOf(".css")!=-1){ //If object is a css filefileref=document.createElement("link")fileref.setAttribute("rel", "stylesheet");fileref.setAttribute("type", "text/css");fileref.setAttribute("href", file);}}if (fileref!=""){document.getElementsByTagName("head").item(0).appendChild(fileref)loadedobjects+=file+" " //Remember this object as being already added to page}}}// =================DATE PICKER=============/**This is a JavaScript library that will allow you to easily add some basic DHTMLdrop-down datepicker functionality to your Notes forms. This script is not asfull-featured as others you may find on the Internet, but it's free, it's easy tounderstand, and it's easy to change.You'll also want to include a stylesheet that makes the datepicker elementslook nice. An example one can be found in the database that this script wasoriginally released with, at:http://www.nsftools.com/tips/NotesTips.htm#datepickerI've tested this lightly with Internet Explorer 6 and Mozilla Firefox. I have no ideahow compatible it is with other browsers.version 1.4December 20, 2004Julian Robichaux -- http://www.nsftools.comHISTORY--  version 1.0 (Sept. 4, 2004):Initial release.--  version 1.1 (Sept. 5, 2004):Added capability to define the date format to be used, either globally (using thedefaultDateSeparator and defaultDateFormat variables) or when the displayDatePickerfunction is called.--  version 1.2 (Sept. 7, 2004):Fixed problem where datepicker x-y coordinates weren't right inside of a table.Fixed problem where datepicker wouldn't display over selection lists on a page.Added a call to the datePickerClosed function (if one exists) after the datepicker is closed, to allow the developer to add their own custom validation after a datehas been chosen. For this to work, you must have a function called datePickerClosedsomewhere on the page, that accepts a field object as a parameter. See theexample in the comments of the updateDateField function for more details.--  version 1.3 (Sept. 9, 2004)Fixed problem where adding the <div> and <iFrame> used for displaying the datepickerwas causing problems on IE 6 with global variables that had handles to objects onthe page (I fixed the problem by adding the elements using document.createElement()and document.body.appendChild() instead of document.body.innerHTML += ...).--  version 1.4 (Dec. 20, 2004)Added "targetDateField.focus();" to the updateDateField function (as suggested by Alan Lepofsky) to avoid a situation where the cursor focus is at the top of the form after a date has been picked. Added "padding: 0px;" to the dpButton CSS style, to keep the table from being so wide when displayed in Firefox.*/var datePickerDivID = "datepicker";var iFrameDivID = "datepickeriframe";var dayArrayShort = new Array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa');var dayArrayMed = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');var dayArrayLong = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');var monthArrayShort = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');var monthArrayMed = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec');var monthArrayLong = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');  // these variables define the date formatting we're expecting and outputting.// If you want to use a different format by default, change the defaultDateSeparator// and defaultDateFormat variables either here or on your HTML page.var defaultDateSeparator = "/";		// common values would be "/" or "."var defaultDateFormat = "dmy"	// valid values are "mdy", "dmy", and "ymd"var dateSeparator = defaultDateSeparator;var dateFormat = defaultDateFormat;/**This is the main function you'll call from the onClick event of a button.Normally, you'll have something like this on your HTML page:Start Date: <input name="StartDate"> <input type=button value="select" onclick="displayDatePicker('StartDate');">That will cause the datepicker to be displayed beneath the StartDate field andany date that is chosen will update the value of that field. If you'd rather have thedatepicker display beneath the button that was clicked, you can code the buttonlike this:<input type=button value="select" onclick="displayDatePicker('StartDate', this);">So, pretty much, the first argument (dateFieldName) is a string representing thename of the field that will be modified if the user picks a date, and the secondargument (displayBelowThisObject) is optional and represents an actual nodeon the HTML document that the datepicker should be displayed below.In version 1.1 of this code, the dtFormat and dtSep variables were added, allowingyou to use a specific date format or date separator for a given call to this function.Normally, you'll just want to set these defaults globally with the defaultDateSeparatorand defaultDateFormat variables, but it doesn't hurt anything to add them as optionalparameters here. An example of use is:<input type=button value="select" onclick="displayDatePicker('StartDate', false, 'dmy', '.');">This would display the datepicker beneath the StartDate field (because the displayBelowThisObject parameter was false), and update the StartDate field withthe chosen value of the datepicker using a date format of dd.mm.yyyy*/function displayDatePicker(dateFieldName, displayBelowThisObject, dtFormat, dtSep){  var targetDateField = document.getElementsByName(dateFieldName).item(0);    // if we weren't told what node to display the datepicker beneath, just display it  // beneath the date field we're updating  if (!displayBelowThisObject)    displayBelowThisObject = targetDateField;    // if a date separator character was given, update the dateSeparator variable  if (dtSep)    dateSeparator = dtSep;  else    dateSeparator = defaultDateSeparator;    // if a date format was given, update the dateFormat variable  if (dtFormat)    dateFormat = dtFormat;  else    dateFormat = defaultDateFormat;    var x = displayBelowThisObject.offsetLeft;  var y = displayBelowThisObject.offsetTop + displayBelowThisObject.offsetHeight;    // deal with elements inside tables and such  var parent = displayBelowThisObject;  while (parent.offsetParent) {    parent = parent.offsetParent;    x += parent.offsetLeft;    y += parent.offsetTop;  }    drawDatePicker(targetDateField, x, y);}/**Draw the datepicker object (which is just a table with calendar elements) at thespecified x and y coordinates, using the targetDateField object as the input tagthat will ultimately be populated with a date.This function will normally be called by the displayDatePicker function.*/function drawDatePicker(targetDateField, x, y){  var dt = getFieldDate(targetDateField.value);    // the datepicker table will be drawn inside of a <div> with an ID defined by the  // global datePickerDivID variable. If such a div doesn't yet exist on the HTML  // document we're working with, add one.  if (!document.getElementById(datePickerDivID)) {    // don't use innerHTML to update the body, because it can cause global variables    // that are currently pointing to objects on the page to have bad references    //document.body.innerHTML += "<div id='" + datePickerDivID + "' class='dpDiv'></div>";    var newNode = document.createElement("div");    newNode.setAttribute("id", datePickerDivID);    newNode.setAttribute("class", "dpDiv");    newNode.setAttribute("style", "visibility: hidden;");    document.body.appendChild(newNode);  }    // move the datepicker div to the proper x,y coordinate and toggle the visiblity  var pickerDiv = document.getElementById(datePickerDivID);  pickerDiv.style.position = "absolute";  pickerDiv.style.left = x + "px";  pickerDiv.style.top = y + "px";  pickerDiv.style.visibility = (pickerDiv.style.visibility == "visible" ? "hidden" : "visible");  pickerDiv.style.zIndex = 10000;    // draw the datepicker table  refreshDatePicker(targetDateField.name, dt.getFullYear(), dt.getMonth(), dt.getDate());}/**This is the function that actually draws the datepicker calendar.*/function refreshDatePicker(dateFieldName, year, month, day){  // if no arguments are passed, use today's date; otherwise, month and year  // are required (if a day is passed, it will be highlighted later)  var thisDay = new Date();    if ((month >= 0) && (year > 0)) {    thisDay = new Date(year, month, 1);  } else {    day = thisDay.getDate();    thisDay.setDate(1);  }    // the calendar will be drawn as a table  // you can customize the table elements with a global CSS style sheet,  // or by hardcoding style and formatting elements below  var crlf = "\r\n";  var TABLE = "<table cols=7 class='dpTable'>" + crlf;  var xTABLE = "</table>" + crlf;  var TR = "<tr class='dpTR'>";  var TR_title = "<tr class='dpTitleTR'>";  var TR_days = "<tr class='dpDayTR'>";  var TR_todaybutton = "<tr class='dpTodayButtonTR'>";  var xTR = "</tr>" + crlf;  var TD = "<td class='dpTD'";	// leave this tag open, because we'll be adding an onClick event  var TD_title = "<td colspan=5 class='dpTitleTD'>";  var TD_buttons = "<td class='dpButtonTD'>";  var TD_todaybutton = "<td colspan=7 class='dpTodayButtonTD'>";  var TD_days = "<td class='dpDayTD'>";  var TD_selected = "<td class='dpDayHighlightTD'";	// leave this tag open, because we'll be adding an onClick event  var xTD = "</td>" + crlf;  var DIV_title = "<div class='dpTitleText'>";  var DIV_selected = "<div class='dpDayHighlight'>";  var xDIV = "</div>";    // start generating the code for the calendar table  var html = TABLE;    // this is the title bar, which displays the month and the buttons to  // go back to a previous month or forward to the next month  html += TR_title;  html += TD_buttons + getButtonCode(dateFieldName, thisDay, -1, "&lt;") + xTD;  html += TD_title + DIV_title + monthArrayLong[thisDay.getMonth()] + " " + thisDay.getFullYear() + xDIV + xTD;  html += TD_buttons + getButtonCode(dateFieldName, thisDay, 1, "&gt;") + xTD;  html += xTR;    // this is the row that indicates which day of the week we're on  html += TR_days;  for(i = 0; i < dayArrayShort.length; i++)    html += TD_days + dayArrayShort[i] + xTD;  html += xTR;    // now we'll start populating the table with days of the month  html += TR;    // first, the leading blanks  for (i = 0; i < thisDay.getDay(); i++)    html += TD + "&nbsp;" + xTD;    // now, the days of the month  do {    dayNum = thisDay.getDate();    TD_onclick = " onclick=\"updateDateField('" + dateFieldName + "', '" + getDateString(thisDay) + "');\">";        if (dayNum == day)      html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD;    else      html += TD + TD_onclick + dayNum + xTD;        // if this is a Saturday, start a new row    if (thisDay.getDay() == 6)      html += xTR + TR;        // increment the day    thisDay.setDate(thisDay.getDate() + 1);  } while (thisDay.getDate() > 1)    // fill in any trailing blanks  if (thisDay.getDay() > 0) {    for (i = 6; i > thisDay.getDay(); i--)      html += TD + "&nbsp;" + xTD;  }  html += xTR;    // add a button to allow the user to easily return to today, or close the calendar  var today = new Date();  var todayString = "Today is " + dayArrayMed[today.getDay()] + ", " + monthArrayMed[today.getMonth()] + " " + today.getDate();  html += TR_todaybutton + TD_todaybutton;  html += "<button class='dpTodayButton' onClick='refreshDatePicker(\"" + dateFieldName + "\");'>this month</button> ";  html += "<button class='dpTodayButton' onClick='updateDateField(\"" + dateFieldName + "\");'>close</button>";  html += xTD + xTR;    // and finally, close the table  html += xTABLE;    document.getElementById(datePickerDivID).innerHTML = html;  // add an "iFrame shim" to allow the datepicker to display above selection lists  adjustiFrame();}/**Convenience function for writing the code for the buttons that bring us back or forwarda month.*/function getButtonCode(dateFieldName, dateVal, adjust, label){  var newMonth = (dateVal.getMonth() + adjust) % 12;  var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);  if (newMonth < 0) {    newMonth += 12;    newYear += -1;  }    return "<button class='dpButton' onClick='refreshDatePicker(\"" + dateFieldName + "\", " + newYear + ", " + newMonth + ");'>" + label + "</button>";}/**Convert a JavaScript Date object to a string, based on the dateFormat and dateSeparatorvariables at the beginning of this script library.*/function getDateString(dateVal){  var dayString = "00" + dateVal.getDate();  var monthString = "00" + (dateVal.getMonth()+1);  dayString = dayString.substring(dayString.length - 2);  monthString = monthString.substring(monthString.length - 2);    switch (dateFormat) {    case "dmy" :      return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear();    case "ymd" :      return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString;    case "mdy" :    default :      return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear();  }}/**Convert a string to a JavaScript Date object.*/function getFieldDate(dateString){  var dateVal;  var dArray;  var d, m, y;    try {    dArray = splitDateString(dateString);    if (dArray) {      switch (dateFormat) {        case "dmy" :          d = parseInt(dArray[0], 10);          m = parseInt(dArray[1], 10) - 1;          y = parseInt(dArray[2], 10);          break;        case "ymd" :          d = parseInt(dArray[2], 10);          m = parseInt(dArray[1], 10) - 1;          y = parseInt(dArray[0], 10);          break;        case "mdy" :        default :          d = parseInt(dArray[1], 10);          m = parseInt(dArray[0], 10) - 1;          y = parseInt(dArray[2], 10);          break;      }      dateVal = new Date(y, m, d);    } else {      dateVal = new Date(dateString);    }  } catch(e) {    dateVal = new Date();  }    return dateVal;}/**Try to split a date string into an array of elements, using common date separators.If the date is split, an array is returned; otherwise, we just return false.*/function splitDateString(dateString){  var dArray;  if (dateString.indexOf("/") >= 0)    dArray = dateString.split("/");  else if (dateString.indexOf(".") >= 0)    dArray = dateString.split(".");  else if (dateString.indexOf("-") >= 0)    dArray = dateString.split("-");  else if (dateString.indexOf("\\") >= 0)    dArray = dateString.split("\\");  else    dArray = false;    return dArray;}/**Update the field with the given dateFieldName with the dateString that has been passed,and hide the datepicker. If no dateString is passed, just close the datepicker withoutchanging the field value.Also, if the page developer has defined a function called datePickerClosed anywhere onthe page or in an imported library, we will attempt to run that function with the updatedfield as a parameter. This can be used for such things as date validation, setting defaultvalues for related fields, etc. For example, you might have a function like this to validatea start date field:function datePickerClosed(dateField){  var dateObj = getFieldDate(dateField.value);  var today = new Date();  today = new Date(today.getFullYear(), today.getMonth(), today.getDate());    if (dateField.name == "StartDate") {    if (dateObj < today) {      // if the date is before today, alert the user and display the datepicker again      alert("Please enter a date that is today or later");      dateField.value = "";      document.getElementById(datePickerDivID).style.visibility = "visible";      adjustiFrame();    } else {      // if the date is okay, set the EndDate field to 7 days after the StartDate      dateObj.setTime(dateObj.getTime() + (7 * 24 * 60 * 60 * 1000));      var endDateField = document.getElementsByName("EndDate").item(0);      endDateField.value = getDateString(dateObj);    }  }}*/function updateDateField(dateFieldName, dateString){  var targetDateField = document.getElementsByName(dateFieldName).item(0);  if (dateString)    targetDateField.value = dateString;  document.getElementById(datePickerDivID).style.visibility = "hidden";  adjustiFrame();  targetDateField.focus();    // after the datepicker has closed, optionally run a user-defined function called  // datePickerClosed, passing the field that was just updated as a parameter  // (note that this will only run if the user actually selected a date from the datepicker)  if ((dateString) && (typeof(datePickerClosed) == "function"))    datePickerClosed(targetDateField);}/**Use an "iFrame shim" to deal with problems where the datepicker shows up behindselection list elements, if they're below the datepicker. The problem and solution aredescribed at:http://dotnetjunkies.com/WebLog/jking/archive/2003/07/21/488.aspxhttp://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx*/function adjustiFrame(pickerDiv, iFrameDiv){  if (!document.getElementById(iFrameDivID)) {    // don't use innerHTML to update the body, because it can cause global variables    // that are currently pointing to objects on the page to have bad references    //document.body.innerHTML += "<iframe id='" + iFrameDivID + "' src='javascript:false;' scrolling='no' frameborder='0'>";    var newNode = document.createElement("iFrame");    newNode.setAttribute("id", iFrameDivID);    newNode.setAttribute("src", "javascript:false;");    newNode.setAttribute("scrolling", "no");    newNode.setAttribute("frameborder", "0");    document.body.appendChild(newNode);  }    if (!pickerDiv)    pickerDiv = document.getElementById(datePickerDivID);  if (!iFrameDiv)    iFrameDiv = document.getElementById(iFrameDivID);    try {    iFrameDiv.style.position = "absolute";    iFrameDiv.style.width = pickerDiv.offsetWidth;    iFrameDiv.style.height = pickerDiv.offsetHeight;    iFrameDiv.style.top = pickerDiv.style.top;    iFrameDiv.style.left = pickerDiv.style.left;    iFrameDiv.style.zIndex = pickerDiv.style.zIndex - 1;    iFrameDiv.style.visibility = pickerDiv.style.visibility;  } catch(e) {  }}// ============== SORTABLE =============// code from http://webfx.eae.net, some small adaptions made for numbers and first sort order and 	sText = sText.replace(/[\.,]/g,'');function SortableTable(oTable, oSortTypes) {	this.element = oTable;	if ( oTable == null ) return false;	this.tHead = oTable.tHead;	this.tBody = oTable.tBodies[0];	this.document = oTable.ownerDocument || oTable.document;	this.sortColumn = null;	this.descending = null;	var oThis = this;	this._headerOnclick = function (e) {		oThis.headerOnclick(e);	};	// only IE needs this	var win = this.document.defaultView || this.document.parentWindow;	this._onunload = function () {		oThis.destroy();	};	if (win && typeof win.attachEvent != "undefined") {		win.attachEvent("onunload", this._onunload);	}	this.initHeader(oSortTypes || []);}SortableTable.gecko = navigator.product == "Gecko";SortableTable.msie = /msie/i.test(navigator.userAgent);// Mozilla is faster when doing the DOM manipulations on// an orphaned element. MSIE is notSortableTable.removeBeforeSort = SortableTable.gecko;SortableTable.prototype.onsort = function () {};// adds arrow containers and events// also binds sort type to the header cells so that reordering columns does// not break the sort typesSortableTable.prototype.initHeader = function (oSortTypes) {	var cells = this.tHead.rows[0].cells;	var l = cells.length;	var img, c;	for (var i = 0; i < l; i++) {		c = cells[i];		if (oSortTypes[i] != null) {			c._sortType = oSortTypes[i];		}		if (typeof c.addEventListener != "undefined")			c.addEventListener("click", this._headerOnclick, false);		else if (typeof c.attachEvent != "undefined")			c.attachEvent("onclick", this._headerOnclick);	}};// remove arrows and eventsSortableTable.prototype.uninitHeader = function () {	var cells = this.tHead.rows[0].cells;	var l = cells.length;	var c;	for (var i = 0; i < l; i++) {		c = cells[i];		c.removeChild(c.lastChild);		if (typeof c.removeEventListener != "undefined")			c.removeEventListener("click", this._headerOnclick, false);		else if (typeof c.detachEvent != "undefined")			c.detachEvent("onclick", this._headerOnclick);	}};SortableTable.prototype.headerOnclick = function (e) {	// find TD element	var el = e.target || e.srcElement;	while (el.tagName != "TD")		el = el.parentNode;	this.sort(SortableTable.msie ? SortableTable.getCellIndex(el) : el.cellIndex);};// IE returns wrong cellIndex when columns are hiddenSortableTable.getCellIndex = function (oTd) {	var cells = oTd.parentNode.childNodes	var l = cells.length;	var i;	for (i = 0; cells[i] != oTd && i < l; i++)		;	return i;};SortableTable.prototype.getSortType = function (nColumn) {	var cell = this.tHead.rows[0].cells[nColumn];	var val = cell._sortType;	if (val != "")		return val;	return "String";};// only nColumn is required// if bDescending is left out the old value is taken into account// if sSortType is left out the sort type is found from the sortTypes arraySortableTable.prototype.sort = function (nColumn, bDescending, sSortType) {	if (sSortType == null)		sSortType = this.getSortType(nColumn);	// exit if None	if (sSortType == "None")		return;	if (bDescending == null) {		if (this.sortColumn != nColumn)			this.descending = false;		else			this.descending = !this.descending;	}	this.sortColumn = nColumn;	if (typeof this.onbeforesort == "function")		this.onbeforesort();	var f = this.getSortFunction(sSortType, nColumn);	var a = this.getCache(sSortType, nColumn);	var tBody = this.tBody;	a.sort(f);	if (this.descending)		a.reverse();	if (SortableTable.removeBeforeSort) {		// remove from doc		var nextSibling = tBody.nextSibling;		var p = tBody.parentNode;		p.removeChild(tBody);	}	// insert in the new order	var l = a.length;	for (var i = 0; i < l; i++)		tBody.appendChild(a[i].element);	if (SortableTable.removeBeforeSort) {		// insert into doc		p.insertBefore(tBody, nextSibling);	}	this.destroyCache(a);	if (typeof this.onsort == "function")		this.onsort();};SortableTable.prototype.asyncSort = function (nColumn, bDescending, sSortType) {	var oThis = this;	this._asyncsort = function () {		oThis.sort(nColumn, bDescending, sSortType);	};	window.setTimeout(this._asyncsort, 1);};SortableTable.prototype.getCache = function (sType, nColumn) {	var rows = this.tBody.rows;	var l = rows.length;	var a = new Array(l);	var r;	for (var i = 0; i < l; i++) {		r = rows[i];		a[i] = {			value:		this.getRowValue(r, sType, nColumn),			element:	r		};	};	return a;};SortableTable.prototype.destroyCache = function (oArray) {	var l = oArray.length;	for (var i = 0; i < l; i++) {		oArray[i].value = null;		oArray[i].element = null;		oArray[i] = null;	}}SortableTable.prototype.getRowValue = function (oRow, sType, nColumn) {	var s;	var c = oRow.cells[nColumn];	if (typeof c.innerText != "undefined")		s = c.innerText;	else		s = SortableTable.getInnerText(c);	return this.getValueFromString(s, sType);};SortableTable.getInnerText = function (oNode) {	var s = "";	var cs = oNode.childNodes;	var l = cs.length;	for (var i = 0; i < l; i++) {		switch (cs[i].nodeType) {			case 1: //ELEMENT_NODE				s += SortableTable.getInnerText(cs[i]);				break;			case 3:	//TEXT_NODE				s += cs[i].nodeValue;				break;		}	}	return s;}SortableTable.prototype.getValueFromString = function (sText, sType) {	switch (sType) {		case "Number":		sText = sText.replace(/[\.,]/g,'');					return Number(sText);		case "CaseInsensitiveString":			return sText.toUpperCase();		case "Date":			var parts = sText.split("-");			var d = new Date(0);			d.setDate(parts[0]);			d.setMonth(parts[1] - 1);			d.setFullYear(parts[2]);			return d.valueOf();		case "Nothing":			sText = "";			return sText;	}	return sText;};SortableTable.prototype.getSortFunction = function (sType, nColumn) {	return function compare(n1, n2) {		if (n1.value < n2.value)			return -1;		if (n2.value < n1.value)			return 1;		return 0;	};};SortableTable.prototype.destroy = function () {	this.uninitHeader();	var win = this.document.parentWindow;	if (win && typeof win.detachEvent != "undefined") {	// only IE needs this		win.detachEvent("onunload", this._onunload);	}	this._onunload = null;	this.element = null;	this.tHead = null;	this.tBody = null;	this.document = null;	this._headerOnclick = null;	this.sortTypes = null;	this._asyncsort = null;	this.onsort = null;};// VIEW =====var httpObj;	var lastrecord = 0;var startval = 0;var endval = 0;var sortcol = 0;var sortdir = 0;var columnHeaders = new Array();var _viewCount = 30;function loader() {  adjustViewHeight();  getViewCount();  vwAddHoverRows();  vwSetHeaderLinks();  getSortData();}/* set links to header cell onclick */function vwSetHeaderLinks() {  var objDiv = document.getElementById( "view" );  if ( objDiv )    var objTbl = objDiv.getElementsByTagName( "table" )[0];      if ( objTbl )    var objHdr =  objTbl.getElementsByTagName( "tr" )[0];    if ( objHdr )    var vCells = objHdr.getElementsByTagName("th");    if ( vCells )   for ( var i = 0; i < vCells.length; i++ ) {     vCells[i].onclick = function() { vwGoTo(getFirstLink(this));};     if ( getFirstLink(vCells[i]) != "" ) {        vCells[i].style.cursor = "pointer";        vCells[i].title = "Click to Sort by " + vCells[i].firstChild.nodeValue;     }     columnHeaders[ columnHeaders.length ] = vCells[i].firstChild.nodeValue;    }}/* add hover effect to table rows */function vwAddHoverRows() {  var objDiv = document.getElementById( "view" );  var objTbl = objDiv.getElementsByTagName( "table" )[0];  if ( ! objTbl ) return;  var vRows =  objTbl.getElementsByTagName( "tr" );  /* start at 1 to skip the header row */  for ( var i = 1; i < vRows.length; i++ ) {    vRows[i].style.cursor = "pointer";    vRows[i].onmouseover = function() { this.style.backgroundColor = "#ffffaa"; };    vRows[i].onmouseout = function() { this.style.backgroundColor = ""; };    vRows[i].onclick = function() { vwGoTo(getFirstLink(this));}        // ensure that all cells have some content to keep a bottom border    var vCells = vRows[i].getElementsByTagName( "td" );    for ( var j = 0; j < vCells.length; j++ ) {      if ( vCells[j].innerHTML == "" ) vCells[j].innerHTML = "&nbsp;";    }      }  }/* return the first link in a node */function getFirstLink(o) {   var vLinks = o.getElementsByTagName( "a" );  var r = "";  for ( var i = 0; i < vLinks.length; i++ ) {    if ( vLinks[i].href != "" )      var lnk = vLinks[i].href;     if ( o.tagName != "TH" ) {       if (BrowserDetect.browser != "Explorer" ) {         // use ff links         var a = lnk.split("/");         a[a.length-2] = "ff";         lnk = a.join("/");       } else {          // use ie links                var a = lnk.split("/");         a[a.length-2] = "ie";         lnk = a.join("/");                }     }        return lnk;  }  return r;}/* "first page" functionality */function startView() { var srch = "!OpenView&Start=1&Count=" + _viewCount;  if ( getParam( "ResortAscending" ) ) {   srch += "&ResortAscending=" + getParam("ResortAscending" );   } if ( getParam( "ResortDescending" ) ) {   srch += "&ResortDescending=" + getParam("ResortDescending" );   }  if ( getParam( "RestrictToCategory" ) ) {    srch += "&RestrictToCategory=" + getParam("RestrictToCategory" );   } location.search = srch;}/* "last page" functionality */function endView() { var srch = "";  if ( location.search.toLowerCase().indexOf( "endview" ) == -1 ) {   if ( getParam( "ResortAscending" ) ) {     srch += "&ResortAscending=" + getParam("ResortAscending" );     }   if ( getParam( "ResortDescending" ) ) {     srch += "&ResortDescending=" + getParam("ResortDescending" );     }     if ( getParam( "RestrictToCategory" ) ) {     srch += "&RestrictToCategory=" + getParam("RestrictToCategory" );     }    location.search = "!OpenView" + srch + "&EndView&Count=" + _viewCount; } else {   alert( "You are already on the last page." ); }}/* set the view height to fit in whatever screen height the user has */function adjustViewHeight() {  var headerHeight = 120;  document.getElementById( "view" ).style.height = (document.body.clientHeight - ( headerHeight) );  window.onresize = function() { adjustViewHeight(); };}/* build the url and get XML from ?ReadViewEntries for current view state */function getViewCount() {  var frm = document.forms[0];  var args = location.href.toLowerCase().split("!openview" )[1];  var url = location.href.toLowerCase().split(".nsf")[0] + ".nsf/" + vw + "/!ReadViewEntries" + args;  var s = doXMLHTTPGet( url ); }/* perform the XMLHTTP GET Request and update the text when retrieved */function doXMLHTTPGet(url){  var returnData = null;  if (window.XMLHttpRequest)	 {     //We are in a non-IE browser     httpObj = new XMLHttpRequest()       } else if (window.ActiveXObject) {     //We are in IE     httpObj = new ActiveXObject("Microsoft.XMLHTTP")  }  //Return the XML document when it has finished loading  httpObj.onreadystatechange= function()  {	 if (httpObj.readyState==4)  {  	    var dc = document.getElementById( "docCount" );  	    var pc = document.getElementById( "pageCount" );  	             if (httpObj.status==200)  {		     	       var root = httpObj.responseXML.documentElement;   	       var results = root.getElementsByTagName("viewentry");            var viewTotalDocs = parseInt(root.attributes[0].value, 10);            var docsPerPage = _viewCount;            var totalPages = Math.floor(viewTotalDocs/docsPerPage);            if ( totalPages == 0 ) totalPages = 1;                        if ( results[0] ) {              var thisPage = (results[0].attributes[0].value - 0 )/docsPerPage;                          if ( totalPages < ( Math.floor(thisPage) + 1 ) ) {                pc.innerHTML = "Page " + ( Math.floor(thisPage) ) + " of " + Math.floor(totalPages);              } else {                pc.innerHTML = "Page " + ( Math.floor(thisPage) + 1) + " of " + Math.floor(totalPages);                          }              		    startval = results[0].attributes[0].value;		    endval = results[results.length - 1].attributes[0].value; 		  		    if ( startval > endval ) {                var tmp = startval;                startval = endval;                endval = tmp;		    }                        		    dc.innerHTML = startval + " to " + endval + " of " + viewTotalDocs + " records";		  		    lastrecord = viewTotalDocs;		  } else {		    dc.innerHTML = "No records (of " + viewTotalDocs + ")";		  }	    } else {            dc.innerHTML = "Problem retrieving data:" + httpObj.statusText;	    }	 }		 		    }  //Request the XML document  httpObj.open("GET",url,true)  httpObj.send(null)}/* function to get querystring parameters */q = location.href; getParam = function(arg) {  if (q.indexOf(arg) >= 0) {    var pntr = q.indexOf(arg) + arg.length + 1;    if (q.indexOf("&", pntr) >= 0) {      return q.substring(pntr, q.indexOf("&", pntr));    } else {        return q.substring(pntr, q.length);    }  } else {  return null;  }}/* open to a url */function vwGoTo(s) { if ( s != "" )  location.href = s;}/* determine which column is sorted and in what direction */function getSortData() { if ( getParam( "ResortAscending" ) ) {   sortdir = 1;   sortcol = getParam( "ResortAscending" ); } if ( getParam( "ResortDescending" ) ) {   sortdir = -1;   sortcol = getParam( "ResortDescending" ); } }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: "OmniWeb",			versionSearch: "OmniWeb/",			identity: "OmniWeb"		},		{			string: navigator.vendor,			subString: "Apple",			identity: "Safari"		},		{			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();q = location.search;getParam = function(arg) {if (q.indexOf(arg) >= 0) {var pntr = q.indexOf(arg) + arg.length + 1;if (q.indexOf("&", pntr) >= 0) {return q.substring(pntr, q.indexOf("&", pntr));} else {return q.substring(pntr, q.length);}} else {return null;}}// ===== Events =======// I know this part is dirty, yet it is needed to check for the visibility tag in different browsers.var explorer;var netscape4;var netscape6;var theDOM, theSuffix, hiddenKeyword, dhtml;if (document.all) {explorer = true;}else if (document.layers) {netscape4 = true;} else {netscape6 = true;}if(explorer){   theDOM = 'document.all';   theSuffix = '.style';   hiddenKeyword = 'hidden';   dhtml = true;}if(netscape4){   theDOM = 'document';   theSuffix = '';   hiddenKeyword = 'hide';   dhtml = true;}if (netscape6) {  theDOM = "document.getElementsByTagName('*')";  theSuffix = ".style";  hiddenKeyword = "hidden";  dhtml = true;}function CheckRequiredFields(f) {   var sFieldValue = "";   var iIndex = 0;   var iElement = 0;   var iRadio = 0;   var iCheck = 0;      // Retrieve the list of field names and labels   var aFieldList = f.valFieldList.value.split(",");      // Loop through the list of fields   for (iIndex = 0; iIndex < aFieldList.length; iIndex++) {            // Inform the user of what's happening      window.status = "Validating field " + aFieldList[iIndex + 1] + " ...";            // Loop through all elements in the form to find the field      for (iElement = 0; iElement < f.elements.length; iElement++) {         // Check whether the selected element is a required field         if (f.elements[iElement].name == aFieldList[iIndex]) {            // Check whether the field contains a value or not            switch (f.elements[iElement].type) {               // Text fields               case "text" :                  sFieldValue = f.elements[iElement].value;                  break;               // Text areas               case "textarea" :                  sFieldValue = f.elements[iElement].value;                  break;               // Listboxes               case "select-one" :                  if (f.elements[iElement].selectedIndex == 0) {                     sFieldValue = "";                  } else {                     sFieldValue = String(f.elements[iElement].selectedIndex);                  }                  break;               // Checkboxes               case "checkbox" :                  for (iCheck = 0; iCheck < f.elements[aFieldList[iIndex]].length; iCheck++) {                     if (f.elements[iElement + iCheck].checked == false) {                        sFieldValue = "";                     } else {                        sFieldValue = String(f.elements[iElement + iCheck].value);                        break;                     }                  }                  break;               // Radiobuttons               case "radio" :                  for (iRadio = 0; iRadio < f.elements[aFieldList[iIndex]].length; iRadio++) {                     if (f.elements[iElement + iRadio].checked == false) {                        sFieldValue = "";                     } else {                        sFieldValue = String(f.elements[iElement + iRadio].value);                        break;                     }                  }                  break;            }            // Warn the user that the selected field is a required field            if (sFieldValue == "") {               alert(aFieldList[iIndex+1] + " is a required field. Make sure that " +               aFieldList[iIndex+1] + " and all other required fields are filled out before saving the document.");               f.elements[iElement].focus();               return false;            }            break;         }      }      iIndex++;   }   return true;}function QuerySave(f){return CheckRequiredFields(f);}function insertEmoticon(number){	//insert emoticon in comments field	var current = document.frmWComment.comBody.value;	this.number = number;	document.frmWComment.comBody.value = current + " !em" + number + "! ";	document.frmWComment.comBody.focus();}// this function is to make the drop-down menu work in IEstartList = function() {	if (document.all&&document.getElementById) {		navRoot = document.getElementById("menu");		if (navRoot!=null) {		for (i=0; i<navRoot.childNodes.length; i++) {			node = navRoot.childNodes[i];			if (node.nodeName=="LI") {				node.onmouseover=function() {					this.className+=" over";				}				node.onmouseout=function() {					this.className=this.className.replace(" over", "");				}			}		}	}	}}window.onload=startList;// function to load an email address, gives basic protecting from spammers. Provided by codestore.netfunction mailto(name, domain) {  location.href = "mailto:" + name + "@" + domain; } function writeSearchResults(){      for(var i=0;i<a.length;i++){       document.write(a[i] + "\n");    }}	function getDisplay(theObject){	var theObjectReference = eval(theDOM + '.' + theObject + theSuffix);	if(theObjectReference.visibility == hiddenKeyword){     	return false;    	} else {		return true;		}	}	function hideObject(theObject){	var theObjectReference = eval(theDOM + '.' + theObject + theSuffix);	theObjectReference.visibility = hiddenKeyword;	}function loadHash() {	// generate random number in our battle to fight comment spam	return ran_number=Math.floor(Math.random()*1000);}function maxArray( arr ) {	// this function calculates the maximum value in the associative array	var max = 0;	for(var i in arr){  	    if (arr[i] > max)  	    		max = arr[i];  	}  	return max;}function minArray( arr ) {	// this function calculates the minimum value in the associative array	var min;	var count = 0;	for(var i in arr){		// initialize minimum value with first value of associative array		if (count==0)			min = arr[i];		if (arr[i] < min)  	    		min = arr[i];  	    	count++;  	}  	return min;}function drawTagCloud(map, maxStyle) {	// this function draws the tag cloud using the associative javascript array generated by the Notes view	// calculate the maximum entries in the cloud. if not found, no tags are found	var maxEntries = maxArray(map);	if (maxEntries==0) {		document.write('No tags found');		return false;	}		//	calculate the minimum entries in the cloud	var minEntries = minArray(map);		// calculate the range	var range = maxEntries - minEntries;	if (range <= 0)		range = 1; 		// get handle on div container to write tag cloud into	var tagcloud = document.getElementById('tagcloud');		// temp variable to store all tags in 	var tagsresult = '';		// loop through the tag map to draw each tag.	for(var tag in map){		tagsresult = tagsresult + calculateTag(tag, map[tag], minEntries, maxEntries, maxStyle);  	}  	  	// finally, write the full tags result to the inner html of the tagcloud div  	tagcloud.innerHTML = tagsresult;	var tagcloud = document.getElementById('tagcloud');  	tagcloud.style.innerHTML = "width:200px;"  	}function calculateTag(tag, count, min, max, maxStyle) {  // this function renders a tag line. first determine  // the size tag to use for this tag count  sizeTag = Math.round((((maxStyle-1)/(max-min))*count) +(1*max-maxStyle*min)/(max-min));    // return link to write to page  return '&nbsp;<a href="categories?open&id=' + tag + '" class="tag' + sizeTag + '">' + tag + ' </a>&nbsp;';}