var gWindowCounter = Math.round(Math.random() * 10000);
var winModalWindow

function GetRWID(xiSpan)
{
  if (IsIe())
  {
    return xiSpan.RWID;
  }
  else
  {
    var lRWID = xiSpan.attributes["RWID"];
    return lRWID != null ? lRWID.value : null;
  }
}
function ShowSectionsByRWID(xiControlToCheck, xiValueToHide, xiRWIDToHide)
{
  var lDropDown      = GetElementInDocument(xiControlToCheck);
  
  var lSpans = document.getElementsByTagName("span");
  for (var j = 0; j < lSpans.length; j++)
  {      
    if (GetRWID(lSpans[j]) == xiRWIDToHide)
    {
      if (lDropDown.value == xiValueToHide)
      {                
        lSpans[j].style.display = 'none';
      }
      else
      {
        lSpans[j].style.display = '';
      }
    }
  }
}  

function ShowSectionsByRWID(xiRWIDToHide, xiShow)
{  
  var lSpans = document.getElementsByTagName("span");
  for (var j = 0; j < lSpans.length; j++)
  {      
    if (GetRWID(lSpans[j]) == xiRWIDToHide)
    {
      if (!xiShow)
      {                
        lSpans[j].style.display = 'none';
      }
      else
      {
        lSpans[j].style.display = '';
      }
    }
  }
}  

function FindControlByRWID(xiTagName, xiRWID)
{
  var lControls = document.getElementsByTagName(xiTagName);
  for (var j = 0; j < lControls.length; j++)
  {      
    if (GetRWID(lControls[j]) == xiRWID)
    {
      return lControls[j];
    }
  }
  
  return null;
}

function DisableControlsByRWID(xiControlToCheck, xiValueToHide, xiRWIDToHide, xiValueWhenDisabled)
{
  var lDropDown      = GetElementInDocument(xiControlToCheck);
  
  var lSpans = document.getElementsByTagName("span"); 
  for (var j = 0; j < lSpans.length; j++)
  {      
    if (GetRWID(lSpans[j]) == xiRWIDToHide)
    {
      var lInputs = lSpans[j].getElementsByTagName("input");
    
      for (var i = 0; i < lInputs.length; i++)
      {    
        if (lDropDown.value == xiValueToHide)
        {                  
          lInputs[i].value    = xiValueWhenDisabled;
          lInputs[i].disabled = true;
        }
        else
        {
          lInputs[i].disabled = false;
        }
      }
    }
  }
}                     

//<%-- Reads the value from xiControl, and sets the visibility of xiControlToHide based on it --%>
function ShowSection(xiControl, xiValueToHide, xiControlToHide)
{
  var lDropDown      = GetElementInDocument(xiControl);
  var lControlToHide = GetElementInDocument(xiControlToHide);
  if (lControlToHide != null)
  {
    if (lDropDown.value == xiValueToHide)
    {
      lControlToHide.style.display = "none";
    }
    else
    {
      lControlToHide.style.display = "";
    }
  }
}

//<%-- toggles the visibility of a control, optionally caching the value in a hidden input field to preserve it across post-backs --%>
function ToggleVisibility(xiControl, xiCache)
{
  var lControl = GetElementInDocument(xiControl);
  var lCache = FindControlByRWID("input", xiCache);
  if (lControl != null)
  {
    if (lControl.style.display == "none")
    {
      lControl.style.display = "";
      if (lCache)
      {
        lCache.value = "true";
      }
    }
    else
    {
      lControl.style.display = "none";
      if (lCache)
      {
        lCache.value = "false";
      }
    }
  }
}


//<%-- restores the cached visibility information (see ToggleVisibility above) --%>
function RestoreVisibility(xiControl, xiCache, xiReversePolarity)
{
  var lControl = GetElementInDocument(xiControl);
  var lCache = FindControlByRWID("input", xiCache);
  if (lControl && lCache)
  {
    if (lCache.value == "true")
    {
      lControl.style.display = xiReversePolarity ? "none" : "";
    }
    else
    {
      lControl.style.display = xiReversePolarity ? "" : "none";
    }
  }
}

