<!-- Hide from older browsers
/*******************************************************************************
 *
 * Filename: lib.js
 * Author:   Jeff Duhaime
 *
 * Description: This JavaScript file defines functions used on most pages on
 *              Web Site.
 *
 * Revision History:
 *    For 2003 history, see the files in the revs/ directory
 *
 *           JS
 *   Date   SLOC Eng Description
 * -------- ---- --- ----------------------------------------------------
 * 
 ******************************************************************************/

/*******************************************************************************
 *                               Global Variables
 *
 * g_wm        - "IDS SEC Web Team"
 * g_wm_em     - "selwebteam@raytheon.com"
 * g_co        - Content Owner of the page
 * g_co_em     - Content Owner's E-Mail
 * dirNames    - Array of directories to link to in the top navigation bar.
 * arPath      - Path to the current page, split into an array.  For example,
 *               if the path is /pal/project/qpm_sqm/index.shtml,
 *               arPath is ["pal", "project", "qpm_sqm", "index.shtml"]
 * level1      - The first entry in arPath.  This may be changed by the topNav
 *               function if someone passes a forceTab parameter to it.
 * level2      - The second in arPath.
 * level3      - The third in arPath.
 * amp         - browser-specific ampersand character
 * DSURL       - URL to DocuShare
 * serverName - URL (including the http://) of this web site
 ******************************************************************************/
var g_wm    = "WebMaster";
var g_wm_em = "admin28@comcast.net";
var serverName = location.protocol + '//' + location.host;
var SEC_Site   = "http://www.jeffduhaime.com";

/*******************************************************************************
 *                     Hard Code Links that live throughout this site
 *
 ******************************************************************************/
 WebCITIS_URL = "https://wwwce.msd.ray.com";
 WebCal_URL = "http://sudweb2.ed.ray.com/RAPID/html/cal/calendar.html";
 SEPGCal_URL = "/cgi-bin/Calcium3.5/Calcium35?CalendarName=SEPG_Calendar";
 WSTR_URL = "http://sudweb2.ed.ray.com/C3S/TOOLS/WSTR"; 

/*******************************************************************************
 * Determine content owner based on which page the user is on.
 ******************************************************************************/
var g_co;
var g_co_em;
if (location.pathname.search(/pal\/repository/) >= 0)  {
   g_co    = "John O'Hara";
   g_co_em = "John_J_Ohara@raytheon.com";
}
else if (location.pathname.search(/contact/) >= 0)  {
   g_co    = g_wm;
   g_co_em = g_wm_em;
}
else  {
   g_co = "Brad Kaye";
   g_co_em = "granitegulf@yahoo.com";
}

var LEFT  = 138;
var RIGHT = 207;

//var dirNames = ["home", "projects", "learning", "sepg", "pal", "people"];
var dirNames = ["home", "projects", "learning", "sepg", "pal", "people"];

var arPath = splitPath(location.pathname);

/*******************************************************************************
 * Assign level1, level2 and level3 to the first 3 elements of arPath.  These
 * will be used to determine which tab or podNav to highlight.
 ******************************************************************************/
var level1 = arPath[0];
var level2 = arPath[1];
var level3 = arPath[2];
var leveln = arPath[arPath.length-1];

/*******************************************************************************
 *                            Browser Customizations
 *
 * Certain customizations must be made depending on whether the user is using
 * Netscape or Internet Explorer, and whether they're using SunOS or Windows.
 ******************************************************************************/

/*******************************************************************************
 *                              Initial CSS Setup
 *
 * The following code is run automatically when this script is included in an
 * HTML page.  It sets up the stylesheet for the page based on the client's
 * machine (whether it's SunOS or not), and whether the browser is Internet
 * Explorer or Netscape.  While we're at it, we also set the "amp" variable to
 * either "&" for IE or "&&" for NS.
 ******************************************************************************/
var stylesheet = '<link rel="stylesheet" type="text/css" href="/style.css';
if (userMachine()=="SunOS") stylesheet += '_unix';
stylesheet += '.css">';
document.write(stylesheet);

var amp;
if (browser()=="IE")  {
   document.write(
      '<style type="text/css">' +
      ' OL.compact  {'          +
      '    font-size: 10pt;'    +
      '    left: -1em;'         +
      '    position: relative;' +
      ' }'                      +
      ' UL.compact  {'          +
      '    font-size: 10pt;'    +
      '    left: -1em;'         +
      '    position: relative;' +
      ' }'                      +
      '</style>');
   amp = "&";
}
else  {
   document.write(
      '<style type="text/css">' +
      ' OL.compact  {'          +
      '    font-size: 10pt;'    +
      '    margin-left: -1em;'  +
      ' }'                      +
      ' UL.compact  {'          +
      '    font-size: 10pt;'    +
      '    margin-left: -1em;'  +
      ' }'                      +
      '</style>');
   amp = "&&";
}

var DSURL = "http://docushare1.app.ray.com/dscgi/ds.py/";

/*******************************************************************************
 * We need to define Array.push() and Array.shift() for users of all versions
 * of IE except 5.5 and up, since JScript doesn't support it.
 ******************************************************************************/
if (browser() == "IE")  {
   var appV = navigator.appVersion;
   var re = /MSIE\s([^;]+)/;
   var ver = appV.match(re)[1];

   if (ver < '5.5')  {
      /*************************************************************************
       *                             Array.shift()
       *
       * Array.shift() removes and returns the first element of the Array
       * object.  The rest of the elements are shifted to the left (or up,
       * depending on your perspective).  The array size is reduced by one.
       ************************************************************************/
      Array.prototype.push = function(value)  {
         this[this.length] = value;
      }

      /*************************************************************************
       *                             Array.push()
       *
       * Array.push() adds the passed-in value to an Array object.
       ************************************************************************/
      Array.prototype.shift = function()  {
         var retval = this[0];
         for (var x=0; x<this.length; x++)  {
            this[x] = this[x+1];
         }
         this.length--;
         return retval;
      }
   }
}
/*******************************************************************************
 * End Browser Customizations
 ******************************************************************************/

/*******************************************************************************
 *                                lib.js Classes
 *
 * Certain classes must be defined in lib.js in order to expedite the creation
 * of the top- and and pod-navigation bars.  These classes are as follows:
 *
 *    NavGroup     - Generic Navigation Group class.
 *    TopNavGroup  - Subclass of NavGroup.  Represents a top navigation bar.
 *    PodNavGroup  - Subclass of NavGroup.  Represents a pod navigation box.
 *    Nav          - Generic Navigation class.
 *    TopNavTab    - Subclass of Nav.  Represents a top navigation bar tab.
 *    PodNavTab    - Subclass of Nav.  Represents a pod navigation box tab.
 *
 ******************************************************************************/

/*******************************************************************************
 *                               NavGroup object
 *
 * An object representing a generic Navigation Group object like a topNav or a
 * podNav.
 *
 * Created by:
 *
 *    The NavGroup constructor:
 *
 *       new NavGroup();
 *
 *       Parameters:
 *
 *          none.
 *
 *
 * Properties:
 *
 *    navs - Array of Nav Objects contained in the NavGroup.
 *
 * Methods:
 *
 *    add  -  Description: Adds a Nav object to the navs array.
 *            Syntax:      add(navObj)
 *            Parameters:  navObj - the Nav object to add.
 *
 ******************************************************************************/
function NavGroup()  {
   this.navs = new Array();
   this.add  = function(theNav)  {
      this.navs.push(theNav);
   }
}

/*******************************************************************************
 *                              TopNavGroup object
 *
 * An object representing a top navigation element for a web site.
 *
 * Created by:
 *
 *    The TopNavGroup constructor:
 *
 *       new TopNavGroup(siteName [, forceTab]);
 *
 *       Parameters:
 *
 *          siteName - The name of the Web Site.  This will be used for the ALT
 *                     attribute of the Site ID image.
 *
 *          forceTab - May be specified to force a page to highlight a certain
 *                     tab.  This can be a number, specifying which tab to
 *                     highlight (0-5), or a directory name (e.g. "org").
 *
 * Properties:
 *
 *    navs     - Array of TopNavTab Objects contained in the TopNavGroup.
 *    siteName - The name of the Web Site
 *
 * Methods inherited from NavGroup:  add
 *
 * Methods of TopNavGroup:
 *
 *    toString  -  Description: Returns the top navigation table in HTML format
 *                 Syntax:      toString([pretty])
 *                 Parameters:  pretty - a boolean value specifying whether to
 *                              insert newlines before each start tag.
 *
 *    write     -  Description: Outputs the top navigation table in HTML format
 *                              to the document object.
 *                 Syntax:      write([pretty])
 *                 Parameters:  pretty - a boolean value specifying whether to
 *                              insert newlines before each start tag.
 *
 ******************************************************************************/
