  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // Browser & URL Support
  //
  function openURL(sURL, W, H) {
    _popup = window.open(sURL,'popupwin', 'width='+W+',height='+H+',toolbar=0,resizable=1')
  }

  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // Browser Selection
  //
  //var isNN = document.layers ? true : false;
  //var isIE = document.all ? true : false;

  var isIE = false;
  var browserSniff = {
    byName: function() {
                  var rxp = /internet explorer/i;
                  if (rxp.exec(navigator.appName)) return true;
                  else return false;
                },
    byLayers: function() {
                  return document.all ? true : false;
                },

    Init: function() {
                  var trybyName = this.byName();
                  var trybyLayers = this.byLayers();
                  if (trybyName && trybyLayers) { isIE = true; return true; }
                }
  };
  browserSniff.Init();


  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // Page/Document Details & Statistics
  //
  var hzScroll;
  var vtScroll;

  function updateScroll()
  {
    if (window.innerWidth) {                                                         // All browsers but Internet Explorer
      hzScroll = window.pageXOffset;
      vtScroll = window.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.clientWidth) {     // These are for Internet Explorer 6 when a DOCTYPE is defined
      hzScroll = document.documentElement.scrollLeft;
      vtScroll = document.documentElement.scrollTop;
    }
    else if (document.body.clientWidth) {                                            // These are for Internet Explorer 5/6 without a DOCTYPE
      hzScroll = document.body.scrollLeft;
      vtScroll = document.body.scrollTop;
    }
  }


  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // Element Utilities
  //
  function elemGet(eid) {
    return document.getElementById(eid);
  }

  // quick getElement reference: returns elements array of all elements matching.... ??
  //
  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;
  }

/*
  function $() {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i++) {
      var element = arguments[i];
      if (typeof element == 'string') {
        element = getElementByIdCompat(element);
        alert('type is string...classname is ' + element.className);
      }
      if (arguments.length == 1) {
        return element;
      }
      elements.push(element);
    }
    return elements;
  }

  function getElementByIdCompat(name) {
    if (document.getElementById) {
      return document.getElementById(name);
    } else if (document.all) {
             return document.all[name];
           } else if (document.layers) {
                    var theobj = {};
                    theobj = document.layers[name];
                    theobj.style = document.layers[name];
                    return theobj;
                  }
  }
*/

  function elemToggleShow(eid) {
    var el = document.getElementById(eid);
    el.style.display = (el.style.display != 'none' ? 'none' : '' );
  }

  function elemSetDisplay(eid, show) {
    var elem = document.getElementById(eid);
    if (! show) { elem.style.display = "none"; }
    else { elem.style.display = show; } // = '';
  }

  function elemSetInnerHTML(eid, data) {
    var elem = document.getElementById(eid);
    elem.innerHTML = data;
  }

  function elemAppendInnerHTML(eid, data) {
    var elem = document.getElementById(eid);
    elem.innerHTML = elem.innerHTML + data;
  }

  function getElementsByClass(searchClass, node, tag) {
    var classElements = new Array();
    if ( node == null ) node = document;
    if ( tag == null )  tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
    for (i = 0, j = 0; i < elsLen; i++) {
      if ( pattern.test(els[i].className) ) {
        classElements[j] = els[i];
        j++;
      }
    }
    return classElements;
  }

  function elemAddClass(elem, classname) {
    elemRemoveClass(elem, classname);
    elem.className = (elem.className + " " + classname).trim();
  }

  function elemRemoveClass(elem, classname) {
    elem.className = elem.className.replace(classname, "").trim();
  }

  function limitText(idLimited, idCounter, cLimit, sMsg, bMsgLast) {
    var defMsg = 'Remaining characters: ';
    var eLimited = elemGet(idLimited);
    var eCounter = elemGet(idCounter);
    var curcount = eLimited.value.length;                           // Grab the current count
    if (curcount > cLimit) {                                        // this key press puts us over
      eLimited.value = eLimited.value.substring(0, cLimit);
    } else {
      if (!sMsg) sMsg = defMsg;
      if (bMsgLast) elemSetInnerHTML(idCounter, (cLimit - curcount) + sMsg);
      else elemSetInnerHTML(idCounter, sMsg + (cLimit - curcount));
    }
  }