function SWTRound(xiValue, xiDecimalPlaces)
{
  if (isNaN(xiValue)) return xiValue;
  
  var lIntString;
  if (xiDecimalPlaces > 0)
  {
    lIntString = String(Math.round(xiValue * Math.pow(10, xiDecimalPlaces)));
  }
  else
  {
    lIntString = String(Math.round(xiValue));
  }
    
  var lPointPos  = lIntString.length - xiDecimalPlaces;
  
  var lRet;
  if (lPointPos <= 0)
  {
    lRet = "0.";
    for (var i = 0; i < -lPointPos; i++)
    {
      lRet += "0";
    }
    lRet += lIntString;
  }
  else if (lPointPos < lIntString.length)
  {
    lRet =  lIntString.substring(0, lPointPos);
    lRet += ".";
    lRet += lIntString.substring(lPointPos, lIntString.length);
  }
  else
  {
    lRet = lIntString;
  }
  
  return lRet;
}

function GetSpansByName(xiName)
{
  var lArray = new Array();

  if (!IsIe())
  {
    var lElements = document.getElementsByName(xiName);
    for (var i = 0; i < lElements.length; i++)
    {
      lArray.push(lElements[i]);
    }
  }
  else
  {
    var lElements = document.getElementsByTagName("span");
    for (var i = 0; i < lElements.length; i++)
    {
      if (lElements[i].name == xiName)
      {
        lArray.push(lElements[i]);
      }
    }
  }
  
  return lArray;
}

function ShowPicture(xiUrl, xiCaption, xiWidth, xiHeight)
{              
  /* We use a document.write to write HTML to a new window. This ensures that 
      we have no unnecessary border around the image */
      
  var lLeft = 100;
  var lTop  = 100;
  
  if(screen)
  {
    lLeft = (screen.availWidth - xiWidth) / 2;
    lTop  = (screen.availHeight - xiHeight) / 2;
  }
      
  gWindowCounter++;
  var windowName = "Picture" + gWindowCounter;
  var win = window.open("", windowName, "width=" + xiWidth + ",height=" + xiHeight + ",left=" + lLeft + ",top=" + lTop + ",screenX=" + lLeft + ",screenY=" + lTop + ",location=no,status=no,toolbar=no,menubar=no,scrollbars=no,resizable=no");    
  win.document.write('<html><head><title>' + xiCaption + '</title></head><body style="margin: 0px 0px 0px 0px;"><img src="' + xiUrl + '"></body></html>');
  return;
}

function OpenPopupWindow(xiUrl, xiWidth, xiHeight)
{
  var lLeft = 100;
  var lTop  = 100;
  
  if(screen)
  {
    lLeft = (screen.availWidth - xiWidth) / 2;
    lTop  = (screen.availHeight - xiHeight) / 2;
  }

  window.open(xiUrl,'',"width=" + xiWidth + ",height=" + xiHeight + ",left=" + lLeft + ",top=" + lTop + ",location=no,status=no,toolbar=no,menubar=no,scrollbars,resizable");
      
  return;
}

function ShowUrl(xiUrl, xiCaption, xiWidth, xiHeight, xiAllowScroll)
{
  var lLeft = 100;
  var lTop  = 100;
  
  if(screen)
  {
    lLeft = (screen.availWidth - xiWidth) / 2;
    lTop  = (screen.availHeight - xiHeight) / 2;
  }
  
  gWindowCounter++;
  var lAllowScroll = xiAllowScroll ? "yes" : "no";
  var windowName = "Popup" + gWindowCounter;
  var win = window.open(xiUrl, windowName, "width=" + xiWidth + ",height=" + xiHeight + ",left=" + lLeft + ",top=" + lTop + ",screenX=" + lLeft + ",screenY=" + lTop + ",location=no,status=no,toolbar=no,menubar=no,scrollbars=" + lAllowScroll + ",resizable=no");
  return;
}

// Returns an element from the document given its name
// For modern browses this uses getElementById; 
//    for older IEs it uses document.all; 
//    for older NS it uses document.layers (although this may not always work in the same way...)
function GetElementInDocument(xiName)
{    
  if (IsModern())
  {
    var lRet = document.getElementById(xiName);
    if (lRet == null)
    {
      var lElements = document.getElementsByName(xiName);
      if (lElements.length > 0)
      {
        lRet = lElements[0];
      }
    }
    return lRet;
  }
  else if (IsIe())
  {
    return document.all[xiName];
  }
  else
  {
    return document.layers[xiName];
  }
}