TopNavGroup.prototype = new NavGroup();
function TopNavGroup(siteName, forceTab)  {
   this.navs     = new Array();
   this.siteName = siteName;

   if (forceTab != undefined)
      if (forceTab.toString().search(/\D/) >= 0)
         level1 = forceTab;
      else
         level1 = dirNames[forceTab];

   this.write = function(pretty)  {
      document.write(this.toString(pretty));
   }

   this.toString = function(pretty)  {
      var numNavs = this.navs.length;
      var retVal =
         '<map name="utilities">'
       +  '<area shape="rect" coords="460,3,488,13" target="_top"'
       +       ' href="http://home.ray.com/web_help/" alt="Web Help">'
       +  '<area shape="rect" coords="384,3,452,13" target="_top"'
       +       ' href="http://home.ray.com/collaboration/"'
       +       ' alt="Collaboration Center">'
       +  '<area shape="rect" coords="322,3,376,13" target="_top"'
       +       ' href="http://home.ray.com/newsroom/" alt="Newsroom">'
       +  '<area shape="rect" coords="277,3,315,13" target="_top"'
       +       ' href="http://home.ray.com/search.html" alt="Search">'
       +  '<area shape="rect" coords="220,3,270,13" target="_top"'
       +       ' href="http://home.directory.ray.com/" alt="Directory">'
       +  '<area shape="rect" coords="141,3,216,13" target="_top"'
       +       ' href="http://home.ray.com/" alt="Raytheon Home">'
       + '</map>'
       + '<table width=760 border=0 cellpadding=0 cellspacing=0 align="center">'
       +  '<tr>'
       +   '<td width=150 height=32>'
       +    '<a href="http://home.ray.com" target="_top">'
       +     '<img src="/js_lib/topNav/RayLogo.gif" border=0 alt="Raytheon"'
       +         ' width=150 height=32 border=0></a></td>'
       +   '<td width=610 height=32>'
       +    '<img src="/js_lib/topNav/siteid.old.gif" width=610 height=32'
       +        ' border=0 alt="'+this.siteName+'"></td></tr>'
       +  '<tr>'
       +   '<td width=760 height=16 colspan=2>'
       +    '<img src="/js_lib/topNav/globals.gif" width=760 height=16'
       +        ' usemap="#utilities" border=0 alt=""></td></tr>'
       +  '<tr><td width=760 height=1 bgcolor="#666666" colspan=2>'
       +    spacer(760,1) + '</td></tr>'
       + '</table>'
       + '<table width=760 border=0 cellpadding=0 cellspacing=0 align="center">';

      /*************************************************************************
       * Determine the sum of the textWidths of all the tabs except the first.
       ************************************************************************/
      var totalTextWidth = 0;
      for (var i=1; i<numNavs; i++)
         totalTextWidth += this.navs[i].textWidth

      /*************************************************************************
       * Determine the number of tab divisions we need besides the first, and
       * the number of pads we need besides the padding in the first tab.  Note
       * a "pad" is the total padding in a cell - not just one side.
       ************************************************************************/
      var numDivs = numNavs - 2;
      var numPads = (numNavs - 1);

      /*************************************************************************
       * Determine the ideal size of each pad.  Ideal meaning if we could use
       * fractions of pixels (which we can't).  This may be a floating-point
       * number.
       ************************************************************************/
      var tabSpc = (622-totalTextWidth-numDivs) / numPads;

      /*************************************************************************
       * Loop through the navs array to determine each tab's width.
       ************************************************************************/
      var totalIdealWidthUsed = 0;
      for (var i=0; i<numNavs; i++)  {
         /**********************************************************************
          * Determine the ideal width of the tab.  Per the web template, the
          * first tab is always 138 (137 plus 1 for the tabDiv).  If this is
          * not the last tab, add one for the tab division.
          *********************************************************************/
         var textWidth = this.navs[i].textWidth;
         var idealTabWidth;
         if (i==0)
            idealTabWidth = 137;
         else  {
            idealTabWidth = tabSpc + textWidth;
         }

         if (i<numNavs-1) idealTabWidth++;

         /**********************************************************************
          * Increment totalIdealWidthUsed by the ideal tab width.
          * Set the endOffset property of the tab to the totalWidthUsed,
          * rounded to the nearest integer.
          *********************************************************************/
         totalIdealWidthUsed += idealTabWidth;
         this.navs[i].endOffset = Math.round(totalIdealWidthUsed);

         /**********************************************************************
          * The width of the first tab is the amount of width used (138).  For
          * all others, subtract the endOffset of the previous tab from the
          * endOffset of the current tab.
          *********************************************************************/
         if (i==0)
            this.navs[0].tabWidth = this.navs[0].endOffset;
         else
            this.navs[i].tabWidth = this.navs[i].endOffset -
                                    this.navs[i-1].endOffset;

         /**********************************************************************
          * Determine the width of the two padding halves.  Subtract the text
          * width from the tab width without the tabDiv.  This is the total
          * padding in the tab.  Since this could be an odd number, divide it
          * by two and take the Floor of the result.  Set this as the width of
          * the left padding.  Set the width of the right padding to the total
          * width minus the text width minus the width of the left padding.
          *********************************************************************/
         var tabWidth  = this.navs[i].tabWidth;
         if (i < numNavs-1) tabWidth--;
         var leftPad = Math.floor((tabWidth - textWidth) / 2);
         this.navs[i].leftPad = leftPad;
         this.navs[i].rightPad = tabWidth - textWidth - leftPad;
      }

      var row = "<tr>";
      for (var i=0; i<numNavs; i++)  {
         var theNav = this.navs[i];
         var imgSrc = theNav.alt;
         //         imgSrc = imgSrc.toLowerCase();
         imgSrc = imgSrc.replace(/ /g, '_');
         imgSrc = imgSrc.replace(/\//g, '');

         var arURL = splitPath(theNav.url);
         var bg;
         var suffix;

         if (arURL[0] == level1)  {
            bg = "#FFFFF3";
            suffix = ".d.gif";
         }
         else  {
            bg = "#FFFFCC";
            suffix = ".n.gif";
         }

         imgSrc = "/js_lib/topNav/"+imgSrc+suffix;

         row +=
            '<td width='+theNav.tabWidth+' height=19 bgcolor="'+bg+'">'
          +  '<a href="'+theNav.url+'" target="_top">'
          +   '<img src="/images/spacer.gif" width='+theNav.leftPad+' height=19'
          +       ' border=0 alt="">'
          +   '<img src="'+imgSrc+'" width='+theNav.textWidth+' height=19'
          +       ' border=0 alt="'+theNav.alt+'">'
          +   '<img src="/images/spacer.gif" width='+theNav.rightPad
          +       ' height=19 border=0 alt=""></a>';
         if (i < numNavs-1)  {
            row += '<img src="/js_lib/topNav/tab_div.gif"'
                 +     ' width=1 height=19 alt="">';
         }
         row += '</a></td>';
      }
      row += '</tr>';

      retVal += row;
      retVal +=
         '<tr><td width=760 height=2 colspan='+(numNavs)+'>'
       +  '<img src="/js_lib/topNav/tab_shadow.gif" width=760 height=2'
       +      ' alt=""></td></tr></table>';

      if (pretty)
         retVal = retVal.replace(/<([^\/])/g, "\n<$1");

      return retVal;
   }
}

/*******************************************************************************
 *                              PodNavGroup object
 *
 * An object representing a pod navigation element for a level 1 tab.
 *
 * Created by:
 *
 *    The PodNavGroup constructor:
 *
 *       new PodNavGroup();
 *
 *       Parameters:
 *
 *          none.
 *
 * Properties:
 *
 *    navs     - Array of PodNavTab Objects contained in the PodNavGroup.
 *    offSites - Array of PodNavTab Objects representing outside (level-0)
 *               websites to put in the PodNavGroup.
 *
 * Methods inherited from NavGroup:  N/A
 *
 * Methods of PodNavGroup:
 *
 *    add       -  Description: Adds a PodNavTab to the navs array.
 *                 Syntax:      add(podNav)  OR  add(url, alt, lines)
 *                 Parameters:  podNav - PodNavTab object to add to navs
 *                              url    - URL of a new PodNavTab object to add
 *                              alt    - ALT text of the new PodNav Tab object
 *                              lines  - number of lines the image takes up
 *
 *    addOff    -  Description: Adds a PodNavTab to the offSites array.
 *                 Syntax:      addOff(podNav)  OR  addOff(url, alt, lines)
 *                 Parameters:  podNav - PodNavTab object to add to addOff.
 *                              url    - URL of a new PodNavTab object to add
 *                              alt    - ALT text of the new PodNav Tab object
 *                              lines  - number of lines the image takes up
 *
 *    toString  -  Description: Returns the pod navigation in HTML format
 *                 Syntax:      toString([pretty])
 *                 Parameters:  pretty - a boolean value specifying whether to
 *                                       insert newlines before each start tag.
 *
 *    write     -  Description: Outputs the pod navigation in HTML format
 *                              to the document object.
 *                 Syntax:      write([pretty])
 *                 Parameters:  pretty - a boolean value specifying whether to
 *                                       insert newlines before each start tag.
 *
 ******************************************************************************/
PodNavGroup.prototype = new NavGroup();
function PodNavGroup()  {
   this.navs     = new Array();
   this.offSites = new Array();

   this.add = function(urlOrNav, alt, lines)  {
      if (getType(urlOrNav) == 'Object')
         this.navs.push(urlOrNav);
      else
         this.navs.push(new PodNavTab(urlOrNav, alt, lines));
   }

   this.addOff = function(urlOrNav, alt, lines)  {
      if (getType(urlOrNav) == 'PodNavTab')
         this.offSites.push(urlOrNav);
      else
         this.offSites.push(new PodNavTab(urlOrNav, alt, lines));
   }

   this.write = function(pretty)  {
      document.write(this.toString(pretty));
   }

   this.toString = function(pretty)  {
      var retVal = "";
      var numNavs = this.navs.length;
      var numOffs = this.offSites.length;

      /*************************************************************************
       * If either the navs or the offSites array contains elements, create
       * a table for the podNav navigation.
       ************************************************************************/
      if (numNavs > 0 || numOffs > 0)  {
         retVal +=
            '<table border=0 cellpadding=0 cellspacing=0 width=138'
          +       ' bgcolor="#fffff0">'
          +  '<tr><td width=138 height=7>'
          +   '<img src="/images/spacer.gif" width=138 height=7'
          +       ' alt=""></td></tr>';

         /**********************************************************************
          * Add the HTML for each of the pod navs in the navs array.
          *********************************************************************/
         for (var i=0; i<numNavs; i++)  {
            retVal += this.navs[i].toString(2);
         }

         /**********************************************************************
          * If there are off-site links, we need to add them to the podNav
          * navigation.
          *********************************************************************/
         if (numOffs > 0)  {

            /*******************************************************************
             * But first, if there were level-2 navs, we need to add a dividing
             * line to the podNav navigation.
             ******************************************************************/
            if (numNavs > 0)
               retVal +=
                  '<tr><td width=138 height=10>'
                +  '<img src="/js_lib/podNav/pod_divider.gif"'
                +      ' width=138 height=10 alt=""></td></tr>';

            /*******************************************************************
             * Add the HTML for each of the pod navs in the offSites array.
             ******************************************************************/
            for (var i=0; i<numOffs; i++)
               retVal += this.offSites[i].toString(2);
         }

         /**********************************************************************
          * Add the pod underline graphic and close the table.
          *********************************************************************/
         retVal +=
             '<tr><td>'
           +  '<img src="/js_lib/podNav/pod_underline.gif" width=138 height=20'
           +      ' alt=""></td></tr></table><br>';

         if (this.subNav)
            retVal += this.subNav.toString();
      }

      if (pretty)
         retVal = retVal.replace(/<([^\/])/g, "\n<$1");

      return retVal;
   }
}

/*******************************************************************************
 *                                  Nav object
 *
 * An object representing a generic Navigation object like a Tab or a PodNav.
 *
 * Created by:
 *
 *    The Nav constructor:
 *
 *       new Nav(url, alt);
 *
 *       Parameters:
 *
 *          url - Required.  The web URL to link to.
 *
 *          alt - Required.  The title of this nav object.  This will be used
 *                in the ALT attribute of the <IMG> tag.
 *
 * Properties:
 *
 *    url    - String representing the URL to link to
 *    alt    - String representing the title of this nav object
 *    subNav - NavGroup object representing the navigation group associated with
 *             this Nav.
 *
 * Methods:
 *
 *    none.
 *
 ******************************************************************************/
function Nav(url, alt)  {
   this.url = url;
   this.alt = alt;
   this.subNav;
}

/*******************************************************************************
 *                               TopNavTab object
 *
 * A Nav Object representing a top navigation tab.
 *
 * Created by:
 *
 *    The TopNavTab constructor:
 *
 *       new TopNavTab(url, alt, textWidth);
 *
 *       Parameters:
 *
 *          url       - Required.  The web URL to link to.
 *          alt       - Required.  The title of this nav object.  This will be
 *                      used in the ALT attribute of the <IMG> tag.
 *          textWidth - Required.  Width of the text image.  This is used to
 *                      determine the amount of padding needed in the tab.
 *
 * Properties:
 *
 *    url         - String representing the URL to link to
 *    alt         - String representing the title of this nav object
 *    textWidth   - Number representing the width of the supplied text image
 *
 *    The following Properties are private and should not be manipulated by the
 *    client:
 *
 *    endOffSet - distance from the beginning of the row to the last pixel in
 *                the tab
 *    tabWidth  - width of the tab in pixels
 *    leftPad   - width in pixels of the padding to the left of the text image
 *    rightPad  - width in pixels of the padding to the right of the text image
 *
 * Methods:
 *
 *    none.
 *
 ******************************************************************************/
TopNavTab.prototype = Nav();
function TopNavTab(url, alt, textWidth)  {
   this.url         = url;
   this.alt         = alt;
   this.textWidth   = textWidth;

   this.endOffset = 0;   // private
   this.tabWidth  = 0;   // private
   this.leftPad   = 0;   // private
   this.rightPad  = 0;   // private
}

/*******************************************************************************
 *                               PodNavTab object
 *
 * A Nav Object representing a pod navigation tab.
 *
 * Created by:
 *
 *    The PodNavTab constructor:
 *
 *       new PodNavTab(url, alt);
 *
 *       Parameters:
 *
 *          url       - Required.  The web URL to link to.
 *          alt       - Required.  The title of this nav object.  This will be
 *                      used in the ALT attribute of the <IMG> tag.
 *          lines     - Optional.  The number of text lines in the pod image.
 *
 * Properties:
 *
 *    url    - String representing the URL to which to link.
 *    alt    - String representing the title of this nav object.
 *    height - Number representing the height in pixels of this nav object.
 *
 * Methods:
 *
 *    add       -  Description: Adds a podNavTab to this podNav's subNav group,
 *                              creating a new one if necessary.
 *                 Syntax:      add(podNav)  OR  add(url, alt, lines)
 *                 Parameters:  podNav - PodNavTab object to add
 *                              url    - URL of a new PodNavTab object to add
 *                              alt    - ALT text of the new PodNav Tab object
 *                              lines  - number of lines the image takes up
 *
 *    toString  -  Description: Returns the pod nav tab in HTML format
 *                 Syntax:      toString([pretty])
 *                 Parameters:  pretty - a boolean value specifying whether to
 *                                       insert newlines before each start tag.
 *
 *
 ******************************************************************************/
PodNavTab.prototype = Nav();
function PodNavTab(url, alt, lines)  {
   this.url    = url;
   this.alt    = alt;
   this.h      = (lines == 2) ? 30 : 18;

   this.add = function(urlOrNav, alt, lines)  {
      if (getType(urlOrNav) == 'Object')
         this.navs.push(urlOrNav);
      else
         this.navs.push(new PodNavTab(urlOrNav, alt, lines));
   }

   this.add = function(urlOrNav, alt, lines)  {
      if (!this.subNav)
         this.subNav = new PodNavGroup();

      this.subNav.add(urlOrNav, alt, lines);
   }

   this.toString = function(level, pretty)  {
      var alt  = new String(this.alt);
      var file = alt.replace(/\//g, '');

      file = file.replace(/ /g, '_');
      for (var x=3; x<=level; x++)
         file = "_" + file;

      alt  = alt.replace(/&/g, amp);
      file = "/js_lib/podNav/" + file + ".";
      if (location.pathname == this.url)
         file += "d";
      else
         file += "n";
      file += ".gif";

      var retVal =
         '<tr><td width=138 height='+this.h+'>'
       +  '<a href="'+this.url+'" target="_top">'
       +  '<img src="'+file+'" width=138 height='+this.h+' border=0'
       +      ' alt="'+alt+'"></a></td></tr>';

      if (location.pathname.indexOf(this.url) == 0 && this.subNav)  {
         for (var i=0; i<this.subNav.navs.length; i++)  {
            retVal += this.subNav.navs[i].toString(level+1, pretty);
         }
      }

      if (pretty)
         retVal = retVal.replace(/<([^\/])/g, "\n<$1");
      return retVal;
   }
}

/*******************************************************************************
 * End lib.js Classes
 ******************************************************************************/

/*******************************************************************************
 *                                User functions
 *
 * The following functions may be called from an HTML page.  If the function
 * uses document.write() or document.writeln(), it is not recommended that it
 * be called from within another Javascript function.  This can cause
 * unpredictable results.
 *
 *       blueLine()       - Outputs a line of blue pixels of the given length
 *       br()             - Returns an HTML line break.
 *       browser()        - returns "IE", "NS" or 0 depending on the client's
 *                          browser.
 *       co_link()        - outputs a link to the content owners' e-mails.
 *       contact()        - outputs contact info to the calling page.
 *       counter()        - outputs a counter by calling the counter.pl script
 *       Desc()           - puts up an alert with text that describes something
 *       divider()        - Outputs a horizontal line of the specified color
 *                          and length
 *       Document()       - Document object.
 *       docLink()        - Outputs a link to a document using the given string
 *                          as the linked text, along with 16x16 icons
 *                          representing the format(s) the user specifies
 *       docLinkHTML()    - Returns a link to a document using the given string
 *                          as the linked text, along with 16x16 icons
 *                          representing the format(s) the user specifies
 *       DSCollLink       - Link to a DocuShare Collection
 *       DSCollURL        - DocuShare Collection URL
 *       DSFileLink       - Link to a DocuShare File
 *       DSFileURL        - DocuShare File URL
 *       email()          - Outputs a link to the email script
 *       emailHTML()      - Returns a link to the email script
 *       getType()        - Returns the type of the given object
 *       icon()           - ouptutsf a 16x16 icon of the given format
 *       icon_html()      - returns a 16x16 icon of the given format
 *       memoLink()       - returns a link to a Memo in the /PDFs/memos dir.
 *       nbsp()           - returns a number of &nbsp; elements
 *       new_icon()       - returns HTML code for a "New!" icon for a specified
 *                          number of days.
 *       openwin()        - Opens a new window and loads the specified URL
 *       oval()           - outputs a blue optional button oval with the
 *                          specified text
 *       p()              - defines the String.p() method.
 *       pageTitle()      - outputs a Page Title image (must be in
 *                          /js_lib/titles)
 *       parentTitle()    - outputs a Parent Title image (must be in
 *                          /js_lib/titles)
 *       pdfWarning()     - outputs a message advising the user to wait for
 *                          Acrobat Reader to open, if he or she is on a Unix
 *                          platform.
 *       Person()         - Person object (name & e-mail address)
 *       podNav()         - outputs level 2 pod nav box to the calling page.
 *       redirect()       - Outputs HTML telling the user about a redirection,
 *                          and schedules a call to redirect_to().
 *       redirect_to()    - Calls the redirect.pl script, which redirects the
 *                          user to another page, and e-mails the webmaster if
 *                          a link should be updated
 *       redLine()        - Outputs a line of red pixels of the given length
 *       rotatingImages() - Displays a series of images, rotating them at a
 *                          specified interval.
 *       rotate()         - Loads the next image in a series of images
 *       spacer()         - returns a spacer image of the specified h & w
 *       splitPath()      - Splits a URL or pathname into an array
 *       String.out()     - Outputs a string object to the document.
 *       to_top()         - outputs a "^ Top of page" link.
 *       toolsLink()      - Return a link to a Patriot Tool on slpzap
 *       toolsURL()       - Return a fully-qualified URL for a tool on slpzap
 *       topOfPage()      - returns a "^ Top of page" link.
 *       Tombstone()      - implements a Tombstone element
 *       topNav()         - outputs level 1 top nav bar to the calling page.
 *       userMachine()    - returns "SunOS", "WinNT" or "Other", depending on
 *                          the client's platform.
 *       wm_link()        - outputs a link to the webmasters' e-mails.
 *
 ******************************************************************************/

/*******************************************************************************
 *                                  blueLine()
 *
 * Description: Outputs a blue line across the page.
 *
 * Syntax:      blueLine([width]);
 *
 * Parameters:
 *
 *    width - Width in pixels or percent of the line.  Default is "100%".
 *
 ******************************************************************************/
function blueLine(width)  {
   divider('#003366', width);
}

/*******************************************************************************
 *                                     br()
 *
 * Description: Returns an HTML Line Break (<BR>) tag.
 *
 * Syntax:      br()
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function br()  {
   return "<BR>";
}

/*******************************************************************************
 *                                  browser()
 *
 * The browser() function looks at the navigator.appName property and returns
 * IE, NS or 0 depending on the user's browser.  This is useful when writing
 * scripts that will work in one browser but not another.
 ******************************************************************************/
function browser()  {
   if (navigator.appName == "Microsoft Internet Explorer")
      return "IE";
   else if (appV == "Netscape")
      return "NS";
   else
      return 0;
}

/*******************************************************************************
 *                                  co_link()
 *
 * The co_link() function outputs a link to the content owners' e-mails defined
 * in g_co_em variable at the top of the script.
 ******************************************************************************/
function co_link(linkText)  {
   if (!linkText)  {
      linkText = "content owner";
      if (g_co_em.search(/,/) >= 0) linkText += "s";
   }
   email(g_co_em, linkText);
}

/*******************************************************************************
 *                                  contact()
 *
 * The contact() function outputs the "^ To top" link and the Contact footer to
 * the calling HTML page.  All the parameters are optional, but the use of lu
 * is strongly encouraged.
 *    lu    - a string representing the "last updated" date.  Default is
 *            today's date
 *    co    - the content owner(s).  Default is "Gregg Jernigan".
 *    co_em - the e-mail address(es) of the content owner(s).
 *    wm    - the webmasters.  Default is "IDS SEC Web Team".
 *    wm_em - the webmasters' e-mail addresses.  Default is
 *            "selwebteam@raytheon.com"
 *    br    - boolean - output a BR() before the start of the contact info.
 *            Default is true.
 *
 ******************************************************************************/
function contact(lu, co, co_em, wm, wm_em, br)  {
   var now = new Date();
   var months = new Array("January", "February", "March", "April", "May",
           "June", "July", "August", "September", "October",
           "November", "December");
   if (!lu) lu = months[now.getMonth()] + " " + now.getDate() + ", "
          + now.getFullYear();
   if (!wm) wm       = g_wm;
   if (!wm_em) wm_em = g_wm_em;
   if (!co) co       = g_co;
   if (!co_em) co_em = g_co_em;
   if (br == undefined) br    = true;

   if (br) document.write('<br>');

   document.write(
      '<table border=0 cellpadding=0 cellspacing=0 width=760 align="center">'
    +  '<tr>'
    +   '<td width=150 colspan=2>'+spacer(150,1)+'</td>'
    +   '<td width=379 colspan=2>'+topOfPage()+'</td>'
    +   '<td width=231 align="right" class="small">'
    +    'Updated: '+lu+'</td></tr>'
    +  '<tr>'
    +   '<td width=150 height=1 colspan=2>'+spacer(150,1)+'</td>'
    +   '<td width=610 height=1 bgcolor="#ff3300" colspan=3>'
    +     spacer(610,1)+'</td></tr>'
    +  '<tr valign="top">'
    +   '<td width=138>'
    +    '<img src="/js_lib/contact.gif" width=138 height=21'
    +        ' alt="Contact"></td>'
    +   '<td width=12>'+spacer(12,1)+'</td>'
    +   '<td width=189>'
    +    'Content Owner'.bold() + '<br>'
    +    emailHTML(co_em, co) + '</td>'
    +   '<td width=190>'
    +    'Technical Contact'.bold() + '<br>'
    +    emailHTML(wm_em, wm) + '</td>'
    +   '<td width=231 align="right">'
    +    "Copyright &copy; 2003-2009<br> Granite Gulf"
    +    '</td></tr></table>');
}

/*******************************************************************************
 *                                  counter()
 *
 * Title:       Output counter
 *
 * Description: The counter() function outputs an image tag that calls the
 *              counter.pl script.  The counter.pl script generates a counter
 *              GIF.  The reason we need the dummy random number in the URL is
 *              because, when the same URL gets called more than once, the
 *              browser looks in its cache.  If it finds the URL there, it just
 *              loads it from the cache.  This would cause the counter not to
 *              get incremented.  Therefore, since the random number will cause
 *              the URL to be different almost every time, it will never find
 *              the URL in the cache.  The subPage parameter is used to
 *              override the "counter" CGI parameter on the referring page
 *              which allows different counts for different pages of the same
 *              URL (e.g. a CGI script outputting multiple pages).
 *
 * Syntax:      counter([subPage])
 *
 * Parameters:  subPage - a trivial but unique string identifying a page to be
 *                        counted separately from other pages generated by the
 *                        same URL.
 *
 * Examples:
 *
 *    For a basic HTML page, use the following:
 *       counter();
 *    This will output: <img src="/cgi-bin/counter.pl?dummy=xxxx">
 *
 *    For a CGI script that generates different HTML pages, you might do this:
 *       counter('formPage');
 *    in the portion of the CGI that generates the form page, and this:
 *       counter('resultsPage');
 *    in the portion of the CGI that displays the results.  This way you can
 *    track how many times the form page was loaded, vs. how many times a user
 *    actually got to the results page.
 *
 ******************************************************************************/
function counter(subPage)  {
   var dummy = Math.random();
   var query = "dummy=" + dummy;
   if (subPage) query += "&subPage=" + subPage;

   document.write('<img src="/cgi-bin/counter.pl?' + query
                     + '" align="top" alt="Counter">');
}

/*******************************************************************************
 *                                    Desc()
 *
 * The Desc() function provides a mechanism for displaying an alert regarding a
 * specific element on the web site.  Normally this is called from an <A HREF>
 * link.  For example:
 *    <input type="checkbox" name="set_cookie"> Remember my info.
 *    <a href="javascript:Desc('cookie');"> (what's this?)</a>
 * Clicking on the link would bring up an alert describing a browser cookie.
 *
 ******************************************************************************/
function Desc(item)  {
   switch(item)  {
      // Notify - comes from Site Submission page.
      case "cookie":
         description = 'Selecting this checkbox allows this page to place a '
            + 'small piece of information\ncalled a "cookie" on your hard '
            + 'drive.  This information contains personalized\nsettings that '
            + 'will be used whenever you come back to this web page.';
         break;
      case "Notify":
         description = "If there are others whom you wish to be notified that "
            + "you have submitted this document, enter their e-mail addresses "
            + "here.  You may separate each address with spaces or commas.";
         break;
      default:
         description = "No information on this item is currently available. ";
   }
   alert(description);
}

/*******************************************************************************
 *                                  divider()
 *
 * The divider() function outputs a horizontal line of the specified color (c)
 * and width (w).
 ******************************************************************************/
function divider(c, w)  {
   var output;
   if (!c) c = "Black";
   if (!w) w = "100%";

   output = '<table border=0 cellpadding=0 cellspacing=0 width="'+w+'">'
          +  '<tr><td bgcolor="'+c+'">'
          +   '<img src="/images/spacer.gif" width=1 height=1 alt="">'
          +  '</td></tr>'
          + '</table>';
   document.write(output);
}

/*******************************************************************************
 *                                   Document
 *
 * Document object.  Used in tables that list documents.
 *
 * Created by   :  Document object constructor:
 *                    new Document(dateOrCustom, title, path, formats, author)
 * Parameters   :  dateOrCustom - If this is a custom document entry,
 *                                dateOrCustom should be an Array of the
 *                                contents of the cells to be used in
 *                                outputting the table row for this document.
 *                                If this is a standard document entry,
 *                                dateOrCustom is a String specifying the
 *                                date of the document.
 *                 title        - Title of the document for a standard document
 *                                entry
 *                 path         - URL of the document (excluding the
 *                                extension) for a standard document entry
 *                 formats      - Comma-separated string of the file
 *                                formats for which to output links to the
 *                                document
 *                 authors      - Person object of the Author of the document
 *                                or Array of Person objects
 *
 * Property  Data Type  Description
 * --------  ---------  --------------------------------------------------------
 * custom    Array      Strings to be put in table cells for this document entry
 * date      String     Date of the document
 * title     String     Title of the document
 * path      String     URL of the document, minus the extension
 * formats   String     File formats for which the document should be linked.
 *                      Ex: "pdf, doc"
 * authors   Array      Array of authors of the document
 * rowColor  String     Color of the Row (s/b in a class)
 *
 * Method    Description
 * ------    -------------------------------------------------------------------
 * toString  Returns this document entry as an HTML table row.
 *
 ******************************************************************************/
function Document(dateOrCustom, title, path, formats, authors, notes, rowColor)  {

   /****************************************************************************
    * If dateOrCustom is an array, set it to the custom property.
    ***************************************************************************/
   if (getType(dateOrCustom) == "Array")  {
      this.custom   = dateOrCustom;
      this.rowColor = title;
   }

   /****************************************************************************
    * If dateOrCustom is not an array, set it to the date property.  Store the
    * rest of the input parameters in the object's properties.
    ***************************************************************************/
   else  {
      this.date    = dateOrCustom;
      this.title   = title;
      this.path    = path;
      this.formats = formats;
      this.authors = (authors)
                        ? ((getType(authors) == "Array") ? authors : [authors])
                        : "";
      this.notes   = notes;
     this.rowColor = rowColor;
   }

   /****************************************************************************
    *                                 toString
    *
    * Returns a table row containing the info for this Document.
    *
    * Syntax      :  toString()
    * Parameters  :  none
    * Notes       :  If custom is defined, the entries of it are used for each
    *                table cell.  If not, the date is used for the first table
    *                cell.  For the second cell, the title of the document is
    *                linked to the URL of the document, using the first
    *                extension found in formats.  The author's name, linked to
    *                his e-mail is appended to the title in italics.  The third
    *                cell contains icons representing each format in formats,
    *                linked to the corresponding file.
    ***************************************************************************/
   this.toString = function ()  {
     if (this.rowColor) {
         var retVal = '<tr valign="top" class="' + this.rowColor + '">';
     } else {
         var retVal = '<tr valign="top">';
    }
      if (this.custom)  {
         for (var i=0; i<this.custom.length; i++)  {
            retVal += '<td>';
            if (i==0)  {
               this.custom[i] =
                  '<span class="bluedate2">'
                +   this.custom[i]+'</span>&nbsp;';
            }
            retVal += this.custom[i]+'</td>';
         }
      }
      else  {
         var arFormats = this.formats.split(/,\s*/);
         var text = this.title;

         if (this.path)  {
            text = text.link(this.path + "." + arFormats[0]);
         }

         for (var i=0; i<this.authors.length; i++)  {
            text += (i==0) ? " - " : ", ";
            text += this.authors[i].toString().italics();
         }

         if (this.notes)
            text += " " + this.notes;

         if (text.search(/\t/) >= 0)
            text = "<table border=0 cellpadding=0 cellspacing=0>"
                 +  "<tr>"
                 +   "<td>&nbsp; &nbsp; </td>"
                 +   "<td>" + text.replace(/\t/, "") + "</td></tr></table>";

         retVal +=
            '<td><span class="bluedate2">'+this.date+'</span>&nbsp;</td>'
          + '<td>'+ text +'</td>'
          + '<td>'
          +   docLinkHTML('', this.path, this.formats) + '</td>';
      }
      retVal += '</tr>'
      return retVal;
   }                                            // End function toString()
}                                               // End Document class


/******************************************************************************
 *                                     docLink
 *
 * Title       -  Output HTML Document Link
 *
 * Overview    -  Write the return value of docLinkHTML() to the current
 *                document.
 *
 * Syntax      -  docLink([linkText], pathname, exts [, target] [, icons])
 *
 * Parameters  -  see docLinkHTML() function.
 *
 * Examples    -  see docLinkHTML() function.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    docLink is called by    -  N/A
 *
 *    docLink calls           -  docLinkHTML
 *
 ******************************************************************************/
function docLink(strLinkText, strPathname, exts, strTarget, icons)  {
   document.write(docLinkHTML(strLinkText, strPathname,
                              exts, strTarget, icons));
}  // end function docLink()

/*******************************************************************************
 *                                   docLinkHTML
 *
 * Title       -  HTML Document Link
 *
 * Overview    -  Returns an HTML-formatted link to a document using specified
 *                link text, followed by icons for each format specified.  See
 *                example.
 *
 * Syntax      -  docLinkHTML([linkText], path, exts [, target] [,icons])
 *
 * Parameters:
 *
 *    linkText -  The text to use to link to the file.
 *    path     -  An absolute or relative URL to the file(s), minus the
 *                extension.  The formats parameter is used to complete the
 *                pathname.
 *    exts     -  Either an array or a comma-separated string of format types,
 *                each of which will be concatenated to pathname to form a real
 *                URL.
 *    target   -  Optional.  The target window to open the file in.
 *    icons    -  Optional.  Either an array or a comma-separated string of
 *                format types, each of which will be used to specify the icon
 *                image for each element of "exts".  If omitted, exts will be
 *                used.  You can specify "none" to supress the icons.
 *
 * Note: If linkText is specified, the first format in formats will be used for
 *       the link.
 *
 * Example:
 *
 *    docLinkHTML("News", "PDFs/news", "pdf,doc")
 *       will return:
 *    <A HREF="PDFs/news.pdf">News</a>
 *    <A HREF="PDFs/news.pdf"><img src="/icons/pdf16.gif" ...></A>
 *    <A HREF="PDFs/news.doc"><img src="/icons/word16.gif" ...></A>
 *
 * Note - If an empty string is passed in for strLinkText, only the icons are
 *        returned.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    docLinkHTML is called by   -  Document.toString    docLink  memoLink
 *
 *    docLinkHTML calls          -  icon_html
 *
 ******************************************************************************/
function docLinkHTML(strLinkText, strPathname, exts, strTarget, icons)  {
   if (!icons) icons = exts
   else if (icons.toString().toLowerCase() == "none") icons = "";
   var strLinkFormat;
   var arExts        = exts.toString().split(/,\s*/);
   var strFirstExt   = arExts[0];
   var arIcons;
   var strFirstIcon;
   if (icons)  {
      arIcons       = icons.toString().split(/,\s*/);
      strFirstIcon  = arIcons[0];
   }
   var strFilename = strPathname + "." + strFirstExt;
   var retVal = "";

   if (strLinkText.length > 0)  {
      retVal = '<A HREF="'+strFilename+'"';
      if (strTarget) retVal += ' TARGET="'+strTarget
      retVal += '">'+strLinkText+'</A>';
      if (icons) retVal += "&nbsp;";
   }

   if (icons)  {
      retVal += icon_html(strFirstIcon).link(strFilename);
      for (var x=1; x<arExts.length; x++)  {
         var strExt  = arExts[x];
         var strIcon = arIcons[x];
         strFilename = strPathname + "." + strExt;
         retVal += "&nbsp;" + icon_html(strIcon).link(strFilename);
   }  // end for (var x=1; x<arFormats.length; x++)
   }     // end if (icons)

   return retVal;
}                                                  // end function docLinkHTML()

/*******************************************************************************
 *                                  DSCollLink
 *
 * Title       -  Link to a DocuShare Collection
 *
 * Overview    -  Returns an HTML hyperlink to a DocuShare Collection
 *
 * Syntax      -  DSCollLink(text, collection, target)
 *
 * Parameters:
 *    text        -  text to apply the link to
 *    collection  -  the number (handle) of the collection
 *    target      -  target window for the link
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    DSCollLink is called by    -  N/A
 *
 *    DSCollLink calls           -  DSCollURL
 *
 ******************************************************************************/
function DSCollLink(text, collection, target)  {
    theLink = '<A HREF="'+DSCollURL(collection)+'"';
    if (target) theLink += ' TARGET="'+target+'"';
    theLink += '>'+text+'</A>';
    return theLink;
}                                                   // end function DSCollLink()

/*******************************************************************************
 *                                  DSCollURL
 *
 * Title       -  DocuShare Collection URL
 *
 * Overview    -  Returns the fully qualified URL of a Collection in DocuShare.
 *                The collection can be specified either by its DocuShare handle
 *                or a predefined string, as described below.
 *
 * Syntax      -  DSCollURL(collection)
 *
 * Parameters:
 *    collection  -  the id (handle) of the collection, or one of the following
 *                   case-insensitive strings, used to select the proper
 *                   collection handle:
 *                      OTP   -  The Organizational Training Plan collection
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    DSCollURL is called by  -  DSCollLink
 *
 *    DSCollURL calls         -  DSURL
 *
 ******************************************************************************/
function DSCollURL(collection)  {
   if (isNaN(collection))  {
      switch (collection.toLowerCase())  {
         case 'otp':
            collection = 26107; break;
         default:
            alert("Invalid call to DSCollURL().  collection = " + collection);
            return;
      }
   }
   return DSURL + "View/Collection-" + collection;
}                                                    // end function DSCollURL()

/*******************************************************************************
 *                                  DSFileLink
 *
 * Title       -  Link to a DocuShare File
 *
 * Overview    -  Returns an HTML hyperlink to a DocuShare File
 *
 * Syntax      -  DSFileLink(text, fileID, target, icon)
 *
 * Parameters:
 *    text     - Optional.  Text to apply the link to.  If omitted, an empty
 *               string ("") must be used to keep the parameter order intact.
 *               Also, specifying no text and "none" for the icon generates an
 *               error.
 *    fileID   - Required.  The ID (handle) of the file, or a selector
 *               specifying which predefined handle to use.  See the selector
 *               parameter for DSFileURL.
 *    target   - Optional.  Target window for the link. If target is omitted,
 *               but icon is not, an empty string ("") must be used to keep the
 *               parameter order intact.
 *    icon     - Optional.  The icon to display after the file.  If omitted, the
 *               icon type is taken from the first 3 characters of the fileID.
 *               To supress the icon, specify "none".  Also, if you specify a
 *               numeric fileID and no icon, 'none' is assumed.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    DSFileLink is called by    -  N/A
 *
 *    DSFileLink calls           -  DSFileURL   icon_html
 *
 ******************************************************************************/
function DSFileLink(stText, fileID, stTarget, icon)  {
   if (icon)          icon   = icon.toLowerCase();
   if (isNaN(fileID)) fileID = fileID.toLowerCase();

   if (!stText && icon == 'none')  {
      alert("Invalid call to DSFileLink(text, fileID, target, icon):\n"
          + "\ttext   = " + stText   + "\n"
          + "\tfileID   = " + fileID   + "\n"
          + "\ttarget = " + stTarget + "\n"
          + "\ticon     = " + icon     + "\n"
          + "You must specify either a text or an icon, or both.");
      return;
   }

   if (!icon)  {
      if (isNaN(fileID))
         icon = fileID.substr(0, 3);
      else
         icon = 'none';
   }

   var url = DSFileURL(fileID);
   var aTag = '<a href="'+url+'"'
   if (stTarget) aTag += ' target="'+stTarget+'"'
   aTag    += '>';
   var aEnd = "</a>";

   var theLink = "";
   if (stText) theLink += aTag + stText + aEnd;
   if (icon != 'none')  {
      if (stText) theLink += "&nbsp;"
      theLink += aTag + icon_html(icon) + aEnd;
   }

   return theLink;
}                                                   // end function DSFileLink()

/*******************************************************************************
 *                                 DSFileURL()
 *
 * Title:       DocuShare File URL
 *
 * Description: Returns the fully qualified URL of a file in DocuShare.  The
 *              file can be specified either by its DocuShare handle or a
 *              predefined string, as described below.
 *
 * Syntax:      DSFileURL(fileID);
 *              DSFileURL(selector);
 *
 * Parameters:
 *    fileID   -  the ID (handle) of the file
 *    selector -  One of the following case-insensitive strings, specifying the
 *                latest version of the indicated document:
 *                   pdfBB       -  Blue Book in PDF format
 *                   docBBmain   -  Blue Book Main, App I & II in Word format
 *                   docBBApp3   -  Blue Book Appendix III in Word format
 *                   docBBApp4   -  Blue Book Appendix IV in Word format
 *                   docBBApp5   -  Blue Book Appendix V in Word format
 *                   docBBApp6   -  Blue Book Appendix VI in Word format
 *                   pdfOTP      -  Organizational Training Plan in PDF format
 *                   docOTP      -  Organizational Training Plan in Word format
 *                   xlsOTP      -  Competency Training Matrix Tool in Excel
 *                   pdfQPMSQMpp -  QPM/SQM Plans & Procedures in PDF format
 *                   docQPMSQMpp -  QPM/SQM Plans & Procedures in DOC format
 *                   xlsEPGPOCs  -  Points of Contact for all Raytheon EPGs
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    DSFileURL is called by  -  DSFileLink
 *
 *    DSFileURL calls         -  DSURL
 *
 ******************************************************************************/
function DSFileURL(fileID)  {
   if (isNaN(fileID))  {
      switch (fileID.toLowerCase())  {
         case 'pdfbb':
            fileID = 159391; break;
         case 'docbbmain':
            fileID = 143442; break;
         case 'docbbapp3':
            fileID = 145251; break;
         case 'docbbapp4':
            fileID = 145553; break;
         case 'docbbapp5':
            fileID = 145412; break;
         case 'docbbapp6':
            fileID = 145748; break;
         case 'pdfotp':
            fileID = 161887; break;
         case 'docotp':
            fileID = 161888; break;
         case 'xlsotp':
            fileID = 161886; break;
         case 'pdfqpmsqmpp':
            fileID = 158557; break;
         case 'docqpmsqmpp':
            fileID = 146358; break;
         case 'xlsepgpocs':
            fileID = 222943; break;
         default:
            alert("Invalid call to DSFileURL().  fileID = " + fileID);
            return;
      }
   }
   return DSURL + "Get/File-" + fileID;
}                                                    // end function DSFileURL()

/*******************************************************************************
 *                                   email()
 *
 * Description: Writes the string returned by a call to emailHTML() with the
 *              same parameters to the active document.
 *
 * Syntax:      email(recips [, linkText [, strTarget]]);
 *
 * Parameters:  see function emailHTML()
 *
 * Examples:    see function emailHTML()
 *
 ******************************************************************************/
function email(recips, linkText, strTarget)  {
   document.write(emailHTML(recips, linkText, strTarget));
}

/*******************************************************************************
 *                                 emailHTML()
 *
 * Description: Returns a link to the /cgi-bin/email.pl script, which provides
 *              a means for the user to send an e-mail without using his
 *              browser's default e-mail program, which may not be set up to
 *              send e-mails.
 *
 * Syntax:      emailHTML(recips, [linkText], [strTarget]);
 *
 * Parameters:
 *
 *    recips    - A String containing an e-mail address, or an Array of Strings
 *                containing e-mail addresses.  If recips (or any element of
 *                recips if recips is an array) contains spaces, they are
 *                converted to underscores.  If recips lacks a "@server.com"
 *                suffix, "@raytheon.com" (if length of string is more than 5
 *                characters) or "@swl.msd.ray.com" is added.
 *    linkText  - A String containing the text to put this link on.  If omitted,
 *                recips is used.
 *    strTarget - A String containing the target window in which to load the
 *                email script.  If omitted, "_top" is used.
 *
 * Examples:
 *
 *    emailHTML("selwebteam", "SEC Web Team");
 *       would return:
 *    <a href="/cgi-bin/email.pl?to=selwebteam%40raytheon.com">SEC Web Team</a>
 *
 *    emailHTML("Joseph Engineer", "Joe");
 *       would return:
 *    <a href="/cgi-bin/email.pl?to=Joseph_Engineer%40raytheon.com">Joe</a>
 *
 *    emailHTML("Joseph Engineer");
 *       would return:
 *    <a href="/cgi-bin/email.pl?to=Joseph_Engineer%40raytheon.com">
 *     Joseph Engineer</a>
 *
 ******************************************************************************/
function emailHTML(recips, linkText, strTarget)  {
   recips = recips.toString();   // Convert array to string, if necessary
   if (!linkText) linkText = recips;
   if (!strTarget) strTarget = "_top";
   var addresses = recips.split(/,\s*/); // Split the addresses at the commas

   for (x=0; x<addresses.length; x++)  {
      addresses[x] = addresses[x].replace(/\s/g, "_");
      addresses[x] = addresses[x].replace(/@/g, "%40");
      if (addresses[x].search(/%40/) < 0)
         addresses[x] += "%40"
                       + ((addresses[x].length <= 5)
                             ? "swl.msd.ray"
                             : "comcast")
                       + ".net";
   }

   var theLink = "<A HREF='mailto:"+addresses.join(',')+"'"
                 + " TARGET='"+strTarget+"'>"+linkText+"</A>";

   return theLink;
}

/*******************************************************************************
 *                                  getType()
 *
 * Description: Returns the object type of the given object.
 *
 * Syntax:      getType(obj);
 *
 * Parameters:
 *
 *    obj   - A JavaScript Core or User-Defined object.
 *
 * Examples:
 *
 *    var myObject = new Array();
 *    typeOfMyObject = getType(myObject);      // returns "Array"
 *
 ******************************************************************************/
function getType(obj)  {
   var re = /function ([^\(]+)\(/;
   var typeMatch = obj.constructor.toString().match(re);
   return typeMatch[1];
}

/*******************************************************************************
 *                                     icon
 * Title       -  Icon
 *
 * Overview    -  Writes out the return value of icon_html(format) to the
 *                current document.
 *
 * Syntax      -  icon(format);
 *
 * Parameters:
 *
 *    format   - A String containing any of the formats accepted by the
 *               icon_html() function.
 *
 * Examples:
 *
 *    icon("pdf");
 *       would output:
 *    <img src="/icon/pdf16.gif" width=16 height=16 border=0
 *         alt="Adobe Acrobat format">
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    icon is called by    -  N/A
 *
 *    icon calls           -  icon_html
 *
 ******************************************************************************/
function icon(strFormat)  {
   document.write(icon_html(strFormat));
}

/*******************************************************************************
 *                                 icon_html
 *
 * Title       -  Icon HTML
 *
 * Overview    -  Returns an <IMG> tag that will display a 16x16 icon
 *                representing the passed-in document format.
 *
 * Syntax      -  icon_html(format)
 *
 * Parameters:
 *
 *    format   -  A String specifying any of the following formats:
 *                   adobe, acrobat, pdf, doc, work, xls, excel, ppt,
 *                   powerpoint, mdb, access, txt, text, html, web, netscape,
 *                   tif, tiff, gif
 *
 * Examples:
 *
 *    icon_html("pdf");
 *       would return:
 *    <img src="/icon/pdf16.gif" width=16 height=16 border=0
 *         alt="Adobe Acrobat format">
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    icon_html is called by  -  docLinkHTML    DSFileLink  icon
 *
 *    icon_html calls         -  N/A
 *
 ******************************************************************************/
function icon_html(strFormat)  {
   strFormat = strFormat.toLowerCase();
   switch (strFormat)  {
      case "adobe":
      case "acrobat":
      case "pdf":
         file = "pdf16.gif";
         alt = "Adobe Acrobat format";
         break;
      case "doc":
      case "word":
         file = "word16.gif";
         alt = "Microsoft Word format";
         break;
      case "xls":
      case "excel":
         file = "excel16.gif";
         alt = "Microsoft Excel format";
         break;
      case "ppt":
      case "powerpoint":
         file = "ppt16.gif";
         alt = "Microsoft Powerpoint format";
         break;
      case "mdb":
      case "access":
         file = "mdb16.gif";
         alt = "Microsoft Access format";
         break;
      case "txt":
      case "text":
         file = "txt16.gif";
         alt = "Plain text format";
         break;
     /* case "html":
      case "web":
      case "netscape":
         file = "netscape16.gif";
         alt = "Netscape HTML format";
         break; */
      case "html":
      case "web":
      case "IE":
         file = "IE16.gif";
         alt = "IE HTML format";
         break;
      case "tif":
      case "tiff":
         file = "tif16.gif";
         alt = "Tagged Image Format (TIF) download";
         break;
      case "gif":
         file = "gif16.gif";
         alt = "Graphics Interchange Format (GIF)";
         break;
      case "zip":
         file = "zip16.gif";
         alt = "ZIP Format";
         break;
   }

   return '<img src="/icon/'+file+'" width=16 height=16 border=0 align="top"'
        +     ' alt="'+alt+'" \>';
}

/*******************************************************************************
 *                                   memoLink
 *
 * Title       -  Memo Link
 *
 * Overview    -  memoLink() returns an HTML hyperlink to a memo using the
 *                passed-in text, org, year, and memo number; plus hyperlinked
 *                icons representing the different specified formats.
 *
 *------------------------------------------------------------------------------
 *
 * Syntax:
 *
 *    memoLink([linkText], org, year, memoNum, exts, [target], [icon])
 *
 * Parameters:
 *
 *    linkText - Optional.  The text to be linked.  If no text is desired, the
 *               empty string ("") must be used.
 *    org      - Organization of the memo (7146, SEPG, etc)
 *    year     - Year of the memo (1999, 2000, 2001, etc)
 *    memoNum  - Bare memo number (153A, e.g.)
 *    exts     - Either an array or a comma-separated string of format types,
 *               each of which will be concatenated to pathname to form a real
 *               URL.
 *    target   - Optional.  The target window to open the file in.
 *    icons    - Optional.  Either an array or a comma-separated string of
 *               format types, each of which will be used to specify the icon
 *               image for each element of "exts".  If omitted, exts will be
 *               used.
 *
 * Note: If linkText is specified, the first format in formats will be used for
 *       the link.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    memoLink is called by   -  N/A
 *
 *    memoLink calls          -  docLinkHTML
 *
 *------------------------------------------------------------------------------
 *
 * Examples:
 *
 *   memoLink("FH04-RHST Waiver", 7146, 2003, 235, "pdf,doc", "_blank")
 *
 *   will return:
 *      <A HREF="/PDFs/memos/7146/2003/7146-03-235.pdf" TARGET="_blank">
 *       FH04-RHST Waiver</a>
 *      <A HREF="/PDFs/memos/7146/2003/7146-03-235.pdf">
 *       <img src="/icons/pdf16.gif" ...></A>
 *      <A HREF="/PDFs/memos/7146/2003/7146-03-235.doc">
 *       <img src="/icons/word16.gif" ...></A>
 *   Newlines added for comment clarity - they will not be included in the
 *   returned string.
 *   Note - to output to the document, use the String.out() method:
 *   memoLink("FH04-RHST Waiver", 7146, 2003, 235, "pdf,doc", "_blank").out();
 *
 ******************************************************************************/
function memoLink(linkText, org, year, memoNum, exts, targ, icons)  {
   org     = org.toString().toUpperCase();

   /****************************************************************************
    * year can be passed in as 2-digit or 4-digit.  If year is less than 97,
    * then it's a 2-digit year, so set year2D to year.  Since it's less than
    * 07, and we don't have any memos before 97, then it must be 00, 01, 02,
    * etc.  So we set year4D to year plus 2000.  If year between 97 and 99, set
    * year2D to year, but set year4D to 1900 plus year.  If year is 100 or
    * more, then it's most likely a 4-digit year, so set year2D to year mod
    * 100, and set year4D to year.  Finally, make sure year2D has 2 digits,
    * including a leading zero if necessary.
    ***************************************************************************/
   var year2D;
   var year4D;
   if (year < 97)  {
      year2D = year;
      year4D = year + 2000;
   }
   else if (year < 100)  {
      year2D = year;
      year4D = year + 1900;
   }
   else  {  // year >= 100
      year2D = year % 100;
      year4D = year;
   }

   if (year2D.toString().length == 1)  {
      year2D = "0" + year2D;
   }

   /****************************************************************************
    * Convert memoNum to a string, if necessary, and convert it to uppercase.
    * Separate the number part from the rev part (which might not exist) (e.g.
    * 123A -> 123, A).  Make sure the number part has three digits, adding
    * leading zeros if necessary.  Stick the rev part back on.
    ***************************************************************************/
   memoNum = memoNum.toString().toUpperCase();
   var re = /(\d+)([A-Z]?)/;
   var arMatch = memoNum.match(re);
   var numPart = arMatch[1];
   var revPart = arMatch[2];
   var numPartLen = numPart.toString().length;
   for (var x=1; x<=(3-numPartLen); x++)  {
      numPart = "0" + numPart;
   }
   memoNum = numPart + revPart;

   /****************************************************************************
    * Build the URL to the memo. e.g.: /PDFs/memos/7146/2003/7146-03-123A
    * Call docLinkHTML to build the appropriate HTML for the link and the icons.
    * Note that we're using the SEC_Site variable because this lib.js is
    * symbolically linked from the SEC Web Team site.
    ***************************************************************************/
   path = SEC_Site+"/PDFs/memos/"+org+"/"+year4D+"/"+org+"-"+year2D+"-"+memoNum;
   return docLinkHTML(linkText, path, exts, targ, icons);
}                                                     // end function memoLink()

/*******************************************************************************
 *                                     nbsp
 *
 * Title       -  Non-breaking spaces
 *
 * Overview    -  Returns an number of non-breaking spaces (&nbsp;)
 *
 * Syntax      -  nbsp([n])
 *
 * Parameters:
 *    n        -  The number of &nbsp;'s to return.  If omitted, 1 is used.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    nbsp is called by    -  N/A
 *
 *    nbsp calls           -  N/A
 *
 ******************************************************************************/
function nbsp(n)  {
   var retVal = new String();
   if (!n) n=1;
   for (var x=1; x<=n; x++)
      retVal += "&nbsp;";
   return retVal;
}                                                         // end function nbsp()

/*******************************************************************************
 *                                 new_icon()
 *
 * Description: returns a "New!" icon while the current date is within a
 *              a certain time interval.
 *
 * Syntax:      new_icon(post_date [, duration]);
 *
 * Parameters:
 *
 *    post_date - A String containing the date a document was posted.  It must
 *                be in a format accepted by the Date() object constructor.
 *    duration  - Number of days to display the New icon.  Default is 10.
 *
 * Examples:
 *
 *    new_icon("10/04/2002", 20);
 *
 ******************************************************************************/
function new_icon(post_date, duration)  {
   if (!duration) duration=10;

   duration *= 24  // hours in a day
   duration *= 60  // minutes in an hour
   duration *= 60  // seconds in a minute
   duration *= 1000        // milliseconds in a second

   var now         = new Date();
   var date_posted = new Date(post_date);
   var date_expire = new Date(Date.parse(date_posted) + duration);

   // document.write(now+"<BR>")
   // document.write(date_posted+"<BR>")
   // document.write(date_expire+"<BR>")

   if (now >= date_posted && now <= date_expire)
      return ('<img src="/images/new1.gif" width="55" height="21"'
            + '     border="" alt="New!">');
   else
      return '';

}   // End function new_icon()

/*******************************************************************************
 *                                 openwin()
 *
 * Description: Opens a window with the specified URL.  The new window will be
 *              named "displayWindow".
 *
 * Syntax:      openwin(URL, width, height, status, toolbar, menubar,
 *                      scrollbars, resizable);
 *
 * Parameters:
 *
 *    URL        - Required.  The URL to open in the new window.
 *    width      - Optional.  The width of the new window.  Default is 480.
 *    height     - Optional.  The height of the new window.  Default is 450.
 *    status     - Optional.  "yes" or "no" - whether to display the status bar.
 *                            Default is "no".
 *    toolbar    - Optional.  "yes" or "no" - whether to display the tool bar.
 *                            Default is "no".
 *    menubar    - Optional.  "yes" or "no" - whether to display the menu bar.
 *                            Default is "no".
 *    scrollbars - Optional.  "yes" or "no" - whether to display the scrollbars.
 *                            Default is "yes".
 *    resizable  - Optional.  "yes" or "no" - whether window is resizable.
 *                            Default is "yes".
 *
 ******************************************************************************/
function openwin(URL, width, height, status,
                 toolbar, menubar, scrollbars, resizable)  {
   if (!URL)  {
      alert("Cannot open new window.");
      return;
   }  // end if (!URL)
   if (!width) width=480;
   if (!height) height=450;
   if (!status) status="no";
   if (!toolbar) toolbar="no";
   if (!menubar) menubar="no";
   if (!scrollbars) scrollbars="yes";
   if (!resizable) resizable="yes";

   windowFeatures = "width=" + width
                  + ",height=" + height
                  + ",status=" + status
                  + ",toolbar=" + toolbar
                  + ",menubar=" + menubar
                  + ",scrollbars=" + scrollbars
                  + ",resizable=" + resizable;

   var dispWin = open("", "displayWindow");
   dispWin.close();
   dispWin = open(URL, "displayWindow", windowFeatures);

}  // end function openwin()

/*******************************************************************************
 *                                    oval()
 *
 * Description: Outputs a linked oval button.
 *
 * Syntax:      oval(url, alt_text);
 *
 * Parameters:
 *
 *    url     - URL of web page to which to link the oval button.
 *    altText - Text on the oval button.  This will be used in the ALT
 *              attribute of the <IMG> tag.  It will also be used to determine
 *              the filename of the oval button image.  The filename is altText
 *              with spaces and slashes (/) converted to underscores.  The
 *              filename is given a ".gif" extension, and is prefixed with
 *              "/js_lib/ovals/".  Be sure your file matches this format.
 *
 ******************************************************************************/
function oval(url, altText)  {
   var ovalHTML = altText.replace(/[ \/]/g, '_');
   ovalHTML =
      '<img src="/js_lib/ovals/'+ovalHTML+'" width=138 height=16 border=0'
    +     ' alt="'+altText+'">';

   ovalHTML = ovalHTML.link(url);
   document.write(ovalHTML);
}

/*******************************************************************************
 *                                     p()
 *
 * p() takes the String object and wraps it in <p>...</p> tags.  If align is
 * defined, then "align="'+align is inserted into the <p> tag.  If attribs is
 * defined, it is inserted into the <p> tag.  Thus,
 *    var Hi = "Hello World!";
 *    Hi.p("center", "class='size10'");
 * yields:
 *    <p align='center' class='size10'>Hello World!</p>
 * Note: no error checking is done on the align or attribs parameters.
 ******************************************************************************/
String.prototype.p = function(align, attribs)  {
   var retVal = "<p";
   if (align)
      retVal += " align='"+align+"'"
   if (attribs)
      retVal += " " + attribs
   retVal += ">"+this+"</p>";
   return retVal;
}

/*******************************************************************************
 *                                  pageTitle
 *
 * Title       -  Page Title
 *
 * Overview    -  Outputs a GIF image from /js_lib/titles for the Page title
 *
 * Syntax      -  pageTitle(alt_text, [lines]);
 *
 * Parameters:
 *
 *    alt_text - Text of the page title.  This will be used in the ALT attribute
 *               of the <IMG> tag.  It will also be used to determine the
 *               filename of the page title image.  To determine the filename,
 *               any international characters are converted to their English
 *               approximations, any spaces are converted to underscores, and
 *               any slashes, commas and parentheses are removed.  Any double-
 *               or single ampersands are converted to an "a" character.  The
 *               filename is given a ".gif" extension, and is prefixed with
 *               "/js_lib/titles/".  Be sure your file matches this format.
 *    lines    - If lines is 2, more vertical space is allocated for the image.
 *
 *------------------------------------------------------------------------------
 *
 * Interface List:
 *
 *    pageTitle is called by  -  N/A
 *
 *    pageTitle calls         -  N/A
 *
 ******************************************************************************/
function pageTitle(alt_text, lines)  {
   var imgsrc = alt_text.replace(/ /g, '_');
   imgsrc = imgsrc.replace(/[\/,()']/g, '');
   imgsrc = imgsrc.replace(/&&/g, '&');
   imgsrc = imgsrc.replace(/&/g, 'a');
   imgsrc = "/js_lib/titles/" + imgsrc + ".gif";
   var imgh = (lines == 2) ? 54 : 30;

   document.write(
      '<img src="'+imgsrc+'" width=379 height='+imgh+' alt="'+alt_text+'">');
}

/*******************************************************************************
 *                                parentTitle()
 *
 * Description: Outputs a parent page title.
 *
 * Syntax:      parentTitle(alt_text);
 *
 * Parameters:
 *
 *    alt_text - Text of the parent page title.  This will be used in the ALT
 *               attribute of the <IMG> tag.  It will also be used to determine
 *               the filename of the parent page title image.  To determine the
 *               filename, any spaces are converted to underscores, and any
 *               slashes, commas and parentheses are removed.  Any double- or
 *               single ampersands are converted to an "a" character.  The
 *               filename is given a ".parent.gif" extension, and is prefixed
 *               with "/js_lib/titles/".  Be sure your file matches this format.
 *
 ******************************************************************************/
function parentTitle(alt_text)  {
   var imgsrc = alt_text.replace(/ /g, '_');
   imgsrc = imgsrc.replace(/[\/,()']/g, '');
   imgsrc = imgsrc.replace(/&&/g, '&');
   imgsrc = imgsrc.replace(/&/g, 'a');
   imgsrc = "/js_lib/titles/" + imgsrc + ".parent.gif";

   document.write(
      '<img src="'+imgsrc+'" width=379 height=23 alt="'+alt_text+'">');
}

/*******************************************************************************
 *                                    Person
 *
 * Name and e-mail address of a person.
 *
 * Created by   :  Person Object constructor:
 *                    new Person(name)
 * Parameters   :  name  - Full name of the Person
 *                 email - Optional.  E-mail (without @raytheon.com or
 *                         @swl.msd.ray.com) of the Person.  If email is not
 *                         specified, name is used, with any spaces converted
 *                         to underscores.
 *
 * Notes - When the Person object is created, if the caller doesn't specify a
 *         domain for the e-mail address, either "@swl.msd.ray.com" or
 *         "@raytheon.com" is appended, depending on the length of email.
 *
 * Property  Data Type  Description
 * --------  ---------  --------------------------------------------------------
 * name      String     Name of the Person
 * email     String     E-Mail address of the person
 *
 * Method    Description
 * ------    ------------------------------------------------------------------
 * toString  Returns a link to email.pl using the Person's name and e-mail
 *           address.
 *
 ******************************************************************************/
function Person(name, email)  {
   this.name  = name;
   this.email = (email) ? email : name.replace(/\s/, "_");

   /****************************************************************************
    *                              toString
    *
    * Returns a link to email.pl using the Person's name and e-mail.
    *
    * Syntax      :  toString()
    * Parameters  :  none
    * Notes       :  email is URL-encoded before being placed in the HREF
    *                tag.
    ***************************************************************************/
   this.toString = function()  {
      return emailHTML(this.email, this.name);
}
}


/*******************************************************************************
 *                                 pdfWarning()
 *
 * Description: Writes out a warning to be patient while Adobe Acrobat Reader
 *              loads if the user is on a SunOS platform.
 *
 * Syntax:      pdfWarning();
 *
 * Parameters:
 *
 *    none.
 *
 ******************************************************************************/
function pdfWarning()  {
   if (userMachine() == "SunOS")  {
      document.write('<p><b>Note:</b> Some of the documents on this page are'
        + ' Adobe Acrobat (PDF) files. &nbsp;When clicking on PDF links, please'
        + ' be patient while Acrobat Reader loads (wait time is typically 30-60'
        + ' seconds). &nbsp;Please do not click the link more than once.</p>');
   }
}

/*******************************************************************************
 *                               podNav function
 *
 * Title:       Web Page Pod Navigation Creation
 *
 * Description: The podNav() function creates a new PodNavGroup and adds the
 *              level-2 and level-0 podNav tabs to it.  It then outputs it to
 *              the page.  The PodNavGroup specifies the a Level-2 navigation
 *              bar.  There is a different podNavGroup for each Level-1 Tab.
 *              The level-2 PodNavGroup to display is determined by the level1
 *              variable, which was computed at the beginning of the script and
 *              possibly modified by a call to the topNav() function.
 *
 * Syntax:      podNav()
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function podNav()  {

   var pods = new Array();
   pods['home']     = new PodNavGroup();
   pods['projects'] = new PodNavGroup();
   pods['learning'] = new PodNavGroup();
   pods['sepg']     = new PodNavGroup();
   pods['pal']      = new PodNavGroup();
   pods['people']   = new PodNavGroup();

   var newsPod = new PodNavTab("/index.php", "Home");
   pods['home'].add(newsPod);
   pods['home'].add("/services/service.html", "Service");
   pods['home'].add("/cooper.html", "Cooper Tires");
   pods['home'].add("/specials.shtml", "Specials Coupons");
   pods['home'].add("/appointments.html", "Appointments");
   pods['home'].add("/seasonal.html", "seasonal");
   pods['home'].add("/raffle.php", "gas_raffle"); 
   pods['home'].add("/employees/employees.html", "Our Employees");
   pods['home'].add("/About_Us.html", "About Us");
   pods['home'].add("/directions_hours.html", "Directions");
   pods['home'].add("/wwwboard/wwwboard.html", "Blog");
   pods['home'].add("/sitemap.html", "Site Map");

   pods['projects'].add("/patriot/index.shtml", "Patriot");
   pods['projects'].add("/efogm/",   "EFOGM");
   pods['projects'].add("/hawk/",    "HAWK");
   pods['projects'].add("/ceceor/",  "CEC/EOR");

   pods['learning'].add("/learning/cpd.html", "Continuous Professional Development", 2);
   pods['learning'].add("/learning/university.html", "Universities & Colleges");
   pods['learning'].add("http://www.petersons.com/", "Thomson Petersons Guide");

   pods['sepg'].add("/sepg/council/", "SEPG Council");
   pods['sepg'].add("/sepg/working_groups/", "Working Groups");
   pods['sepg'].add("/sepg/org_chart.html", "SEPG Organizational Chart");
   pods['sepg'].add(SEPGCal_URL, "SEPG Calendar");
   pods['sepg'].add("/sepg/documentation.html", "Documentation");
   pods['sepg'].add("/sepg/other_sepgs.html",
                    "Other Raytheon Process Groups", 2);
   pods['sepg'].add("/sepg/photos/", "Photo Gallery");
   pods['sepg'].add("/sitemap.html", "Site Map");
   pods['sepg'].addOff("http://mrc.rsc.ray.com/engprocess/",
                       "Engineering Process");

   var processPod = new PodNavTab("/pal/process/", "Process");
   processPod.add("/pal/process/proc_dir_struct.shtml",
                  "Process Directive Structure", 2);
   processPod.add("/PDFs/pal/process/jobaid.xls",
                  "SOI Compliance Checklists", 2);
   processPod.add("/pal/process/process_bulletins.html", "Process Bulletins");
   processPod.add("/pal/process/proc_imp_sug.html",
                  "Process Improvement Suggestions", 2);
   processPod.add("/pal/process/presentations.html", "Presentations");
   processPod.add("/pal/process/conference_reports.html", "Conference Reports");

   var metricsPod = new PodNavTab("/pal/process/metrics/", "Metrics");
   processPod.add(metricsPod);
   metricsPod.add("/pal/process/metrics/defect_containment/",
                  "Defect Containment");
   metricsPod.add("/pal/process/metrics/cycle_time.html",
                  "Cycle Time Reduction");
   metricsPod.add("/pal/process/metrics/stoplight.shtml", "Stoplight Charts");
   processPod.add("/pal/process/templates/", "Templates");
   processPod.add("/pal/process/tools/", "Tools");
   processPod.add("/pal/process/prep_material.html",
                  "Assessment Preparation Material", 2);
   processPod.add("/PDFs/pal/project/documentation/gooseversion2.pdf",
                  "Object Oriented Standards - GOOSE", 2);
   pods['pal'].add(processPod);

   var projectPod = new PodNavTab("/pal/project/", "Project");
   var planningPod = new PodNavTab("/pal/project/planning/",
                                   "Planning Material");
   planningPod.add("/pal/project/planning/proposal_packages.html",
                   "Proposal Packages");
   planningPod.add("/pal/project/planning/project_startup.html",
                   "Project Startup");
   planningPod.add("/pal/project/planning/sdp.html", "SDPs");
   planningPod.add("/pal/project/planning/statement_of_work.html",
                   "Statement of work");
   planningPod.add("/pal/project/planning/risk_mgmt_plans.html",
                   "Risk Management Plans");
   planningPod.add(DSFileURL("pdfQPMSQMpp"), "QPM &amp; SQM Plan");
   planningPod.add("/pal/project/planning/scm_plan.html", "SCM Plans");
   planningPod.add("/pal/project/planning/sqe_plan.html", "SQE Plans");
   planningPod.add("/pal/project/planning/training_plans.html",
                   "Training Plans");
   planningPod.add("/pal/project/planning/tail_checklist.html",
                   "Tailoring Checklists");
   planningPod.add("/pal/project/planning/proj_sizing_data.html",
                   "Sizing Data");
   projectPod.add(planningPod);

   var qpmsqmPod = new PodNavTab("/pal/project/qpm_sqm/", "QPM & SQM");
   qpmsqmPod.add("/pal/project/qpm_sqm/arch_met_min.shtml", "Archive");
   qpmsqmPod.add("/pal/project/qpm_sqm/org.html", "Organizational Material");
   qpmsqmPod.add("/pal/project/qpm_sqm/faq.html", "FAQ");
   qpmsqmPod.add("/pal/project/qpm_sqm/level4logo.html", "Level 4 Logos");
   projectPod.add(qpmsqmPod);

   projectPod.add("/pal/project/dp/", "Defect Prevention");
   projectPod.add("/pal/project/teams_of_4.html", "Teams of Four");
   projectPod.add("http://slpyeh.ed.ray.com/tracking/",
                  "Tracking Book Central");

   var docPod = new PodNavTab("/pal/project/documentation/", "Documentation");
   docPod.add("/pal/project/documentation/kpa_matrix.html",
              "Completed CMM KPA Matrices", 2);
   docPod.add("/pal/project/documentation/proj_proc_bul.html",
              "Process Bulletins");
   docPod.add("/pal/project/documentation/soft_tech_noti.html",
              "Software Technical Notices", 2);
   projectPod.add(docPod);

   projectPod.add("/pal/project/lessons_learned.html", "Lessons Learned");
   projectPod.add("/pal/project/fdm.html", "Formalized Decision Making", 2);
   projectPod.add("/pal/project/project_history_reports.html",
                  "Project History Reports");
   pods['pal'].add(projectPod);

   var commonPod = new PodNavTab("/pal/common/", "Common Resources");
   commonPod.add("http://home.ray.com/library/stds_partdb/",
                 "Military Standards");
   commonPod.add("/pal/common/links.html", "Process Links");
   commonPod.add("/pal/common/policy_procedures.html",
                 "Referenced P&Ps");
   commonPod.add("http://7149web.msd.ray.com/nesto/index.html",
                 "NESTO");
   commonPod.add("PDFs/qatp_revb.pdf",
                 "QE Training_Plan");
   commonPod.add("/pal/common/industry.html", "Industry Standards");
   commonPod.add("/PDFs/pal/common/audit_schedule.pdf",
                 "SW Baseline Audit Schedule", 2);
   commonPod.add("http://cmmi.rsc.raytheon.com/", "Raytheon CMMI");
   commonPod.add("http://www.stsc.hill.af.mil/", "CrossTalk");
   commonPod.add("http://sites1.it.ray.com/amdsqe/",
                 "AMDS QE");
   commonPod.add("http://sudweb2.ed.ray.com/C3S/SEPG/scm.html",
                 "SCM");
   commonPod.add("http://www.tantara.ab.ca/info.htm", "Informational Hotlist");
   commonPod.add("http://www.interscience.wiley.com", "Wiley Interscience");
   pods['pal'].add(commonPod);
   pods['pal'].add("/pal/repository/", "Improvement Collection");
   pods['pal'].add("/sitemap.html", "Site Map");
   pods['pal'].addOff("http://mrc.rsc.ray.com/engprocess/",
                      "Engineering Process");
		      
   var newsboardPod = new PodNavTab("/people/newsboard/", "News Board");
   newsboardPod.add("/people/newsboard/helpful_links/", "Helpful Links");
   newsboardPod.add("/people/newsboard/work_links/", "Work Links"); 
   pods['people'].add(newsboardPod);
   pods['people'].add(new PodNavTab("/people/our_people.html", "A Closer Look")); 
                  
     
   pods[level1].write();
}

/******************************************************************************
 *                                  redirect()
 *
 * The redirect() function writes out HTML notifying the user that the page has
 * moved to _fullURL_.  It tells them to update their links and bookmarks, and
 * that they will be redirected to the new page in _interval_ seconds.  After
 * _interval_ seconds, redirect() then calls redirect_to() to perform the
 * redirection.
 ******************************************************************************/
function redirect(fullURL, interval)  {
   if (!interval) interval = 10;

   var para = "We're sorry.  This page has moved.  The new URL is:";
   document.writeln(para.p());
   para = fullURL.link("javascript:redirect_to('"+fullURL+"')");
   document.writeln(para.p('center'));
   para = "Please update your links and bookmarks. &nbsp;You will be redirected"
        + " to the new page in "+interval+" seconds.";
   document.writeln(para.p());
   setInterval("redirect_to('"+fullURL+"')", interval*1000);
}                                                     // End function redirect()

/*******************************************************************************
 *                                redirect_to()
 *
 * The redirect_to() function is called by the redirect() function after a
 * specified number of seconds.  It redirects the browser to the redirect.pl
 * CGI script.
 *
 * If document.referrer is not "[unknown origin]", the redirect.pl script then
 * sends mail to the webmasters notifying them that the link on the referring
 * page needs to be updated.  redirect.pl then redirects the browser to the new
 * location.
 *
 * Note that this function uses the location.replace() method so that a new
 * browser history entry is not made.  When the user presses the back button
 * from the new URL, he or she will return to the page they were at before the
 * obsolete page.
 *
 ******************************************************************************/
function redirect_to(fullURL)  {
   location.replace("/cgi-bin/redirect.pl"
                  + "?referrer="+escape(document.referrer)
                  + "&oldURL="+escape(location.href)
                  + "&newURL="+escape(fullURL));
}                                                  // end function redirect_to()

/*******************************************************************************
 *                                  redLine()
 *
 * Description: Outputs a red line across the page.
 *
 * Syntax:      redLine([width]);
 *
 * Parameters:
 *
 *    width - Width in pixels or percent of the line.  Default is "100%".
 *
 ******************************************************************************/
function redLine(width)  {
   divider('#FF3300', width);
}

/*******************************************************************************
 *                               rotatingImages()
 *
 * Description: Displays a series of images.  Every interval seconds, the
 *              current image is replaced with the next one in the array.
 *              Note: every image must be the same height and width.
 *
 *
 * Syntax:      rightCol(images, imgWidth, imgHeight, align, interval);
 *
 * Parameters:
 *
 *    arImageFiles - Array of image filenames
 *    imgWidth     - Width of the images
 *    imgHeight    - Height of the images
 *    align        - Text for the ALIGN attribute of the image
 *    interval     - Time in seconds (can be floating-point) for each image to
 *                   be displayed.
 *
 ******************************************************************************/
var rotator = {imgIndex:1};
function rotatingImages()  {
   var arImageFiles;
   var imgWidth;
   var imgHeight;
   var align;
   var interval;

   for (var x=0; x<arguments.length; x++)  {
      var arg = arguments[x];
      var argType = getType(arg);
      if (argType == 'Array')
         arImageFiles = arg;
      /*************************************************************************
       * Assign numbers to imgWidth, imgHeight, interval - in that order.
       ************************************************************************/
      else if (argType == 'Number')  {
         if (imgWidth)
            if (imgHeight)
               interval = arg;
            else
               imgHeight = arg;
         else
            imgWidth = arg;

      }
      else if (argType == 'String')
         align = arg;
      else  {
         alert(argType);
      }
   }

   if (!interval) interval = 3;
   interval *= 1000;

   var arImages = new Array();
   for (var x=0; x<arImageFiles.length; x++)  {
      arImages.push(new Image(imgWidth, imgHeight));
      arImages[x].src = arImageFiles[x];
   }

   document.write(
      '<img src="'+arImageFiles[0]+'" width='+imgWidth+' height='+imgHeight
    +     ' align="'+align+'" name="rotatingImage" alt="Rotating Images"><br>');

   rotator.images = arImages;
   setInterval("rotate(rotator)", interval);
}

/*******************************************************************************
 *                                   rotate()
 *
 * Description: Loads the next image in the series of images.
 *
 *
 * Syntax:      rotate(theRotator);
 *
 * Parameters:
 *
 *    theRotator - Object containing an array of Image objects, and an integer
 *                 specifying the image index (where we are in the array).
 *
 ******************************************************************************/
function rotate(theRotator)  {
   var imgIndex = theRotator.imgIndex;
   var images = theRotator.images;
   document.images['rotatingImage'].src = images[imgIndex].src;
   theRotator.imgIndex = (imgIndex+1) % images.length;
}

/*******************************************************************************
 *                                 searchForm()
 *
 * Description: Outputs the standard Raytheon Web left-column search form.
 *
 * Syntax:      searchForm();
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function searchForm()  {
   var searchForm =
      '<table border=0 cellpadding=0 cellspacing=0 bgcolor="#fffff0" width=138>'
    +  '<tr><td>'
    +   '<img src="/js_lib/search/search.gif" width=138 height=24'
    +       ' alt="Search"></td></tr>'
    +  '<form method="get" name="search" target="resource window"'
    +       ' action="http://home.directory.ray.com/multiplematches.epl"'
    +       ' onSubmit="return sfValidate(this);">'
    +   '<input type="hidden" name="search_type" value="magic">'
    +   '<tr><td>'
    +    '<table border=0 cellpadding=0 cellspacing=0 width=138>'
    +     '<tr><td colspan=2>'
    +      '<input type="text" size=13 value="Find a person..."'
    +            ' name="search_string" class="size8"'
    +            ' onFocus="this.value=\'\';"></td></tr>'
    +     '<tr>'
    +      '<td width=45>'
    +       '<input type="image" border=0 src="/js_lib/search/go_p.gif"'
    +             ' width=45 height=19 alt="Go" name="image"></td>'
    +      '<td width=93 class="size9" align="right">'
    +       '<a href="http://home.directory.ray.com/advanced.epl"'
    +         ' target="_top">advanced</a></td></tr>'
    +    '</table></td></tr></form>'
    +  '<form method="get" name="site_search" target="resource window"'
    +       ' action="http://krs.res.ray.com/search97cgi/s97_cgi"'
    +       ' onSubmit="return sfValidate(this);">'
    +   '<input type="hidden" name="Collection" value="res_web">'
    +   '<input type="hidden" name="ResultTemplate"'
    +          'value="raytheon_allsearch_results.hts">'
    +   '<input type="hidden" name="Action" value="FilterSearch">'
    +   '<input type="hidden" name="Filter" value="res_web_filter_zone.hts">'
    +   '<input type="hidden" name="Title_zone" value="">'
    +   '<input type="hidden" name="Modified" value="">'
    +   '<input type="hidden" name="SortField" value="Score">'
    +   '<input type="hidden" name="SortOrder" value="Desc">'
    +   '<tr><td>'
    +    '<table border=0 cellpadding=0 cellspacing=0 width=138>'
    +     '<tr><td colspan=2>'
    +      '<input type="text" size=13 value="Search this site..."'
    +            ' name="QueryText" class="size8"'
    +            ' onFocus="this.value=\'\';"></td></tr>'
    +     '<tr>'
    +      '<td width=45>'
    +       '<input type="image" border=0 src="/js_lib/search/go_w.gif"'
    +             ' width=45 height=19 alt="Go" name="image"></td>'
    +      '<td width=93 class="size9" align="right">'
    +       '<a href="http://home.ray.com/search.html" target="_top">'
    +        'advanced</a></td></tr>'
    +   '</table></td></tr></form>'
    + '</table>';
   document.write(searchForm);
}


      /*************************************************************************
       *                                Section
       *
       * Collection of data defining a Section name along with its documents
       *
       * Created by   :  Project Object constructor:
       *                    new Project(name)
       * Parameters   :  name - Name of the Project.
       *
       * Property  Data Type       Description
       * --------  --------------  --------------------------------------------
       * name      String          Name of the Section
       * Docs      Array of Documents  Document entries
       *
       * Method    Description
       * ------    ------------------------------------------------------------
       * addDoc    Adds a Document to the Docs array
       * toString  Returns the Project with its Documents in HTML format
       *
       ************************************************************************/

      function Section(name, border, bordercolor, padding, spacing)  {
         this.name = name;
       this.border = border;
       this.bordercolor = bordercolor;
       this.padding = padding;
       this.spacing = spacing;
         this.Docs  = new Array();


         /**********************************************************************
          *                               addDoc
          *
          * Adds a documents to the Docs array.
          *
          * Syntax      :  addDoc(doc)
          * Parameters  :  doc - Documentobject representing a file
          * Description :  addDoc uses the Array.push() method to add the
          *                document to the Docs array.
          *********************************************************************/

         this.addDoc  = function (doc)  {
            this.Docs.push(doc);
         }

         /**********************************************************************
          *                              toString
          *
          * Returns Project and its documents in HTML format.
          *
          * Syntax      :  toString()
          * Parameters  :  none
          * Description :  toString() builds a string containing the name as an
          *                <P> heading.  It then adds a table for the Documents
        *                and adds each Document using its own toString() method.
          *                It then returns the built string.
          *********************************************************************/

         this.toString = function ()  {
            var retVal = '<a name="'+this.name+'"></a>'
                       + '<p class="bluehead2">'+this.name+'</p>';
            var numDocs  = this.Docs.length;

            /*******************************************************************
             * If there are any Documents, create a new table for each
             * document to the string using the document's own
             * toString() method.  End the table.
             ******************************************************************/
            if (numDocs > 0)  {
               retVal +=
                  '<table border=' + this.border
             + ' bordercolor="'+ this.bordercolor + '"'
             + ' cellpadding=' + this.padding
             + ' cellspacing=' + this.spacing +'>'

               for (var i=0; i<numDocs; i++)
                  retVal += this.Docs[i].toString();
               retVal += '</table>';
            }

            return retVal;
         }                                            // End function toString()
      }                                               // End Section class


/*******************************************************************************
 *                                   spacer()
 *
 * Title:       Outputs a spacer image.
 *
 * Description: spacer() outputs an IMG tag that displays the //andrea/images/spacer.gif
 *              image.  It puts w and h into the width and height attributes of
 *              the IMG tag.
 *
 * Syntax:      spacer(w, h)
 *
 * Parameters:  w - width of spacer.   Default = 1.
 *              h - height of spacer.  Default = 1.
 *
 ******************************************************************************/
function spacer(w, h)  {
   if (!w) w = 1;
   if (!h) h = 1;
   return '<img src="/images/spacer.gif" width='+w+' height='+h+' alt="">';
}

/*******************************************************************************
 *                                 splitPath()
 *
 * Title:       Split a URL / pathname into an array
 *
 * Description: splitPath() takes a URL or an array and splits each node into
 *              an array.  If a path starts with "cgi-bin", it is removed.  If a
 *              pathname does not start with one of the directories in the
 *              dirNames array, "home" is inserted at the beginning of the
 *              array.
 *
 * Syntax:      splitPath(path)
 *
 * Parameters:  path - A String representing a URL or a path
 *
 * Examples:
 *    arPath = splitPath("http://mrc.rsc.ray.com/ipds");
 *       -> arPath: ['http://mrc.ray.com', 'ipds']
 *    arPath = splitPath("/tech/ip/inventions.html");
 *       -> arPath: ['tech', 'ip', 'inventions.html']
 *    arPath = splitPath("/sitemap.html");
 *       -> arPath: ['home', 'sitemap.html']
 *
 ******************************************************************************/
function splitPath(path)  {

   /****************************************************************************
    * If the path begins with an outside website reference, store it in array
    * arHost.  Remove the outside website reference from the path, as well as
    * any leading slash.
    ***************************************************************************/
   var httpRe = "^(http://[^/]+)";
   var arHost = path.match(httpRe);

   path = path.replace(httpRe, "");
   path = path.replace(/^\//, "");

   /****************************************************************************
    * Split the path into directory tree nodes.  i.e.:
    *    /org/fellows/index.html becomes:
    *    ('org', 'fellows', 'index.html');
    ***************************************************************************/
   var arTree = path.split("/");

   /****************************************************************************
    * If the first node is "cgi-bin", remove it.  The CGI scripts' directory
    * structure should be set up the same way as the documents' directory
    * structure.  Thus, removing 'cgi-bin' from the beginning is necessary and
    * sufficient to obtain the correct location.
    ***************************************************************************/
   if (arTree[0] == 'cgi-bin')
      arTree.shift();

   /****************************************************************************
    * If arHost is defined, insert the first element of it before the first
    * element of the directory tree node array.
    ***************************************************************************/
   if (arHost)
      arTree.unshift(arHost[0]);

   /****************************************************************************
    * If arHost is not defined, then the path refers to a file on this server.
    * If the first element of arTree does not match one of the elements of
    * dirNames, insert "home" before the first element of arTree.  This
    * reflects the fact that any Level 2 pages off of the home page will be on
    * the same directory level as the rest of the Level 1 pages.
    ***************************************************************************/
   else if (!arTree[0] || dirNames.join(",").indexOf(arTree[0]) < 0)
      arTree.unshift('home');

   return arTree;
}

/*******************************************************************************
 *                                 String.out()
 *
 * Title:       Output a String object
 *
 * Description: The out() method outputs the String object to the document
 *              object
 *
 * Syntax:      myString.out();
 *
 * Parameters:  none.
 *
 ******************************************************************************/
String.prototype.out = function ()  {
   document.write(this);
}

/*******************************************************************************
 *                                   to_top()
 *
 * Title:       Outputs a "^Top of Page" link.
 *
 * Description: to_top() outputs an IMG tag that displays the ^Top of Page icon.
 *              The IMG tag is linked to a "top" page anchor.
 *
 * Syntax:      to_top()
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function to_top()  {
   document.write(topOfPage());
}

/*******************************************************************************
 *                                 toolsLink()
 *
 * Title:       Link to a Patriot Tool
 *
 * Description: Returns an HTML hyperlink to a Patriot Tool
 *
 * Syntax:      toolsLink(text, relURL, target)
 *
 * Parameters:
 *    text   - text to apply the link to
 *    relURL - the URL of the tool, minus the hostname and server port
 *    target - target window for the link
 *
 ******************************************************************************/
function toolsLink(text, relURL, target)  {
    theLink = '<A HREF="'+toolsURL(relURL)+'"';
    if (target) theLink += ' TARGET="'+target+'"';
    theLink += '>'+text+'</A>';
    return theLink;
}                                                    // end function toolsLink()

/*******************************************************************************
 *                                  toolsURL()
 *
 * Title:       Tools URL
 *
 * Description: Returns the fully qualified URL of a Patriot Tool
 *
 * Syntax:      toolsURL(relURL);
 *
 * Parameters:
 *    relURL - the URL of the tool, minus the hostname and server port
 *
 ******************************************************************************/
function toolsURL(relURL)  {
   var port = (relURL.search(/wstr/i) >= 0) ? 8080 : 8086;
   return 'http://slpzap.msd.ray.com:'+port+relURL;
}                                                     // end function toolsURL()

/*******************************************************************************
 *                                 topOfPage()
 *
 * Title:       Returns a "^Top of Page" link.
 *
 * Description: to_top() returns an IMG tag that displays the ^Top of Page icon.
 *              The IMG tag is linked to a "top" page anchor.
 *
 * Syntax:      topOfPage()
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function topOfPage()  {
   var html =
      '<img src="/icon/top.gif" width=138 height=18 border=0'
    +     ' alt="^ Top of page">';
   html = html.link("#top");
   return html;
}

/*******************************************************************************
 *                               Tombstone
 *
 * Raytheon Web Template Tombstone element.
 *
 * Created by  -  Tombstone Object constructor:
 *                   new Tombstone(title, column, highlight);
 *
 * Parameters (can be specified in any order) -
 *    title      -  Title of the tombstone.  Used to determine tombstone title
 *                  gif filename
 *    column     -  Either LEFT or RIGHT
 *    highlight  -  Boolean - whether to highlight this tombstone
 *    arrowColor -  Either "RED", "GRAY" or "NONE".  Default is "GRAY".
 *
 * Note -  The title parameter is used in two places:
 *            1) As the ALT tag in the tombstone heading image
 *            2) Determines the tombstone heading image filename.
 *         Choose the heading image filename to match title.  toString() will
 *         replace spaces with underscores and remove any apostrophes to
 *         determine the filename.  If the file is for the left column, append
 *         ".138.gif" to the filename.  If it is for the right column, append
 *         ".207.gif" to the filename.  Put it in the /js_lib/tombstone/
 *         directory.
 *
 * Example  -
 *
 *    var myTS = new Tombstone("Highlights", LEFT, true);
 *    myTS.add("Bullet Item 1");    // These can be HTML-formatted
 *    myTS.add("Bullet Item 2");    // These can be HTML-formatted
 *    myTS.out();
 *
 * Property    Data Type         Description
 * ---------   --------------    -----------------------------------------------
 * stTitle     String            Title of the tombstone
 * arBullets   Array of Strings  Bullets in the tombstone
 * nWidth      Number            Width of column in which tombstone will go
 * stBGColor   String            Background color of the tombstone
 * stArrowCol  String            Color of the arrows - Red, Gray or none.
 *
 * Method    Description
 * --------  -------------------------------------------------------------------
 * add       Adds a bullet to the arBullets
 * toString  Returns the tombstone in HTML format
 * out       Outputs the tombstone to document.window
 *
 ******************************************************************************/
function Tombstone()  {
   this.stTitle;                     // Tombstone title
   this.arBullets  = new Array();    // Tombstone bullets;
   this.nWidth;                      // LEFT or RIGHT
   this.stBGColor  = "#F5F5F5";      // "#F5F5F5" or "#FFFFFC"
   this.stArrowCol = "gray";

   for (var i=0; i<arguments.length; i++)  {
      var arg = arguments[i];
      var argType = getType(arg);
      switch (argType)  {
         case "String":
            if (arg == 'RED' || arg == 'GRAY')
               this.stArrowCol = arg.toLowerCase();
            else if (arg == 'NONE')
               this.stArrowCol = "";
            else
               this.stTitle = arg;

            break;
         case "Number":
            this.nWidth = arg;
            break;
         case "Boolean":
            this.stBGColor = (arg) ? "#FFFFCC" : "#F5F5F5";
            break;
      }
   }

   this.add = function(bullet)  {
      this.arBullets.push(bullet);
   }

   this.toString = function(pretty)  {
      var stFile = this.stTitle.replace(/'/g, ''); // Delete apostrophes
      stFile     = stFile.replace(/\//g, '');   // Delete slashes
      stFile     = stFile.replace(/\s/g, '_');  // Replace spaces w/underscores
      stFile     = "/js_lib/tombstone/"+stFile+"."+this.nWidth+".gif";

      var nBulls = this.arBullets.length;
      var nWid   = this.nWidth;

      var ts =
         '<table border=0 cellpadding=0 cellspacing=0'
       +       ' bgcolor="'+this.stBGColor+'">'
       +  '<tr>';

      if (nWid == RIGHT)
         ts +=
            '<td width=24 rowspan='+(nBulls+2)+' bgcolor="White">'
          +  '<img src="/images/spacer.gif" width=24 height=1 alt=""></td>';

      if (this.stArrowCol)  {
         var arrowFile = "/js_lib/tombstone/arrow_"+this.stArrowCol+".gif";
         var nWid2 = nWid - 12;
         ts += '<td colspan=2>'
             +  '<img src="'+stFile+'" width='+nWid+' height=19'
             +      ' alt="'+this.stTitle+'"></td></tr>';
         for (var i=0; i<nBulls; i++)
            ts += '<tr valign="top">'
                +  '<td><img src="'+arrowFile+'" width=12 height=12'
                +          ' alt="&gt;"></td>'
                +  '<td width='+nWid2+'>'+this.arBullets[i]+'</td></tr>';
         ts += '<tr>'
             +  '<td width='+nWid+' height=12 colspan=2>';
      }
      else  {
         ts += '<td>'
             +  '<img src="'+stFile+'" width='+nWid+' height=19'
             +      ' alt="'+this.stTitle+'"></td></tr>';
         for (var i=0; i<nBulls; i++)
            ts += '<tr valign="top">'
                +  '<td width='+nWid+'>'+this.arBullets[i]+'</td></tr>';
         ts += '<tr>'
             +  '<td width='+nWid+' height=12>';
      }

      ts += '<img src="/js_lib/tombstone/ts_foot.'+nWid+'.gif"'
         +      ' width='+nWid+' height=12 alt=""></td></tr></table>';

      if (pretty)
         ts = ts.replace(/<([^\/])/g, "\n<$1");

      return ts;
   }

   this.out = function()  {
      document.write(this.toString());
   }
}                                                    // end function Tombstone()

/*******************************************************************************
 *                               topNav function
 *
 * Title:       Web Page Top Navigation Creation
 *
 * Description: The topNav() function creates a new TopNavGroup and adds the
 *              tabs along the top.  It then outputs it to the page.  The
 *              TopNavGroup specifies the Level-1 navigation bar, including the
 *              Raytheon logo, the Site ID, and the tabs which link to the
 *              level-1 subpages in the web site.  The Raytheon Standard Web
 *              Template recommends 5-7 tabs be used.  The level-1 tab to
 *              highlight is determined by comparing the URL of each tab to the
 *              level1 variable, which holds the first subdirectory contained in
 *              the URL.  This is computed at the beginning of the script.
 *
 * Syntax:      topNav([force])
 *
 * Parameters:  force - Optional.  force can be specified to ignore which
 *                      directory the page is in, and to highlight the
 *                      corresponding tab.  force can be a number from 0 to one
 *                      less than the number of tabs, or it can be a directory
 *                      (e.g. "org").
 *
 ******************************************************************************/
function topNav(force)  {
   if (force != undefined)
      force--;
   var navGroup = new TopNavGroup("IDS Software Engineering Center", force);

   navGroup.add(new TopNavTab("/index.html",          "IDS SEC Home",     71));
   navGroup.add(new TopNavTab("/projects/", "Projects",               40));
   navGroup.add(new TopNavTab("/learning/", "Learning",               43));
   navGroup.add(new TopNavTab("/sepg/",
                              "Software Engineering Process Group",  184));
   navGroup.add(new TopNavTab("/pal/",      "Process Asset Library", 106));
   navGroup.add(new TopNavTab("/people/",   "People",                 34));

   navGroup.write();
}

/*******************************************************************************
 *                                userMachine()
 *
 * Title:       Determine client's machine type.
 *
 * Description: The userMachine() function looks at the navigator.userAgent
 *              property and returns "SunOS", "WinNT" or "Other", depending on
 *              the client's machine type.
 *
 * Syntax:      userMachine()
 *
 * Parameters:  none.
 *
 ******************************************************************************/
function userMachine()  {
   var machine = navigator.userAgent;
   if (machine.search(/SunOS/) >= 0)
      return "SunOS";
   else if (machine.search(/WinNT/) >= 0)
      return "WinNT";
   else
      return "Other";
}

/*******************************************************************************
 *                                 WebCITISLink
 *
 * Title:   Output link to WebCITIS
 *
 * Description: The WebCITISLink() function outputs a link to WebCITIS to the
 *              html page.
 *
 * Syntax:  WebCITISLink(linktext)
 *
 * Parameters:  linkText - (optional) Text to link.  Default is "WebCITIS".
 *
 ******************************************************************************/
function WebCITISLink(linkText)  {
   if (!linkText) linkText = "WebCITIS";
   document.write('<a href="'+WebCITIS_URL+'"> '+linkText+'</a>');
}

/*******************************************************************************
 *                                  WebCalLink
 *
 * Title:   Output link to WebCal
 *
 * Description: The WebCalLink() function outputs a link to WebCal to the html
 *              page.
 *
 * Syntax:  WebCalLink(linktext)
 *
 * Parameters:  linkText - (optional) Text to link.  Default is "WebCal".
 *
 ******************************************************************************/
function WebCalLink(linkText)  {
   if (!linkText) linkText = "WebCal";
   document.write('<a href="'+WebCal_URL+'"> '+linkText+'</a>');
}

/*******************************************************************************
 *                                 SEPGCalLink
 *
 * Title:   Output link to the SEPG Calendar
 *
 * Description: The SEPGCalLink() function outputs a link to the SEPG Calendar
 *              to the html page.
 *
 * Syntax:  SEPGCalLink(linktext)
 *
 * Parameters:  linkText - (optional) Text to link.  Default is "SEPG Calendar".
 *
 ******************************************************************************/
function SEPGCalLink(linkText)  {
   if (!linkText) linkText = "SEPG Calendar";
   document.write('<a href="'+SEPGCal_URL+'"> '+linkText+'</a>');
}

/*******************************************************************************
 *                                   WSTRLink
 *
 * Title:   Output link to WSTR.
 *
 * Description: The WSTRLink() function outputs a link to WSTR to the html page.
 *
 * Syntax:  WSTRLink(linktext)
 *
 * Parameters:  linkText - (optional) Text to link.  Default is "WSTR".
 *
 ******************************************************************************/
function WSTRLink(linkText)  {
   if (!linkText) linkText = "WSTR";
   document.write('<a href="'+WSTR_URL+'"> '+linkText+'</a>');
}

/*******************************************************************************
 *                                  wm_link()
 *
 * Title:       Output e-mail link to the webmasters.
 *
 * Description: The wm_link() function uses the email() function to output a
 *              link to the webmasters.
 *
 * Syntax:      wm_link([linkText])
 *
 * Parameters:  linkText - Text to use on the e-mail link.  If omitted,
 *              "webmaster" is used.
 *
 ******************************************************************************/
function wm_link(linkText)  {
   if (!linkText)  {
      linkText = "webmasters";
      if (g_wm_em.search(/,/) >= 0) linkText += "s";
   }
   email(g_wm_em, linkText);
}

/*******************************************************************************
 *                               Helper functions
 *
 * The following functions are "helper" functions used by the user functions
 * and objects.  You shouldn't need to use these functions by themselves from
 * your HTML page.
 *
 *       sfValidate() - Search Form Validation
 *
 ******************************************************************************/

/*******************************************************************************
 *                                 sfValidate()
 *
 * Title:       Search Form Validation
 *
 * Description: Validates the search form output by the searchForm() function.
 *
 * Syntax:      <FORM ... onSubmit="return sfValidate(this);">
 *
 * Parameters:  thisForm - the form object to validate.  Normally, the "this"
 *              keyword is used here.
 *
 ******************************************************************************/
function sfValidate(thisForm)  {
   var defVal;
   var textField;
   if (thisForm == document.search)  {
      defVal = "Find a person...";
      textField = thisForm.search_string;
   }
   else if (thisForm == document.site_search)  {
      defVal = "Search this site...";
      textField = thisForm.QueryText;
   }
   else  {
      alert("Error in page design.  Please contact the webmasters."
          + "  Error code 1.");
   }

   if (textField.value == defVal || textField.value == "")  {
      thisForm.target = "_self";
      alert('Error: No valid search criteria entered.  Please try again.');
      textField.value = defVal;
      return false;
   }
   return true;
}

// -->
