<!--// GENERATE TABLE HTML CODE FROM TABLE DATA

// <!--BR--><!-- Source formatting line breaks. Convert to <BR> in source display caller.

// global variables
var orderprev = "";
var ordernumdecend = true;
var collapsed = true;
var region = "";
var axis = 0;
var hillparms = 0;
THclass = new Array();
    THclass['Name']      = "";
    THclass['Gradient']  = "";
    THclass['Length']    = "";
    THclass['Height']    = "";
    THclass['Time']      = "";
    THclass['Latitude']  = "";
    THclass['Longitude'] = "";
    THclass['Direction'] = "";
var shownotes = 1;  // 0 = none, 1 = on second line, 2 = single line in place of speed, lat/lon & from Louisville columns

var order = 'ByRegion';
var firstcall = true;
var climbx = new Array();

// Records are assumed to be grouped by region, county or general areas, each beginning with a region header record

fxrect =  0;  // FIELD 00: 1 = Region Record, 2 = Hill Record
fxcode =  1;  // FIELD 01: Region code

// Region Record fields

fxregt =  2;  // FIELD 02: Region title
fxregd =  3;  // FIELD 03: Region description

// Hill Record fields

fxroll =  2;  // FIELD 02: Pavement length in miles (rolling distance, bottom of climb to top)
fxeifb =  3;  // FIELD 03: Elevation in feet - Bottom of hill
fxeift =  4;  // FIELD 04: Elevation in feet - Top of hill
fxlatb =  5;  // FIELD 05: Latitude  - Bottom of hill
fxlonb =  6;  // FIELD 06: Longitude - Bottom of hill
fxlatt =  7;  // FIELD 07: Latitude  - Top of hill
fxlont =  8;  // FIELD 08: Longitude - Top of hill
fxname =  9;  // FIELD 09: Name of hill or road shown in table (html allowed)
fxtext = 10;  // FIELD 10: Text for online map pushpin
fxnote = 11;  // FIELD 11: Notes

// Calculated Value Fields appended to hill records on first call

fxrise = 12;  // rise
fxgrad = 13;  // gradient
fxdist = 14;  // distance
fxdire = 15;  // direction
fxdirf = 16;  // direction formatted
fxsped = 17;  // speed
fxtime = 18;  // time