function IsModern()
{
  if (document.getElementById)
  {
    return true;
  }
  else
  {
    return false;
  }
}

function IsIe()
{
  var ie = (document.all);
  if (ie)
  {
    return true;
  }
  else
  {
    return false;
  }
}  

function IsMac()
{
  if (navigator.platform.toLowerCase().indexOf("mac") != -1)
  {
    return true;
  }
  else
  {
    return false;
  }
}

function GetParent(xiChild)
{
  if (IsIe())
  {
    return xiChild.parentElement;
  }
  else
  {
    return xiChild.parentNode;
  }
}

function SetControlFocus(xiControlName)
{
  var lControl = null;
  if (xiControlName != null)
  {
    lControl = GetElementInDocument(xiControlName);
  }
  else
  {
    if (document.forms[0] != null)
    {      
      for (var i = 0; i < document.forms[0].elements.length; i++)
      {
        var lElement = document.forms[0].elements[i];        
        var lTagName = lElement.tagName;
        var lType    = lElement.type;
        if (lTagName == "INPUT")
        {
          if (lType != "text" && lType != "checkbox")
          {
            continue;
          }          
        }
        else
        {
          continue;
        }
                
        var lStyle = lElement.style;
        if (lStyle != null)
        {                
          if (lStyle.display    == "none" ||
              lStyle.visibility == "hidden")
          {
            continue;
          }
        }
        
        if (lElement.disabled == true)     
        {
          continue;
        }                
        
        // Work out the rightmost and bottommost bits of the control
        var lParent = lElement;
        var lRight  = lElement.clientWidth;
        var lBottom = lElement.clientHeight;
        
        // Right / Bottom = 0 at this stage means we're invisible
        if (lRight == 0 || lBottom == 0)
        {
          continue;
        }
        
        while (lParent != null)
        {
          lRight  += lParent.offsetLeft;
          lBottom += lParent.offsetTop;
          lParent = lParent.offsetParent;
        }
        
        // If we're not visible on the screen then continue
        var lBody = GetBodyElement();
        if (lRight > lBody.clientWidth || lBottom > lBody.clientHeight)
        {
          continue;
        }
        
        lControl = lElement;
        break;        
      }
    }    
  }
  if( lControl != null )
  {
    try
    {  
      lControl.focus();
      // IE hack to make sure the focus goes to the end of textbox controls
      if (IsIe() && lControl.type == "text")
      {
        lControl.value = lControl.value;
        lControl.focus();
      }
    }  
    catch (Exception)
    {
    }
  }
}

function GetBodyElement()
{
  return (document.compatMode=="CSS1Compat")? document.documentElement : document.body;  
}

function ChangeControlStateRecursive(xiControl, xiTagName, xiEnable)
{  
  if (xiControl.tagName == xiTagName)
  {
    xiControl.disabled = !xiEnable;
    
    if (!xiEnable && xiControl.tagName == "A")
    { /*<%-- Anchors cannot be disabled just by setting their disabled property--%>*/
      xiControl.onclick = function() { return false; };
    }
  }
  else
  {
    for (var i = 0; i < xiControl.children.length; i++)
    {  
      ChangeControlStateRecursive(xiControl.children[i], xiTagName, xiEnable);
    }
  }
}

function ChangeControlStateRecursiveByType(xiControl, xiControlType, xiEnable)
{  
  if (IsControlOfType(xiControl, xiControlType))
  {
    xiControl.disabled = !xiEnable;
  }
  else
  {
    for (var i = 0; i < xiControl.children.length; i++)
    {  
      ChangeControlStateRecursive(xiControl.children[i], xiControlType, xiEnable);
    }
  }
}