/*
Luckily, there is, a relatively simple fix for IE’s problem: instead of simply setting the value of an attribute based on its name, we can loop through all existing attributes until we find the one that we’re looking for and then set its value based on its numeric index in the node’s attributes[] array. The following snippet of JavaScript will get the job done:

var className = 'labrat';
var p3 = document.createElement('p');
p3.appendChild(
  document.createTextNode(
    "And guess what. It works!"
  )
);

// if the node's class already exists
// then replace its value
if (p3.getAttributeNode("class")) {
  for (var i = 0; i < p3.attributes.length; i++) {
    var attrName = p3.attributes[i].name.toUpperCase();
    if (attrName == 'CLASS') {
      p3.attributes[i].value = className;
    }
  }
// otherwise create a new attribute
} else {
  p3.setAttribute("class", className);
}
*/


/*
elemAddRolloverByID
// suffers from having to gather ALL imgs on a page each time to set ONE rollover

function addRollover(obj, url) {
(new Image).src = url
obj.onmouseover = function () {
var lastSrc = this.src
this.src = url
this.onmouseout = function() { this.src = lastSrc }
}
}
allImgs = document.getElementsByTagName(’img’)
for(i=allImgs.length-1; i>=0; i–) {
value = allImgs[i].attributes.rollover ? allImgs[i].attributes.rollover.value : allImgs[i].rollover || 0
if (value) addRollover(allImgs[i], value)
}
*/


  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // String, Filename, Pathname Utilities
  //
  function isEmpty(aStr) {
    if ((aStr.length == 0) || (aStr == "") || (aStr == null)) return true;
    else return false;
  }

  function isEmptyFormField(aFld) {
    var re = /^\s{1,}$/g;                             //match any white space including space, tab, form-feed, etc.
    if ((aFld.length == 0) || (aFld == "") || (aFld == null) || ((aFld.search(re)) > -1)) { return true; }
    else { return false; }
  }


  function strConvertSpecialChars(ins) {            // convert (&, +, =) to string equivs. Needed so URL encoded POST won't choke.
    ins = ins.replace(/&/g,"**am**");
    ins = ins.replace(/=/g,"**eq**");
    ins = ins.replace(/\+/g,"**pl**");
    return ins;
  }

  function basename(path, suffix) {
    var b = path.replace(/^.*[\/\\]/g, '');
    if (typeof(suffix) == 'string' && b.substr(b.length-suffix.length) == suffix) {
        b = b.substr(0, b.length-suffix.length);
    }
    return b;
  }

  function Extract_FileExtension (value) {
    return value.substring(value.lastIndexOf('.') + 1,value.length);
  }

  function ScopeTest() {
    return "this is a test for scope";
  }

  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // Array Support, Extensions & Prototypes
  //
  // Arrays used with string indices are not actually implemented as arrays but as objects
  //if (!Array.prototype.forEach) {
/*    Object.prototype.forEach = function(callback) {
                                var len = this.length;
                                if (typeof fun != "function") throw new TypeError();
                                var thisp = arguments[1];
                                for (var i = 0; i < len; i++ {
                                  if (i in this) callback.call(thisp, this[i], i, this);
                                }
                              };
  //}

  Was trying to do this,

       // var printArray = function (x, idx) { elemAppendInnerHTML('dout', idx + ' = ' + x + '<br />'); }
//    frm_Data.forEach(printArray);


  */
/*
Array.prototype.inArray = function (value) {
  var i;
  for (i=0; i < this.length; i++) {
    if (this[i] === value) {
      return true;
    }
  }
  return false;
};
*/


  //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  // type & details routines
  //
  function isArray( mixed_var ) {
    return ( mixed_var instanceof Array );
  }