function climbsgen(runtime) {
  if (firstcall) {

    // Build a gradient-speed conversion table valid 0-50%
    gradspeed = new Array();
    speed = 12;
    for (grad = 0; grad <= 500; grad++) {
      while (((0.3/speed) - (0.0001837 * speed * speed) - 0.004) < (grad / 1000)) {speed-=0.01};
      gradspeed[grad] = Math.round(speed * 100) / 100; 
    };
    latLouisville =  38.256315 * Math.PI / 180;
    lonLouisville = -85.753258 * Math.PI / 180;

    // Build calculated fields
    for (x = 0; x < climbs.length; x++) {
      if (climbs[x][fxrect] == 2) {
        roll     = climbs[x][fxroll];
        rise     = climbs[x][fxeift] - climbs[x][fxeifb];
        botlat   = climbs[x][fxlatb];
        botlon   = climbs[x][fxlonb];
        toplat   = climbs[x][fxlatt];
        toplon   = climbs[x][fxlont];
        gradient  = rise / Math.sqrt((roll * roll * 27878400) - (rise * rise));
        speed     = gradspeed[Math.round(gradient * 1000)];
        climbtime = Math.round(roll / 0.000621 / speed);
        latHill = botlat * Math.PI / 180;
        lonHill = botlon * Math.PI / 180;
        angDistance = Math.acos((Math.sin(latLouisville) * Math.sin(latHill)) +
          (Math.cos(latLouisville) * Math.cos(latHill) * Math.cos(lonHill - lonLouisville)));
        distance = 3963 * angDistance;
        if ((latHill == latLouisville) && (lonHill == lonLouisville)) {direction = 0}
        else {
          if (lonHill == lonLouisville) {if (latLouisville > latHill) {direction = 180} else {direction = 0}}
          else {
            direction = (Math.asin(Math.cos(latHill) * Math.sin(lonHill - lonLouisville) / Math.sin(angDistance))) * 180 / Math.PI;
            if(latHill < latLouisville) {direction = 180 - direction;}
            else {if (lonHill < lonLouisville) {direction += 360}};
          };
        };
        if (direction <= 22.5)      {dir = "N";  dirfmt = "N"}
        else {if (direction <= 67.5)  {dir = "NE"; dirfmt = "<FONT size=1>NE</FONT>"}
          else {if (direction <= 112.5) {dir = "E";  dirfmt = "E"}
            else {if (direction <= 157.5) {dir = "SE"; dirfmt = "<FONT size=1>SE</FONT>"}
              else {if (direction <= 202.5) {dir = "S";  dirfmt = "S"}
                else {if (direction <= 247.5) {dir = "SW"; dirfmt = "<FONT size=1>SW</FONT>"}
                  else {if (direction <= 292.5) {dir = "W";  dirfmt = "W"}
                    else {if (direction <= 337.5) {dir = "NW"; dirfmt = "<FONT size=1>NW</FONT>"}
                                               else {dir = "N";  dirfmt = "N"};
        };};};};};};};
        climbs[x][fxrise] = rise;
        climbs[x][fxgrad] = gradient;
        climbs[x][fxdist] = distance;
        climbs[x][fxdire] = dir;
        climbs[x][fxdirf] = dirfmt;
        climbs[x][fxsped] = speed;
        climbs[x][fxtime] = climbtime;
      };
    };
    firstcall = false;
  };

  tablehtml = new Array();
  thx = -1;
  count = 0;
  totaldistance = 0;
  totalclimb = 0;

  thx++; tablehtml[thx] = "<CENTER><!--BR--><TABLE><!--BR-->  <TR><!--BR-->    <TD align=\"left\"><CENTER><U><B>MAP LINKS</B></u></CENTER><!--BR-->";
  thx++; tablehtml[thx] =
    "<A href=\"http://maps.google.com/\">" +
        "<IMG src=\"gifs/dotg.gif\" border=0 width=18 height=18 alt=\"Google Maps\" title=\"Google Maps\" target=mymap></A>" +
        " - Google Maps<BR><!--BR-->" +
    "<A href=\"http://maps.live.com/\">" +
        "<IMG src=\"gifs/dotm.gif\" border=0 width=18 height=18 alt=\"MSN Live Maps\" title=\"MSN Live Maps\" target=mymap></A>" +
        " - MSN Live Maps<BR><!--BR-->" +
    "<A href=\"http://www.mappoint.com/\">" +
        "<IMG src=\"gifs/dotp.gif\" border=0 width=18 height=18 alt=\"MapPoint (MSN)\" title=\"MapPoint (MSN)\" target=mymap></A>" +
        " - Map Point (MSN)<BR><!--BR-->" +
    "<A href=\"http://www.mapquest.com/\">" +
        "<IMG src=\"gifs/dotq.gif\" border=0 width=18 height=18 alt=\"MapQuest\" title=\"MapQuest\" target=mymap></A>" +
        " - MapQuest<BR><!--BR-->" +
    "<A href=\"http://www.terraserver.com/\">" +
        "<IMG src=\"gifs/dott.gif\" border=0 width=18 height=18 alt=\"TerraServer USGS-MSN Topo\" title=\"TerraServer USGS-MSN Topo\" target=mymap></A>" +
        " - TerraServer (USGS-MSN) Topographic (free)<BR><!--BR-->" +
    "<A href=\"http://www.topozone.com/\">" +
        "<IMG src=\"gifs/dotz.gif\" border=0 width=18 height=18 alt=\"TopoZone\" title=\"TopoZone\" target=mymap></A>" +
        " - TopoZone Topographic Maps (limited free)<BR><!--BR-->";
  thx++; tablehtml[thx] = "    </TD><!--BR-->  </TR><!--BR--></TABLE>&nbsp<!--BR--><!--BR-->";

  thx++; tablehtml[thx] = "<TABLE><!--BR-->";
  thx++; tablehtml[thx] = "  <TR><TD class=gradtier1>Grade > 12%</TD><TD class=gradtier2>Grade > 9%</TD>" +
    "<TD class=timetier1 rowspan=2 align=center><FONT size=-1>Time > 5 min<BR>(85kg, 250W)<BR>cal=kcalories&nbsp;burned</FONT></TD></TR><!--BR-->";
  thx++; tablehtml[thx] = "  <TR><TD class=hightier1>Height > 100 m</TD><TD class=longtier1>Length > 1.5 km</TD></TR><!--BR-->";
  thx++; tablehtml[thx] = "</TABLE>&nbsp<!--BR--><!--BR-->";

  thx++; tablehtml[thx] = "<TABLE width=640><!--BR-->";
  thx++; tablehtml[thx] = "  <TR><!--BR-->";

// TABLE HEAD

  NumberOfColumns = 9; // IMPORTANT: Update if changed!

  if (runtime && document.getElementById) {
    if (shownotes !=2) {rspan = " rowspan=2"; wspan = " width=33%"} else {rspan = ""; wspan = ""};
    thx++; tablehtml[thx] = "    <TH" + THclass.Name     + rspan + wspan + "><A href=\"Javascript:climbsort('Name')\"" +
      "onMouseOver=\"window.status='Sort by Name' ;return true\" onMouseOut=\"window.status='' ;return true\"" + THclass.Name + ">" +
      "Name</A>&nbsp;&nbsp;</TH><!--BR--><!--BR-->";
    thx++; tablehtml[thx] = "    <TH" + THclass.Gradient + "><A href=\"Javascript:climbsort('Gradient')\"" +
      "onMouseOver=\"window.status='Sort by Gradient' ;return true\" onMouseOut=\"window.status='' ;return true\"" + THclass.Gradient + ">" +
      "<FONT size=-1>Grade</FONT></A></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH" + THclass.Length   + "><A href=\"Javascript:climbsort('Length')\"" +
      "onMouseOver=\"window.status='Sort by Length' ;return true\" onMouseOut=\"window.status='' ;return true\"" + THclass.Length + ">" +
      "<FONT size=-1>Length</FONT></A></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH" + THclass.Height   + "><A href=\"Javascript:climbsort('Height')\"" +
      "onMouseOver=\"window.status='Sort by Height' ;return true\" onMouseOut=\"window.status='' ;return true\"" + THclass.Height + ">" +
      "<FONT size=-1>Height</FONT></A></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH" + THclass.Time     + "><A href=\"Javascript:climbsort('Time')\"" +
      "onMouseOver=\"window.status='Sort by Time' ;return true\" onMouseOut=\"window.status='' ;return true\"" + THclass.Time + ">" +
      "<FONT size=-1>Time</FONT></A></TH><!--BR-->";
    if (shownotes != 2) {
      thx++; tablehtml[thx] = "    <TH><A href=\"Javascript:climbsort('Gradient')\"" +
        "onMouseOver=\"window.status='Sort by Speed (same as Gradient)' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
        "<FONT size=-1>Speed</FONT></A></TH><!--BR-->"; // Same as sorting by gradient
    };
    if (shownotes != 2) {
      thx++; tablehtml[thx] = "    <TH" + THclass.Latitude + THclass.Longitude +
        " colspan=2><FONT size=-1>Maps&nbsp;&nbsp;&nbsp;</FONT><A href=\"Javascript:climbsort('Latitude')\"" +
        "onMouseOver=\"window.status='Sort by Latitude' ;return true\" onMouseOut=\"window.status='' ;return true\"" +
        THclass.Latitude + THclass.Longitude + ">" +
        "<FONT size=-1>Lat</FONT></A><FONT size=-1>&nbsp;&amp;&nbsp;</FONT><!--BR-->";
      thx++; tablehtml[thx] =         "<A href=\"Javascript:climbsort('Longitude')\"" +
        "onMouseOver=\"window.status='Sort by Longitude' ;return true\" onMouseOut=\"window.status='' ;return true\"" +
        THclass.Latitude + THclass.Longitude + ">" +
        "<FONT size=-1>Lon</FONT></A></TH><!--BR-->";
      thx++; tablehtml[thx] = "    <TH" + THclass.Direction + "><A href=\"Javascript:climbsort('Direction')\"" +
        "onMouseOver=\"window.status='Sort by Direction and Distance from Louisville' ;return true\" onMouseOut=\"window.status='' ;return true\""
        + THclass.Direction + ">" +
        "<FONT size=-1>From&nbsp;Lou</FONT></A></TH><!--BR-->";
      thx++; tablehtml[thx] = "  </TR><!--BR-->  <TR><TH colspan=" + (NumberOfColumns - 1) + "><A href=\"Javascript:togglenotes()\"" +
        "onMouseOver=\"window.status='Toggle Notes Display' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
        "<FONT size=-1>N o t e s</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT><!--BR-->";
      if (order != "ByRegion") {
        thx++; tablehtml[thx] = "<A href=\"Javascript:climbsort('ByRegion')\"" +
          "onMouseOver=\"window.status='Show by Region' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>S h o w &nbsp; B y &nbsp; R e g i o n</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT><!--BR-->";
      };
      if (collapsed) {
        thx++; tablehtml[thx] = "<A href=\"Javascript:expandall()\"" +
          "onMouseOver=\"window.status='Show All Hills' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>S h o w &nbsp; A l l</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT></TH><!--BR-->";
      } else {
        thx++; tablehtml[thx] = "<A href=\"Javascript:expandall()\"" +
          "onMouseOver=\"window.status='Show Only Region Names' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>C o l l a p s e</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT></TH><!--BR-->";
      };
    } else {
      thx++; tablehtml[thx] = "    <TH style='padding: 0px; width: 54px;' align='center'><FONT size=-1>Maps</font></TH><!--BR-->";
      thx++; tablehtml[thx] = "    <TH colspan=3 width=40%><A href=\"Javascript:togglenotes()\"" +
        "onMouseOver=\"window.status='Toggle Notes Display' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
        "<FONT size=-1>Notes</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;</FONT><!--BR-->";
      if (order != "ByRegion") {
        thx++; tablehtml[thx] = "<A href=\"Javascript:climbsort('ByRegion')\"" +
          "onMouseOver=\"window.status='Show by Region' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>Show By Region</FONT></A><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;</FONT><!--BR-->";
      };
      if (collapsed) {
        thx++; tablehtml[thx] = "<A href=\"Javascript:expandall()\"" +
          "onMouseOver=\"window.status='Show All Hills' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>Show All</FONT></A><FONT size=-1></FONT></TH><!--BR-->";
      } else {
        thx++; tablehtml[thx] = "<A href=\"Javascript:expandall()\"" +
          "onMouseOver=\"window.status='Show Only Region Names' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          "<FONT size=-1>Collapse</FONT></A><FONT size=-1></FONT></TH><!--BR-->";
      };
    };
  } else {
    thx++; tablehtml[thx] = "    <TH rowspan=2>Name&nbsp;&nbsp;</TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Grade</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Length</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Height</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Time</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Speed</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH width=18></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>Lat&nbsp;&amp;&nbsp;Lon</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "    <TH><FONT size=-1>From&nbsp;Lou</FONT></TH><!--BR-->";
    thx++; tablehtml[thx] = "  </TR><!--BR-->  <TR><TH colspan=" + (NumberOfColumns - 1) +
      "><FONT size=-1>N o t e s</FONT></TH><!--BR-->";
  };
  thx++; tablehtml[thx] = "  </TR><!--BR-->";

// Runtime array will sometimes not have the database end-of-file record, so it is processed but ignored

  for (x = 0; x < climbx.length; x++) {
    xx = climbx[x];

// REGION HEADER RECORD

    if (climbs[xx][fxrect] == 1) {
      if (runtime && (region == "")) {
        thx++; tablehtml[thx] = 
          "  <TR><TD class=\"subhead\" colspan=" + NumberOfColumns + "><A href=\"Javascript:selectregion('" + climbs[xx][fxcode] + "')\" " +
          "style=\"text-decoration: none\" class=\"subhead\" " +
          "onMouseOver=\"window.status='List Hills in This Region' ;return true\" onMouseOut=\"window.status='' ;return true\">" +
          climbs[xx][fxregt] + "</A></TD></TR><!--BR--><!--BR-->";
      } else {
        thx++; tablehtml[thx] = 
          "  <TR><TD class=subhead colspan=" + NumberOfColumns + ">" + climbs[xx][fxregt] + "</TD></TR><!--BR--><!--BR-->";
      };
      // Region Description, if present
      if ((climbs[xx][fxregd] != "") && (!collapsed || (order != "ByRegion") || (region != "") || (climbs[xx][fxregd] != "&nbsp;"))) {
//      if (climbs[xx][fxregd] != "") {
        thx++; tablehtml[thx] = "  <tr><td colspan=" + NumberOfColumns + ">" + climbs[xx][fxregd] + "</td></tr><!--BR--><!--BR-->";
      };
    };

// HILL/ROAD RECORD

    if (climbs[xx][fxrect] == 2) {

// Hill or Road description (rowspan to show notes on second line)

      if (shownotes == 1) {rspan = " rowspan=2"} else {rspan = ""};
      thx++; tablehtml[thx] = 
        "  <TR><!--BR-->" +
        "    <TD" + rspan + ">" + climbs[xx][fxname] + "</TD><!--BR-->";

// Gradient cell, percent grade and degrees calculated from altitude gain and road distance.
// Color cell: Red = Grade >= 12%, Blue= Grade >= 9% (including rounding)

      roll      = climbs[xx][fxroll];
      rise      = climbs[xx][fxeift] - climbs[xx][fxeifb];
      botlat    = climbs[xx][fxlatb];
      botlon    = climbs[xx][fxlonb];
      toplat    = climbs[xx][fxlatt];
      toplon    = climbs[xx][fxlont];
      gradient  = climbs[xx][fxgrad];
      speed     = climbs[xx][fxsped];
      climbtime = climbs[xx][fxtime];
      distance  = climbs[xx][fxdist];
      dir       = climbs[xx][fxdire];
      dirfmt    = climbs[xx][fxdirf];

      if (gradient >= 0.1195) {gflag = " class=gradtier1"} else {if (gradient >= 0.0895) {gflag = " class=gradtier2"} else {gflag = ""};};
      thx++; tablehtml[thx] = "    <TD Align=right" + gflag + ">" + (gradient * 100).toFixed(1) + "%<BR>" +
        (Math.asin(gradient) * 57.2958).toFixed(1) + "&deg;</TD><!--BR-->";

      // Distance cell, imperial miles and metric conversion to meters. Set cell color to green if greater than 1.5 km (0.931 mi)
      if (roll >= 0.931) {dflag = " class=longtier1"} else {dflag=""};
      thx++; tablehtml[thx] = "    <TD Align=right" + dflag + ">" + roll.toFixed(2) +
        "&nbsp;mi<BR>" + (roll / 0.000621).toFixed(0) + "m</TD><!--BR-->";

      // Height cell, imperial feet and metric conversion meters. Set cell color to sky blue if higher than 100m (327' with rounding).
      if (rise >= 327)   {hflag = " class=hightier1"} else {hflag=""};
      thx++; tablehtml[thx] = "    <TD Align=right" + hflag + ">" + rise + "&nbsp;ft<BR>" +
        (rise / 3.28083).toFixed(0) + "m</TD><!--BR-->";

      // Time and calorie cell, assumes 85 kg bike and cyclist and 250W constant output. Set cell color to orange over 4 minutes.
      climbmin = Math.floor(climbtime / 60);
      climbsec = Math.round(climbtime - (climbmin * 60));
      kcal = Math.round(climbtime / 4);  // Rough approximation assuming body burns 4X work done (250W/3600s*0.8598=0.0597kcal * 4 ~ 0.24kcal/s)
      if (climbtime >= 300) {tflag = " class=timetier1"} else {tflag = ""};
      thx++; tablehtml[thx] = "    <TD Align=right" + tflag + ">" +
        climbmin + ":" + ("" + (100 + climbsec)).substring(1) + "<BR>" + kcal + "cal</TD><!--BR-->";

      // Speed cell, assumes 85 kg bike and cyclist and 250W constant output. Set cell color to orange over 4 minutes.
      if (shownotes != 2) {
        thx++; tablehtml[thx] = "    <TD Align=right>" + (speed * 2.2356).toFixed(2) + "&nbsp;mph<BR>" +
          (speed * 3.6).toFixed(2) + "&nbsp;kph</TD><!--BR-->";
      };

      // Create cell for links to launch MSN map and Topozone topographic map in new windows
      thx++; tablehtml[thx] =
        "    <TD style='padding: 3px,0px,0px,0px; vertical-align: top; width: 54px; border-right: 0px;'>" +

// G Google    http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=TITLE@38.27920,-85.66842

        "<A href=\"http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=" + climbs[xx][fxtext].replace(" ","+") +
        "+(" + (gradient * 100).toFixed(1) + "%25,+%5E" + rise + "+feet,+" + roll.toFixed(2) + "+mi" + ")@" +
        botlat + "," + botlon + "\" target=mymap>" +
        "<IMG src=\"gifs/dotg.gif\" border=0 width=18 height=18 alt=\"Google Map\" title=\"Google Map\"></A>" +

// M MSN Live  http://maps.live.com/default.aspx?wip=2&v=2&style=r&lvl=13&rtp=~&&cp=
//                  38.27928~-85.66842&sp=aN.38.27928_-85.66842_Indian%20Hills%20Trail_6.3%,%20^100%20feet,%200.30%20mi

        "<A href=\"http://maps.live.com/default.aspx?wip=2&v=2&style=r&lvl=15&rtp=~&&cp=" + botlat + "~" + botlon +
        "&sp=aN." + botlat + "_" + botlon + "_" + climbs[xx][fxtext] +
        "_" + (gradient * 100).toFixed(1) + "%25,%20%5E" + rise + "%20feet,%20" + roll.toFixed(2) + "%20mi" + "\" target=mymap>" +
        "<IMG src=\"gifs/dotm.gif\" border=0 width=18 height=18 alt=\"MSN Map\" title=\"MSN Map\"></A>" +

// P MapPoint  http://mappoint.msn.com/map.aspx?L=USA&C=38.27928%2c-85.66842&A=14&P=|38.27928%2c-85.66842|1|Indian Hills Trail_LOUISVILLE|L1|   (_ = CRLF)

        "<A href=\"http://mappoint.msn.com/map.aspx?L=USA&C=" + botlat + "%2C" + botlon +
        "&A=14&P=|" + botlat + "%2C" + botlon + "|1|" + climbs[xx][fxtext] +
        "_" + (gradient * 100).toFixed(1) + "%25, %5E" + rise + " feet, " + roll.toFixed(2) + " mi|L1|\" target=mymap>" +
        "<IMG src=\"gifs/dotp.gif\" border=0 width=18 height=18 alt=\"Map Point\" title=\"Map Point\"></A><BR><!--BR-->" +

// Q http://www.mapquest.com/maps/l=38;g=-86#a/maps/m::11:38:-86:0:::::/e

        "<A href=\"http://www.mapquest.com/maps/l=" + botlat + ";g=" + botlon + "#a/maps/m::11:" +
        + botlat + ":" + botlon + ":0:::::/e" + "\" target=mymap>" +
        "<IMG src=\"gifs/dotq.gif\" border=0 width=18 height=18 alt=\"MapQuest\" title=\"MapQuest\"></A>" +

// T TerraServer-USA http://terraserver-usa.com/image.aspx?S=12&T=2&W=2&Z=16&Lat=37.5555&Lon=-88.5555

        "<A href=\"http://terraserver-usa.com/image.aspx?S=12&T=2&W=2&Z=16&Lat=" +
        botlat + "&Lon=" + botlon + "\" target=mymap>" +
        "<IMG src=\"gifs/dott.gif\" border=0 width=18 height=18 alt=\"TerraServer Topo: " +
        botlat + " " + botlon + "\" title=\"TerraServer Topo: " +
        botlat + " " + botlon + "\"></A>" +

// Y Yahoo

// Z TopoZone  http://www.topozone.com/map.asp?lat=38.27928&lon=-85.66842&datum=nad27&u=4&layer=DRG&size=l&s=24

        "<A href=\"http://www.topozone.com/map.asp?lat=" + botlat + "&lon=" + botlon +
        "&datum=nad27&u=4&layer=DRG&size=l&s=24\" target=mymap>" +
        "<IMG src=\"gifs/dotz.gif\" border=0 width=18 height=18 alt=\"TopoZone: " +
        botlat + " " + botlon + "\" title=\"TopoZone: " +
        botlat + " " + botlon + "\"></A>" +

        "</TD><!--BR-->";

      // Create cell for latitude and longitude
      if (shownotes != 2 && distance) {
        latitu = Math.abs(botlat);
        latdeg = Math.floor(latitu);
        latmin = Math.floor(latitu * 60);
        latsec = ((latitu * 60) - latmin) * 60;
        latmin = Math.round(latmin - (latdeg * 60));
        longit = Math.abs(botlon);
        londeg = Math.floor(longit);
        lonmin = Math.floor(longit * 60);
        lonsec = ((longit * 60) - lonmin) * 60;
        lonmin = lonmin - (londeg * 60);
        if (botlat > 0) {hemiNS = "N"} else {if (botlat < 0) {hemiNS = "S"} else {hemiNS = ""}};
        if (botlon < 0) {hemiEW = "W"} else {if (botlat > 0) {hemiEW = "E"} else {hemiEW = ""}};
        thx++; tablehtml[thx] = "    <TD Align=right style='border-left: 0px;'>" +
          "<FONT size=1 style='vertical-align: top;'><SUP>" + hemiNS + "&nbsp;</SUP></FONT>" +
          latdeg + "&deg;&nbsp;" + ("" + (100 + latmin)).substring(1) + "'&nbsp;" +
          (100 + latsec).toFixed(1).substring(1) + "\"<BR>" +
          "<FONT size=1 style='vertical-align: top;'><SUP>" + hemiEW + "&nbsp;</SUP></FONT>" +
          londeg + "&deg;&nbsp;" + ("" + (100 + lonmin)).substring(1) + "'&nbsp;" +
          (100 + lonsec).toFixed(1).substring(1) + "\"</TD><!--BR-->";

      // Direction and Distance from Louisville KY (2nd and Main St.)
        thx++; tablehtml[thx] = "    <TD Align=right>" + distance.toFixed(1) +
          "&nbsp;mi<BR><TABLE width=100% class=noborder><TR class=noborder>" +
          "<TD style=\"padding: 0px;\" class=noborder align=left>" + dirfmt + "</TD>" +
          "<TD style=\"padding: 0px;\" class=noborder align=right>" + (distance / 0.621).toFixed(1) +
          "&nbsp;k</TD></TR></TABLE></TD><!--BR-->";
      };

      // Hill description
      if ((shownotes == 1) || (shownotes == 2)) {
        if (shownotes == 1) {
          rspan = "";
          cspan = NumberOfColumns - 1;
          secline = "</TR><TR>";
        } else {
          rspan = "";
          cspan = "3";
          secline = "";
        };
        thx++; tablehtml[thx] = 
            "    " + secline + "<TD colspan=" + cspan + rspan + " class=descript>" + climbs[xx][fxnote] + "</TD>";
      };

      // Close the table row after each hill statistics set is processed, accumulate totals
      thx++; tablehtml[thx] = "</TR><!--BR--><!--BR-->";
      count++;
      totaldistance += roll;
      totalclimb    += rise;
    };
  };

  // Totals, Averages and Close
  if (count > 0) {
    avggrad = totalclimb / Math.sqrt((totaldistance * totaldistance * 27878400) - (totalclimb * totalclimb));
    speed = gradspeed[Math.round(avggrad * 1000)];
    climbtime = Math.round(totaldistance / 0.000621 / speed);
    climbhrs = Math.floor(climbtime / 3600);
    climbmin = Math.floor(climbtime / 60);
    climbsec = Math.round(climbtime - (climbmin * 60));
    climbmin = Math.floor(climbmin - (climbhrs * 60));
    climbmin = ("0" + climbmin).substr(("0" + climbmin).length - 2);
    climbsec = ("0" + climbsec).substr(("0" + climbsec).length - 2);
    thx++; tablehtml[thx] = "  <TR><TD colspan=" + NumberOfColumns + " style='padding: 0px;'><!--BR-->" +
      "    <TABLE class=totals width=100%><TR class=totals><!--BR-->" +
      "      <TD class=totals align=center vAlign=center>&nbsp;&nbsp;" + count + "&nbsp;Hills&nbsp;&nbsp;</TD><!--BR-->" +
      "      <TD class=totals>Total<BR>Distance<B>:</B></TD><!--BR-->" +
      "      <TD class=totals>" + totaldistance.toFixed(2) + "&nbsp;mi<BR>" + (totaldistance / .621).toFixed(2) + "&nbsp;km</TD><!--BR-->" +
      "      <TD class=totals>Total<BR>Climb<B>:</B></TD><!--BR-->" +
      "      <TD class=totals>" + (totalclimb / 5280).toFixed(2) + "&nbsp;mi<BR>" + (totalclimb / 3280.83).toFixed(2) + "&nbsp;km</TD><!--BR-->" +
      "      <TD class=totals>Average<BR>Gradient<B>:</B></TD><!--BR-->" +
      "      <TD class=totals>" + (avggrad * 100).toFixed(1) + "%<BR>" + (Math.asin(avggrad) * 57.2958).toFixed(1) + "&deg;</TD><!--BR-->" +
      "      <TD class=totals>Avg.&nbsp;Speed<B>:</B><BR>Total&nbsp;Time<B>:</B></TD><!--BR-->" +
      "      <TD class=totals>" + (speed * 3.6).toFixed(1) + " km/h<BR>" + climbhrs + ":" + climbmin + ":" + climbsec + "</TD><!--BR-->" +
      "    </TR></TABLE></TD></TR>";
  };
  thx++; tablehtml[thx] = "</TABLE></CENTER><!--BR--><!--BR-->";
  return tablehtml;
};