// Copies all the form elements contained within one control to another
// control. It's assumed that the form elements within the two controls
// are of the same type and in the same order. If that's not the case then
// the behaviour of this function is indeterminate
function CopyControlData(xiSourceControl, xiDestinationControl)
{    
  var lData                     = new Array();
  var lSourceElementCount       = 0;
  var lDestinationElementCount  = 0;
  
  var lSourceControl      = ResolveControl(xiSourceControl);
  var lDestinationControl = ResolveControl(xiDestinationControl);    
  
  var lSourceElements = GetChildFormElements(lSourceControl);
  for (var i = 0; i < lSourceElements.length; i++)  
  {
    var lSourceElement = lSourceElements[i];
    if (lSourceElement.type == "checkbox")
    {
      lData[lSourceElementCount] = lSourceElement.checked;
    }
    else if (lSourceElement.value)
    {
      lData[lSourceElementCount] = lSourceElement.value;
    }
    lSourceElementCount++;
  }
  
  var lDestinationElements = GetChildFormElements(lDestinationControl);
  for (var i = 0; i < Math.min(lDestinationElements.length, lSourceElements.length); i++)  
  {
    var lDestinationElement = lDestinationElements[i];
    if (lDestinationElement.type == "checkbox")
    {
      lDestinationElement.checked = lData[lDestinationElementCount];
    }
    else if (lData[lDestinationElementCount])
    {          
      lDestinationElement.value = lData[lDestinationElementCount];
    }
    else if (lDestinationElement.value)
    {
      lDestinationElement.value = "";
    }
    lDestinationElementCount++;
  }
}

function IsControlEmpty(xiControl)
{
  var lControl = ResolveControl(xiControl);  
  
  var lChildElements = GetChildFormElements(xiControl);
  for (i = 0; i < lChildElements.length; i++) 
  {        
    var lElement = lChildElements[i]
    if (lElement.tagName == "SELECT")
    {
      var lOption = lElement.options[lElement.selectedIndex];
      if (lOption.value != "" && lOption.innerText != "")
      {
        return false;
      }
    }
    else if (lElement.tagName == "INPUT" && lElement.type == "submit")
    {
      // Do nothing
    }
    else if (lElement.tagName == "INPUT" && lElement.type == "checkbox" && !lElement.checked)
    {
      // Do nothing
    }
    else if (lElement.value != "")
    {
      return false;
    }
  }
  
  return true;
}

// Finds a child control of a given type
function FindChildControl(xiParentControl, xiType, xiIndex)
{
  var lArray      = new Array();
  xiParentControl = ResolveControl(xiParentControl); 
  FindChildControlRecursive(lArray, xiParentControl, xiType, xiIndex);
  if (lArray.length <= xiIndex)
  {
    return null;
  }
  return lArray[xiIndex];
}

// Helper used by FindChildControl
function FindChildControlRecursive(xiArray, xiParentControl, xiType, xiIndex)
{
  for (var i = 0; i < xiParentControl.childNodes.length ; i++)
  {
    var lChildNode = xiParentControl.childNodes[i];
    if (IsControlOfType(lChildNode, xiType))
    {
      xiArray.push(lChildNode);
      if (xiArray.length > xiIndex) return;
    }
    if (lChildNode.childNodes && lChildNode.childNodes.length > 0)
    {
      FindChildControlRecursive(xiArray, lChildNode, xiType);
    }
    if (xiArray.length > xiIndex) return;
  }
}

// Finds a child input control of a given input type
function FindChildInputControl(xiParentControl, xiType, xiIndex)
{
  var lArray      = new Array();
  xiParentControl = ResolveControl(xiParentControl); 
  FindChildInputControlRecursive(lArray, xiParentControl, xiType, xiIndex);
  if (lArray.length <= xiIndex)
  {
    return null;
  }
  return lArray[xiIndex];
}

// Helper used by FindChildInputControl
function FindChildInputControlRecursive(xiArray, xiParentControl, xiType, xiIndex)
{
  for (var i = 0; i < xiParentControl.childNodes.length ; i++)
  {
    var lChildNode = xiParentControl.childNodes[i];
    if (IsControlOfType(lChildNode, "INPUT") && (lChildNode.type == xiType))
    {
      xiArray.push(lChildNode);
      if (xiArray.length > xiIndex) return;
    }
    if (lChildNode.childNodes && lChildNode.childNodes.length > 0)
    {
      FindChildInputControlRecursive(xiArray, lChildNode, xiType);
    }
    if (xiArray.length > xiIndex) return;
  }
}

function FindSummaryRows(xiParentControl)
{
  var lArray = new Array();
  xiParentControl = ResolveControl(xiParentControl); 
  FindSummaryRowsRecursive(lArray, xiParentControl);
  return lArray;
}

function FindSummaryRowsRecursive(xiArray, xiParentControl)
{
  for (var i = 0; i < xiParentControl.childNodes.length; i++)
  {
    var lChildNode = xiParentControl.childNodes[i];
    if (lChildNode.summaryrow)
    {
      xiArray.push(lChildNode);
    }
    if (lChildNode.childNodes && lChildNode.childNodes.length > 0)
    {
      FindSummaryRowsRecursive(xiArray, lChildNode);
    }
  }
}

// Finds a child control by ID
function FindChildControlById(xiParentControl, xiId)
{
  xiParentControl = ResolveControl(xiParentControl); 
  return FindChildControlByIdRecursive(xiParentControl, xiId);
}

// Helper used by FindChildControlById
function FindChildControlByIdRecursive(xiParentControl, xiId)
{
  for (var i = 0; i < xiParentControl.childNodes.length ; i++)
  {
    var lChildNode = xiParentControl.childNodes[i];
    if (lChildNode.id == xiId)
    {
      return lChildNode;
    }
    if (lChildNode.childNodes && lChildNode.childNodes.length > 0)
    {
      lChildNode = FindChildControlByIdRecursive(lChildNode, xiId);
      
      if (lChildNode != null)
      {
        return lChildNode;
      }
    }
  }
  
  return null;
}

function IsControlOfType(xiControl, xiType)
{
  if (xiControl.controlType && xiControl.controlType == xiType)
  {
    return true;
  }
  else if (xiControl.tagName && xiControl.tagName == xiType)
  {
    return true;
  }
  return false;
}

function FindParentByType(control, tagName)
{
  var o = control;
  while ((o != null) && (!IsControlOfType(o, tagName)))
  {
    o = GetParent(o);
  }
  return o;
}

function ResolveControl(xiControl)
{
  if (typeof(xiControl) == "string")
  {
    return GetElementInDocument(xiControl);
  }
  return xiControl;
}

function GetChildFormElements(xiControl)
{
  xiControl = ResolveControl(xiControl);
    
  var lRet = new Array();

  GetChildFormElementsRecursive(xiControl, lRet);  
    
  return lRet;
}

function GetChildFormElementsRecursive(xiControl, xiArray)
{
  for (var i = 0; i < xiControl.childNodes.length; ++i)
  {
    var lControl = xiControl.childNodes[i];
    if (lControl.tagName == "INPUT" || lControl.tagName == "SELECT")
    {
      xiArray.push(lControl);
    }
    
    GetChildFormElementsRecursive(lControl, xiArray);
  }
}

// Retrieves the value of a SWT date picker
// 
// This function is obsolete! Please replace it with a call to DatePicker_GetSelectedDate
function GetDatePickerValue(xiDatePicker)
{
  return DatePicker_GetSelectedDate(xiDatePicker);
}

//=============================================================================
// Javascript for modal dialogs. See 
// http://developer.netscape.com/viewsource/goodman_modal/goodman_modal.html
// for details
//=============================================================================
// Global for browser version branching.
var Nav4 = ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) >= 4));
// One object tracks the current modal dialog opened from this window.
var dialogWin = new Object();

// Generate a modal dialog.
function openDialog(url, width, height, returnFunc, args) {
   if (!dialogWin.win || (dialogWin.win && dialogWin.win.closed)) {
      // Initialize properties of the modal dialog object.
      dialogWin.returnFunc = returnFunc;
      dialogWin.returnedValue = "";
      dialogWin.args = args;
      dialogWin.url = url;
      dialogWin.width = width;
      dialogWin.height = height;
      
      // Keep name unique so Navigator doesn't overwrite an existing dialog.
      dialogWin.name = (new Date()).getSeconds().toString();
      
      // Assemble window attributes and try to center the dialog.
      if (Nav4) {
         // Center on the main window.
         dialogWin.left = window.screenX + ((window.outerWidth - dialogWin.width) / 2);
         dialogWin.top = window.screenY + ((window.outerHeight - dialogWin.height) / 2);
         var attr = "scrollbars,screenX=" + dialogWin.left + ",screenY=" + dialogWin.top + ",resizable=yes,width=" + dialogWin.width + ",height=" + dialogWin.height;
      } else {
         // The best we can do is center in screen.
         dialogWin.left = (screen.width - dialogWin.width) / 2;
         dialogWin.top = (screen.height - dialogWin.height) / 2;
         var attr = "scrollbars,left=" + dialogWin.left + ",top=" + dialogWin.top + ",resizable=yes,width=" + dialogWin.width + ",height=" + dialogWin.height;
      }
      // Generate the dialog and make sure it has focus.
      dialogWin.win=window.open(dialogWin.url, dialogWin.name, attr);
      dialogWin.win.focus();
   } else {
      dialogWin.win.focus();
   }
}