function togglenotes() {
  shownotes--;
  if (shownotes < 0) {shownotes = 2};
  tablehtml = climbsgen(true);
  document.getElementById('climbtable').innerHTML = tablehtml.join('');
};

function selectregion(reg) {
  region = reg;
  collapsed = false;
  climbsort(order);
};

function expandall() {
  collapsed = !collapsed;
  if (collapsed) {
    region = "";
    order = "ByRegion";
  };
  climbsort(order);
};

function climbsort(ord) {
  order = ord;
  z = 0;
  if (order == 'ByRegion') {
    climbx = new Array();
    if (region == "") {
      if (collapsed) {
        for (x = 0; x < climbs.length - 1; x++) {
          if (climbs[x][fxrect] == 1) {
            if (climbs[x][fxcode] != "") {
              climbx[z] = x;
              z++;
            };
          };
        };
      } else {
        for (x = 0; x < climbs.length - 1; x++) {climbx[x] = x};
      };
    } else {
      for (x = 0; x < climbs.length - 1; x++) {
        if (climbs[x][fxrect] == 2) {
          if (climbs[x][fxcode].substr(0,region.length) == region) {
            climbx[z] = x;
            z++;
          };
        } else {
          if ((climbs[x][fxrect] == 1) && (climbs[x][fxcode].substr(0,region.length) == region)) {
            climbx[z] = x;
            z++;
          };
        };
      };
    };
  } else {
    if (region == "") {collapsed = false};
    if (order != orderprev) {
      if (order == 'Name') {ordernumdecend = false} else {ordernumdecend = true};
      if (orderprev == "ByRegion") {
        climbx = new Array();
        if (region == "") {
          for (x = 0; x < climbs.length - 1; x++) {
            if (climbs[x][fxrect] == 2) {
              climbx[z] = x;
              z++;
            };
          };
        } else {
          for (x = 0; x < climbs.length - 1; x++) {
            if (climbs[x][fxrect] == 2) {
              if (climbs[x][fxcode].substr(0,region.length) == region) {
                climbx[z] = x;
                z++;
              };
            } else {
              if ((climbs[x][fxrect] == 1) && (climbs[x][fxcode] == region)) {
                climbx[z] = x;
                z++;
              };
            };
          };
        };
      };
    } else {
      ordernumdecend = !ordernumdecend;
    };
    if (order == 'Name')      {axis = fxname; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Gradient')  {axis = fxgrad; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Length')    {axis = fxroll; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Height')    {axis = fxrise; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Time')      {axis = fxtime; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Latitude')  {axis = fxlatb; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Longitude') {axis = fxlonb; climbx = climbx.sort(sortbyaxes)};
    if (order == 'Direction') {climbx = climbx.sort(sortbydir)};
  };
  THclass[orderprev] = "";
  THclass[order]     = " class='sorted'";
  orderprev = order;
  tablehtml = climbsgen(true);
  document.getElementById('climbtable').innerHTML = tablehtml.join('');
};

function sortbyaxes(a,b) {
  if (climbs[a][fxrect] == "2") {
    if (climbs[a][axis] > climbs[b][axis]) {if (ordernumdecend) {return -1} else {return 1}}
    else {if (climbs[a][axis] < climbs[b][axis]) {if (ordernumdecend) {return 1} else {return -1}} else {return 0}};
  } else {
    if (climbs[a][fxrect] == "1") {return -1} else {return 1};
  };
};

// The sort toggle is between Direction-Distance and Distance Alone rather than reverse order in this function

function sortbydir(a,b) {
  if (climbs[a][fxrect] == "2") {
    if (ordernumdecend) {
      if (climbs[a][fxdire] > climbs[b][fxdire]) {return  1}
      else {
        if (climbs[a][fxdire] < climbs[b][fxdire]) {return -1}
        else {
          if (climbs[a][fxdist] > climbs[b][fxdist]) {return  1}
          else {
            if (climbs[a][fxdist] < climbs[b][fxdist]) {return -1}
            else {return 0}
          };
        };
      };
    } else {
      if (climbs[a][fxdist] > climbs[b][fxdist]) {return 1}
      else {
        if (climbs[a][fxdist] < climbs[b][fxdist]) {return -1}
        else {return 0}
      };
    };
  } else {
    if (climbs[a][fxrect] == "1") {return -1} else {return 1};
  };
};

//-->