// Event handler to inhibit Navigator form element and Internet Explorer
// link activity when dialog window is active.
function deadend() {
   if (dialogWin.win && !dialogWin.win.closed) {
      dialogWin.win.focus()
      return false
   }
}

// Since links in Internet Explorer 4 can't be disabled, preserve IE link onclick 
// event handlers while they're "disabled." Restore when reenabling the main window.
var IELinkClicks
// Disable form elements and links in all frames for IE.
function disableForms() {
   IELinkClicks = new Array()
   for (var h = 0; h < frames.length; h++) {
      for (var i = 0; i < frames[h].document.forms.length; i++) {
         for (var j = 0; j < frames[h].document.forms[i].elements.length; j++) {
            frames[h].document.forms[i].elements[j].disabled = true
         }
      }
      IELinkClicks[h] = new Array()
      for (i = 0; i < frames[h].document.links.length; i++) {
         IELinkClicks[h][i] = frames[h].document.links[i].onclick
         frames[h].document.links[i].onclick = deadend
      }
   }
}
// Restore IE form elements and links to normal behavior.
function enableForms() {
   for (var h = 0; h < frames.length; h++) {
      for (var i = 0; i < frames[h].document.forms.length; i++) {
         for (var j = 0; j < frames[h].document.forms[i].elements.length; j++) {
            frames[h].document.forms[i].elements[j].disabled = false
         }
      }
      for (i = 0; i < frames[h].document.links.length; i++) {
         frames[h].document.links[i].onclick = IELinkClicks[h][i]
      }
   }
}

// Grab all Navigator events that might get through to form elements while 
// dialog is open. For Internet Explorer, disable form elements.
function blockEvents() {
   if (Nav4) {
      window.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP | Event.FOCUS)
      window.onclick = deadend
   } else {
      disableForms()      
   }
   window.onfocus = checkModal
}
// As dialog closes, restore the main window's original event mechanisms.
function unblockEvents() {
   if (Nav4) {
      window.releaseEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP | Event.FOCUS)
      window.onclick = null
      window.onfocus = null
   } else {
      enableForms()
   }
}

function checkModal() {
   if (dialogWin.win && !dialogWin.win.closed) {
      dialogWin.win.focus()
   }   
}

function dialogReturn(xiReturnData)
{
  if (top.opener && !top.opener.closed) 
  {    
    if (top.opener.dialogWin.returnFunc)
    {
      top.opener.dialogWin.returnFunc(xiReturnData);
    }
  }
  else
  {
    alert("You have closed the main window.\n\nNo action will be taken on the choices in this dialog box.");
  }
  window.close();
}

//=============================================================================
// End Modal Dialog Code
//=============================================================================

//=============================================================================
// Sort out arrays in IE 5.0  
//=============================================================================
function ArrayPush()
{
  this[this.length] = arguments[0];
  return(this.length);
}

if (Array.push == null)
{
  Array.prototype.push = ArrayPush;
}

//=============================================================================
// Registering event handlers with an object (as opposed to replacing them)
// happens differently in IE5 this function will register events either way
// NOTE: this doesn't work for IE5 on the Mac
// See http://www.scottandrew.com/weblog/articles/cbs-events
//=============================================================================
function AddEvent(xiObject, xiEventType, xiFunction)
{
  if (xiObject.addEventListener)
  {
    xiObject.addEventListener(xiEventType, xiFunction, false);
    return true;
  }
  else if (xiObject.attachEvent)
  {
    var lRet = xiObject.attachEvent("on" + xiEventType, xiFunction);
    return lRet;
  }
  else
  {
    return false;
  }
}

function TrimString(xiString)
{
  xiString = xiString.replace( /^\s+/g, "" );// strip leading
  return xiString.replace( /\s+$/g, "" );// strip trailing
}


