<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:math="urn:schemas-microsoft-com:JavaScript"
    xmlns:file="urn:schemas-microsoft-com:JavaScript"
    xmlns:str="urn:schemas-microsoft-com:JavaScript"
    xmlns:select="urn:schemas-microsoft-com:JavaScript"
    xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
    xmlns:v="urn:schemas-microsoft-com:vml"
    xmlns:w10="urn:schemas-microsoft-com:office:word"
    xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core"
    xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
    xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
    xmlns:o="urn:schemas-microsoft-com:office:office"
    xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">

<!-- (c) 2016, Trimble Inc. All rights reserved.                                               -->
<!-- Permission is hereby granted to use, copy, modify, or distribute this style sheet for any -->
<!-- purpose and without fee, provided that the above copyright notice appears in all copies   -->
<!-- and that both the copyright notice and the limited warranty and restricted rights notice  -->
<!-- below appear in all supporting documentation.                                             -->

<!-- TRIMBLE INC. PROVIDES THIS STYLE SHEET "AS IS" AND WITH ALL FAULTS.                       -->
<!-- TRIMBLE INC. SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY               -->
<!-- OR FITNESS FOR A PARTICULAR USE. TRIMBLE NAVIGATION LIMITED DOES NOT WARRANT THAT THE     -->
<!-- OPERATION OF THIS STYLE SHEET WILL BE UNINTERRUPTED OR ERROR FREE.                        -->

<xsl:output method="xml" encoding="utf-8"/>

<!-- Set the numeric display details i.e. decimal point, thousands separator etc -->
<xsl:variable name="DecPt" select="string('.')"/>    <!-- Change as appropriate for US/European -->
<xsl:variable name="GroupSep" select="string(',')"/> <!-- Change as appropriate for US/European -->
<!-- Also change decimal-separator & grouping-separator in decimal-format below
     as appropriate for US/European output -->
<xsl:decimal-format name="Standard"
                    decimal-separator="."
                    grouping-separator=","
                    infinity="Infinity"
                    minus-sign="-"
                    NaN="?"
                    percent="%"
                    per-mille="&#2030;"
                    zero-digit="0"
                    digit="#"
                    pattern-separator=";" />

<xsl:variable name="DecPl0" select="string('#0')"/>
<xsl:variable name="DecPl1" select="string(concat('#0', $DecPt, '0'))"/>
<xsl:variable name="DecPl2" select="string(concat('#0', $DecPt, '00'))"/>
<xsl:variable name="DecPl3" select="string(concat('#0', $DecPt, '000'))"/>
<xsl:variable name="DecPl4" select="string(concat('#0', $DecPt, '0000'))"/>
<xsl:variable name="DecPl5" select="string(concat('#0', $DecPt, '00000'))"/>
<xsl:variable name="DecPl6" select="string(concat('#0', $DecPt, '000000'))"/>
<xsl:variable name="DecPl8" select="string(concat('#0', $DecPt, '00000000'))"/>

<xsl:variable name="fileExt" select="'doc'"/>

<!-- Default settings for Options dialog - presented in html application window -->
<xsl:variable name="defaultProfilePtsToDisplay">1</xsl:variable>  <!-- All measured points on profile (All measured points on profile, Last measured points on profile) -->
<xsl:variable name="defaultVerticalDisplay">1</xsl:variable>      <!-- Elevations (Elevations, Offsets) -->
<xsl:variable name="defaultAnnotation">2</xsl:variable>           <!-- Overbreak/Underbreak (Nothing, Overbreak/Underbreak, Point Name) -->
<xsl:variable name="defaultAnnotateEvery">1</xsl:variable>        <!-- Every profile point (Every profile point, Every 2nd profile point, Every 5th profile point) -->
<xsl:variable name="defaultShowGridLines">1</xsl:variable>        <!-- 1 = true, 0 = false -->
<xsl:variable name="defaultCompProfileOffsets">0</xsl:variable>   <!-- 1 = true, 0 = false -->
<xsl:variable name="defaultClosedScans">0</xsl:variable>          <!-- 1 = true, 0 = false -->

<xsl:variable name="surfaces">
  <xsl:variable name="surfaceList">
    <xsl:for-each select="/JOBFile/FieldBook/TunnelCrossSectionRecord">
      <xsl:variable name="surfName" select="TemplateSurface"/>
      <xsl:if test="($surfName != '') and (count(preceding-sibling::TunnelCrossSectionRecord[TemplateSurface = $surfName]) = 0)">
        <xsl:element name="surface" namespace="">
          <xsl:value-of select="$surfName"/>
        </xsl:element>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="$surfaceList = ''"> <!-- No surfaces found -->
      <!-- Create a single surface element with the internal default surface name -->
      <xsl:element name="surface" namespace="">DefaultXSLSurface</xsl:element>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="$surfaceList"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Bring up the Options dialog - uses JavaScript and hta functionality -->
<xsl:variable name="userOptions" select="select:DisplayOptionsDialog(msxsl:node-set($surfaces)/*,
                                                                     number($defaultProfilePtsToDisplay),
                                                                     number($defaultVerticalDisplay),
                                                                     number($defaultAnnotation),
                                                                     number($defaultAnnotateEvery),
                                                                     number($defaultShowGridLines),
                                                                     number($defaultCompProfileOffsets),
                                                                     number($defaultClosedScans))"/>
<xsl:variable name="paramString" select="string(concat($userOptions, '|'))"/>

<!-- Extract the global variable values from the returned userOptions -->
<xsl:variable name="tunnelName">
  <xsl:if test="$paramString = '-1|'">
    <xsl:message terminate="yes">Cancel requested</xsl:message>
  </xsl:if>

  <xsl:call-template name="GetParamValFromOptionsString">
    <xsl:with-param name="index">1</xsl:with-param>
    <xsl:with-param name="paramString" select="$paramString"/>
  </xsl:call-template>
</xsl:variable>

<xsl:variable name="templateSurfToUseForAreas">
  <xsl:call-template name="GetParamValFromOptionsString">
    <xsl:with-param name="index">2</xsl:with-param>
    <xsl:with-param name="paramString" select="$paramString"/>
  </xsl:call-template>
</xsl:variable>

<xsl:variable name="inStartStn">
  <xsl:call-template name="GetParamValFromOptionsString">
    <xsl:with-param name="index">3</xsl:with-param>
    <xsl:with-param name="paramString" select="$paramString"/>
  </xsl:call-template>
</xsl:variable>

<xsl:variable name="inEndStn">
  <xsl:call-template name="GetParamValFromOptionsString">
    <xsl:with-param name="index">4</xsl:with-param>
    <xsl:with-param name="paramString" select="$paramString"/>
  </xsl:call-template>
</xsl:variable>

<xsl:variable name="profilePointsToUse">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">5</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="number($index) = 0">All measured points on profile</xsl:when>
    <xsl:when test="number($index) = 1">Last measured points on profile</xsl:when>
    <xsl:otherwise>All measured points on profile</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="vertValuesAs">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">6</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="number($index) = 0">Elevations</xsl:when>
    <xsl:when test="number($index) = 1">Offsets</xsl:when>
    <xsl:otherwise>Elevations</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="annotateProfilePoints">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">7</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="number($index) = 0">Nothing</xsl:when>
    <xsl:when test="number($index) = 1">Overbreak/Underbreak</xsl:when>
    <xsl:when test="number($index) = 2">Point Name</xsl:when>
    <xsl:otherwise>Nothing</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="annotateEvery">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">8</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="number($index) = 0">Every profile point</xsl:when>
    <xsl:when test="number($index) = 1">Every 2nd profile point</xsl:when>
    <xsl:when test="number($index) = 2">Every 5th profile point</xsl:when>
    <xsl:otherwise>Every profile point</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="showGridLines">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">9</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$index = 'True'">Yes</xsl:when>
    <xsl:otherwise>No</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="computeProfileOffsets">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">10</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$index = 'True'">Yes</xsl:when>
    <xsl:otherwise>No</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="closedScans">
  <xsl:variable name="index">
    <xsl:call-template name="GetParamValFromOptionsString">
      <xsl:with-param name="index">11</xsl:with-param>
      <xsl:with-param name="paramString" select="$paramString"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$index = 'True'">Yes</xsl:when>
    <xsl:otherwise>No</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Now the options settings have been handled - continue -->
<xsl:variable name="txlFileName">
  <xsl:choose>
    <xsl:when test="not(contains(str:LowerCase(string($tunnelName)), '.txl'))">   <!-- No .txl extension has been specified in tunnelName so append it -->
      <xsl:value-of select="concat($tunnelName, '.txl')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$tunnelName"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="tunnelDefinition">
  <xsl:if test="($txlFileName != '') and file:CheckFileExists(string($txlFileName))">
    <xsl:copy-of select="document(string($txlFileName))"/>
  </xsl:if>
</xsl:variable>

<!-- Flag variables that can be used to switch on or off drawing items -->
<xsl:variable name="joinPoints" select="'Yes'"/>
<xsl:variable name="showScannedPoints" select="'Yes'"/>
<xsl:variable name="showOverUnderBreakLines" select="'Yes'"/>
<xsl:variable name="showMaxMinOverUnderBreaks" select="'Yes'"/>
<xsl:variable name="useChainageNotation" select="'false'"/>

<xsl:variable name="annotatePoints">
  <xsl:choose>
    <xsl:when test="($showOverUnderBreakLines = 'Yes') and ($annotateProfilePoints != 'Nothing')">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="outputVertValuesAs">
  <xsl:choose>
    <xsl:when test="($vertValuesAs = 'Elevations') and (count(msxsl:node-set($tunnelDefinition)/*) != 0)">Elevations</xsl:when>
    <xsl:otherwise>Offsets</xsl:otherwise>
  </xsl:choose>
</xsl:variable>


<xsl:variable name="showDesignLines">
  <xsl:choose>
    <xsl:when test="$tunnelDefinition != ''">Yes</xsl:when>
    <xsl:otherwise>No</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="profileOriginX" select="0"/>       <!-- In points -->
<xsl:variable name="profileOriginY">                   <!-- In points - space between last paragraph and top of grid -->
  <xsl:choose>
    <xsl:when test="$computeProfileOffsets = 'Yes'">20</xsl:when>  <!-- Cut down space above grid as there is more text -->
    <xsl:otherwise>100</xsl:otherwise>
  </xsl:choose>
</xsl:variable>
<xsl:variable name="profileSizeX" select="360"/>       <!-- In points -->
<xsl:variable name="profileSizeY" select="360"/>       <!-- In points -->

<xsl:variable name="gridOriginX" select="0"/>
<xsl:variable name="gridOriginY" select="0"/>
<xsl:variable name="gridSizeX" select="$profileSizeX * 10"/>
<xsl:variable name="gridSizeY" select="$profileSizeY * 10"/>

<xsl:variable name="DistUnit"   select="/JOBFile/Environment/DisplaySettings/DistanceUnits" />
<xsl:variable name="AngleUnit"  select="/JOBFile/Environment/DisplaySettings/AngleUnits" />
<xsl:variable name="CoordOrder" select="/JOBFile/Environment/DisplaySettings/CoordinateOrder" />
<xsl:variable name="TempUnit"   select="/JOBFile/Environment/DisplaySettings/TemperatureUnits" />
<xsl:variable name="PressUnit"  select="/JOBFile/Environment/DisplaySettings/PressureUnits" />
<xsl:variable name="AreaUnit"   select="/JOBFile/Environment/DisplaySettings/AreaUnits" />

<!-- Setup conversion factor for coordinate and distance values -->
<xsl:variable name="DistConvFactor">
  <xsl:choose>
    <xsl:when test="$DistUnit = 'Metres'">1.0</xsl:when>
    <xsl:when test="$DistUnit = 'InternationalFeet'">3.280839895</xsl:when>
    <xsl:when test="$DistUnit = 'USSurveyFeet'">3.2808333333357</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="distUnitAbbrev">
  <xsl:choose>
    <xsl:when test="$DistUnit = 'Metres'">m</xsl:when>
    <xsl:when test="$DistUnit = 'InternationalFeet'">ift</xsl:when>
    <xsl:when test="$DistUnit = 'USSurveyFeet'">sft</xsl:when>
    <xsl:otherwise>m</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup conversion factor for angular values -->
<xsl:variable name="AngleConvFactor">
  <xsl:choose>
    <xsl:when test="$AngleUnit='DMSDegrees'">1.0</xsl:when>
    <xsl:when test="$AngleUnit='Gons'">1.111111111111</xsl:when>
    <xsl:when test="$AngleUnit='Mils'">17.77777777777</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup conversion factor for area values -->
<xsl:variable name="AreaConvFactor">
  <xsl:choose>
    <xsl:when test="$AreaUnit = 'SquareMetres'">1.0</xsl:when>
    <xsl:when test="$AreaUnit = 'SquareMiles'">
      <xsl:value-of select="1.0 div 2589988.110336"/>
    </xsl:when>
    <xsl:when test="$AreaUnit = 'SquareFeet'">
      <xsl:value-of select="3.280839895 * 3.280839895"/>
    </xsl:when>
    <xsl:when test="$AreaUnit = 'SquareUSSurveyFeet'">
      <xsl:value-of select="3.2808333333357 * 3.2808333333357"/>
    </xsl:when>
    <xsl:when test="$AreaUnit = 'Acres'">
      <xsl:value-of select="1.0 div 4046.8564224"/>
    </xsl:when>
    <xsl:when test="$AreaUnit = 'Hectares'">0.0001</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup boolean variable for coordinate order -->
<xsl:variable name="NECoords">
  <xsl:choose>
    <xsl:when test="$CoordOrder='North-East-Elevation'">true</xsl:when>
    <xsl:when test="$CoordOrder='X-Y-Z'">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="stnFormatStyle">
  <xsl:value-of select="/JOBFile/Environment/DisplaySettings/StationingFormat"/>
</xsl:variable>

<xsl:variable name="stnIndexIncrement">
  <xsl:value-of select="/JOBFile/Environment/DisplaySettings/StationIndexIncrement"/>
</xsl:variable>

<xsl:variable name="spiralType">
  <xsl:choose>
    <xsl:when test="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/HorizontalAlignment/@spiralType">   <!-- Attribute exists so read it -->
      <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/HorizontalAlignment/@spiralType"/>
    </xsl:when>
    <xsl:otherwise>Clothoid</xsl:otherwise>  <!-- Default to clothoid -->
  </xsl:choose>
</xsl:variable>

<xsl:variable name="useComputedDeltaValues">true</xsl:variable>

<xsl:variable name="roadScaleFactor">1.0</xsl:variable>

<!-- Define key to speed up searching -->
<xsl:key name="obsPointID-search" match="/JOBFile/FieldBook/PointRecord" use="@ID"/>

<xsl:variable name="Pi" select="3.14159265358979323846264"/>
<xsl:variable name="halfPi" select="$Pi div 2.0"/>

<!-- **************************************************************** -->
<!-- ********************* Root Node Processing ********************* -->
<!-- **************************************************************** -->
<xsl:template match="/">

  <xsl:variable name="allProfilesMinMax">
    <xsl:call-template name="GetProfilesMinMaxVals">
      <xsl:with-param name="showDesignLines" select="$showDesignLines"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="sortedTunnelCrossSectionRecords">
    <xsl:for-each select="/JOBFile/FieldBook/TunnelCrossSectionRecord">
      <xsl:sort order="ascending" data-type="number" select="Station"/>
      <xsl:copy-of select="./Station"/>
    </xsl:for-each>
  </xsl:variable>
  
  <xsl:variable name="startStn">
    <xsl:choose>
      <xsl:when test="contains($inStartStn, ':')">  <!-- An equated station with zone has been entered -->
        <xsl:variable name="trueStn">
          <xsl:call-template name="TrueStationValue">
            <xsl:with-param name="equatedStation" select="substring-before($inStartStn, ':')"/>
            <xsl:with-param name="zone" select="substring-after($inStartStn, ':')"/>
            <xsl:with-param name="stationEquations" select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/StationEquations"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
          <xsl:when test="string(number($trueStn)) = 'NaN'">  <!-- Didn't get valid true station value -->
            <xsl:value-of select="msxsl:node-set($sortedTunnelCrossSectionRecords)/Station[1]"/>  <!-- Revert to first station -->
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$trueStn"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>

      <xsl:otherwise>  <!-- This is a specified 'true' station -->
        <xsl:choose>
          <xsl:when test="string(number($inStartStn)) != 'NaN'">
            <xsl:value-of select="number($inStartStn)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedTunnelCrossSectionRecords)/Station[1]"/>  <!-- Revert to first station -->
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="endStn">
    <xsl:choose>
      <xsl:when test="contains($inEndStn, ':')">  <!-- An equated station with zone has been entered -->
        <xsl:variable name="trueStn">
          <xsl:call-template name="TrueStationValue">
            <xsl:with-param name="equatedStation" select="substring-before($inEndStn, ':')"/>
            <xsl:with-param name="zone" select="substring-after($inEndStn, ':')"/>
            <xsl:with-param name="stationEquations" select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/StationEquations"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
          <xsl:when test="string(number($trueStn)) = 'NaN'">  <!-- Didn't get valid true station value -->
            <xsl:value-of select="msxsl:node-set($sortedTunnelCrossSectionRecords)/Station[1]"/>  <!-- Revert to first station -->
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$trueStn"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>

      <xsl:otherwise>  <!-- This is a specified 'true' station -->
        <xsl:choose>
          <xsl:when test="string(number($inEndStn)) != 'NaN'">
            <xsl:value-of select="number($inEndStn)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedTunnelCrossSectionRecords)/Station[last()]"/>  <!-- Revert to last station -->
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="tunnelProfiles">  <!-- Build up a node set containing all the details to be drawn for each profile -->
    <xsl:call-template name="BuildTunnelProfiles">
      <xsl:with-param name="allProfilesMinMax" select="$allProfilesMinMax"/>
      <xsl:with-param name="gridSizeX" select="$gridSizeX"/>
      <xsl:with-param name="gridSizeY" select="$gridSizeY"/>
      <xsl:with-param name="startStn" select="$startStn"/>
      <xsl:with-param name="endStn" select="$endStn"/>
      <xsl:with-param name="annotatePoints" select="$annotatePoints"/>
      <xsl:with-param name="showDesignLines" select="$showDesignLines"/>
      <xsl:with-param name="computeProfileOffsets" select="$computeProfileOffsets"/>
      <xsl:with-param name="specifiedSurface" select="$templateSurfToUseForAreas"/>  <!-- Force the use of the surface selected for the area computations -->
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="tunnelProfilesForAreas">  <!-- Build up a node set containing all the details for the area calcs -->
    <xsl:call-template name="BuildTunnelProfilesForAreaCalcs">
      <xsl:with-param name="startStn" select="$startStn"/>
      <xsl:with-param name="endStn" select="$endStn"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="profileAreas">
    <xsl:call-template name="ComputeProfileAreas">
      <xsl:with-param name="tunnelProfiles" select="$tunnelProfilesForAreas"/>
      <xsl:with-param name="templateSurfToUseForAreas" select="$templateSurfToUseForAreas"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="nbrProfiles" select="count(msxsl:node-set($tunnelProfiles)/profile)"/>

  <!-- Set up the Word XML header records -->
  <xsl:call-template name="NewLine"/>
  <xsl:value-of disable-output-escaping="yes" select="'&lt;?mso-application progid=&quot;Word.Document&quot;?&gt;'"/>

  <xsl:call-template name="NewLine"/>
  <xsl:element name="w:wordDocument">  <!-- This is the root element for the output XML file -->
    <xsl:attribute name="w:macrosPresent">no</xsl:attribute>
    <xsl:attribute name="w:embeddedObjPresent">no</xsl:attribute>
    <xsl:attribute name="w:ocxPresent">no</xsl:attribute>
    <xsl:attribute name="xml:space">preserve</xsl:attribute>

    <xsl:call-template name="OutputDocumentProperties">
      <xsl:with-param name="docName" select="'Tunnel profile report'"/>
      <xsl:with-param name="author">
        <xsl:for-each select="/JOBFile/FieldBook/JobPropertiesRecord[last()]">
          <xsl:value-of select="Operator"/>
        </xsl:for-each>
      </xsl:with-param>
      <xsl:with-param name="created" select="/JOBFile/@TimeStamp"/>
    </xsl:call-template>
    <xsl:call-template name="NewLine"/>

    <xsl:call-template name="OutputFontDefinition"/>

    <xsl:element name="w:styles">
      <xsl:call-template name="DefineDefaultTable"/>
      <xsl:call-template name="DefineGridTable"/>
      <xsl:call-template name="DefineNoBordersTable"/>
    </xsl:element>

    <xsl:call-template name="OutputDocumentHeaderDetails"/>
    <xsl:call-template name="NewLine"/>

    <!-- Now the document proper starts -->
    <w:body>
      <xsl:call-template name="NewLine"/>
      <wx:sect>
        <xsl:call-template name="NewLine"/>

        <xsl:call-template name="OutputDocumentHeaderPage"/>

        <xsl:for-each select="msxsl:node-set($tunnelProfiles)/profile[count(TunnelPointDeltaRecord) != 0]">
          <xsl:call-template name="NewPage"/>  <!-- Start each profile on a new page -->
          <xsl:call-template name="NewLine"/>

          <xsl:variable name="stn">
            <xsl:choose>
              <xsl:when test="EquatedStation">
                <xsl:call-template name="FormatStationVal">
                  <xsl:with-param name="stationVal" select="EquatedStation/Station"/>
                  <xsl:with-param name="zoneVal" select="EquatedStation/Zone"/>
                  <xsl:with-param name="definedFmt" select="$stnFormatStyle"/>
                  <xsl:with-param name="stationIndexIncrement" select="$stnIndexIncrement"/>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                <xsl:call-template name="FormatStationVal">
                  <xsl:with-param name="stationVal" select="Station"/>
                  <xsl:with-param name="definedFmt" select="$stnFormatStyle"/>
                  <xsl:with-param name="stationIndexIncrement" select="$stnIndexIncrement"/>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">
              <xsl:text>Tünel Kesiti </xsl:text>
              <xsl:value-of select="position()"/>
              <xsl:choose>
                <xsl:when test="$useChainageNotation = 'true'"> (Chainage = </xsl:when>
                <xsl:otherwise> (Km = </xsl:otherwise>
              </xsl:choose>
              <xsl:value-of select="$stn"/>
              <xsl:text>)</xsl:text>
            </xsl:with-param>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="size" select="14"/>
            <xsl:with-param name="justify" select="'left'"/>
          </xsl:call-template>
          <xsl:call-template name="NewLine"/>

          <xsl:if test="string(TemplateSurface) != ''">  <!-- There was a TemplateSurface element in the TunnelCrossSectionRecord -->
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text">
                <xsl:text>Tipkesit Tabakası: </xsl:text>
                <xsl:value-of select="TemplateSurface"/>
              </xsl:with-param>
              <xsl:with-param name="bold" select="'Yes'"/>
              <xsl:with-param name="size" select="14"/>
              <xsl:with-param name="justify" select="'left'"/>
            </xsl:call-template>
            <xsl:call-template name="NewLine"/>
          </xsl:if>

          <!-- Output details of the as-built alignment offset if this has been requested -->
          <xsl:if test="$computeProfileOffsets = 'Yes'">
            <xsl:call-template name="OutputAsBuiltProfileOffsetDetails"/>
          </xsl:if>

          <w:p>
            <w:pict>
              <xsl:call-template name="NewLine"/>
              <v:group editas="canvas" style="position:absolute;margin-left:{$profileOriginX}pt;margin-top:{$profileOriginY}pt;width:{$profileSizeX}pt;height:{$profileSizeY}pt;z-index:-1;mso-position-horizontal-relative:text;mso-position-vertical-relative:text"
                       coordorigin="{$gridOriginX},{$gridOriginY}" coordsize="{$gridSizeX},{$gridSizeY}">
                <xsl:call-template name="NewLine"/>
                <o:lock v:ext="edit" aspectratio="t"/>
                <xsl:call-template name="NewLine"/>

                <!-- Draw box around drawing area -->
  							<v:shape type="#_x0000_t75" style="position:absolute;left:{$gridOriginX};top:{$gridOriginY};width:{$gridSizeX};height:{$gridSizeY}" o:preferrelative="f" stroked="t" strokeweight="0.75pt">
  								<v:fill o:detectmouseclick="t"/>
  								<v:path o:extrusionok="t" o:connecttype="none"/>
  							</v:shape>
                <xsl:call-template name="NewLine"/>

                <xsl:if test="($annotatePoints = 'true') or ($showGridLines = 'Yes')">
                  <xsl:call-template name="SetupRotatableTextDefn"/>
                </xsl:if>

                <xsl:if test="$showGridLines = 'Yes'">
                  <xsl:call-template name="DrawGridLines"/>
                </xsl:if>
                
                <!-- Draw the design template lines first so that they are 'under' the points -->
                <xsl:if test="$showDesignLines = 'Yes'">
                  <xsl:call-template name="DrawTemplateDesignElements">
                    <xsl:with-param name="templateSurface" select="TemplateSurface"/>
                  </xsl:call-template>
                </xsl:if>

                <!-- Draw the lines between the points first so that they are 'under' the points -->
                <xsl:if test="($joinPoints = 'Yes') and ($showScannedPoints = 'Yes')">
                  <xsl:call-template name="DrawLinesBetweenScannedPoints"/>
                </xsl:if>

                <!-- Draw lines showing the under/over break 'vectors' (perpendicular to design) -->
                <xsl:if test="($showOverUnderBreakLines = 'Yes') and ($showDesignLines = 'Yes')">
                  <xsl:call-template name="DrawOverUnderBreakLines">
                    <xsl:with-param name="templateSurface" select="TemplateSurface"/>
                  </xsl:call-template>
                </xsl:if>

                <!-- Output all the points at the selected cross-section -->
                <xsl:if test="$showScannedPoints = 'Yes'">
                  <xsl:call-template name="DrawScannedPoints"/>
                </xsl:if>

                <w10:wrap type="tight"/>
                <xsl:call-template name="NewLine"/>
              </v:group>
              <xsl:call-template name="NewLine"/>
            </w:pict>
          </w:p>

          <!-- Now output a table of the offset and delta values -->
          <xsl:call-template name="OutputProfileAreaAndPointsTable">
            <xsl:with-param name="station" select="Station"/>
            <xsl:with-param name="profileAreas" select="$profileAreas"/>
          </xsl:call-template>
        </xsl:for-each>

        <xsl:call-template name="OutputPageSettings"/>
      </wx:sect>  <!-- wx:sect -->
    </w:body>  <!-- w:body -->

  </xsl:element>  <!-- w:wordDocument -->
</xsl:template>


<!-- **************************************************************** -->
<!-- ***************** Output document header page ****************** -->
<!-- **************************************************************** -->
<xsl:template name="OutputDocumentHeaderPage">

  <!-- Output a Trimble Logo -->
  <xsl:call-template name="OutputLogo"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">&#160;</xsl:with-param>
    <xsl:with-param name="size" select="36"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <!-- Attempt to get the tunnel name from the loaded design if possible otherwise -->
  <!-- use the tunnel name from the first TunnelSettingsRecord in the JobXML file. -->
  <xsl:variable name="displayTunnelName">
    <xsl:choose>
      <xsl:when test="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Name != ''">
        <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Name"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="/JOBFile/FieldBook/TunnelSettingsRecord[1]/TunnelName"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Tünel Kesitleri: ', $displayTunnelName)"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="20"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>
  
  <xsl:variable name="firstSectionDate" select="substring(/JOBFile/FieldBook/TunnelCrossSectionRecord[1]/@TimeStamp, 1, 10)"/>
  <xsl:variable name="lastSectionDate" select="substring(/JOBFile/FieldBook/TunnelCrossSectionRecord[last()]/@TimeStamp, 1, 10)"/>
  
  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">&#160;</xsl:with-param>
    <xsl:with-param name="size" select="20"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">
      <xsl:text>Ölçü Tarihi: </xsl:text>
      <xsl:choose>
        <xsl:when test="$firstSectionDate = $lastSectionDate">
          <xsl:call-template name="FormattedDate">
            <xsl:with-param name="timeStamp" select="$firstSectionDate"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="FormattedDate">
            <xsl:with-param name="timeStamp" select="$firstSectionDate"/>
          </xsl:call-template>
          <xsl:text> - </xsl:text>
          <xsl:call-template name="FormattedDate">
            <xsl:with-param name="timeStamp" select="$lastSectionDate"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="18"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">&#160;</xsl:with-param>
    <xsl:with-param name="size" select="36"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Dosya Adı: ', /JOBFile/@jobName)"/>
    <xsl:with-param name="size" select="12"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="size" select="12"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat(/JOBFile/@product, ' version: ', /JOBFile/@productVersion)"/>
    <xsl:with-param name="size" select="12"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="size" select="12"/>
    <xsl:with-param name="justify" select="'center'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:variable name="distUnitsStr">
    <xsl:choose>
      <xsl:when test="$DistUnit = 'Metres'">Metre</xsl:when>
      <xsl:when test="$DistUnit = 'InternationalFeet'">International Feet</xsl:when>
      <xsl:when test="$DistUnit = 'USSurveyFeet'">US Survey Feet</xsl:when>
      <xsl:otherwise>Metre</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Ölçü Birimi: ', $distUnitsStr)"/>
    <xsl:with-param name="size" select="12"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Output the offsets from the design profile centre ****** -->
<!-- **************************************************************** -->
<xsl:template name="OutputAsBuiltProfileOffsetDetails">

  <xsl:call-template name="OutputTextInParagraph"/>  <!-- Output blank line -->

  <xsl:variable name="stationStr">
    <!-- We know the true station for this point (computed mean position based on -->
    <!-- station deltas) so get the equated station (if any) for it.              -->
    <xsl:variable name="equatedStn">
      <xsl:call-template name="EquatedStationValue">
        <xsl:with-param name="station" select="alignDetails/meanStn"/>
        <xsl:with-param name="stationEquations" select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/StationEquations"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:call-template name="FormatStationVal">
      <xsl:with-param name="stationVal" select="msxsl:node-set($equatedStn)/stnValue"/>
      <xsl:with-param name="zoneVal" select="msxsl:node-set($equatedStn)/zone"/>
      <xsl:with-param name="definedFmt" select="$stnFormatStyle"/>
      <xsl:with-param name="stationIndexIncrement" select="$stnIndexIncrement"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">
      <xsl:text>HESAPLANAN ASBUILT GÜZERGAH NOKTASI (</xsl:text>
      <xsl:value-of select="$stationStr"/>
      <xsl:text>)</xsl:text>
    </xsl:with-param>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Yat.ofset:&#09;', format-number(profileOffsets/hzOffsetDelta * $DistConvFactor, $DecPl3, 'Standard'))"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Düş.ofset:&#09;', format-number(profileOffsets/vtOffsetDelta * $DistConvFactor, $DecPl3, 'Standard'))"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Delta:&#09;&#09;', format-number(profileOffsets/polarDelta * $DistConvFactor, $DecPl3, 'Standard'))"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Hes.Yçap:&#09;', format-number(profileOffsets/computedRadius * $DistConvFactor, $DecPl3, 'Standard'))"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <!-- Compute the grid coordinates for the computed profile centre position using -->
  <!-- the available alignDetails elements.                                        -->
  <xsl:variable name="azToDesignPt">
    <xsl:choose>
      <xsl:when test="profileOffsets/hzOffsetComputed &lt;= 0.0">  <!-- Computed position hz offset is -ve so point is to left of design -->
        <xsl:value-of select="alignDetails/azimuth - 90.0"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="alignDetails/azimuth + 90.0"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="gradeAngle">
    <xsl:choose>
      <xsl:when test="alignDetails/templateApplyMethod = 'Vertical'">0</xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="math:atan(number(math:abs(number(alignDetails/grade)) div 100.0))"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="alongDist" select="profileOffsets/vtOffsetComputed * math:sin(number($gradeAngle))"/>
  <xsl:variable name="upDist" select="profileOffsets/vtOffsetComputed * math:cos(number($gradeAngle))"/>

  <xsl:variable name="tempPt">  <!-- Compute the position along the alignment azimuth to allow for perpendicular templates -->
    <xsl:call-template name="FollowAzimuth">
      <xsl:with-param name="azimuth">
        <xsl:choose>
          <xsl:when test="(alignDetails/grade &gt;= 0.0) and ($alongDist &gt;= 0.0)">
            <xsl:value-of select="alignDetails/azimuth + 180.0"/> <!-- +ve grade results in position prior to design cl point -->
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="alignDetails/azimuth"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:with-param>
      <xsl:with-param name="distance" select="math:abs(number($alongDist))"/>
      <xsl:with-param name="startN" select="alignDetails/clCoordinates/north"/>
      <xsl:with-param name="startE" select="alignDetails/clCoordinates/east"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- Now compute final position orthogonal to the tempPt -->
  <xsl:variable name="rptPt">
    <xsl:call-template name="FollowAzimuth">
      <xsl:with-param name="azimuth" select="$azToDesignPt"/>
      <xsl:with-param name="distance" select="math:abs(number(profileOffsets/hzOffsetComputed))"/>
      <xsl:with-param name="startN" select="msxsl:node-set($tempPt)/north"/>
      <xsl:with-param name="startE" select="msxsl:node-set($tempPt)/east"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">
      <xsl:choose>
        <xsl:when test="$NECoords = 'true'">
          <xsl:value-of select="concat('Yukarı:&#09;', format-number(msxsl:node-set($rptPt)/north * $DistConvFactor, $DecPl3, 'Standard'))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat('Sağa:&#09;', format-number(msxsl:node-set($rptPt)/east * $DistConvFactor, $DecPl3, 'Standard'))"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text">
      <xsl:choose>
        <xsl:when test="$NECoords = 'true'">
          <xsl:value-of select="concat('Sağa:&#09;', format-number(msxsl:node-set($rptPt)/east * $DistConvFactor, $DecPl3, 'Standard'))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat('Yukarı:&#09;', format-number(msxsl:node-set($rptPt)/north * $DistConvFactor, $DecPl3, 'Standard'))"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>

  <xsl:call-template name="OutputTextInParagraph">
    <xsl:with-param name="text" select="concat('Kot:&#09;', format-number((alignDetails/clCoordinates/elevation + $upDist) * $DistConvFactor, $DecPl3, 'Standard'))"/>
    <xsl:with-param name="bold" select="'Yes'"/>
    <xsl:with-param name="size" select="10"/>
    <xsl:with-param name="justify" select="'left'"/>
  </xsl:call-template>
  <xsl:call-template name="NewLine"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Output a table with the template point details ******** -->
<!-- **************************************************************** -->
<xsl:template name="OutputProfileAreaAndPointsTable">
  <xsl:param name="station"/>
  <xsl:param name="profileAreas"/>

  <xsl:variable name="originX">
    <xsl:choose>
      <xsl:when test="$computeProfileOffsets = 'Yes'">8000</xsl:when>
      <xsl:otherwise>8500</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:if test="count(msxsl:node-set($profileAreas)/profile[@station = $station]/*) != 0">
    <w:tbl>
      <w:tblPr>
        <w:tblStyle w:val="TableGrid"/>
        <w:tblpPr w:leftFromText="180" w:rightFromText="180" w:tblpX="{$originX}" w:tblpY="1000"/>
        <w:tblW w:w="0" w:type="auto"/>
        <w:tblLook w:val="01E0"/>
      </w:tblPr>

      <!-- Column headings -->
      <xsl:call-template name="StartTableRow"/>
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1400"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">Tipkesit Alanı</xsl:with-param>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="justify" select="'center'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1400"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">Kazılacak Alan</xsl:with-param>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="justify" select="'center'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1400"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">Dolgu Alanı</xsl:with-param>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="justify" select="'center'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1400"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">Ölçülen Alan</xsl:with-param>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="justify" select="'center'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>
      <xsl:call-template name="EndTableRow"/>

      <xsl:for-each select="msxsl:node-set($profileAreas)/profile[@station = $station]">
        <xsl:call-template name="StartTableRow"/>
          <xsl:call-template name="NewLine"/>
          <xsl:call-template name="StartTableCell">
            <xsl:with-param name="cellWidth" select="1400"/>
          </xsl:call-template>
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text">
                <xsl:value-of select="format-number(templateArea * $AreaConvFactor, $DecPl2, 'Standard')"/>
                <xsl:call-template name="AreaUnitsString"/>
              </xsl:with-param>
              <xsl:with-param name="bold" select="'No'"/>
              <xsl:with-param name="justify" select="'center'"/>
              <xsl:with-param name="size" select="8"/>
            </xsl:call-template>
          <xsl:call-template name="EndTableCell"/>

          <xsl:call-template name="NewLine"/>
          <xsl:call-template name="StartTableCell">
            <xsl:with-param name="cellWidth" select="1400"/>
          </xsl:call-template>
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text">
                <xsl:value-of select="format-number(undercutArea * $AreaConvFactor, $DecPl2, 'Standard')"/>
                <xsl:call-template name="AreaUnitsString"/>
              </xsl:with-param>
              <xsl:with-param name="bold" select="'No'"/>
              <xsl:with-param name="justify" select="'center'"/>
              <xsl:with-param name="size" select="8"/>
            </xsl:call-template>
          <xsl:call-template name="EndTableCell"/>

          <xsl:call-template name="NewLine"/>
          <xsl:call-template name="StartTableCell">
            <xsl:with-param name="cellWidth" select="1400"/>
          </xsl:call-template>
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text">
                <xsl:value-of select="format-number(overcutArea * $AreaConvFactor, $DecPl2, 'Standard')"/>
                <xsl:call-template name="AreaUnitsString"/>
              </xsl:with-param>
              <xsl:with-param name="bold" select="'No'"/>
              <xsl:with-param name="justify" select="'center'"/>
              <xsl:with-param name="size" select="8"/>
            </xsl:call-template>
          <xsl:call-template name="EndTableCell"/>

          <xsl:call-template name="NewLine"/>
          <xsl:call-template name="StartTableCell">
            <xsl:with-param name="cellWidth" select="1400"/>
          </xsl:call-template>
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text">
                <xsl:value-of select="format-number(measuredArea * $AreaConvFactor, $DecPl2, 'Standard')"/>
                <xsl:call-template name="AreaUnitsString"/>
              </xsl:with-param>
              <xsl:with-param name="bold" select="'No'"/>
              <xsl:with-param name="justify" select="'center'"/>
              <xsl:with-param name="size" select="8"/>
            </xsl:call-template>
          <xsl:call-template name="EndTableCell"/>
        <xsl:call-template name="EndTableRow"/>
      </xsl:for-each>
    </w:tbl>
    <xsl:call-template name="NewLine"/>
  </xsl:if>

  <xsl:variable name="vertOffset">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($profileAreas)/profile[@station = $station]/*) != 0">1600</xsl:when>
      <xsl:otherwise>1000</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <w:tbl>
    <w:tblPr>
      <w:tblStyle w:val="TableGrid"/>
      <w:tblpPr w:leftFromText="180" w:rightFromText="180" w:tblpX="{$originX}" w:tblpY="{$vertOffset}"/>
      <w:tblW w:w="0" w:type="auto"/>
      <w:tblLook w:val="01E0"/>
    </w:tblPr>

    <!-- Column headings -->
    <xsl:call-template name="StartTableRow"/>
      <xsl:call-template name="NewLine"/>
      <xsl:call-template name="StartTableCell">
        <xsl:with-param name="cellWidth" select="1000"/>
      </xsl:call-template>
        <xsl:call-template name="OutputTextInParagraph">
          <xsl:with-param name="text" select="'Nokta'"/>
          <xsl:with-param name="bold" select="'Yes'"/>
          <xsl:with-param name="justify" select="'center'"/>
          <xsl:with-param name="size" select="8"/>
        </xsl:call-template>
      <xsl:call-template name="EndTableCell"/>

      <xsl:call-template name="NewLine"/>
      <xsl:call-template name="StartTableCell">
        <xsl:with-param name="cellWidth" select="1100"/>
      </xsl:call-template>
        <xsl:call-template name="OutputTextInParagraph">
          <xsl:with-param name="text" select="'Yat.Ofset'"/>
          <xsl:with-param name="bold" select="'Yes'"/>
          <xsl:with-param name="justify" select="'center'"/>
          <xsl:with-param name="size" select="8"/>
        </xsl:call-template>
      <xsl:call-template name="EndTableCell"/>

      <xsl:call-template name="NewLine"/>
      <xsl:call-template name="StartTableCell">
        <xsl:with-param name="cellWidth" select="1100"/>
      </xsl:call-template>
        <xsl:call-template name="OutputTextInParagraph">
          <xsl:with-param name="text">
            <xsl:choose>
              <xsl:when test="$outputVertValuesAs = 'Elevations'">Kot</xsl:when>
              <xsl:otherwise>Düş.Ofset</xsl:otherwise>
            </xsl:choose>
          </xsl:with-param>
          <xsl:with-param name="bold" select="'Yes'"/>
          <xsl:with-param name="justify" select="'center'"/>
          <xsl:with-param name="size" select="8"/>
        </xsl:call-template>
      <xsl:call-template name="EndTableCell"/>

      <xsl:call-template name="NewLine"/>
      <xsl:call-template name="StartTableCell">
        <xsl:with-param name="cellWidth" select="1100"/>
      </xsl:call-template>
        <xsl:call-template name="OutputTextInParagraph">
          <xsl:with-param name="text" select="'Delta'"/>
          <xsl:with-param name="bold" select="'Yes'"/>
          <xsl:with-param name="justify" select="'center'"/>
          <xsl:with-param name="size" select="8"/>
        </xsl:call-template>
      <xsl:call-template name="EndTableCell"/>

      <xsl:call-template name="NewLine"/>
      <xsl:call-template name="StartTableCell">
        <xsl:with-param name="cellWidth" select="1100"/>
      </xsl:call-template>
        <xsl:call-template name="OutputTextInParagraph">
          <xsl:with-param name="text">
            <xsl:choose>
              <xsl:when test="$useChainageNotation = 'true'">Chn Delta</xsl:when>
              <xsl:otherwise>Ist. Delta</xsl:otherwise>
            </xsl:choose>
          </xsl:with-param>
          <xsl:with-param name="bold" select="'Yes'"/>
          <xsl:with-param name="justify" select="'center'"/>
          <xsl:with-param name="size" select="8"/>
        </xsl:call-template>
      <xsl:call-template name="EndTableCell"/>

      <xsl:if test="$computeProfileOffsets = 'Yes'">
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1100"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text" select="'Delta (en uygun kesit)'"/>
            <xsl:with-param name="bold" select="'Yes'"/>
            <xsl:with-param name="justify" select="'center'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>
      </xsl:if>
    <xsl:call-template name="EndTableRow"/>

    <xsl:variable name="overbreakTol" select="overbreakTolerance"/>
    <xsl:variable name="underbreakTol" select="underbreakTolerance"/>

    <xsl:variable name="designElev">
      <xsl:if test="$outputVertValuesAs = 'Elevations'">
        <xsl:value-of select="alignDetails/clCoordinates/elevation"/>
      </xsl:if>
    </xsl:variable>
    
    <xsl:variable name="design" select="design"/>  <!-- Assign the design element to a node-set variable to pass to TemplateElementForPoint function -->

    <xsl:for-each select="TunnelPointDeltaRecord">
      <xsl:call-template name="StartTableRow"/>
        <!-- Point name -->
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1000"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text" select="name"/>
            <xsl:with-param name="justify" select="'left'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <!-- Horizontal offset -->
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1100"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text" select="format-number(HorizontalOffset * $DistConvFactor, $DecPl3, 'Standard')"/>
            <xsl:with-param name="justify" select="'right'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <!-- Vertical offset or elevation -->
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1100"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text">
              <xsl:choose>
                <xsl:when test="$outputVertValuesAs = 'Elevations'">
                  <xsl:value-of select="format-number((VerticalOffset + $designElev) * $DistConvFactor, $DecPl3, 'Standard')"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="format-number(VerticalOffset * $DistConvFactor, $DecPl3, 'Standard')"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="justify" select="'right'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <!-- Delta -->
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1100"/>
        </xsl:call-template>
          <xsl:variable name="delta">  <!-- Report the computed delta value if possible -->
            <xsl:choose>
              <xsl:when test="string(number(calcDelta)) != 'NaN'">
                <xsl:value-of select="calcDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text" select="format-number($delta * $DistConvFactor, $DecPl3, 'Standard')"/>
            <xsl:with-param name="justify" select="'right'"/>
            <xsl:with-param name="size" select="8"/>
            <xsl:with-param name="colour">
              <xsl:variable name="absDelta" select="math:abs(number($delta))"/>
              <xsl:choose>
                <xsl:when test="(string(number($underbreakTol)) != 'NaN') and ($delta &lt; 0) and
                                ($absDelta &gt; $underbreakTol)">red</xsl:when>
                <xsl:when test="(string(number($overbreakTol)) != 'NaN') and ($delta &gt; 0) and
                                ($absDelta &gt; $overbreakTol)">blue</xsl:when>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <!-- Station delta -->
        <xsl:call-template name="NewLine"/>
        <xsl:call-template name="StartTableCell">
          <xsl:with-param name="cellWidth" select="1100"/>
        </xsl:call-template>
          <xsl:call-template name="OutputTextInParagraph">
            <xsl:with-param name="text" select="format-number(DeltaStation * $DistConvFactor, $DecPl3, 'Standard')"/>
            <xsl:with-param name="justify" select="'right'"/>
            <xsl:with-param name="size" select="8"/>
          </xsl:call-template>
        <xsl:call-template name="EndTableCell"/>

        <!-- Delta from best fit profile -->
        <xsl:if test="$computeProfileOffsets = 'Yes'">
          <xsl:call-template name="NewLine"/>
          <xsl:call-template name="StartTableCell">
            <xsl:with-param name="cellWidth" select="1100"/>
          </xsl:call-template>
            <xsl:variable name="ptName" select="name"/>
            <xsl:call-template name="OutputTextInParagraph">
              <xsl:with-param name="text" select="format-number(../calcCircleDeltas/delta[@name = $ptName] * $DistConvFactor, $DecPl3, 'Standard')"/>
              <xsl:with-param name="justify" select="'right'"/>
              <xsl:with-param name="size" select="8"/>
              <xsl:with-param name="colour">
                <xsl:variable name="absDelta" select="math:abs(number(../calcCircleDeltas/delta[@name = $ptName]))"/>
                <xsl:choose>
                  <xsl:when test="(string(number($underbreakTol)) != 'NaN') and (../calcCircleDeltas/delta[@name = $ptName] &lt; 0) and
                                  ($absDelta &gt; $underbreakTol)">red</xsl:when>
                  <xsl:when test="(string(number($overbreakTol)) != 'NaN') and (../calcCircleDeltas/delta[@name = $ptName] &gt; 0) and
                                  ($absDelta &gt; $overbreakTol)">blue</xsl:when>
                </xsl:choose>
              </xsl:with-param>
            </xsl:call-template>
          <xsl:call-template name="EndTableCell"/>
        </xsl:if>
      <xsl:call-template name="EndTableRow"/>
    </xsl:for-each>
  </w:tbl>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Compute the X plot coord for a vertical offset value ***** -->
<!-- **************************************************************** -->
<xsl:template name="XPlotCoord">
  <xsl:param name="xVal"/>
  <xsl:param name="plotParams"/>

  <xsl:value-of select="$gridOriginX + msxsl:node-set($plotParams)/borderX + ($xVal - msxsl:node-set($plotParams)/minX) * msxsl:node-set($plotParams)/scaleRatio"/>
</xsl:template>

<!-- **************************************************************** -->
<!-- ***** Compute the Y plot coord for a vertical offset value ***** -->
<!-- **************************************************************** -->
<xsl:template name="YPlotCoord">
  <xsl:param name="yVal"/>
  <xsl:param name="plotParams"/>

  <xsl:value-of select="$gridOriginY + ($gridSizeY - msxsl:node-set($plotParams)/borderY) - (($yVal - msxsl:node-set($plotParams)/minY) * msxsl:node-set($plotParams)/scaleRatio)"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************** Draw the template design elements *************** -->
<!-- **************************************************************** -->
<xsl:template name="DrawTemplateDesignElements">
  <xsl:param name="templateSurface"/>

  <xsl:variable name="plotParams">
    <xsl:element name="minX"><xsl:value-of select="minX"/></xsl:element>
    <xsl:element name="minY"><xsl:value-of select="minY"/></xsl:element>
    <xsl:element name="borderX"><xsl:value-of select="borderX"/></xsl:element>
    <xsl:element name="borderY"><xsl:value-of select="borderY"/></xsl:element>
    <xsl:element name="scaleRatio"><xsl:value-of select="scaleRatio"/></xsl:element>
  </xsl:variable>

  <xsl:comment> Design template elements </xsl:comment>
  <xsl:call-template name="NewLine"/>
  <!-- Output the design template lines and arcs -->
  <xsl:for-each select="design/templateSurface">
    <xsl:variable name="surfaceName" select="@name"/>
    <xsl:variable name="activeSurface">
      <xsl:choose>    <!-- An empty $templateSurface indicates that an older pre template surface support JobXML file is being processed - there will only be 1 surface so make it active -->
        <xsl:when test="($surfaceName = $templateSurface) or (string($templateSurface) = '')">true</xsl:when>
        <xsl:otherwise>false</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:for-each select="element">
      <xsl:choose>
        <xsl:when test="radius">  <!-- This is an arc element -->
          <xsl:call-template name="DrawArc">
            <xsl:with-param name="arcElement" select="."/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
            <xsl:with-param name="activeSurface" select="$activeSurface"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>           <!-- This is a line element -->
          <xsl:variable name="coordX1">
            <xsl:call-template name="XPlotCoord">
              <xsl:with-param name="xVal" select="startHz"/>
              <xsl:with-param name="plotParams" select="$plotParams"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="coordY1">
            <xsl:call-template name="YPlotCoord">
              <xsl:with-param name="yVal" select="startVt"/>
              <xsl:with-param name="plotParams" select="$plotParams"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="coordX2">
            <xsl:call-template name="XPlotCoord">
              <xsl:with-param name="xVal" select="endHz"/>
              <xsl:with-param name="plotParams" select="$plotParams"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="coordY2">
            <xsl:call-template name="YPlotCoord">
              <xsl:with-param name="yVal" select="endVt"/>
              <xsl:with-param name="plotParams" select="$plotParams"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="colour">
            <xsl:choose>
              <xsl:when test="$activeSurface = 'true'">blue</xsl:when>
              <xsl:otherwise>gray</xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:variable name="lineWidth">
            <xsl:choose>
              <xsl:when test="$activeSurface = 'true'">2.0</xsl:when>
              <xsl:otherwise>1.0</xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokecolor="{$colour}" strokeweight="{$lineWidth}pt"/>
          <xsl:call-template name="NewLine"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Draw grid lines on profile ****************** -->
<!-- **************************************************************** -->
<xsl:template name="DrawGridLines">

  <xsl:variable name="plotParams">
    <xsl:element name="minX"><xsl:value-of select="minX"/></xsl:element>
    <xsl:element name="minY"><xsl:value-of select="minY"/></xsl:element>
    <xsl:element name="borderX"><xsl:value-of select="borderX"/></xsl:element>
    <xsl:element name="borderY"><xsl:value-of select="borderY"/></xsl:element>
    <xsl:element name="scaleRatio"><xsl:value-of select="scaleRatio"/></xsl:element>
  </xsl:variable>

  <xsl:comment> Grid lines </xsl:comment>
  <xsl:call-template name="NewLine"/>

  <xsl:variable name="calcMinX" select="(-borderX) div scaleRatio + minX"/>
  <xsl:variable name="calcMaxX" select="($gridSizeX - $gridOriginX - borderX) div scaleRatio + minX"/>

  <xsl:variable name="calcMinY" select="($gridOriginY - borderY) div scaleRatio + minY"/>
  <xsl:variable name="calcMaxY" select="($gridOriginY * 2 - borderY + $gridSizeY) div scaleRatio + minY"/>

  <xsl:variable name="minX">
    <xsl:choose>
      <xsl:when test="$calcMinX &lt; 0">
        <xsl:value-of select="ceiling($calcMinX)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="floor($calcMinX)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  
  <xsl:variable name="maxX">
    <xsl:choose>
      <xsl:when test="$calcMaxX &lt; 0">
        <xsl:value-of select="ceiling($calcMaxX)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="floor($calcMaxX)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="gridIncrement">
    <xsl:choose>
      <xsl:when test="$DistConvFactor = 1.0">1</xsl:when>     <!-- 1m increment -->
      <xsl:otherwise>
        <xsl:value-of select="3 * 1.0 div $DistConvFactor"/>  <!-- 3ft increment -->
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="gridStepsX">
    <xsl:choose>
      <xsl:when test="($minX &lt; 0) and ($maxX &gt; 0)">  <!-- Ensure we get a grid line at 0 -->
        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="0"/>
          <xsl:with-param name="toVal" select="$minX"/>
          <xsl:with-param name="increment" select="-$gridIncrement"/>
        </xsl:call-template>

        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="0"/>
          <xsl:with-param name="toVal" select="$maxX"/>
          <xsl:with-param name="increment" select="$gridIncrement"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="$minX"/>
          <xsl:with-param name="toVal" select="$maxX"/>
          <xsl:with-param name="increment" select="$gridIncrement"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="minY">
    <xsl:choose>
      <xsl:when test="$calcMinY &lt; 0">
        <xsl:value-of select="ceiling($calcMinY)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="floor($calcMinY)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="maxY">
    <xsl:choose>
      <xsl:when test="$calcMaxY &lt; 0">
        <xsl:value-of select="ceiling($calcMaxY)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="floor($calcMaxY)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="gridStepsY">
    <xsl:choose>
      <xsl:when test="($minY &lt; 0) and ($maxY &gt; 0)">  <!-- Ensure we get a grid line at 0 -->
        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="0"/>
          <xsl:with-param name="toVal" select="$minY"/>
          <xsl:with-param name="increment" select="-$gridIncrement"/>
        </xsl:call-template>

        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="0"/>
          <xsl:with-param name="toVal" select="$maxY"/>
          <xsl:with-param name="increment" select="$gridIncrement"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="GridSteps">
          <xsl:with-param name="fromVal" select="$minY"/>
          <xsl:with-param name="toVal" select="$maxY"/>
          <xsl:with-param name="increment" select="$gridIncrement"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="skipVal">
    <xsl:variable name="gridInc">
      <xsl:call-template name="GridStepIncrement">
        <xsl:with-param name="nbrGridSteps" select="count(msxsl:node-set($gridStepsX)/value)"/>
        <xsl:with-param name="maxGridSteps" select="7"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$DistConvFactor = 1.0">
        <xsl:value-of select="$gridInc"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$gridInc * 3 * 1.0 div $DistConvFactor"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Draw vertical grid lines -->
  <xsl:for-each select="msxsl:node-set($gridStepsX)/value">
    <xsl:variable name="testVal" select="(. div $skipVal) - round(. div $skipVal)"/>
    <xsl:variable name="absTestVal" select="math:abs(number($testVal))"/>
    <xsl:if test="$absTestVal &lt; 0.001">
      <xsl:variable name="coordX1">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="."/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="coordY1" select="0"/>

      <xsl:variable name="coordX2" select="$coordX1"/>

      <xsl:variable name="coordY2" select="3600"/>

      <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokecolor="silver" strokeweight="0.1pt"/>
      <xsl:call-template name="NewLine"/>

      <!-- Output the grid line annotation -->
      <xsl:variable name="gridVal" select="format-number(. * $DistConvFactor, $DecPl0, 'Standard')"/>
      <xsl:variable name="textWidth" select="string-length($gridVal) div 0.02"/>
      <xsl:variable name="textHeight" select="100"/>
      <xsl:if test="$coordX1 - $textHeight * 2 &gt; $gridOriginX">
        <v:shape type="#_tunnel_annotation" style="position:absolute;left:{$coordX1 - $textHeight};top:{$coordY2 - 120};width:{$textWidth};height:{$textHeight};rotation:-90" fillcolor="black" stroked="f" strokeweight="0">
        <xsl:call-template name="NewLine"/>
          <v:fill opacity="1" o:opacity2="1" recolor="f" rotate="f"/>
          <xsl:call-template name="NewLine"/>
          <v:textpath on="t" style='font-family:"Arial";font-size:8pt' fitshape="f" string="{$gridVal}"/>
          <xsl:call-template name="NewLine"/>
        </v:shape>
        <xsl:call-template name="NewLine"/>
      </xsl:if>
    </xsl:if>
  </xsl:for-each>

  <!-- Draw horizontal grid lines -->
  <xsl:for-each select="msxsl:node-set($gridStepsY)/value">
    <xsl:variable name="testVal" select="(. div $skipVal) - round(. div $skipVal)"/>
    <xsl:variable name="absTestVal" select="math:abs(number($testVal))"/>
    <xsl:if test="$absTestVal &lt; 0.001">
      <xsl:variable name="coordX1" select="0"/>

      <xsl:variable name="coordY1">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="."/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="coordX2" select="3600"/>

      <xsl:variable name="coordY2" select="$coordY1"/>

      <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokecolor="silver" strokeweight="0.5pt"/>
      <xsl:call-template name="NewLine"/>

      <!-- Output the grid line annotation -->
      <xsl:variable name="gridVal" select="format-number(. * $DistConvFactor, $DecPl0, 'Standard')"/>
      <xsl:variable name="textWidth" select="string-length($gridVal) div 0.02"/>
      <xsl:variable name="textHeight" select="100"/>
      <xsl:if test="$coordY1 - $textHeight * 2 &gt; $gridOriginY">
        <v:shape type="#_tunnel_annotation" style="position:absolute;left:{$coordX1 + 50};top:{$coordY1 - $textHeight};width:{$textWidth};height:{$textHeight};rotation:0" fillcolor="black" stroked="f" strokeweight="0">
        <xsl:call-template name="NewLine"/>
          <v:fill opacity="1" o:opacity2="1" recolor="f" rotate="f"/>
          <xsl:call-template name="NewLine"/>
          <v:textpath on="t" style='font-family:"Arial";font-size:8pt' fitshape="f" string="{$gridVal}"/>
          <xsl:call-template name="NewLine"/>
        </v:shape>
        <xsl:call-template name="NewLine"/>
      </xsl:if>
    </xsl:if>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Draw the lines between the scanned points *********** -->
<!-- **************************************************************** -->
<xsl:template name="DrawLinesBetweenScannedPoints">

  <xsl:variable name="plotParams">
    <xsl:element name="minX"><xsl:value-of select="minX"/></xsl:element>
    <xsl:element name="minY"><xsl:value-of select="minY"/></xsl:element>
    <xsl:element name="borderX"><xsl:value-of select="borderX"/></xsl:element>
    <xsl:element name="borderY"><xsl:value-of select="borderY"/></xsl:element>
    <xsl:element name="scaleRatio"><xsl:value-of select="scaleRatio"/></xsl:element>
  </xsl:variable>

  <xsl:comment> Lines between scanned points </xsl:comment>
  <xsl:call-template name="NewLine"/>

  <xsl:for-each select="TunnelPointDeltaRecord">
    <xsl:if test="position() &gt; 1">
      <xsl:variable name="coordX1">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="preceding-sibling::TunnelPointDeltaRecord[1]/HorizontalOffset"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY1">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="preceding-sibling::TunnelPointDeltaRecord[1]/VerticalOffset"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordX2">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="HorizontalOffset"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY2">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="VerticalOffset"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokeweight="1.0pt"/>
      <xsl:call-template name="NewLine"/>
    </xsl:if>
  </xsl:for-each>
  
  <xsl:if test="count(TunnelPointDeltaRecord) &gt; 3">   <!-- There are more than 3 points -->
    <xsl:variable name="firstX" select="TunnelPointDeltaRecord[1]/HorizontalOffset"/>
    <xsl:variable name="firstY" select="TunnelPointDeltaRecord[1]/VerticalOffset"/>
    <xsl:variable name="lastX" select="TunnelPointDeltaRecord[last()]/HorizontalOffset"/>
    <xsl:variable name="lastY" select="TunnelPointDeltaRecord[last()]/VerticalOffset"/>
    <xsl:variable name="secondLastX" select="TunnelPointDeltaRecord[last() - 1]/HorizontalOffset"/>
    <xsl:variable name="secondLastY" select="TunnelPointDeltaRecord[last() - 1]/VerticalOffset"/>

    <xsl:variable name="distFirstToLast">
      <xsl:call-template name="InverseDistance">
        <xsl:with-param name="deltaN" select="$firstY - $lastY"/>
        <xsl:with-param name="deltaE" select="$firstX - $lastX"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="totalLineLengths">
      <xsl:variable name="lineLengths">
        <xsl:for-each select="TunnelPointDeltaRecord">
          <xsl:if test="position() &gt; 1">
            <xsl:element name="lineLen">
              <xsl:call-template name="InverseDistance">
                <xsl:with-param name="deltaN" select="VerticalOffset - preceding-sibling::*[1]/VerticalOffset"/>
                <xsl:with-param name="deltaE" select="HorizontalOffset - preceding-sibling::*[1]/HorizontalOffset"/>
              </xsl:call-template>
            </xsl:element>
          </xsl:if>
        </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="sum(msxsl:node-set($lineLengths)/lineLen)"/>
    </xsl:variable>

    <!-- If the distance from the last point to the first point is less than a quarter of the total -->
    <!-- length of the measured segments then join them together to complete the cross-section.     -->
    <xsl:if test="$distFirstToLast &lt; ($totalLineLengths div 4)">
      <xsl:variable name="coordX1">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="$lastX"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY1">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="$lastY"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordX2">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="$firstX"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY2">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="$firstY"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokeweight="1.0pt"/>
      <xsl:call-template name="NewLine"/>
    </xsl:if>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************* Draw lines showing over/under breaks ************* -->
<!-- **************************************************************** -->
<xsl:template name="DrawOverUnderBreakLines">
  <xsl:param name="templateSurface"/>

  <xsl:variable name="plotParams">
    <xsl:element name="minX"><xsl:value-of select="minX"/></xsl:element>
    <xsl:element name="minY"><xsl:value-of select="minY"/></xsl:element>
    <xsl:element name="borderX"><xsl:value-of select="borderX"/></xsl:element>
    <xsl:element name="borderY"><xsl:value-of select="borderY"/></xsl:element>
    <xsl:element name="scaleRatio"><xsl:value-of select="scaleRatio"/></xsl:element>
  </xsl:variable>

  <xsl:variable name="design" select="design"/>  <!-- Assign the design element to a node-set variable to pass to TemplateElementForPoint function -->

  <xsl:variable name="templateSurf">
    <xsl:choose>
      <xsl:when test="string($templateSurface) != ''">
        <xsl:value-of select="$templateSurface"/>
      </xsl:when>
      <xsl:otherwise>DefaultXSLSurface</xsl:otherwise>  <!-- No multiple surfaces so set to internal default -->
    </xsl:choose>
  </xsl:variable>

  <xsl:comment> Over/underbreak lines projected onto design profile </xsl:comment>
  <xsl:call-template name="NewLine"/>

  <xsl:variable name="overUnderBreakLines">
    <xsl:for-each select="TunnelPointDeltaRecord">
      <xsl:variable name="closestDesignElement">
        <xsl:call-template name="TemplateElementForPoint">
          <xsl:with-param name="designTemplate" select="$design"/>
          <xsl:with-param name="templateSurface" select="$templateSurf"/>
          <xsl:with-param name="ptHz" select="HorizontalOffset"/>
          <xsl:with-param name="ptVt" select="VerticalOffset"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="endPosn">
        <xsl:variable name="element">
          <xsl:copy-of select="msxsl:node-set($design)/templateSurface[@name = $templateSurf]/element[number(msxsl:node-set($closestDesignElement)/index)]"/>
        </xsl:variable>

        <xsl:choose>
          <xsl:when test="msxsl:node-set($closestDesignElement)/extCornerPt = 'true'"> <!-- This is an external corner point -->
            <!-- Determine the closest end of the indexed element and get the direction to it -->
            <xsl:variable name="distStart">
              <xsl:call-template name="InverseDistance">
                <xsl:with-param name="deltaN" select="VerticalOffset - msxsl:node-set($element)/element/startVt"/>
                <xsl:with-param name="deltaE" select="HorizontalOffset - msxsl:node-set($element)/element/startHz"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:variable name="distEnd">
              <xsl:call-template name="InverseDistance">
                <xsl:with-param name="deltaN" select="VerticalOffset - msxsl:node-set($element)/element/endVt"/>
                <xsl:with-param name="deltaE" select="HorizontalOffset - msxsl:node-set($element)/element/endHz"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:variable name="dirn">
              <xsl:choose>
                <xsl:when test="$distStart &lt; $distEnd">
                  <xsl:call-template name="InverseAzimuth">
                    <xsl:with-param name="deltaN" select="msxsl:node-set($element)/element/startVt - VerticalOffset"/>
                    <xsl:with-param name="deltaE" select="msxsl:node-set($element)/element/startHz - HorizontalOffset"/>
                    <xsl:with-param name="returnInRadians">true</xsl:with-param>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:call-template name="InverseAzimuth">
                    <xsl:with-param name="deltaN" select="msxsl:node-set($element)/element/endVt - VerticalOffset"/>
                    <xsl:with-param name="deltaE" select="msxsl:node-set($element)/element/endHz - HorizontalOffset"/>
                    <xsl:with-param name="returnInRadians">true</xsl:with-param>
                  </xsl:call-template>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

            <xsl:call-template name="FollowDirection">
              <xsl:with-param name="direction" select="$dirn"/>
              <xsl:with-param name="distance" select="math:abs(number(Delta))"/>
              <xsl:with-param name="startVt" select="VerticalOffset"/>
              <xsl:with-param name="startHz" select="HorizontalOffset"/>
            </xsl:call-template>

            <xsl:element name="calcDelta">  <!-- By definition this will be a point beyond a corner and so will be an over-break (+ve) value -->
              <xsl:choose>
                <xsl:when test="string(number(msxsl:node-set($closestDesignElement)/delta)) != 'NaN'">
                  <xsl:value-of select="msxsl:node-set($closestDesignElement)/delta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:element>
          </xsl:when>
          <xsl:otherwise>
            <xsl:choose>
              <xsl:when test="msxsl:node-set($element)/element/radius">  <!-- Arc element -->
                <!-- Get the direction from the arc centre to the point -->
                <xsl:variable name="dirn">
                  <xsl:call-template name="InverseAzimuth">
                    <xsl:with-param name="deltaN" select="VerticalOffset - msxsl:node-set($element)/element/centreVt"/>
                    <xsl:with-param name="deltaE" select="HorizontalOffset - msxsl:node-set($element)/element/centreHz"/>
                    <xsl:with-param name="returnInRadians">true</xsl:with-param>
                  </xsl:call-template>
                </xsl:variable>

                <!-- The end position for the computed delta is the point on the arc circumference -->
                <xsl:call-template name="FollowDirection">
                  <xsl:with-param name="direction" select="$dirn"/>
                  <xsl:with-param name="distance" select="msxsl:node-set($element)/element/radius"/>
                  <xsl:with-param name="startVt" select="msxsl:node-set($element)/element/centreVt"/>
                  <xsl:with-param name="startHz" select="msxsl:node-set($element)/element/centreHz"/>
                </xsl:call-template>

                <xsl:element name="calcDelta">
                  <xsl:choose>
                    <xsl:when test="string(number(msxsl:node-set($closestDesignElement)/delta)) != 'NaN'">
                      <xsl:value-of select="msxsl:node-set($closestDesignElement)/delta"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="Delta"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:when>

              <xsl:otherwise>  <!-- Straight element -->
                <!-- Get the coordinates of the point projected onto the profile line from the measured position -->
                <xsl:variable name="projPt">
                  <xsl:call-template name="PointToLineProjectionPoint">
                    <xsl:with-param name="x1" select="msxsl:node-set($element)/element/startHz"/>
                    <xsl:with-param name="y1" select="msxsl:node-set($element)/element/startVt"/>
                    <xsl:with-param name="x2" select="msxsl:node-set($element)/element/endHz"/>
                    <xsl:with-param name="y2" select="msxsl:node-set($element)/element/endVt"/>
                    <xsl:with-param name="xPt" select="HorizontalOffset"/>
                    <xsl:with-param name="yPt" select="VerticalOffset"/>
                  </xsl:call-template>
                </xsl:variable>
                
                <xsl:element name="horizOffset">
                  <xsl:value-of select="msxsl:node-set($projPt)/x"/>
                </xsl:element>
                
                <xsl:element name="vertOffset">
                  <xsl:value-of select="msxsl:node-set($projPt)/y"/>
                </xsl:element>

                <xsl:element name="calcDelta">
                  <xsl:choose>
                    <xsl:when test="string(number(msxsl:node-set($closestDesignElement)/delta)) != 'NaN'">
                      <xsl:value-of select="msxsl:node-set($closestDesignElement)/delta"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="Delta"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:element name="line">
        <xsl:element name="coordX1">
          <xsl:call-template name="XPlotCoord">
            <xsl:with-param name="xVal" select="HorizontalOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:element>
        <xsl:element name="coordY1">
          <xsl:call-template name="YPlotCoord">
            <xsl:with-param name="yVal" select="VerticalOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:element>
        <xsl:element name="coordX2">
          <xsl:call-template name="XPlotCoord">
            <xsl:with-param name="xVal" select="msxsl:node-set($endPosn)/horizOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:element>
        <xsl:element name="coordY2">
          <xsl:call-template name="YPlotCoord">
            <xsl:with-param name="yVal" select="msxsl:node-set($endPosn)/vertOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:element>

        <xsl:element name="colour">
          <xsl:choose>
            <xsl:when test="msxsl:node-set($endPosn)/calcDelta &lt; 0">red</xsl:when>
            <xsl:otherwise>green</xsl:otherwise>
          </xsl:choose>
        </xsl:element>

        <xsl:if test="$annotatePoints = 'true'">
          <xsl:variable name="annotateIndex">
            <xsl:choose>
              <xsl:when test="$annotateEvery = 'Every profile point'">1</xsl:when>
              <xsl:when test="$annotateEvery = 'Every 2nd profile point'">2</xsl:when>
              <xsl:when test="$annotateEvery = 'Every 5th profile point'">5</xsl:when>
              <xsl:otherwise>1</xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:if test="(position() - 1) mod $annotateIndex = 0">  <!-- Annotate every, every 2nd or every 5th point -->
            <xsl:element name="annotation">
              <xsl:variable name="text">
                <xsl:choose>
                  <xsl:when test="$annotateProfilePoints = 'Point Name'">
                    <xsl:value-of select="name"/>
                  </xsl:when>
                  <xsl:otherwise>  <!-- Annotate with the delta values -->
                    <xsl:value-of select="format-number(msxsl:node-set($endPosn)/calcDelta * $DistConvFactor, $DecPl3, 'Standard')"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>

              <xsl:variable name="textWidth" select="string-length($text) div 0.02"/>
              <xsl:variable name="textHeight" select="100"/>

              <xsl:variable name="dirn">
                <xsl:call-template name="InverseAzimuth">
                  <xsl:with-param name="deltaN" select="VerticalOffset - msxsl:node-set($endPosn)/vertOffset"/>
                  <xsl:with-param name="deltaE" select="HorizontalOffset - msxsl:node-set($endPosn)/horizOffset"/>
                  <xsl:with-param name="returnInRadians">true</xsl:with-param>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="offsetVal" select="$gridSizeX * 0.008 div msxsl:node-set($plotParams)/scaleRatio"/>
              <xsl:variable name="halfTextWidth" select="$textWidth div 2.0 div msxsl:node-set($plotParams)/scaleRatio"/>

              <xsl:variable name="textInsPt">
                <xsl:call-template name="FollowDirection">
                  <xsl:with-param name="direction" select="$dirn"/>
                  <xsl:with-param name="distance" select="$offsetVal + $halfTextWidth"/>  <!-- Offset plus half text length -->
                  <xsl:with-param name="startVt" select="VerticalOffset"/>
                  <xsl:with-param name="startHz" select="HorizontalOffset"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="altTextInsPt">
                <xsl:call-template name="FollowDirection">
                  <xsl:with-param name="direction" select="$dirn + math:PI()"/>
                  <xsl:with-param name="distance" select="$offsetVal + $halfTextWidth"/>  <!-- Offset plus half text length -->
                  <xsl:with-param name="startVt" select="msxsl:node-set($endPosn)/vertOffset"/>
                  <xsl:with-param name="startHz" select="msxsl:node-set($endPosn)/horizOffset"/>
                </xsl:call-template>
              </xsl:variable>

              <!-- Record values in 'world' dimensions to use in text clash routines -->
              <xsl:element name="worldTextCentrePtX">
                <xsl:value-of select="msxsl:node-set($textInsPt)/horizOffset"/>
              </xsl:element>
              
              <xsl:element name="worldTextCentrePtY">
                <xsl:value-of select="msxsl:node-set($textInsPt)/vertOffset"/>
              </xsl:element>

              <xsl:element name="worldDirn">  <!-- Retain the actual 'azimuth' direction to use in rectangle corner computation -->
                <xsl:value-of select="$dirn"/>
              </xsl:element>

              <xsl:element name="worldTextWidth">
                <xsl:value-of select="$textWidth div msxsl:node-set($plotParams)/scaleRatio"/>
              </xsl:element>

              <xsl:element name="worldTextHeight">
                <xsl:value-of select="$textHeight div msxsl:node-set($plotParams)/scaleRatio"/>
              </xsl:element>

              <xsl:element name="coordX">
                <xsl:call-template name="XPlotCoord">
                  <xsl:with-param name="xVal" select="msxsl:node-set($textInsPt)/horizOffset"/>
                  <xsl:with-param name="plotParams" select="$plotParams"/>
                </xsl:call-template>
              </xsl:element>

              <xsl:element name="coordY">
                <xsl:call-template name="YPlotCoord">
                  <xsl:with-param name="yVal" select="msxsl:node-set($textInsPt)/vertOffset"/>
                  <xsl:with-param name="plotParams" select="$plotParams"/>
                </xsl:call-template>
              </xsl:element>

              <xsl:element name="altCoordX">
                <xsl:call-template name="XPlotCoord">
                  <xsl:with-param name="xVal" select="msxsl:node-set($altTextInsPt)/horizOffset"/>
                  <xsl:with-param name="plotParams" select="$plotParams"/>
                </xsl:call-template>
              </xsl:element>

              <xsl:element name="altCoordY">
                <xsl:call-template name="YPlotCoord">
                  <xsl:with-param name="yVal" select="msxsl:node-set($altTextInsPt)/vertOffset"/>
                  <xsl:with-param name="plotParams" select="$plotParams"/>
                </xsl:call-template>
              </xsl:element>

              <xsl:variable name="textRotn">
                <xsl:variable name="rotn" select="$dirn * 180.0 div math:PI() - 90.0"/>
                <xsl:choose>
                  <xsl:when test="($rotn &gt; 90.0) and ($rotn &lt; 270.0)">
                    <xsl:variable name="temp" select="$rotn - 180.0"/>
                    <xsl:choose>
                      <xsl:when test="$temp &lt; 0">
                        <xsl:value-of select="$temp + 360.0"/>
                      </xsl:when>
                      <xsl:otherwise>
                        <xsl:value-of select="$temp"/>
                      </xsl:otherwise>
                    </xsl:choose>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="$rotn"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>

              <xsl:element name="textWidth">
                <xsl:value-of select="$textWidth"/>
              </xsl:element>

              <xsl:element name="textHeight">
                <xsl:value-of select="$textHeight"/>
              </xsl:element>

              <xsl:element name="textRotn">
                <xsl:value-of select="$textRotn"/>
              </xsl:element>

              <xsl:element name="text">
                <xsl:value-of select="$text"/>
              </xsl:element>
            </xsl:element>
          </xsl:if>  <!-- $annotatePoints = 'true' -->
        </xsl:if>    <!-- (position() - 1) mod $annotateIndex = 0 -->
      </xsl:element>
    </xsl:for-each>
  </xsl:variable>   <!-- overUnderBreakLines node set variable -->

  <xsl:for-each select="msxsl:node-set($overUnderBreakLines)/line">
    <xsl:if test="(string(number(coordX1)) != 'NaN') and (string(number(coordY1)) != 'NaN') and
                  (string(number(coordX2)) != 'NaN') and (string(number(coordY2)) != 'NaN')">
      <!-- Draw the overbreak/underbreak line -->
      <xsl:comment> Overbreak/Underbreak line </xsl:comment>
      <xsl:call-template name="NewLine"/>
      <v:line style="position:absolute" from="{coordX1},{coordY1}" to="{coordX2},{coordY2}" strokecolor="{colour}" strokeweight="1.0pt"/>
      <xsl:call-template name="NewLine"/>

      <xsl:if test="annotation">
        <xsl:comment> Profile point annotation </xsl:comment>
        <xsl:call-template name="NewLine"/>

        <xsl:variable name="textClash">
          <xsl:variable name="rect1">
            <xsl:call-template name="ComputeRectangleCoords">
              <xsl:with-param name="centreX" select="annotation/worldTextCentrePtX"/>
              <xsl:with-param name="centreY" select="annotation/worldTextCentrePtY"/>
              <xsl:with-param name="dirn" select="annotation/worldDirn"/>
              <xsl:with-param name="textHeight" select="annotation/worldTextHeight"/>
              <xsl:with-param name="textWidth" select="annotation/worldTextWidth"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="rect2">
            <xsl:choose>
              <xsl:when test="position() &lt; last()">
                <xsl:call-template name="ComputeRectangleCoords">
                  <xsl:with-param name="centreX" select="preceding-sibling::*[annotation][1]/annotation/worldTextCentrePtX"/>
                  <xsl:with-param name="centreY" select="preceding-sibling::*[annotation][1]/annotation/worldTextCentrePtY"/>
                  <xsl:with-param name="dirn" select="preceding-sibling::*[annotation][1]/annotation/worldDirn"/>
                  <xsl:with-param name="textHeight" select="preceding-sibling::*[annotation][1]/annotation/worldTextHeight"/>
                  <xsl:with-param name="textWidth" select="preceding-sibling::*[annotation][1]/annotation/worldTextWidth"/>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>  <!-- For the last annotation check against the first one for a text clash -->
                <xsl:call-template name="ComputeRectangleCoords">
                  <xsl:with-param name="centreX" select="preceding-sibling::*[annotation][last()]/annotation/worldTextCentrePtX"/>
                  <xsl:with-param name="centreY" select="preceding-sibling::*[annotation][last()]/annotation/worldTextCentrePtY"/>
                  <xsl:with-param name="dirn" select="preceding-sibling::*[annotation][last()]/annotation/worldDirn"/>
                  <xsl:with-param name="textHeight" select="preceding-sibling::*[annotation][last()]/annotation/worldTextHeight"/>
                  <xsl:with-param name="textWidth" select="preceding-sibling::*[annotation][last()]/annotation/worldTextWidth"/>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:call-template name="RectanglesOverlap1">
            <xsl:with-param name="rect1" select="$rect1"/>
            <xsl:with-param name="rect2" select="$rect2"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="insertPt">
          <xsl:choose>
            <xsl:when test="$textClash = 'true'">
              <xsl:element name="X">
                <xsl:value-of select="annotation/altCoordX"/>
              </xsl:element>
              <xsl:element name="Y">
                <xsl:value-of select="annotation/altCoordY"/>
              </xsl:element>
            </xsl:when>
            <xsl:otherwise>
              <xsl:element name="X">
                <xsl:value-of select="annotation/coordX"/>
              </xsl:element>
              <xsl:element name="Y">
                <xsl:value-of select="annotation/coordY"/>
              </xsl:element>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <v:shape type="#_tunnel_annotation" style="position:absolute;left:{msxsl:node-set($insertPt)/X - annotation/textWidth div 2};top:{msxsl:node-set($insertPt)/Y - annotation/textHeight div 2};width:{annotation/textWidth};height:{annotation/textHeight};rotation:{annotation/textRotn}" fillcolor="black" stroked="f" strokeweight="0">
        <xsl:call-template name="NewLine"/>
          <v:fill opacity="1" o:opacity2="1" recolor="f" rotate="f"/>
          <xsl:call-template name="NewLine"/>
          <v:textpath on="t" style='font-family:"Arial";font-size:8pt' fitshape="f" string="{annotation/text}"/>
          <xsl:call-template name="NewLine"/>
        </v:shape>
        <xsl:call-template name="NewLine"/>
      </xsl:if>
    </xsl:if>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******************* Draw the scanned points ******************** -->
<!-- **************************************************************** -->
<xsl:template name="SetupRotatableTextDefn">

  <v:shapetype id="_tunnel_annotation" coordsize="10000,10000" coordorigin="0,0" adj="0" path="m0,5000 l10000,5000e">
  <xsl:call-template name="NewLine"/>
    <v:path textpathok="t" o:connecttype="none"/>
    <xsl:call-template name="NewLine"/>
    <v:textpath on="t" fitshape="f"/>
    <xsl:call-template name="NewLine"/>
    <v:handles>
    <xsl:call-template name="NewLine"/>
      <v:h position="center,center" xrange="0,0"/>
      <xsl:call-template name="NewLine"/>
    </v:handles>
    <xsl:call-template name="NewLine"/>
    <o:lock v:ext="edit" text="t" shapetype="f"/>
    <xsl:call-template name="NewLine"/>
  </v:shapetype>
  <xsl:call-template name="NewLine"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******************* Draw the scanned points ******************** -->
<!-- **************************************************************** -->
<xsl:template name="DrawScannedPoints">

  <xsl:variable name="plotParams">
    <xsl:element name="minX"><xsl:value-of select="minX"/></xsl:element>
    <xsl:element name="minY"><xsl:value-of select="minY"/></xsl:element>
    <xsl:element name="borderX"><xsl:value-of select="borderX"/></xsl:element>
    <xsl:element name="borderY"><xsl:value-of select="borderY"/></xsl:element>
    <xsl:element name="scaleRatio"><xsl:value-of select="scaleRatio"/></xsl:element>
  </xsl:variable>

  <xsl:variable name="underbreakTol" select="underbreakTolerance"/>
  <xsl:variable name="overbreakTol" select="overbreakTolerance"/>
  <xsl:variable name="stnTol" select="stationTolerance"/>

  <xsl:comment> Scanned points </xsl:comment>
  <xsl:call-template name="NewLine"/>

  <xsl:for-each select="TunnelPointDeltaRecord">
    <xsl:variable name="delta">
      <xsl:choose>
        <xsl:when test="string(number(calcDelta)) != 'NaN'">
          <xsl:value-of select="calcDelta"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="Delta"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="underBreak">
      <xsl:call-template name="IsUnderBreakPoint">
        <xsl:with-param name="underbreakTol" select="$underbreakTol"/>
        <xsl:with-param name="delta" select="$delta"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="overBreak">
      <xsl:call-template name="IsOverBreakPoint">
        <xsl:with-param name="overbreakTol" select="$overbreakTol"/>
        <xsl:with-param name="delta" select="$delta"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="outsideStnTol">
      <xsl:call-template name="IsOutsideStnTolPoint">
        <xsl:with-param name="stnTol" select="$stnTol"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="colour">
      <xsl:choose>
        <xsl:when test="$underBreak = 'true'">red</xsl:when>
        <xsl:when test="$overBreak = 'true'">blue</xsl:when>
        <xsl:when test="$outsideStnTol = 'true'">#f60</xsl:when>  <!-- Orange -->
        <xsl:otherwise>green</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="coordX">
      <xsl:call-template name="XPlotCoord">
        <xsl:with-param name="xVal" select="HorizontalOffset"/>
        <xsl:with-param name="plotParams" select="$plotParams"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="coordY">
      <xsl:call-template name="YPlotCoord">
        <xsl:with-param name="yVal" select="VerticalOffset"/>
        <xsl:with-param name="plotParams" select="$plotParams"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="circleSize" select="$gridSizeX * 0.012"/>

    <v:oval style="position:absolute;left:{$coordX - $circleSize div 2};top:{$coordY - $circleSize div 2};width:{$circleSize};height:{$circleSize}" fillcolor="{$colour}" strokeweight="0.5pt"/>
    <xsl:call-template name="NewLine"/>
  </xsl:for-each>
  
  <!-- Draw the scanned profile centre point if requested -->
  <xsl:if test="($computeProfileOffsets = 'Yes') and
                (string(number(profileOffsets/hzOffsetDesign)) != 'NaN') and
                (string(number(profileOffsets/vtOffsetDesign)) != 'NaN')">
    <xsl:variable name="circleSize" select="$gridSizeX * 0.012"/>

    <xsl:comment> Design profile centre point </xsl:comment>
    <xsl:call-template name="NewLine"/>

    <xsl:variable name="coordXDesign">
      <xsl:call-template name="XPlotCoord">
        <xsl:with-param name="xVal" select="profileOffsets/hzOffsetDesign"/>
        <xsl:with-param name="plotParams" select="$plotParams"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="coordYDesign">
      <xsl:call-template name="YPlotCoord">
        <xsl:with-param name="yVal" select="profileOffsets/vtOffsetDesign"/>
        <xsl:with-param name="plotParams" select="$plotParams"/>
      </xsl:call-template>
    </xsl:variable>

    <!-- Draw a cross at the design centre position -->
    <v:line style="position:absolute" from="{$coordXDesign - $circleSize div 2},{$coordYDesign}" to="{$coordXDesign + $circleSize div 2},{$coordYDesign}" strokecolor="black" strokeweight="1.0pt"/>
    <xsl:call-template name="NewLine"/>
    <v:line style="position:absolute" from="{$coordXDesign},{$coordYDesign - $circleSize div 2}" to="{$coordXDesign},{$coordYDesign + $circleSize div 2}" strokecolor="black" strokeweight="1.0pt"/>
    <xsl:call-template name="NewLine"/>

    <xsl:if test="(string(number(profileOffsets/hzOffsetComputed)) != 'NaN') and (string(number(profileOffsets/vtOffsetComputed)) != 'NaN')">
      <!-- We have a computed profile centre so draw and annotate it -->
      <xsl:comment> Computed profile centre point </xsl:comment>
      <xsl:call-template name="NewLine"/>

      <xsl:variable name="coordX">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="profileOffsets/hzOffsetComputed"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="profileOffsets/vtOffsetComputed"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <v:oval style="position:absolute;left:{$coordX - $circleSize div 2};top:{$coordY - $circleSize div 2};width:{$circleSize};height:{$circleSize}" fillcolor="red" strokeweight="0.5pt"/>
      <xsl:call-template name="NewLine"/>

      <xsl:if test="string(number(profileOffsets/polarDelta)) != 'NaN'">
        <!-- Now write out the polar delta value for the offset from the design centre rotated to match the delta direction -->
        <xsl:comment> Computed profile polar delta value </xsl:comment>
        <xsl:call-template name="NewLine"/>
        <xsl:variable name="text" select="format-number(profileOffsets/polarDelta * $DistConvFactor, $DecPl3, 'Standard')"/>
        <xsl:variable name="textWidth" select="string-length($text) div 0.02"/>
        <xsl:variable name="textHeight" select="100"/>
        <xsl:variable name="offsetVal" select="$gridSizeX * 0.008 div msxsl:node-set($plotParams)/scaleRatio"/>
        <xsl:variable name="halfTextWidth" select="$textWidth div 2.0 div msxsl:node-set($plotParams)/scaleRatio"/>

        <xsl:variable name="dirn">
          <xsl:call-template name="InverseAzimuth">
            <xsl:with-param name="deltaN" select="profileOffsets/vtOffsetComputed - profileOffsets/vtOffsetDesign"/>
            <xsl:with-param name="deltaE" select="profileOffsets/hzOffsetComputed - profileOffsets/hzOffsetDesign"/>
            <xsl:with-param name="returnInRadians">true</xsl:with-param>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="textRotn">
          <xsl:variable name="rotn" select="$dirn * 180.0 div math:PI() - 90.0"/>
          <xsl:choose>
            <xsl:when test="($rotn &gt; 90.0) and ($rotn &lt; 270.0)">
              <xsl:variable name="temp" select="$rotn - 180.0"/>
              <xsl:choose>
                <xsl:when test="$temp &lt; 0">
                  <xsl:value-of select="$temp + 360.0"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$temp"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$rotn"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:variable name="textInsPt">
          <xsl:call-template name="FollowDirection">
            <xsl:with-param name="direction" select="$dirn"/>
            <xsl:with-param name="distance" select="$offsetVal + $halfTextWidth"/>  <!-- Offset plus half text length -->
            <xsl:with-param name="startVt" select="profileOffsets/vtOffsetComputed"/>
            <xsl:with-param name="startHz" select="profileOffsets/hzOffsetComputed"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="coordTextX">
          <xsl:call-template name="XPlotCoord">
            <xsl:with-param name="xVal" select="msxsl:node-set($textInsPt)/horizOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="coordTextY">
          <xsl:call-template name="YPlotCoord">
            <xsl:with-param name="yVal" select="msxsl:node-set($textInsPt)/vertOffset"/>
            <xsl:with-param name="plotParams" select="$plotParams"/>
          </xsl:call-template>
        </xsl:variable>

        <v:shape type="#_tunnel_annotation" style="position:absolute;left:{$coordTextX - $textWidth div 2};top:{$coordTextY - $textHeight div 2};width:{$textWidth};height:{$textHeight};rotation:{$textRotn}" fillcolor="black" stroked="f" strokeweight="0">
        <xsl:call-template name="NewLine"/>
          <v:fill opacity="1" o:opacity2="1" recolor="f" rotate="f"/>
          <xsl:call-template name="NewLine"/>
          <v:textpath on="t" style='font-family:"Arial";font-size:8pt' fitshape="f" string="{$text}"/>
          <xsl:call-template name="NewLine"/>
        </v:shape>
        <xsl:call-template name="NewLine"/>
      </xsl:if>
    </xsl:if>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Draw an arc based on the specified definition ******** -->
<!-- **************************************************************** -->
<xsl:template name="DrawArc">
  <xsl:param name="arcElement"/>
  <xsl:param name="plotParams"/>
  <xsl:param name="activeSurface"/>

  <xsl:variable name="colour">
    <xsl:choose>
      <xsl:when test="$activeSurface = 'true'">blue</xsl:when>
      <xsl:otherwise>gray</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="lineWidth">
    <xsl:choose>
      <xsl:when test="$activeSurface = 'true'">2.0</xsl:when>
      <xsl:otherwise>1.0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Encountered a case where the radius for template elements was of the order of 1000000m -->
  <!-- and the arc commands didn't seem to be able to handle the very large resulting values  -->
  <!-- very well at all.  As a way of resolving this check the arc to chord separation and    -->
  <!-- if it is less than 1/200th of the chord length then draw a straight line instead.      -->
  <xsl:variable name="chordLen">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="msxsl:node-set($arcElement)/startVt - msxsl:node-set($arcElement)/endVt"/>
      <xsl:with-param name="deltaE" select="msxsl:node-set($arcElement)/startHz - msxsl:node-set($arcElement)/endHz"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="minArcToChordSep" select="$chordLen div 200.0"/>
  <xsl:variable name="arcToChordSep" select="msxsl:node-set($arcElement)/radius - msxsl:node-set($arcElement)/radius * math:cos(number(msxsl:node-set($arcElement)/deltaAngle div 2.0))"/>

  <xsl:choose>
    <xsl:when test="$arcToChordSep &lt; $minArcToChordSep">  <!-- Draw the chord line -->
      <xsl:variable name="coordX1">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="msxsl:node-set($arcElement)/startHz"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY1">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="msxsl:node-set($arcElement)/startVt"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordX2">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="msxsl:node-set($arcElement)/endHz"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="coordY2">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="msxsl:node-set($arcElement)/endVt"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <v:line style="position:absolute" from="{$coordX1},{$coordY1}" to="{$coordX2},{$coordY2}" strokecolor="{$colour}" strokeweight="{$lineWidth}pt"/>
    </xsl:when>

    <xsl:otherwise>
      <xsl:variable name="centreCoordX">
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="msxsl:node-set($arcElement)/centreHz"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="centreCoordY">
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="msxsl:node-set($arcElement)/centreVt"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="insertCoordX">   <!-- Left -->
        <xsl:call-template name="XPlotCoord">
          <xsl:with-param name="xVal" select="msxsl:node-set($arcElement)/centreHz - msxsl:node-set($arcElement)/radius"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="insertCoordY">   <!-- Top -->
        <xsl:call-template name="YPlotCoord">
          <xsl:with-param name="yVal" select="msxsl:node-set($arcElement)/centreVt + msxsl:node-set($arcElement)/radius"/>
          <xsl:with-param name="plotParams" select="$plotParams"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="widthHeight" select="($centreCoordX - $insertCoordX) * 2.0"/>

      <xsl:variable name="startAngle">
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="msxsl:node-set($arcElement)/startVt - msxsl:node-set($arcElement)/centreVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($arcElement)/startHz - msxsl:node-set($arcElement)/centreHz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="endAngle" select="$startAngle + msxsl:node-set($arcElement)/deltaAngle * math:PI() div 180.0"/>

      <v:arc style="position:absolute;top:{$insertCoordY};left:{$insertCoordX};width:{$widthHeight};height:{$widthHeight}" startangle="{$startAngle * 180.0 div math:PI()}" endangle="{$endAngle * 180.0 div math:PI()}" strokecolor="{$colour}" strokeweight="{$lineWidth}pt" filled="f"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:call-template name="NewLine"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Returns node set containing the profile areas ******** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeProfileAreas">
  <xsl:param name="tunnelProfiles"/>
  <xsl:param name="templateSurfToUseForAreas"/>

  <xsl:variable name="profileAreas">
    <xsl:copy-of select="msxsl:node-set($tunnelProfiles)/profile[1]/tunnelName"/>
    <!-- This node set variable only contains the profiles within the range specified -->
    <xsl:for-each select="msxsl:node-set($tunnelProfiles)/profile">
      <xsl:variable name="templateSurface">
        <xsl:choose>
          <xsl:when test="string($templateSurfToUseForAreas) != ''">
            <xsl:value-of select="$templateSurfToUseForAreas"/>
          </xsl:when>
          <xsl:otherwise>DefaultXSLSurface</xsl:otherwise>  <!-- No surface defined so from pre multiple surface support - set to internal default surface -->
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="stn">
        <xsl:choose>
          <xsl:when test="EquatedStation">
            <xsl:call-template name="FormatStationVal">
              <xsl:with-param name="stationVal" select="EquatedStation/Station"/>
              <xsl:with-param name="zoneVal" select="EquatedStation/Zone"/>
              <xsl:with-param name="definedFmt" select="$stnFormatStyle"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="FormatStationVal">
              <xsl:with-param name="stationVal" select="Station"/>
              <xsl:with-param name="definedFmt" select="$stnFormatStyle"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="$distUnitAbbrev"/>   <!-- Add the distance unit abbreviation -->
      </xsl:variable>

      <xsl:variable name="templateArea">   <!-- Compute the area of the design template -->
        <xsl:call-template name="ComputeTemplateArea">
          <xsl:with-param name="design" select="design"/>
          <xsl:with-param name="templateSurface" select="$templateSurface"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="profilePointsArray">
        <xsl:call-template name="BuildProfilePointsArray">
          <xsl:with-param name="profile" select="."/>
          <xsl:with-param name="templateSurface" select="$templateSurface"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="segmentedPointsArray">
        <xsl:variable name="tempArray">
          <xsl:for-each select="msxsl:node-set($profilePointsArray)/point">
            <xsl:element name="point">
              <xsl:attribute name="segment">
                <xsl:choose>
                  <xsl:when test="position() = 1">1</xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="count(preceding-sibling::point[delta = 0])"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
              <xsl:copy-of select="*"/>
            </xsl:element>
          </xsl:for-each>
        </xsl:variable>

        <xsl:for-each select="msxsl:node-set($tempArray)/point">
          <xsl:variable name="currSegment" select="@segment"/>
          <xsl:if test="(position() = 1) or ($currSegment != preceding-sibling::point[1]/@segment)">
            <xsl:element name="segment">
              <xsl:if test="position() &gt; 1">
                <xsl:copy-of select="preceding-sibling::point[1]"/>
              </xsl:if>
              <xsl:copy-of select="."/>
              <xsl:for-each select="following-sibling::point[@segment = $currSegment]">
                <xsl:copy-of select="."/>
              </xsl:for-each>
            </xsl:element>
          </xsl:if>
        </xsl:for-each>
      </xsl:variable>

      <xsl:variable name="design" select="design"/>  <!-- Retain a copy of the design details in a local variable for use in following loop -->

      <xsl:element name="profile">   <!-- Create a profile element for each station to hold the area values -->
        <xsl:attribute name="station">
          <xsl:value-of select="Station"/>
        </xsl:attribute>
        <xsl:attribute name="displayStn">
          <xsl:value-of select="$stn"/>
        </xsl:attribute>
        <xsl:attribute name="templateSurface">
          <xsl:value-of select="$templateSurface"/>
        </xsl:attribute>

        <xsl:element name="templateArea">
          <xsl:value-of select="$templateArea"/>
        </xsl:element>

        <xsl:element name="computedAreas">
          <xsl:for-each select="msxsl:node-set($segmentedPointsArray)/segment">
            <xsl:element name="area">
              <xsl:attribute name="type">
                <xsl:for-each select="point[2]">
                  <xsl:choose>
                    <xsl:when test="delta &lt; 0.0">Undercut</xsl:when>
                    <xsl:otherwise>Overcut</xsl:otherwise>
                  </xsl:choose>
                </xsl:for-each>
              </xsl:attribute>

              <!-- Now add the required template elements to the segment measured point elements -->
              <!-- to complete the figure ready for area computation.                            -->
              <xsl:variable name="closedFigure">
                <xsl:call-template name="AddTemplateElementsToFigure">
                  <xsl:with-param name="pointsArray" select="."/>
                  <xsl:with-param name="design" select="$design"/>
                  <xsl:with-param name="templateSurface" select="$templateSurface"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:call-template name="ComputeFigureArea">
                <xsl:with-param name="pointsArray" select="$closedFigure"/>
              </xsl:call-template>
            </xsl:element>
          </xsl:for-each>
        </xsl:element>
      </xsl:element>
    </xsl:for-each>
  </xsl:variable>

  <xsl:element name="tunnelName">
    <xsl:value-of select="msxsl:node-set($profileAreas)/tunnelName"/>
  </xsl:element>
  <xsl:for-each select="msxsl:node-set($profileAreas)/profile">
    <xsl:element name="profile">
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="templateArea"/>

      <xsl:variable name="undercutArea" select="sum(computedAreas/area[@type = 'Undercut'])"/>
      <xsl:element name="undercutArea">
        <xsl:value-of select="$undercutArea"/>
      </xsl:element>

      <xsl:variable name="overcutArea" select="sum(computedAreas/area[@type = 'Overcut'])"/>
      <xsl:element name="overcutArea">
        <xsl:value-of select="$overcutArea"/>
      </xsl:element>

      <xsl:element name="measuredArea">
        <xsl:value-of select="templateArea + $overcutArea - $undercutArea"/>
      </xsl:element>
    </xsl:element>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Returns node set containing the tunnel profiles ******* -->
<!-- **************************************************************** -->
<xsl:template name="BuildTunnelProfilesForAreaCalcs">
  <xsl:param name="startStn"/>
  <xsl:param name="endStn"/>

  <xsl:for-each select="JOBFile/FieldBook/TunnelCrossSectionRecord">
    <xsl:sort order="ascending" data-type="number" select="Station"/>
    <xsl:variable name="stn" select="Station"/>
    <xsl:variable name="templateSurface">
      <xsl:choose>
        <xsl:when test="string(TemplateSurface) != ''">
          <xsl:value-of select="TemplateSurface"/>
        </xsl:when>
        <xsl:otherwise>DefaultXSLSurface</xsl:otherwise>  <!-- No surface defined so from pre multiple surface support - set to internal default surface -->
      </xsl:choose>
    </xsl:variable>

    <xsl:if test="(Station &gt;= number($startStn)) and (Station &lt;= number($endStn))">
      <xsl:variable name="stnTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/StationTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/StationTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanStationTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="overbreakTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/OverbreakTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/OverbreakTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanOverbreakTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="underbreakTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/UnderbreakTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/UnderbreakTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanUnderbreakTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="profileDeltas">
        <!-- Ensure we have the first TunnelCrossSectionRecord for a given station and template surface (either   -->
        <!-- the template surface specified in the TunnelCrossSectionRecord or, if there is no template surface   -->
        <!-- specified (an older format file) then the template surface will use the internal 'DefaultXSLSurface' -->
        <!-- name.                                                                                                -->
        <xsl:if test="count(preceding-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                        ((TemplateSurface = $templateSurface) or
                                                                         ((string(TemplateSurface) = '') and
                                                                          ($templateSurface = 'DefaultXSLSurface')))]) = 0">
          <!-- Add the points from the first profile scan at this station if:  -->
          <!-- 1. Outputting all scanned points at this station or             -->
          <!-- 2. Only outputting last scanned points and this is the one and  -->
          <!--    only scan at this station                                    -->
          <xsl:if test="($profilePointsToUse = 'All measured points on profile') or
                        (($profilePointsToUse = 'Last measured points on profile') and
                         (count(following-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                            ((TemplateSurface = $templateSurface) or
                                                                             ((string(TemplateSurface) = '') and
                                                                              ($templateSurface = 'DefaultXSLSurface')))]) = 0))">
            <xsl:for-each select="TunnelPointDeltaRecord">
              <!-- Only add deltas for non-deleted points -->
              <xsl:variable name="obsID" select="ObservationID"/>
              <xsl:if test="/JOBFile/FieldBook/PointRecord[(@ID = $obsID) and (Deleted = 'false')]">
                <xsl:element name="TunnelPointDeltaRecord">
                  <xsl:copy-of select="./*"/>
                  <xsl:element name="obsPtName">
                    <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Name"/>
                  </xsl:element>
                </xsl:element>
              </xsl:if>
            </xsl:for-each>
          </xsl:if>

          <xsl:for-each select="following-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                            ((TemplateSurface = $templateSurface) or
                                                                             ((string(TemplateSurface) = '') and
                                                                              ($templateSurface = 'DefaultXSLSurface')))]">
            <!-- Use the same test for each subsequent TunnelCrossSectionRecord -->
            <!-- encountered with the same station value.                       -->
            <xsl:if test="($profilePointsToUse = 'All measured points on profile') or
                          (($profilePointsToUse = 'Last measured points on profile') and
                           (count(following-sibling::TunnelCrossSectionRecord[Station = $stn]) = 0))">
              <xsl:for-each select="TunnelPointDeltaRecord">
                <!-- Only add deltas for non-deleted points -->
                <xsl:variable name="obsID" select="ObservationID"/>
                <xsl:if test="/JOBFile/FieldBook/PointRecord[(@ID = $obsID) and (Deleted = 'false')]">
                  <xsl:element name="TunnelPointDeltaRecord">
                    <xsl:copy-of select="./*"/>
                    <xsl:element name="obsPtName">
                      <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Name"/>
                    </xsl:element>
                  </xsl:element>
                </xsl:if>
              </xsl:for-each>
            </xsl:if>
          </xsl:for-each>
        </xsl:if>
      </xsl:variable>

      <xsl:if test="count(msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord) != 0"> <!-- There are some deltas to output -->
        <xsl:element name="profile">
          <xsl:element name="tunnelName">
            <xsl:value-of select="TunnelName"/>
          </xsl:element>
          <xsl:copy-of select="Station"/>
          <xsl:copy-of select="EquatedStation"/>
          <xsl:copy-of select="TemplateSurface"/>
          <xsl:element name="stationTolerance">
            <xsl:value-of select="$stnTolerance"/>
          </xsl:element>
          <xsl:element name="overbreakTolerance">
            <xsl:value-of select="$overbreakTolerance"/>
          </xsl:element>
          <xsl:element name="underbreakTolerance">
            <xsl:value-of select="$underbreakTolerance"/>
          </xsl:element>

          <!-- Now include the design definition at this station -->
          <!-- Put into a node-set variable so that it can be used in the sorting of the measured points -->
          <xsl:variable name="tempDesignTemplate">
            <!-- Get the rotation values that apply at this station -->
            <xsl:variable name="templateRotationVals">
              <xsl:call-template name="GetTemplateRotationValues">
                <xsl:with-param name="station" select="Station"/>
              </xsl:call-template>
            </xsl:variable>

            <!-- Get the alignment offset values that apply at this station -->
            <xsl:variable name="templateOffsetVals">
              <xsl:call-template name="GetTemplateOffsetValues">
                <xsl:with-param name="station" select="Station"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:variable name="templateWithoutOffsets">
              <xsl:choose>
                <xsl:when test="msxsl:node-set($templateRotationVals)/rotationAngle != 0">
                  <xsl:variable name="unrotatedTemplate">
                    <xsl:call-template name="ExtractDesignElementsForAreaCalcs">
                      <xsl:with-param name="station" select="Station"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:call-template name="ComputeRotatedTemplate">
                    <xsl:with-param name="unrotatedTemplate" select="$unrotatedTemplate"/>
                    <xsl:with-param name="templateRotationVals" select="$templateRotationVals"/>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:call-template name="ExtractDesignElementsForAreaCalcs">
                    <xsl:with-param name="station" select="Station"/>
                  </xsl:call-template>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

            <xsl:call-template name="ApplyAlignmentOffsets">
              <xsl:with-param name="template" select="$templateWithoutOffsets"/>
              <xsl:with-param name="templateOffsetVals" select="$templateOffsetVals"/>
            </xsl:call-template>
          </xsl:variable>

          <!-- Check the tempDesignTemplate elements to see if it starts and ends at the same point -->
          <!-- to form a closed figure - if not add a line element to close it.                     -->
          <xsl:variable name="closedDesignTemplate">
            <xsl:for-each select="msxsl:node-set($tempDesignTemplate)/templateSurface">
              <xsl:element name="templateSurface">
                <xsl:attribute name="name">
                  <xsl:value-of select="@name"/>
                </xsl:attribute>

                <xsl:copy-of select="*"/>  <!-- Copy the existing elements -->

                <xsl:if test="(element[1]/startHz != element[last()]/endHz) or
                              (element[1]/startVt != element[last()]/endVt)">
                  <xsl:element name="element">
                    <xsl:element name="startHz">
                      <xsl:value-of select="element[last()]/endHz"/>
                    </xsl:element>
                    <xsl:element name="startVt">
                      <xsl:value-of select="element[last()]/endVt"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="element[1]/startHz"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="element[1]/startVt"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:call-template name="InverseDistance">
                        <xsl:with-param name="deltaN" select="element[last()]/endVt - element[1]/startVt"/>
                        <xsl:with-param name="deltaE" select="element[last()]/endHz - element[1]/startHz"/>
                      </xsl:call-template>
                    </xsl:element>
                  </xsl:element>
                </xsl:if>
              </xsl:element>
            </xsl:for-each>
          </xsl:variable>

          <xsl:variable name="designTemplate">  <!-- Add perimeter length into each surface -->
            <xsl:for-each select="msxsl:node-set($closedDesignTemplate)/templateSurface">
              <xsl:element name="templateSurface">
                <xsl:attribute name="name">
                  <xsl:value-of select="@name"/>
                </xsl:attribute>

                <xsl:variable name="designPerimeterLength">
                  <xsl:variable name="lengths">
                    <xsl:for-each select="element">
                      <xsl:element name="length">
                        <xsl:value-of select="length"/>
                      </xsl:element>
                    </xsl:for-each>
                  </xsl:variable>

                  <xsl:value-of select="sum(msxsl:node-set($lengths)/length)"/>  <!-- Return sum of the element lengths -->
                </xsl:variable>

                <xsl:element name="designPerimeterLength">
                  <xsl:value-of select="$designPerimeterLength"/>
                </xsl:element>

                <xsl:copy-of select="*"/>
              </xsl:element>
            </xsl:for-each>
          </xsl:variable>


          <!-- Hold all the tunnel deltas in a variable so that the distance around the design  -->
          <!-- or the direction from the centroid position to each delta position can be        -->
          <!-- computed for use in sorting the positions.                                       -->
          <xsl:variable name="tunnelDeltas">
            <xsl:for-each select="msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord">
              <xsl:copy>
                <xsl:copy-of select="* | @*"/>
                <xsl:element name="name">
                  <xsl:for-each select="key('obsPointID-search', ObservationID)">
                    <xsl:value-of select="Name"/>
                  </xsl:for-each>
                </xsl:element>

                <xsl:variable name="distAroundAndCalcdDelta">
                  <xsl:call-template name="CalcDistAroundTemplate">
                    <xsl:with-param name="designTemplate" select="$designTemplate"/>
                    <xsl:with-param name="templateSurface" select="$templateSurface"/>
                    <xsl:with-param name="ptHz" select="HorizontalOffset"/>
                    <xsl:with-param name="ptVt" select="VerticalOffset"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:element name="distAround">
                  <xsl:value-of select="msxsl:node-set($distAroundAndCalcdDelta)/distAround"/>
                </xsl:element>

                <xsl:element name="calcdDelta">
                  <xsl:value-of select="msxsl:node-set($distAroundAndCalcdDelta)/calcdDelta"/>
                </xsl:element>
              </xsl:copy>
            </xsl:for-each>
          </xsl:variable>

          <!-- Add the tunnel deltas (sorted by distance around design or direction) -->
          <xsl:for-each select="msxsl:node-set($tunnelDeltas)/*">
            <xsl:sort data-type="number" order="ascending" select="distAround"/>
            <xsl:copy>
              <xsl:copy-of select="* | @*"/>
            </xsl:copy>
          </xsl:for-each>

          <!-- Now include the design definition at this station -->
          <xsl:element name="design">
            <xsl:copy-of select="$designTemplate"/>
          </xsl:element>

        </xsl:element>   <!-- profile element -->
      </xsl:if>
    </xsl:if>  <!-- In station range -->
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Extract design template elements *************** -->
<!-- **************************************************************** -->
<xsl:template name="ExtractDesignElementsForAreaCalcs">
  <xsl:param name="station"/>

  <xsl:variable name="templateNames">
    <xsl:call-template name="GetTemplateNames">
      <xsl:with-param name="station" select="$station"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:if test="msxsl:node-set($templateNames)/prevTemplateName != ''">
    <xsl:variable name="prevTemplate">
      <xsl:call-template name="GetTemplateElementsForAreaCalcs">
        <xsl:with-param name="templateName" select="msxsl:node-set($templateNames)/prevTemplateName"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="nextTemplate">
      <xsl:call-template name="GetTemplateElementsForAreaCalcs">
        <xsl:with-param name="templateName" select="msxsl:node-set($templateNames)/nextTemplateName"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="templatesAreEquivalent">
      <xsl:choose>
        <xsl:when test="msxsl:node-set($templateNames)/nextTemplateName = ''">true</xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="TemplatesAreEquivalent">
            <xsl:with-param name="prevTemplate" select="$prevTemplate"/>
            <xsl:with-param name="nextTemplate" select="$nextTemplate"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="(msxsl:node-set($templateNames)/prevTemplateName = msxsl:node-set($templateNames)/nextTemplateName) or
                      (msxsl:node-set($templateNames)/nextTemplateName = '') or ($templatesAreEquivalent = 'true')">
        <!-- Both templates are the same or there is no next template - return the prevTemplate -->
        <xsl:copy-of select="$prevTemplate"/>
      </xsl:when>

      <xsl:otherwise>
        <xsl:variable name="templateSurfacesToUse">
          <xsl:call-template name="GetCommonTemplateSurfaces">
            <xsl:with-param name="templateNames" select="$templateNames"/>
          </xsl:call-template>
        </xsl:variable>

        <!-- Work through the common template surfaces determining whether they can be interpolated -->
        <xsl:for-each select="msxsl:node-set($templateSurfacesToUse)/surface">
          <xsl:variable name="surfaceName" select="."/>

          <!-- Need to compute an interpolated template if both template surfaces have same number of elements -->
          <xsl:if test="count(msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]/element) = count(msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]/element)">
            <xsl:variable name="deltaStation" select="msxsl:node-set($templateNames)/nextTemplateStation - msxsl:node-set($templateNames)/prevTemplateStation"/>
            <xsl:variable name="ratio" select="($station - msxsl:node-set($templateNames)/prevTemplateStation) div $deltaStation"/>

            <xsl:element name="templateSurface">
              <xsl:attribute name="name">
                <xsl:value-of select="$surfaceName"/>
              </xsl:attribute>

              <!-- Use a special Norwegian interpolation method if the previous and next templates each contain -->
              <!-- 3 or 5 sequential tangential arc elements and the template elements are not inclined.        -->
              <xsl:variable name="useNorwegianInterpolation">
                <xsl:variable name="prevNorwegianStyleSection">
                  <xsl:call-template name="NorwegianStyleSection">
                    <xsl:with-param name="templateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="nextNorwegianStyleSection">
                  <xsl:call-template name="NorwegianStyleSection">
                    <xsl:with-param name="templateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="matchingArcIndices">
                  <xsl:variable name="prevArcIndices">
                    <xsl:call-template name="SequentialArcCount">
                      <xsl:with-param name="templateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:variable name="nextArcIndices">
                    <xsl:call-template name="SequentialArcCount">
                      <xsl:with-param name="templateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:if test="(msxsl:node-set($prevArcIndices)/firstArcIndex = msxsl:node-set($nextArcIndices)/firstArcIndex) and
                                (msxsl:node-set($prevArcIndices)/lastArcIndex = msxsl:node-set($nextArcIndices)/lastArcIndex)">true</xsl:if>
                </xsl:variable>

                <xsl:if test="($prevNorwegianStyleSection = 'true') and ($nextNorwegianStyleSection = 'true') and
                              ($matchingArcIndices = 'true')">
                  <xsl:value-of select="'true'"/>
                </xsl:if>
              </xsl:variable>

              <xsl:choose>
                <xsl:when test="$useNorwegianInterpolation = 'true'">
                  <xsl:variable name="norwegianInterpArcs">
                    <xsl:call-template name="NorwegianInterpolatedArcs">
                      <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                      <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                      <xsl:with-param name="ratio" select="$ratio"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:call-template name="AssembleCompleteNorwegianTemplate">
                    <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="norwegianInterpArcs" select="$norwegianInterpArcs"/>
                    <xsl:with-param name="ratio" select="$ratio"/>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>  <!-- Use standard interpolation -->
                  <xsl:call-template name="StandardInterpolatedElements">
                    <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="ratio" select="$ratio"/>
                  </xsl:call-template>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:element>   <!-- templateSurface -->
          </xsl:if>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Get the design template elements *************** -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateElementsForAreaCalcs">
  <xsl:param name="templateName"/>

  <!-- Build up a node set of the template element components -->
  <xsl:variable name="templateDeltas">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface) != 0">
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface">
          <xsl:element name="templateSurface">
            <xsl:attribute name="name">
              <xsl:value-of select="Name"/>
            </xsl:attribute>

            <xsl:call-template name="GetTemplateDeltasForAreaCalcs"/>
          </xsl:element>  <!-- templateSurface element -->
        </xsl:for-each>
      </xsl:when>

      <xsl:otherwise>  <!-- An old txl file with no surfaces defined in it -->
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]">
          <xsl:element name="templateSurface">
            <xsl:attribute name="name">
              <xsl:value-of select="'DefaultXSLSurface'"/>  <!-- Unique default name for surface -->
            </xsl:attribute>

            <xsl:call-template name="GetTemplateDeltasForAreaCalcs"/>
          </xsl:element>  <!-- templateSurface element -->
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>   <!-- templateDeltas -->

  <xsl:variable name="standardisedTemplateElements">
    <xsl:for-each select="msxsl:node-set($templateDeltas)/templateSurface">
      <xsl:variable name="surfaceName" select="@name"/>
      <xsl:element name="templateSurface">
        <xsl:attribute name="name">
          <xsl:value-of select="@name"/>
        </xsl:attribute>
        <xsl:variable name="deltas">   <!-- Get the deltas into an appropriate node-set form to pass to AddTemplateElements function -->
          <xsl:copy-of select="*"/>
        </xsl:variable>

        <xsl:variable name="startHz">
          <xsl:choose>
            <xsl:when test="$surfaceName = 'DefaultXSLSurface'">
              <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateStartPoint/HorizontalOffset"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface[Name = $surfaceName]/TemplateSurfaceStartPoint/HorizontalOffset"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:variable name="startVt">
          <xsl:choose>
            <xsl:when test="$surfaceName = 'DefaultXSLSurface'">
              <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateStartPoint/VerticalOffset"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface[Name = $surfaceName]/TemplateSurfaceStartPoint/VerticalOffset"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:call-template name="AddTemplateElements">
          <xsl:with-param name="templateDeltas" select="$deltas"/>
          <xsl:with-param name="startHz" select="$startHz"/>
          <xsl:with-param name="startVt" select="$startVt"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:for-each>
  </xsl:variable>

  <xsl:call-template name="StartFirstElementAtZeroHzOffset">
    <xsl:with-param name="inTemplateDeltas" select="$standardisedTemplateElements"/>
  </xsl:call-template>

</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Get the design template element deltas ************ -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateDeltasForAreaCalcs">

  <xsl:for-each select="*">
    <xsl:choose>
      <xsl:when test="name(.) = 'LineDistanceAndVerticalDistance'">
        <xsl:element name="delta">
          <xsl:element name="hz">
            <xsl:value-of select="HorizontalDistance"/>
          </xsl:element>
          <xsl:element name="vt">
            <xsl:value-of select="VerticalDistance"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'LineDistanceAndGrade'">
        <xsl:element name="delta">
          <xsl:element name="hz">
            <xsl:value-of select="HorizontalDistance"/>
          </xsl:element>
          <xsl:element name="vt">
            <xsl:value-of select="HorizontalDistance * (Grade div 100.0)"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'LineEndpoint'">
        <xsl:element name="delta">
          <xsl:element name="endHz">
            <xsl:value-of select="HorizontalEnd"/>
          </xsl:element>
          <xsl:element name="endVt">
            <xsl:value-of select="VerticalEnd"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcEndPointAndRadius'">
        <xsl:element name="delta">
          <xsl:element name="endHz">
            <xsl:value-of select="HorizontalEnd"/>
          </xsl:element>
          <xsl:element name="endVt">
            <xsl:value-of select="VerticalEnd"/>
          </xsl:element>
          <xsl:element name="radius">
            <xsl:value-of select="Radius"/>
          </xsl:element>
          <xsl:element name="largeArc">
            <xsl:value-of select="LargeArc"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcAlignmentAndAngle'">
        <xsl:element name="delta">
          <!-- Always centred on 0,0 -->
          <xsl:element name="centreHz">0.0</xsl:element>
          <xsl:element name="centreVt">0.0</xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="DeltaAngle"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcCenterAndAngle'">
        <xsl:element name="delta">
          <xsl:element name="centreHz">
            <xsl:value-of select="HorizontalCenter"/>
          </xsl:element>
          <xsl:element name="centreVt">
            <xsl:value-of select="VerticalCenter"/>
          </xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="DeltaAngle"/>
          </xsl:element>
        </xsl:element>
      </xsl:when>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Ensure the first template element starts at zero offset **** -->
<!-- **************************************************************** -->
<xsl:template name="StartFirstElementAtZeroHzOffset">
  <xsl:param name="inTemplateDeltas"/>

  <!-- First make sure that the templateDeltas start from the bottom of the profile -->
  <xsl:variable name="templateDeltas">
    <xsl:call-template name="StartTemplateFromBottom">
      <xsl:with-param name="templateDeltas" select="$inTemplateDeltas"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- If the start point for the template is not on the alignment generate a new start -->
  <!-- point on the alignment and appropriate new start and end elements.               -->
  <xsl:for-each select="msxsl:node-set($templateDeltas)/templateSurface">
    <xsl:element name="templateSurface">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>

      <xsl:choose>
        <xsl:when test="element[1]/startHz != 0.0">
          <xsl:variable name="closedFigure">
            <xsl:call-template name="SamePosition">
              <xsl:with-param name="hz1" select="element[1]/startHz"/>
              <xsl:with-param name="vt1" select="element[1]/startVt"/>
              <xsl:with-param name="hz2" select="element[last()]/endHz"/>
              <xsl:with-param name="vt2" select="element[last()]/endVt"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:choose>
            <xsl:when test="element[1]/startHz &lt; 0.0">
              <!-- Start point is on the left of alignment - if the last element ends at the first point we need to split the last element -->
              <xsl:choose>
                <xsl:when test="(($closedFigure = 'true') and not(element[last()]/radius)) or ($closedFigure = 'false')">
                  <!-- A closed figure with line as last element or not a closed figure - linear interpolation for start point -->
                  <xsl:variable name="vtAtZero">
                    <xsl:call-template name="InterpolatedVtValue">
                      <xsl:with-param name="hz1" select="element[1]/startHz"/>
                      <xsl:with-param name="vt1" select="element[1]/startVt"/>
                      <xsl:with-param name="hz2" select="element[last()]/endHz"/>
                      <xsl:with-param name="vt2" select="element[last()]/endVt"/>
                      <xsl:with-param name="targetHz">0</xsl:with-param>
                    </xsl:call-template>
                  </xsl:variable>

                  <!-- Add the new first element -->
                  <xsl:element name="element">
                    <xsl:element name="startHz">0</xsl:element>   <!-- By definition -->
                    <xsl:element name="startVt">
                      <xsl:value-of select="$vtAtZero"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="element[1]/startHz"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="element[1]/startVt"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:call-template name="InverseDistance">
                        <xsl:with-param name="deltaN" select="$vtAtZero - element[1]/startVt"/>
                        <xsl:with-param name="deltaE" select="element[1]/startHz"/>
                      </xsl:call-template>
                    </xsl:element>
                  </xsl:element>

                  <xsl:variable name="inc">
                    <xsl:choose>
                      <xsl:when test="$closedFigure = 'true'">0</xsl:when>
                      <xsl:otherwise>1</xsl:otherwise>
                    </xsl:choose>
                  </xsl:variable>

                  <!-- Add the remaining template elements - don't include any -->
                  <!-- closing element since it will be closed later anyway.   -->
                  <xsl:for-each select="element[position() &lt; last() + $inc]">
                    <xsl:copy-of select="."/>
                  </xsl:for-each>
                </xsl:when>

                <xsl:otherwise>  <!-- Must be a closed figure ending on an arc -->
                  <xsl:variable name="arcZeroOffsetPoint">
                    <xsl:call-template name="ArcZeroHzOffsetPoint">
                      <xsl:with-param name="arcDefn" select="element[last()]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:variable name="firstArcAngle">  <!-- Radians angle -->
                    <xsl:call-template name="ScribedAngle">
                      <xsl:with-param name="startHz" select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                      <xsl:with-param name="startVt" select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                      <xsl:with-param name="endHz" select="element[last()]/endHz"/>
                      <xsl:with-param name="endVt" select="element[last()]/endVt"/>
                      <xsl:with-param name="centreHz" select="element[last()]/centreHz"/>
                      <xsl:with-param name="centreVt" select="element[last()]/centreVt"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <!-- Add the new first element -->
                  <xsl:element name="element">
                    <xsl:element name="startHz">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                    </xsl:element>
                    <xsl:element name="startVt">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="element[last()]/endHz"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="element[last()]/endVt"/>
                    </xsl:element>
                    <xsl:element name="radius">
                      <xsl:value-of select="element[last()]/radius"/>
                    </xsl:element>
                    <xsl:element name="centreHz">
                      <xsl:value-of select="element[last()]/centreHz"/>
                    </xsl:element>
                    <xsl:element name="centreVt">
                      <xsl:value-of select="element[last()]/centreVt"/>
                    </xsl:element>
                    <xsl:element name="deltaAngle">
                      <xsl:value-of select="$firstArcAngle * 180.0 div math:PI()"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:value-of select="math:abs(number($firstArcAngle * element[last()]/radius))"/>
                    </xsl:element>
                  </xsl:element>

                  <!-- Add all the template elements except the last arc -->
                  <xsl:for-each select="element[position() &lt; last()]">
                    <xsl:copy-of select="."/>
                  </xsl:for-each>

                  <!-- Build a new last arc that runs to the zero horizontal offset point -->
                  <xsl:variable name="lastArcAngle">  <!-- Radians angle -->
                    <xsl:call-template name="ScribedAngle">
                      <xsl:with-param name="startHz" select="element[last()]/startHz"/>
                      <xsl:with-param name="startVt" select="element[last()]/startVt"/>
                      <xsl:with-param name="endHz" select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                      <xsl:with-param name="endVt" select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                      <xsl:with-param name="centreHz" select="element[last()]/centreHz"/>
                      <xsl:with-param name="centreVt" select="element[last()]/centreVt"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:element name="element">
                    <xsl:element name="startHz">
                      <xsl:value-of select="element[last()]/startHz"/>
                    </xsl:element>
                    <xsl:element name="startVt">
                      <xsl:value-of select="element[last()]/startVt"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                    </xsl:element>
                    <xsl:element name="radius">
                      <xsl:value-of select="element[last()]/radius"/>
                    </xsl:element>
                    <xsl:element name="centreHz">
                      <xsl:value-of select="element[last()]/centreHz"/>
                    </xsl:element>
                    <xsl:element name="centreVt">
                      <xsl:value-of select="element[last()]/centreVt"/>
                    </xsl:element>
                    <xsl:element name="deltaAngle">
                      <xsl:value-of select="$lastArcAngle * 180.0 div math:PI()"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:value-of select="math:abs(number($lastArcAngle * element[last()]/radius))"/>
                    </xsl:element>
                  </xsl:element>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:when>

            <xsl:otherwise>
              <!-- Start point is on the right of alignment -->
              <xsl:choose>
                <xsl:when test="(($closedFigure = 'true') and not(element[1]/radius)) or ($closedFigure = 'false')">
                  <!-- A closed figure with line as first element or not a closed figure - linear interpolation for start point -->
                  <xsl:variable name="vtAtZero">
                    <xsl:call-template name="InterpolatedVtValue">
                      <xsl:with-param name="hz1" select="element[1]/startHz"/>
                      <xsl:with-param name="vt1" select="element[1]/startVt"/>
                      <xsl:with-param name="hz2" select="element[1]/endHz"/>
                      <xsl:with-param name="vt2" select="element[1]/endVt"/>
                      <xsl:with-param name="targetHz">0</xsl:with-param>
                    </xsl:call-template>
                  </xsl:variable>

                  <!-- Add the new first element -->
                  <xsl:element name="element">
                    <xsl:element name="startHz">0</xsl:element>   <!-- By definition -->
                    <xsl:element name="startVt">
                      <xsl:value-of select="$vtAtZero"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="element[1]/endHz"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="element[1]/endVt"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:call-template name="InverseDistance">
                        <xsl:with-param name="deltaN" select="$vtAtZero - element[1]/endVt"/>
                        <xsl:with-param name="deltaE" select="element[1]/endHz"/>
                      </xsl:call-template>
                    </xsl:element>
                  </xsl:element>

                  <!-- Add all the template elements except the original first one - this -->
                  <!-- will miss a closing element but it will be closed later anyway.    -->
                  <xsl:for-each select="element[position() &gt; 1]">
                    <xsl:copy-of select="."/>
                  </xsl:for-each>
                </xsl:when>

                <xsl:otherwise>  <!-- Must be a closed figure starting with an arc -->
                  <xsl:variable name="arcZeroOffsetPoint">
                    <xsl:call-template name="ArcZeroHzOffsetPoint">
                      <xsl:with-param name="arcDefn" select="element[1]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:variable name="firstArcAngle">  <!-- Radians angle -->
                    <xsl:call-template name="ScribedAngle">
                      <xsl:with-param name="startHz" select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                      <xsl:with-param name="startVt" select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                      <xsl:with-param name="endHz" select="element[1]/endHz"/>
                      <xsl:with-param name="endVt" select="element[1]/endVt"/>
                      <xsl:with-param name="centreHz" select="element[1]/centreHz"/>
                      <xsl:with-param name="centreVt" select="element[1]/centreVt"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <!-- Add the new first element -->
                  <xsl:element name="element">
                    <xsl:element name="startHz">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                    </xsl:element>
                    <xsl:element name="startVt">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="element[1]/endHz"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="element[1]/endVt"/>
                    </xsl:element>
                    <xsl:element name="radius">
                      <xsl:value-of select="element[1]/radius"/>
                    </xsl:element>
                    <xsl:element name="centreHz">
                      <xsl:value-of select="element[1]/centreHz"/>
                    </xsl:element>
                    <xsl:element name="centreVt">
                      <xsl:value-of select="element[1]/centreVt"/>
                    </xsl:element>
                    <xsl:element name="deltaAngle">
                      <xsl:value-of select="$firstArcAngle * 180.0 div math:PI()"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:value-of select="math:abs(number($firstArcAngle * element[1]/radius))"/>
                    </xsl:element>
                  </xsl:element>

                  <!-- Add all the template elements except the first arc -->
                  <xsl:for-each select="element[position() &gt; 1]">
                    <xsl:copy-of select="."/>
                  </xsl:for-each>

                  <!-- Build a new last arc that runs to the zero horizontal offset point -->
                  <xsl:variable name="lastArcAngle">  <!-- Radians angle -->
                    <xsl:call-template name="ScribedAngle">
                      <xsl:with-param name="startHz" select="element[1]/startHz"/>
                      <xsl:with-param name="startVt" select="element[1]/startVt"/>
                      <xsl:with-param name="endHz" select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                      <xsl:with-param name="endVt" select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                      <xsl:with-param name="centreHz" select="element[1]/centreHz"/>
                      <xsl:with-param name="centreVt" select="element[1]/centreVt"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:element name="element">
                    <xsl:element name="startHz">
                      <xsl:value-of select="element[1]/startHz"/>
                    </xsl:element>
                    <xsl:element name="startVt">
                      <xsl:value-of select="element[1]/startVt"/>
                    </xsl:element>
                    <xsl:element name="endHz">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/hzOffset"/>
                    </xsl:element>
                    <xsl:element name="endVt">
                      <xsl:value-of select="msxsl:node-set($arcZeroOffsetPoint)/vtOffset"/>
                    </xsl:element>
                    <xsl:element name="radius">
                      <xsl:value-of select="element[1]/radius"/>
                    </xsl:element>
                    <xsl:element name="centreHz">
                      <xsl:value-of select="element[1]/centreHz"/>
                    </xsl:element>
                    <xsl:element name="centreVt">
                      <xsl:value-of select="element[1]/centreVt"/>
                    </xsl:element>
                    <xsl:element name="deltaAngle">
                      <xsl:value-of select="$lastArcAngle * 180.0 div math:PI()"/>
                    </xsl:element>
                    <xsl:element name="length">
                      <xsl:value-of select="math:abs(number($lastArcAngle * element[1]/radius))"/>
                    </xsl:element>
                  </xsl:element>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>

        <xsl:otherwise>   <!-- Template definition started at zero offset anyway so simply return it -->
          <xsl:copy-of select="*"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:element>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Ensure the template definition starts from the bottom ***** -->
<!-- **************************************************************** -->
<xsl:template name="StartTemplateFromBottom">
  <xsl:param name="templateDeltas"/>

  <xsl:for-each select="msxsl:node-set($templateDeltas)/templateSurface">
    <xsl:element name="templateSurface">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
      <!-- Find the lowest vertical offset value -->
      <xsl:variable name="minStartVt">
        <xsl:for-each select="element">
          <xsl:sort data-type="number" order="ascending" select="startVt"/>
          <xsl:if test="position() = 1">
            <xsl:value-of select="startVt"/>
          </xsl:if>
        </xsl:for-each>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="element[1]/startVt &gt; $minStartVt">
          <!-- Find the first element with its startVt equal to the $minStartVt - this is the element we want to start the template with -->
          <xsl:variable name="minStartVtElement">
            <xsl:for-each select="element">
              <xsl:if test="(startVt = $minStartVt) and (count(preceding-sibling::*[startVt = $minStartVt]) = 0)">
                <xsl:value-of select="position()"/>
              </xsl:if>
            </xsl:for-each>
          </xsl:variable>

          <!-- We need to keep the same order of elements but effectively 'rotate' them -->
          <!-- around so that we start with an element at the bottom of the template.   -->
          <!-- Copy all the elements starting with the 'low' element through to the last element -->
          <xsl:for-each select="element[position() &gt;= $minStartVtElement]">
            <xsl:copy-of select="."/>
          </xsl:for-each>

          <!-- Now copy all the elements prior to the 'low' element -->
          <xsl:for-each select="element[position() &lt; $minStartVtElement]">
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="*"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:element>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************** Compute arc point at zero hz offset ************* -->
<!-- **************************************************************** -->
<xsl:template name="ArcZeroHzOffsetPoint">
  <xsl:param name="arcDefn"/>

  <!-- Compute the vertical delta from the arc centre point to the zero offset point -->
  <xsl:variable name="vtDelta" select="math:sqrt(number(msxsl:node-set($arcDefn)/radius * msxsl:node-set($arcDefn)/radius - msxsl:node-set($arcDefn)/centreHz * msxsl:node-set($arcDefn)/centreHz))"/>
  <!-- Assume that the arc is at the bottom of the profile - unlikely to be defined any other way -->
  <xsl:element name="hzOffset">0</xsl:element>
  <xsl:element name="vtOffset">
    <xsl:value-of select="msxsl:node-set($arcDefn)/centreVt - $vtDelta"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Test if 2 positions are the same within small tolerance **** -->
<!-- **************************************************************** -->
<xsl:template name="SamePosition">
  <xsl:param name="hz1"/>
  <xsl:param name="vt1"/>
  <xsl:param name="hz2"/>
  <xsl:param name="vt2"/>

  <xsl:variable name="hzDelta" select="math:abs(number($hz1 - $hz2))"/>
  <xsl:variable name="vtDelta" select="math:abs(number($vt1 - $vt2))"/>

  <xsl:choose>
    <xsl:when test="($hzDelta &lt; 0.001) and ($vtDelta &lt; 0.001)">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Return interpolated vert value for given horiz valkue **** -->
<!-- **************************************************************** -->
<xsl:template name="InterpolatedVtValue">
  <xsl:param name="hz1"/>
  <xsl:param name="vt1"/>
  <xsl:param name="hz2"/>
  <xsl:param name="vt2"/>
  <xsl:param name="targetHz"/>

  <xsl:variable name="deltaHz" select="$hz1 - $hz2"/>

  <xsl:variable name="ratio" select="($targetHz - $hz1) div $deltaHz"/>

  <xsl:value-of select="$vt1 + ($vt1 - $vt2) div $ratio"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Build array of the profile pts to be used for area calcs *** -->
<!-- **************************************************************** -->
<xsl:template name="BuildProfilePointsArray">
  <xsl:param name="profile"/>
  <xsl:param name="templateSurface"/>

  <xsl:choose>
    <xsl:when test="$closedScans = 'Yes'">
      <xsl:call-template name="BuildClosedScanProfilePointsArray">
        <xsl:with-param name="profile" select="$profile"/>
        <xsl:with-param name="templateSurface" select="$templateSurface"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:call-template name="BuildUnclosedScanProfilePointsArray">
        <xsl:with-param name="profile" select="$profile"/>
        <xsl:with-param name="templateSurface" select="$templateSurface"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Build array of profile pts (closed) for use in area calcs ** -->
<!-- **************************************************************** -->
<xsl:template name="BuildClosedScanProfilePointsArray">
  <xsl:param name="profile"/>
  <xsl:param name="templateSurface"/>

  <!-- Start at 0,0 position -->
  <xsl:element name="point">
    <xsl:element name="dist">0</xsl:element>
    <xsl:element name="delta">0</xsl:element>
    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[1]/startHz"/>
    </xsl:element>
    <xsl:element name="VerticalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[1]/startVt"/>
    </xsl:element>
  </xsl:element>

  <!-- Compute the interpolated y value at the zero offset position -->
  <xsl:variable name="designPerimeterLength" select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/designPerimeterLength"/>
  <xsl:variable name="proportionLen" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/distAround + ($designPerimeterLength - msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/distAround)"/>
  <xsl:variable name="ratio" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/distAround div $proportionLen"/>
  <xsl:variable name="vtValAtZeroOffset">
    <xsl:value-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/VerticalOffset + (msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/VerticalOffset - msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/VerticalOffset) * $ratio"/>
  </xsl:variable>
  <xsl:variable name="deltaAtZeroOffset">
    <xsl:value-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/Delta + (msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/Delta - msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/Delta) * $ratio"/>
  </xsl:variable>

  <!-- Add element for interpolated zero offset y value -->
  <xsl:element name="point">
    <xsl:element name="dist">0</xsl:element>
    <xsl:element name="delta">
      <xsl:value-of select="$deltaAtZeroOffset"/>
    </xsl:element>
    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[1]/startHz"/>
    </xsl:element>
    <xsl:element name="VerticalOffset">
      <xsl:value-of select="$vtValAtZeroOffset"/>
    </xsl:element>
  </xsl:element>

  <xsl:for-each select="msxsl:node-set($profile)/TunnelPointDeltaRecord">
    <xsl:choose>
      <xsl:when test="position() = 1">
        <!-- If first delta record check to see if the delta value has same sign as $vtValAtZeroOffset -->
        <xsl:variable name="hasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2" select="$deltaAtZeroOffset"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$hasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="0"/>
            <xsl:with-param name="profPt1Vt" select="$vtValAtZeroOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>

        <!-- Write out the actual point -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="position() = last()">
        <!-- First check for a 'cross over' between the previous point and this last point -->
        <xsl:variable name="prevHasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$prevHasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="preceding-sibling::TunnelPointDeltaRecord[1]/HorizontalOffset"/>
            <xsl:with-param name="profPt1Vt" select="preceding-sibling::TunnelPointDeltaRecord[1]/VerticalOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>

        <!-- Now write out the actual point -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>

        <!-- Now check to see if the delta value has same sign as $vtValAtZeroOffset -->
        <xsl:variable name="hasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2" select="$deltaAtZeroOffset"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$hasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="0"/>
            <xsl:with-param name="profPt1Vt" select="$vtValAtZeroOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>
      </xsl:when>

      <xsl:otherwise>
        <!-- Need to check whether the deltas 'cross over' before this point -->
        <!-- Check for a 'cross over' between the previous point and the current point -->
        <xsl:variable name="prevHasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$prevHasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="preceding-sibling::TunnelPointDeltaRecord[1]/HorizontalOffset"/>
            <xsl:with-param name="profPt1Vt" select="preceding-sibling::TunnelPointDeltaRecord[1]/VerticalOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>

        <!-- Now write out the current point details -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>

  <!-- Add element for interpolated total length offset (also zero offset) y value -->
  <xsl:element name="point">
    <xsl:element name="dist">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/designPerimeterLength"/>
    </xsl:element>
    <xsl:element name="delta">
      <xsl:value-of select="$deltaAtZeroOffset"/>
    </xsl:element>
    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[last()]/endHz"/>
    </xsl:element>
    <xsl:element name="VerticalOffset">
      <xsl:value-of select="$vtValAtZeroOffset"/>
    </xsl:element>
  </xsl:element>

  <!-- Force the inclusion of the closure to the end point at 0 y position -->
  <xsl:element name="point">
    <xsl:element name="dist">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/designPerimeterLength"/>
    </xsl:element>
    <xsl:element name="delta">0</xsl:element>
    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[last()]/endHz"/>
    </xsl:element>
    <xsl:element name="VerticalOffset">
      <xsl:value-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[last()]/endVt"/>
    </xsl:element>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ** Build array of profile pts (unclosed) for use in area calcs * -->
<!-- **************************************************************** -->
<xsl:template name="BuildUnclosedScanProfilePointsArray">
  <xsl:param name="profile"/>
  <xsl:param name="templateSurface"/>

  <xsl:variable name="startPtOnTemplate">
    <xsl:call-template name="ComputeProjectedPoint">
      <xsl:with-param name="profile" select="$profile"/>
      <xsl:with-param name="templateSurface" select="$templateSurface"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- Set up the point element for the point projected onto the template -->
  <xsl:element name="point">
    <xsl:element name="dist">
      <xsl:value-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/distAround"/>
    </xsl:element>

    <xsl:element name="delta">0</xsl:element>  <!-- By definition -->

    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($startPtOnTemplate)/horizOffset"/>
    </xsl:element>

    <xsl:element name="VerticalOffset">
      <xsl:value-of select="msxsl:node-set($startPtOnTemplate)/vertOffset"/>
    </xsl:element>
  </xsl:element>

  <xsl:for-each select="msxsl:node-set($profile)/TunnelPointDeltaRecord">
    <xsl:choose>
      <xsl:when test="position() = 1">
        <!-- Write out the actual point - there cannot be a 'cross-over' prior to this point -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="position() = last()">
        <!-- First check for a 'cross over' between the previous point and this last point -->
        <xsl:variable name="prevHasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:variable>

        <xsl:if test="$prevHasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="preceding-sibling::TunnelPointDeltaRecord[1]/HorizontalOffset"/>
            <xsl:with-param name="profPt1Vt" select="preceding-sibling::TunnelPointDeltaRecord[1]/VerticalOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>

        <!-- Now write out the actual point -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>
      </xsl:when>

      <xsl:otherwise>
        <!-- Need to check whether the deltas 'cross over' before this point -->
        <!-- Check for a 'cross over' between the previous point and the current point -->
        <xsl:variable name="prevHasSameSign">
          <xsl:call-template name="SameSign">
            <xsl:with-param name="val1">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="preceding-sibling::TunnelPointDeltaRecord[1]/Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="val2">
              <xsl:choose>
                <xsl:when test="$useComputedDeltaValues = 'true'">
                  <xsl:value-of select="calcdDelta"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="Delta"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$prevHasSameSign = 'false'">
          <xsl:call-template name="ComputeIntPointOnDesignProfile">
            <xsl:with-param name="profPt1Hz" select="preceding-sibling::TunnelPointDeltaRecord[1]/HorizontalOffset"/>
            <xsl:with-param name="profPt1Vt" select="preceding-sibling::TunnelPointDeltaRecord[1]/VerticalOffset"/>
            <xsl:with-param name="profPt2Hz" select="HorizontalOffset"/>
            <xsl:with-param name="profPt2Vt" select="VerticalOffset"/>
            <xsl:with-param name="profile" select=".."/>
            <xsl:with-param name="templateSurface" select="$templateSurface"/>
          </xsl:call-template>
        </xsl:if>

        <!-- Now write out the current point details -->
        <xsl:element name="point">
          <xsl:element name="dist">
            <xsl:value-of select="distAround"/>
          </xsl:element>
          <xsl:element name="delta">
            <xsl:choose>
              <xsl:when test="$useComputedDeltaValues = 'true'">
                <xsl:value-of select="calcdDelta"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="Delta"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>
          <xsl:copy-of select="HorizontalOffset"/>
          <xsl:copy-of select="VerticalOffset"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>

  <!-- Now add the point projected from the last point onto the template element -->
  <xsl:variable name="endPtOnTemplate">
    <xsl:call-template name="ComputeProjectedPoint">
      <xsl:with-param name="profile" select="$profile"/>
      <xsl:with-param name="templateSurface" select="$templateSurface"/>
      <xsl:with-param name="firstPt">false</xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <!-- Set up the point element for the point projected onto the template -->
  <xsl:element name="point">
    <xsl:element name="dist">
      <xsl:value-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/distAround"/>
    </xsl:element>

    <xsl:element name="delta">0</xsl:element>  <!-- By definition -->

    <xsl:element name="HorizontalOffset">
      <xsl:value-of select="msxsl:node-set($endPtOnTemplate)/horizOffset"/>
    </xsl:element>

    <xsl:element name="VerticalOffset">
      <xsl:value-of select="msxsl:node-set($endPtOnTemplate)/vertOffset"/>
    </xsl:element>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Compute point projected onto template element ******** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeProjectedPoint">
  <xsl:param name="profile"/>
  <xsl:param name="templateSurface"/>
  <xsl:param name="firstPt" select="'true'"/>

  <xsl:variable name="closestDesignElement">
    <xsl:choose>
      <xsl:when test="$firstPt = 'true'">
        <xsl:call-template name="TemplateElementForPoint">
          <xsl:with-param name="designTemplate" select="msxsl:node-set($profile)/design"/>
          <xsl:with-param name="templateSurface" select="$templateSurface"/>
          <xsl:with-param name="ptHz" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/HorizontalOffset"/>
          <xsl:with-param name="ptVt" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/VerticalOffset"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="TemplateElementForPoint">
          <xsl:with-param name="designTemplate" select="msxsl:node-set($profile)/design"/>
          <xsl:with-param name="templateSurface" select="$templateSurface"/>
          <xsl:with-param name="ptHz" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/HorizontalOffset"/>
          <xsl:with-param name="ptVt" select="msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/VerticalOffset"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="element">
    <xsl:copy-of select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element[number(msxsl:node-set($closestDesignElement)/index)]"/>
  </xsl:variable>

  <xsl:variable name="scanPt">
    <xsl:choose>
      <xsl:when test="$firstPt = 'true'">
        <xsl:copy-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/VerticalOffset"/>
        <xsl:copy-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[1]/HorizontalOffset"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/VerticalOffset"/>
        <xsl:copy-of select="msxsl:node-set($profile)/TunnelPointDeltaRecord[last()]/HorizontalOffset"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="msxsl:node-set($closestDesignElement)/extCornerPt = 'true'"> <!-- This is an external corner point -->
      <!-- Determine the closest end of the indexed element and get the direction to it -->
      <xsl:variable name="distStart">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="msxsl:node-set($scanPt)/VerticalOffset - msxsl:node-set($element)/element/startVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($scanPt)/HorizontalOffset - msxsl:node-set($element)/element/startHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="distEnd">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="msxsl:node-set($scanPt)/VerticalOffset - msxsl:node-set($element)/element/endVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($scanPt)/HorizontalOffset - msxsl:node-set($element)/element/endHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="$distStart &lt; $distEnd">
          <xsl:element name="horizOffset">
            <xsl:value-of select="msxsl:node-set($element)/element/startHz"/>
          </xsl:element>
          <xsl:element name="vertOffset">
            <xsl:value-of select="msxsl:node-set($element)/element/startVt"/>
          </xsl:element>
        </xsl:when>
        <xsl:otherwise>
          <xsl:element name="horizOffset">
            <xsl:value-of select="msxsl:node-set($element)/element/endHz"/>
          </xsl:element>
          <xsl:element name="vertOffset">
            <xsl:value-of select="msxsl:node-set($element)/element/endVt"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>

    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="msxsl:node-set($element)/element/radius">  <!-- Arc element -->
          <!-- Get the direction from the arc centre to the point -->
          <xsl:variable name="dirn">
            <xsl:call-template name="InverseAzimuth">
              <xsl:with-param name="deltaN" select="msxsl:node-set($scanPt)/VerticalOffset - msxsl:node-set($element)/element/centreVt"/>
              <xsl:with-param name="deltaE" select="msxsl:node-set($scanPt)/HorizontalOffset - msxsl:node-set($element)/element/centreHz"/>
              <xsl:with-param name="returnInRadians">true</xsl:with-param>
            </xsl:call-template>
          </xsl:variable>

          <!-- The end position for the computed delta is the point on the arc circumference -->
          <xsl:call-template name="FollowDirection">
            <xsl:with-param name="direction" select="$dirn"/>
            <xsl:with-param name="distance" select="msxsl:node-set($element)/element/radius"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($element)/element/centreVt"/>
            <xsl:with-param name="startHz" select="msxsl:node-set($element)/element/centreHz"/>
          </xsl:call-template>
        </xsl:when>

        <xsl:otherwise>  <!-- Straight element -->
          <!-- Get the coordinates of the point projected onto the profile line from the measured position -->
          <xsl:variable name="projPt">
            <xsl:call-template name="PointToLineProjectionPoint">
              <xsl:with-param name="x1" select="msxsl:node-set($element)/element/startHz"/>
              <xsl:with-param name="y1" select="msxsl:node-set($element)/element/startVt"/>
              <xsl:with-param name="x2" select="msxsl:node-set($element)/element/endHz"/>
              <xsl:with-param name="y2" select="msxsl:node-set($element)/element/endVt"/>
              <xsl:with-param name="xPt" select="msxsl:node-set($scanPt)/HorizontalOffset"/>
              <xsl:with-param name="yPt" select="msxsl:node-set($scanPt)/VerticalOffset"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:element name="horizOffset">
            <xsl:value-of select="msxsl:node-set($projPt)/x"/>
          </xsl:element>

          <xsl:element name="vertOffset">
            <xsl:value-of select="msxsl:node-set($projPt)/y"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Tests to see if two parameters have the same sign ******* -->
<!-- **************************************************************** -->
<xsl:template name="SameSign">
  <xsl:param name="val1"/>
  <xsl:param name="val2"/>

  <xsl:choose>
    <xsl:when test="(($val1 &lt; 0.0) and ($val2 &lt; 0.0)) or (($val1 &gt;= 0.0) and ($val2 &gt;= 0.0))">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Compute the intersection point on the design profile ***** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeIntPointOnDesignProfile">
  <xsl:param name="profPt1Hz"/>
  <xsl:param name="profPt1Vt"/>
  <xsl:param name="profPt2Hz"/>
  <xsl:param name="profPt2Vt"/>
  <xsl:param name="profile" select=".."/>
  <xsl:param name="templateSurface"/>

  <xsl:for-each select="msxsl:node-set($profile)/design/templateSurface[@name = $templateSurface]/element">
    <xsl:choose>
      <xsl:when test="radius">  <!-- This is an arc element -->
        <xsl:variable name="intPt">
          <xsl:call-template name="ComputeLineArcIntersection">
            <xsl:with-param name="profPt1Hz" select="$profPt1Hz"/>
            <xsl:with-param name="profPt1Vt" select="$profPt1Vt"/>
            <xsl:with-param name="profPt2Hz" select="$profPt2Hz"/>
            <xsl:with-param name="profPt2Vt" select="$profPt2Vt"/>
            <xsl:with-param name="element" select="."/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="msxsl:node-set($intPt)/intersection = 'true'">
          <xsl:element name="point">
            <xsl:variable name="distAround">
              <xsl:call-template name="CalcDistAroundTemplate">
                <xsl:with-param name="designTemplate" select="msxsl:node-set($profile)/design"/>
                <xsl:with-param name="templateSurface" select="$templateSurface"/>
                <xsl:with-param name="ptHz" select="msxsl:node-set($intPt)/x"/>
                <xsl:with-param name="ptVt" select="msxsl:node-set($intPt)/y"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:element name="dist">
              <xsl:value-of select="msxsl:node-set($distAround)/distAround"/>
            </xsl:element>
            <xsl:element name="delta">0</xsl:element>
            <xsl:element name="HorizontalOffset">
              <xsl:value-of select="msxsl:node-set($intPt)/x"/>
            </xsl:element>
            <xsl:element name="VerticalOffset">
              <xsl:value-of select="msxsl:node-set($intPt)/y"/>
            </xsl:element>
          </xsl:element>
        </xsl:if>
      </xsl:when>

      <xsl:otherwise>  <!-- This is a line element -->
        <xsl:variable name="linesCross">
          <xsl:call-template name="LinesCross">
            <xsl:with-param name="x1" select="$profPt1Hz"/>
            <xsl:with-param name="y1" select="$profPt1Vt"/>
            <xsl:with-param name="x2" select="$profPt2Hz"/>
            <xsl:with-param name="y2" select="$profPt2Vt"/>
            <xsl:with-param name="x3" select="startHz"/>
            <xsl:with-param name="y3" select="startVt"/>
            <xsl:with-param name="x4" select="endHz"/>
            <xsl:with-param name="y4" select="endVt"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="$linesCross = 'true'">
          <xsl:variable name="intPt">
            <xsl:call-template name="IntersectionPointForTwoLines">
              <xsl:with-param name="x1" select="$profPt1Hz"/>
              <xsl:with-param name="y1" select="$profPt1Vt"/>
              <xsl:with-param name="x2" select="$profPt2Hz"/>
              <xsl:with-param name="y2" select="$profPt2Vt"/>
              <xsl:with-param name="x3" select="startHz"/>
              <xsl:with-param name="y3" select="startVt"/>
              <xsl:with-param name="x4" select="endHz"/>
              <xsl:with-param name="y4" select="endVt"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:element name="point">
            <xsl:variable name="distAround">
              <xsl:call-template name="CalcDistAroundTemplate">
                <xsl:with-param name="designTemplate" select="msxsl:node-set($profile)/design"/>
                <xsl:with-param name="templateSurface" select="$templateSurface"/>
                <xsl:with-param name="ptHz" select="msxsl:node-set($intPt)/x"/>
                <xsl:with-param name="ptVt" select="msxsl:node-set($intPt)/y"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:element name="dist">
              <xsl:value-of select="msxsl:node-set($distAround)/distAround"/>
            </xsl:element>
            <xsl:element name="delta">0</xsl:element>
            <xsl:element name="HorizontalOffset">
              <xsl:value-of select="msxsl:node-set($intPt)/x"/>
            </xsl:element>
            <xsl:element name="VerticalOffset">
              <xsl:value-of select="msxsl:node-set($intPt)/y"/>
            </xsl:element>
          </xsl:element>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>

</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Compute the intersection of a line segment and arc ****** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeLineArcIntersection">
  <xsl:param name="profPt1Hz"/>
  <xsl:param name="profPt1Vt"/>
  <xsl:param name="profPt2Hz"/>
  <xsl:param name="profPt2Vt"/>
  <xsl:param name="element"/>

  <xsl:variable name="distCentreToPt1">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$profPt1Vt - msxsl:node-set($element)/centreVt"/>
      <xsl:with-param name="deltaE" select="$profPt1Hz - msxsl:node-set($element)/centreHz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="distCentreToPt2">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$profPt2Vt - msxsl:node-set($element)/centreVt"/>
      <xsl:with-param name="deltaE" select="$profPt2Hz - msxsl:node-set($element)/centreHz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <!-- If both distances are less than the radius or greater than the radius then there cannot be an intersection -->
    <xsl:when test="(($distCentreToPt1 &lt; msxsl:node-set($element)/radius) and ($distCentreToPt2 &lt; msxsl:node-set($element)/radius)) or
                    (($distCentreToPt1 &gt; msxsl:node-set($element)/radius) and ($distCentreToPt2 &gt; msxsl:node-set($element)/radius))">
      <xsl:element name="intersection">false</xsl:element>
    </xsl:when>

    <xsl:otherwise>   <!-- Investigate potential intersection further -->
      <!-- Compute azimuth of line segment and the determine its cotangent -->
      <!-- Use the following formulae to compute the intersection of a line and circle first    -->
      <!-- Use the formula to find the roots of a quadratic equation:                           -->
      <!--   x = (-b +/- sqrt(b * b - 4 * a * c)) / 2 * a                                       -->
      <!--   where:                                                                             -->
      <!--   a = 1 + m * m  and m = cotangent of 'slope' of line                                -->
      <!--   b = -2 * (circleCentreX + m * m * lineStartX - m * lineStartY + m * circleCentreY) -->
      <!--   c = circleCentreX * circleCentreX + circleCentreY * circleCentreY +                -->
      <!--       lineStartY * lineStartY + m * m * lineStartX * lineStartX -                    -->
      <!--       radius * radius - 2 * m * lineStartX * lineStartY +                            -->
      <!--       2 * circleCentreY * m * lineStartX - 2 * circleCentreY * lineStartY            -->
      <xsl:variable name="lineAz">   <!-- Returned in radians -->
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="$profPt2Vt - $profPt1Vt"/>
          <xsl:with-param name="deltaE" select="$profPt2Hz - $profPt1Hz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="cotanAz" select="1.0 div math:tan(number($lineAz))"/>
      <xsl:variable name="a" select="1.0 + $cotanAz * $cotanAz"/>
      <xsl:variable name="b" select="-2.0 * (msxsl:node-set($element)/centreHz + $cotanAz * $cotanAz * $profPt1Hz -
                                             $cotanAz * $profPt1Vt + $cotanAz * msxsl:node-set($element)/centreVt)"/>
      <xsl:variable name="c" select="msxsl:node-set($element)/centreHz * msxsl:node-set($element)/centreHz +
                                     msxsl:node-set($element)/centreVt * msxsl:node-set($element)/centreVt +
                                     $profPt1Vt * $profPt1Vt + $cotanAz * $cotanAz * $profPt1Hz * $profPt1Hz -
                                     msxsl:node-set($element)/radius * msxsl:node-set($element)/radius -
                                     2.0 * $cotanAz * $profPt1Hz * $profPt1Vt +
                                     2.0 * msxsl:node-set($element)/centreVt * $cotanAz * $profPt1Hz -
                                     2.0 * msxsl:node-set($element)/centreVt * $profPt1Vt"/>
      <!-- First check to see if b * b - 4 * a * c is positive - if not then there is no intersection -->
      <!-- between the circle and the line.                                                           -->
      <xsl:variable name="test" select="$b * $b - 4.0 * $a * $c"/>
      <xsl:choose>
        <xsl:when test="$test &lt; 0.0">  <!-- No roots to equation possible so no intersection -->
          <xsl:element name="intersection">false</xsl:element>
        </xsl:when>
        <xsl:otherwise>  <!-- There are either 1 or 2 intersections of the line with the circle -->
          <!-- Now determine the intersection coordinates -->
          <xsl:variable name="x1" select="(-1.0 * $b + math:sqrt(number($test))) div (2.0 * $a)"/>
          <xsl:variable name="x2" select="(-1.0 * $b - math:sqrt(number($test))) div (2.0 * $a)"/>
          <xsl:variable name="y1" select="$cotanAz * ($x1 - $profPt1Hz) + $profPt1Vt"/>
          <xsl:variable name="y2" select="$cotanAz * ($x2 - $profPt1Hz) + $profPt1Vt"/>

          <!-- Next check to see if the intersection points lie on the line segment -->
          <xsl:variable name="pt1OnSegment">
            <xsl:call-template name="PointOnLineSegment">
              <xsl:with-param name="profPt1Hz" select="$profPt1Hz"/>
              <xsl:with-param name="profPt1Vt" select="$profPt1Vt"/>
              <xsl:with-param name="profPt2Hz" select="$profPt2Hz"/>
              <xsl:with-param name="profPt2Vt" select="$profPt2Vt"/>
              <xsl:with-param name="ptHz" select="$x1"/>
              <xsl:with-param name="ptVt" select="$y1"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="pt2OnSegment">
            <xsl:call-template name="PointOnLineSegment">
              <xsl:with-param name="profPt1Hz" select="$profPt1Hz"/>
              <xsl:with-param name="profPt1Vt" select="$profPt1Vt"/>
              <xsl:with-param name="profPt2Hz" select="$profPt2Hz"/>
              <xsl:with-param name="profPt2Vt" select="$profPt2Vt"/>
              <xsl:with-param name="ptHz" select="$x2"/>
              <xsl:with-param name="ptVt" select="$y2"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:choose>
            <xsl:when test="($pt1OnSegment = 'false') and ($pt2OnSegment = 'false')">
              <xsl:element name="intersection">false</xsl:element>
            </xsl:when>

            <xsl:otherwise>    <!-- One of the intersection points does lie on the line segment - now check if it lies on the arc -->
              <xsl:choose>
                <xsl:when test="$pt1OnSegment = 'true'">
                  <xsl:variable name="ptOnArc">
                    <xsl:call-template name="PointOnArc">
                      <xsl:with-param name="ptHz" select="$x1"/>
                      <xsl:with-param name="ptVt" select="$y1"/>
                      <xsl:with-param name="element" select="$element"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:choose>
                    <xsl:when test="$ptOnArc = 'true'">
                      <xsl:element name="intersection">true</xsl:element>
                      <xsl:element name="x">
                        <xsl:value-of select="$x1"/>
                      </xsl:element>
                      <xsl:element name="y">
                        <xsl:value-of select="$y1"/>
                      </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:element name="intersection">false</xsl:element>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:when>

                <xsl:otherwise>  <!-- Point 2 must be the one on the line segment -->
                  <xsl:variable name="ptOnArc">
                    <xsl:call-template name="PointOnArc">
                      <xsl:with-param name="ptHz" select="$x2"/>
                      <xsl:with-param name="ptVt" select="$y2"/>
                      <xsl:with-param name="element" select="$element"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:choose>
                    <xsl:when test="$ptOnArc = 'true'">
                      <xsl:element name="intersection">true</xsl:element>
                      <xsl:element name="x">
                        <xsl:value-of select="$x2"/>
                      </xsl:element>
                      <xsl:element name="y">
                        <xsl:value-of select="$y2"/>
                      </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:element name="intersection">false</xsl:element>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Test if point is within line segment ************** -->
<!-- **************************************************************** -->
<xsl:template name="PointOnLineSegment">
  <xsl:param name="profPt1Hz"/>
  <xsl:param name="profPt1Vt"/>
  <xsl:param name="profPt2Hz"/>
  <xsl:param name="profPt2Vt"/>
  <xsl:param name="ptHz"/>
  <xsl:param name="ptVt"/>

  <xsl:variable name="lineSegLen">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$profPt1Vt - $profPt2Vt"/>
      <xsl:with-param name="deltaE" select="$profPt1Hz - $profPt2Hz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="ptToStartDist">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$profPt1Vt - $ptVt"/>
      <xsl:with-param name="deltaE" select="$profPt1Hz - $ptHz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="ptToEndDist">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$profPt2Vt - $ptVt"/>
      <xsl:with-param name="deltaE" select="$profPt2Hz - $ptHz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="($ptToStartDist &lt;= $lineSegLen) and ($ptToEndDist &lt;= $lineSegLen)">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***************** Test if point is within arc ****************** -->
<!-- **************************************************************** -->
<xsl:template name="PointOnArc">
  <xsl:param name="ptHz"/>
  <xsl:param name="ptVt"/>
  <xsl:param name="element"/>

  <!-- Arcs are defined in a clockwise direction so we can use this to determine if the intersection     -->
  <!-- point is on the correct (left) side of the diameter (start pt to end pt) using the cross product. -->
  <xsl:variable name="crossProd">
    <xsl:call-template name="CrossProduct">
      <xsl:with-param name="pointX" select="$ptHz"/>
      <xsl:with-param name="pointY" select="$ptVt"/>
      <xsl:with-param name="startX" select="msxsl:node-set($element)/startHz"/>
      <xsl:with-param name="startY" select="msxsl:node-set($element)/startVt"/>
      <xsl:with-param name="endX" select="msxsl:node-set($element)/endHz"/>
      <xsl:with-param name="endY" select="msxsl:node-set($element)/endVt"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$crossProd &lt;= 0">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *********** Return a node set of points along an arc *********** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeIntermediateArcPoints">
  <xsl:param name="startHz"/>
  <xsl:param name="startVt"/>
  <xsl:param name="endHz"/>
  <xsl:param name="endVt"/>
  <xsl:param name="centreHz"/>
  <xsl:param name="centreVt"/>
  <xsl:param name="radius"/>
  <xsl:param name="deltaAngle"/>  <!-- Expected to be in radians -->

  <!-- We want to compute points every 2cm along the arc for use in the area calcs -->
  <xsl:variable name="arcLen" select="math:abs(number($deltaAngle * $radius))"/>
  <xsl:variable name="steps" select="math:floor(number($arcLen div 0.02))"/>
  <xsl:variable name="stepAngle" select="$deltaAngle div $steps"/>
  <xsl:variable name="startAz">
    <xsl:call-template name="InverseAzimuth">
      <xsl:with-param name="deltaN" select="$startVt - $centreVt"/>
      <xsl:with-param name="deltaE" select="$startHz - $centreHz"/>
      <xsl:with-param name="returnInRadians">true</xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:if test="$steps &gt; 0">
    <xsl:call-template name="ComputedArcPoints">
      <xsl:with-param name="baseAzimuth" select="$startAz"/>
      <xsl:with-param name="radius" select="$radius"/>
      <xsl:with-param name="azIncrement" select="$stepAngle"/>
      <xsl:with-param name="centreHz" select="$centreHz"/>
      <xsl:with-param name="centreVt" select="$centreVt"/>
      <xsl:with-param name="steps" select="$steps"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Recursive routine to return the points along the arc ***** -->
<!-- **************************************************************** -->
<xsl:template name="ComputedArcPoints">
  <xsl:param name="baseAzimuth"/>
  <xsl:param name="radius"/>
  <xsl:param name="azIncrement"/>
  <xsl:param name="centreHz"/>
  <xsl:param name="centreVt"/>
  <xsl:param name="steps"/>
  <xsl:param name="count" select="1"/>

  <xsl:if test="$steps - $count &gt; 0">
    <xsl:variable name="posn">
      <xsl:call-template name="FollowDirection">
        <xsl:with-param name="direction" select="$baseAzimuth + $azIncrement * $count"/>
        <xsl:with-param name="distance" select="$radius"/>
        <xsl:with-param name="startVt" select="centreVt"/>
        <xsl:with-param name="startHz" select="centreHz"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:element name="point">
      <xsl:element name="HorizontalOffset">
        <xsl:value-of select="msxsl:node-set($posn)/horizOffset"/>
      </xsl:element>
      <xsl:element name="VerticalOffset">
        <xsl:value-of select="msxsl:node-set($posn)/vertOffset"/>
      </xsl:element>
    </xsl:element>

    <!-- Now recurse the function -->
    <xsl:call-template name="ComputedArcPoints">
      <xsl:with-param name="baseAzimuth" select="$baseAzimuth"/>
      <xsl:with-param name="radius" select="$radius"/>
      <xsl:with-param name="azIncrement" select="$azIncrement"/>
      <xsl:with-param name="centreHz" select="$centreHz"/>
      <xsl:with-param name="centreVt" select="$centreVt"/>
      <xsl:with-param name="steps" select="$steps"/>
      <xsl:with-param name="count" select="$count + 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Compute the area of a figure based on array of points **** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeFigureArea">
  <xsl:param name="pointsArray"/>

  <!-- The pointsArray consists of a set of the following elements:
       <point>
         <HorizontalOffset>value</HorizontalOffset>
         <VerticalOffset>value</VerticalOffset>
       </point>
   -->

  <xsl:variable name="areaVals">
    <xsl:for-each select="msxsl:node-set($pointsArray)/point">
      <xsl:choose>
        <xsl:when test="position() &lt; last()">
          <xsl:element name="value">
            <xsl:value-of select="HorizontalOffset * following-sibling::point[1]/VerticalOffset - following-sibling::point[1]/HorizontalOffset * VerticalOffset"/>
          </xsl:element>
        </xsl:when>
        <xsl:otherwise>  <!-- On last point - match up with first point -->
          <xsl:element name="value">
            <xsl:value-of select="HorizontalOffset * msxsl:node-set($pointsArray)/point[1]/VerticalOffset - msxsl:node-set($pointsArray)/point[1]/HorizontalOffset * VerticalOffset"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="sum" select="math:abs(number(sum(msxsl:node-set($areaVals)/value)))"/>
  <xsl:value-of select="$sum div 2.0"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Compute the area of the design template *********** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeTemplateArea">
  <xsl:param name="design"/>
  <xsl:param name="templateSurface"/>

  <xsl:variable name="templatePts">
    <xsl:for-each select="msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element">
      <xsl:if test="position() = 1">
        <xsl:element name="point">
          <xsl:element name="HorizontalOffset">
            <xsl:value-of select="startHz"/>
          </xsl:element>
          <xsl:element name="VerticalOffset">
            <xsl:value-of select="startVt"/>
          </xsl:element>
        </xsl:element>
      </xsl:if>

      <xsl:choose>
        <xsl:when test="radius">  <!-- An arc element -->
          <xsl:call-template name="ComputeIntermediateArcPoints">
            <xsl:with-param name="startHz" select="startHz"/>
            <xsl:with-param name="startVt" select="startVt"/>
            <xsl:with-param name="endHz" select="endHz"/>
            <xsl:with-param name="endVt" select="endVt"/>
            <xsl:with-param name="centreHz" select="centreHz"/>
            <xsl:with-param name="centreVt" select="centreVt"/>
            <xsl:with-param name="radius" select="radius"/>
            <xsl:with-param name="deltaAngle" select="deltaAngle * math:PI() div 180.0"/>  <!-- Convert angle to radians for this function -->
          </xsl:call-template>

          <!-- Now add the end point -->
          <xsl:element name="point">
            <xsl:element name="HorizontalOffset">
              <xsl:value-of select="endHz"/>
            </xsl:element>
            <xsl:element name="VerticalOffset">
              <xsl:value-of select="endVt"/>
            </xsl:element>
          </xsl:element>
        </xsl:when>

        <xsl:otherwise>  <!-- A line element - record the end point -->
          <xsl:element name="point">
            <xsl:element name="HorizontalOffset">
              <xsl:value-of select="endHz"/>
            </xsl:element>
            <xsl:element name="VerticalOffset">
              <xsl:value-of select="endVt"/>
            </xsl:element>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:variable>

  <xsl:call-template name="ComputeFigureArea">
    <xsl:with-param name="pointsArray" select="$templatePts"/>
  </xsl:call-template>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Add portions of template to complete closed figure ****** -->
<!-- **************************************************************** -->
<xsl:template name="AddTemplateElementsToFigure">
  <xsl:param name="pointsArray"/>
  <xsl:param name="design"/>
  <xsl:param name="templateSurface"/>

  <!-- First copy all the existing measured points into the returned node set -->
  <xsl:for-each select="msxsl:node-set($pointsArray)/point">
    <xsl:copy-of select="."/>
  </xsl:for-each>

  <xsl:variable name="startDist" select="msxsl:node-set($pointsArray)/point[1]/dist"/>
  <xsl:variable name="endDist" select="msxsl:node-set($pointsArray)/point[last()]/dist"/>

  <xsl:variable name="startElementIndexStr">
    <xsl:for-each select="msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element">
      <xsl:variable name="currPos" select="position()"/>
      <xsl:if test="$startDist &lt;= sum(msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element[position() &lt;= $currPos]/length)">
        <xsl:value-of select="concat(position(), ' ')"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="startElementIndex" select="substring-before($startElementIndexStr, ' ')"/>

  <xsl:variable name="endElementIndexStr">
    <xsl:for-each select="msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element">
      <xsl:variable name="currPos" select="position()"/>
      <xsl:if test="$endDist &lt;= sum(msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element[position() &lt;= $currPos]/length)">
        <xsl:value-of select="concat(position(), ' ')"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="endElementIndex" select="substring-before($endElementIndexStr, ' ')"/>

   <xsl:choose>
     <xsl:when test="$startElementIndex = $endElementIndex">  <!-- Starts and ends on same element -->
       <xsl:call-template name="AddElementPoints">
         <xsl:with-param name="index" select="$startElementIndex"/>
         <xsl:with-param name="design" select="$design"/>
         <xsl:with-param name="templateSurface" select="$templateSurface"/>
         <xsl:with-param name="intPtLastHz" select="msxsl:node-set($pointsArray)/point[last()]/HorizontalOffset"/>
         <xsl:with-param name="intPtLastVt" select="msxsl:node-set($pointsArray)/point[last()]/VerticalOffset"/>
         <xsl:with-param name="intPtFirstHz" select="msxsl:node-set($pointsArray)/point[1]/HorizontalOffset"/>
         <xsl:with-param name="intPtFirstVt" select="msxsl:node-set($pointsArray)/point[1]/VerticalOffset"/>
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:call-template name="AddElementSequence">
         <xsl:with-param name="endElementIndex" select="$endElementIndex"/>
         <xsl:with-param name="startElementIndex" select="$startElementIndex"/>
         <xsl:with-param name="design" select="$design"/>
         <xsl:with-param name="templateSurface" select="$templateSurface"/>
         <xsl:with-param name="intPtLastHz" select="msxsl:node-set($pointsArray)/point[last()]/HorizontalOffset"/>
         <xsl:with-param name="intPtLastVt" select="msxsl:node-set($pointsArray)/point[last()]/VerticalOffset"/>
         <xsl:with-param name="intPtFirstHz" select="msxsl:node-set($pointsArray)/point[1]/HorizontalOffset"/>
         <xsl:with-param name="intPtFirstVt" select="msxsl:node-set($pointsArray)/point[1]/VerticalOffset"/>
         <xsl:with-param name="count" select="$endElementIndex"/>
       </xsl:call-template>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Pass sequence of design elements to get point elements **** -->
<!-- **************************************************************** -->
<xsl:template name="AddElementSequence">
  <xsl:param name="endElementIndex"/>
  <xsl:param name="startElementIndex"/>
  <xsl:param name="design"/>
  <xsl:param name="templateSurface"/>
  <xsl:param name="intPtLastHz"/>
  <xsl:param name="intPtLastVt"/>
  <xsl:param name="intPtFirstHz"/>
  <xsl:param name="intPtFirstVt"/>
  <xsl:param name="count"/>

  <!-- Recursive routine to call the AddElementPoints for each element - working -->
  <!-- from the endElementIndex to the startElementIndex.                        -->
  <xsl:if test="$count - $startElementIndex &gt;= 0">
    <xsl:call-template name="AddElementPoints">
      <xsl:with-param name="index" select="$count"/>
      <xsl:with-param name="design" select="$design"/>
      <xsl:with-param name="templateSurface" select="$templateSurface"/>
      <xsl:with-param name="intPtLastHz">
        <xsl:if test="$count = $endElementIndex">
          <xsl:value-of select="$intPtLastHz"/>
        </xsl:if>
      </xsl:with-param>
      <xsl:with-param name="intPtLastVt">
        <xsl:if test="$count = $endElementIndex">
          <xsl:value-of select="$intPtLastVt"/>
        </xsl:if>
      </xsl:with-param>
      <xsl:with-param name="intPtFirstHz">
        <xsl:if test="$count = $startElementIndex">
          <xsl:value-of select="$intPtFirstHz"/>
        </xsl:if>
      </xsl:with-param>
      <xsl:with-param name="intPtFirstVt">
        <xsl:if test="$count = $startElementIndex">
          <xsl:value-of select="$intPtFirstVt"/>
        </xsl:if>
      </xsl:with-param>
    </xsl:call-template>

    <!-- Now recurse the function to output the points for the next element -->
    <xsl:call-template name="AddElementSequence">
      <xsl:with-param name="startElementIndex" select="$startElementIndex"/>
      <xsl:with-param name="endElementIndex" select="$endElementIndex"/>
      <xsl:with-param name="design" select="$design"/>
      <xsl:with-param name="templateSurface" select="$templateSurface"/>
      <xsl:with-param name="intPtLastHz" select="$intPtLastHz"/>
      <xsl:with-param name="intPtLastVt" select="$intPtLastVt"/>
      <xsl:with-param name="intPtFirstHz" select="$intPtFirstHz"/>
      <xsl:with-param name="intPtFirstVt" select="$intPtFirstVt"/>
      <xsl:with-param name="count" select="$count - 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ** Add the appropriate point elements for the design element *** -->
<!-- **************************************************************** -->
<xsl:template name="AddElementPoints">
  <xsl:param name="index"/>
  <xsl:param name="design"/>
  <xsl:param name="templateSurface"/>
  <xsl:param name="intPtLastHz"/>
  <xsl:param name="intPtLastVt"/>
  <xsl:param name="intPtFirstHz"/>
  <xsl:param name="intPtFirstVt"/>

  <xsl:for-each select="msxsl:node-set($design)/templateSurface[@name = $templateSurface]/element[number($index)]">
    <xsl:variable name="startPt">
      <xsl:choose>
        <xsl:when test="string(number($intPtLastHz)) != 'NaN'"> <!-- intPtLast is populated so we are starting part way along the element -->
          <xsl:element name="HorizontalOffset">
            <xsl:value-of select="$intPtLastHz"/>
          </xsl:element>
          <xsl:element name="VerticalOffset">
            <xsl:value-of select="$intPtLastVt"/>
          </xsl:element>
        </xsl:when>
        <xsl:otherwise>  <!-- intPtLast not populated so we are starting at the end of the element (working our way in reverse) -->
          <xsl:element name="HorizontalOffset">
            <xsl:value-of select="endHz"/>
          </xsl:element>
          <xsl:element name="VerticalOffset">
            <xsl:value-of select="endVt"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="endPt">
      <xsl:choose>
        <xsl:when test="string(number($intPtFirstHz)) != 'NaN'"> <!-- intPtFirst is populated so we are ending part way along the element -->
          <xsl:element name="HorizontalOffset">
            <xsl:value-of select="$intPtFirstHz"/>
          </xsl:element>
          <xsl:element name="VerticalOffset">
            <xsl:value-of select="$intPtFirstVt"/>
          </xsl:element>
        </xsl:when>
        <xsl:otherwise>  <!-- intPtFirst not populated so we are ending at the start of the element (working our way in reverse) -->
          <xsl:element name="HorizontalOffset">
            <xsl:value-of select="startHz"/>
          </xsl:element>
          <xsl:element name="VerticalOffset">
            <xsl:value-of select="startVt"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="radius">  <!-- This is an arc element -->
        <!-- Need to determine the delta angle for this arc - it will always be an anti-clockwise angle -->
        <xsl:variable name="azToStart">
          <xsl:call-template name="InverseAzimuth">
            <xsl:with-param name="deltaN" select="msxsl:node-set($startPt)/VerticalOffset - centreVt"/>
            <xsl:with-param name="deltaE" select="msxsl:node-set($startPt)/HorizontalOffset - centreHz"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="azToEnd">
          <xsl:call-template name="InverseAzimuth">
            <xsl:with-param name="deltaN" select="msxsl:node-set($endPt)/VerticalOffset - centreVt"/>
            <xsl:with-param name="deltaE" select="msxsl:node-set($endPt)/HorizontalOffset - centreHz"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="clockwiseScribedAngle">
          <xsl:call-template name="ClockwiseAngle">
            <xsl:with-param name="fromAzimuth" select="$azToStart"/>
            <xsl:with-param name="toAzimuth" select="$azToEnd"/>
          </xsl:call-template>
        </xsl:variable>

        <!-- Now get the delta angle as the negative reciprocal of the clockwise angle -->
        <xsl:variable name="deltaAngle" select="$clockwiseScribedAngle - 360.0"/>

        <xsl:call-template name="ComputeIntermediateArcPoints">
          <xsl:with-param name="startHz" select="msxsl:node-set($startPt)/HorizontalOffset"/>
          <xsl:with-param name="startVt" select="msxsl:node-set($startPt)/VerticalOffset"/>
          <xsl:with-param name="endHz" select="msxsl:node-set($endPt)/HorizontalOffset"/>
          <xsl:with-param name="endVt" select="msxsl:node-set($endPt)/VerticalOffset"/>
          <xsl:with-param name="centreHz" select="centreHz"/>
          <xsl:with-param name="centreVt" select="centreVt"/>
          <xsl:with-param name="radius" select="radius"/>
          <xsl:with-param name="deltaAngle" select="$deltaAngle * math:PI() div 180.0"/>  <!-- Convert angle to radians for this function -->
        </xsl:call-template>

        <!-- Output the end point as the arc intermediate points will skip the very last point -->
        <xsl:element name="point">
          <xsl:copy-of select="$endPt"/>
        </xsl:element>
      </xsl:when>

      <xsl:otherwise>  <!-- This is a line element -->
        <!-- Already have the start point (which is the end point when working in reverse) -->
        <!-- so add the end point (either element end point or passed in end point) - may  -->
        <!-- end up with a duplicate adjacent coordinate in the list but this will not     -->
        <!-- affect the computed area.                                                     -->
        <xsl:element name="point">
          <xsl:copy-of select="$endPt"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- *********** Return appropriate area units identifier *********** -->
<!-- **************************************************************** -->
<xsl:template name="AreaUnitsString">

  <xsl:choose>
    <xsl:when test="$AreaUnit = 'SquareMetres'">m&#178;</xsl:when>
    <xsl:when test="$AreaUnit = 'SquareMiles'">Sq Miles</xsl:when>
    <xsl:when test="$AreaUnit = 'SquareFeet'">ft&#178;</xsl:when>
    <xsl:when test="$AreaUnit = 'SquareUSSurveyFeet'">USft&#178;</xsl:when>
    <xsl:when test="$AreaUnit = 'Acres'">Acres</xsl:when>
    <xsl:when test="$AreaUnit = 'Hectares'">ha</xsl:when>
    <xsl:otherwise>m&#178;</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Get specified item from a '|' delimited string ******** -->
<!-- **************************************************************** -->
<xsl:template name="GetParamValFromOptionsString">
  <xsl:param name="index"/>
  <xsl:param name="paramString"/>

  <xsl:choose>
    <xsl:when test="$index = 1">
      <xsl:value-of select="substring-before($paramString, '|')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="GetParamValFromOptionsString">
        <xsl:with-param name="index" select="$index - 1"/>
        <xsl:with-param name="paramString" select="substring-after($paramString, '|')"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************** Output Paragraph Text ******************* -->
<!-- **************************************************************** -->
<xsl:template name="OutputTextInParagraph">
  <xsl:param name="text" select="''"/>
  <xsl:param name="bold" select="'No'"/>
  <xsl:param name="size" select="12"/>
  <xsl:param name="justify" select="''"/>
  <xsl:param name="colour" select="''"/>
  <xsl:param name="keepParaWithNext" select="'No'"/>

  <xsl:choose>
    <xsl:when test="$text = ''">
      <xsl:element name="w:p"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:element name="w:p">
        <xsl:if test="$justify != ''">  <!-- Justification has been specified -->
          <xsl:element name="w:pPr">
            <xsl:element name="w:jc">
              <xsl:choose>
                <xsl:when test="$justify = 'left'">
                  <xsl:attribute name="w:val">left</xsl:attribute>
                </xsl:when>
                <xsl:when test="$justify = 'right'">
                  <xsl:attribute name="w:val">right</xsl:attribute>
                </xsl:when>
                <xsl:when test="$justify = 'center'">
                  <xsl:attribute name="w:val">center</xsl:attribute>
                </xsl:when>
              </xsl:choose>
            </xsl:element>
          </xsl:element>
        </xsl:if>
        <xsl:if test="$keepParaWithNext != 'No'">
          <xsl:element name="w:pPr">
            <xsl:element name="w:keepNext"/>
          </xsl:element>
        </xsl:if>
        <xsl:element name="w:r">
          <xsl:element name="w:rPr">
            <xsl:if test="$bold != 'No'">
              <xsl:element name="w:b"/>
            </xsl:if>
            <xsl:element name="w:sz">     <!-- Output the font size - point size * 2 -->
              <xsl:attribute name="w:val"><xsl:value-of select="$size * 2"/></xsl:attribute>
            </xsl:element>
            <xsl:element name="w:sz-cs">  <!-- Output the font size - point size * 2 -->
              <xsl:attribute name="w:val"><xsl:value-of select="$size * 2"/></xsl:attribute>
            </xsl:element>
            <xsl:if test="$colour != ''">
              <xsl:element name="w:color">
                <xsl:attribute name="w:val"><xsl:value-of select="$colour"/></xsl:attribute>
              </xsl:element>
            </xsl:if>
          </xsl:element>
          <xsl:element name="w:t"><xsl:value-of select="$text"/></xsl:element>
        </xsl:element>
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Output the Document Properties Element ************ -->
<!-- **************************************************************** -->
<xsl:template name="OutputDocumentProperties">
  <xsl:param name="docName" select="'Document'"/>
  <xsl:param name="author" select="''"/>
  <xsl:param name="created" select="''"/>

  <xsl:call-template name="NewLine"/>
  <o:DocumentProperties><xsl:call-template name="NewLine"/>
    <o:Title><xsl:value-of select="$docName"/></o:Title><xsl:call-template name="NewLine"/>
 	  <o:Author><xsl:value-of select="$author"/></o:Author><xsl:call-template name="NewLine"/>
    <o:LastAuthor><xsl:value-of select="$author"/></o:LastAuthor><xsl:call-template name="NewLine"/>
    <o:Revision>1</o:Revision><xsl:call-template name="NewLine"/>
    <o:TotalTime>1</o:TotalTime><xsl:call-template name="NewLine"/>
    <o:Created><xsl:value-of select="$created"/></o:Created><xsl:call-template name="NewLine"/>
    <o:LastSaved><xsl:value-of select="$created"/></o:LastSaved><xsl:call-template name="NewLine"/>
    <o:Pages/><xsl:call-template name="NewLine"/>
    <o:Words/><xsl:call-template name="NewLine"/>
    <o:Characters/><xsl:call-template name="NewLine"/>
    <o:Company>Trimble Navigation New Zealand Limited</o:Company><xsl:call-template name="NewLine"/>
    <o:Lines/><xsl:call-template name="NewLine"/>
    <o:Paragraphs/><xsl:call-template name="NewLine"/>
    <o:CharactersWithSpaces/><xsl:call-template name="NewLine"/>
    <o:Version>11.6568</o:Version><xsl:call-template name="NewLine"/>
  </o:DocumentProperties><xsl:call-template name="NewLine"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************* Output Font Definition ******************* -->
<!-- **************************************************************** -->
<xsl:template name="OutputFontDefinition">
  <w:fonts>
    <w:defaultFonts w:ascii="Arial" w:fareast="Arial" w:h-ansi="Arial" w:cs="Arial"/>
  </w:fonts>
</xsl:template>


<!-- **************************************************************** -->
<!-- *********** Include Definition of the Default Table ************ -->
<!-- **************************************************************** -->
<xsl:template name="DefineDefaultTable">

  <w:style w:type="table" w:default="on" w:styleId="TableNormal">
    <w:name w:val="Normal Table"/>
    <w:basedOn w:val="TableNormal"/>
    <w:name w:val="Normal Table"/>
    <wx:uiName wx:val="Table Normal"/>
    <w:semiHidden/>
    <w:rPr>
      <wx:font wx:val="Times New Roman"/>
    </w:rPr>
    <w:tblPr>
      <w:tblInd w:w="0" w:type="dxa"/>
      <w:tblCellMar>
        <w:top w:w="40" w:type="dxa"/>
        <w:left w:w="108" w:type="dxa"/>
        <w:bottom w:w="0" w:type="dxa"/>
        <w:right w:w="108" w:type="dxa"/>
      </w:tblCellMar>
    </w:tblPr>
  </w:style>

</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Include Definition of the Output Table ************ -->
<!-- **************************************************************** -->
<xsl:template name="DefineGridTable">

  <w:style w:type="table" w:styleId="TableGrid">
    <w:name w:val="Table Grid"/>
    <w:basedOn w:val="TableNormal"/>
    <w:rsid w:val="00AD6DA3"/>
    <w:rPr>
      <wx:font wx:val="Times New Roman"/>
    </w:rPr>
    <w:tblPr>
      <w:tblInd w:w="0" w:type="dxa"/>
      <w:tblBorders>
        <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
        <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
        <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
        <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
        <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
        <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>
      </w:tblBorders>
      <w:tblCellMar>
        <w:top w:w="40" w:type="dxa"/>
        <w:left w:w="108" w:type="dxa"/>
        <w:bottom w:w="0" w:type="dxa"/>
        <w:right w:w="108" w:type="dxa"/>
      </w:tblCellMar>
    </w:tblPr>
  </w:style>

</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Include Definition of the Output Table ************ -->
<!-- **************************************************************** -->
<xsl:template name="DefineNoBordersTable">

  <w:style w:type="table" w:styleId="TableNoBorders">
    <w:name w:val="Table No Borders"/>
    <w:basedOn w:val="TableNormal"/>
    <w:rsid w:val="00AD6DA3"/>
    <w:rPr>
      <wx:font wx:val="Times New Roman"/>
    </w:rPr>
    <w:tblPr>
      <w:tblInd w:w="0" w:type="dxa"/>
      <w:tblBorders>
        <w:top w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
        <w:left w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
        <w:bottom w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
        <w:right w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
        <w:insideH w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
        <w:insideV w:val="none" w:sz="0" wx:bdrwidth="0" w:space="0" w:color="auto"/>
      </w:tblBorders>
      <w:tblCellMar>
        <w:top w:w="40" w:type="dxa"/>
        <w:left w:w="108" w:type="dxa"/>
        <w:bottom w:w="0" w:type="dxa"/>
        <w:right w:w="108" w:type="dxa"/>
      </w:tblCellMar>
    </w:tblPr>
  </w:style>

</xsl:template>


<!-- **************************************************************** -->
<!-- *************************** New Page *************************** -->
<!-- **************************************************************** -->
<xsl:template name="NewPage">
  <w:p>
    <w:r>
      <w:br w:type="page"/>
    </w:r>
  </w:p>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Output Document Header Details ************** -->
<!-- **************************************************************** -->
<xsl:template name="OutputDocumentHeaderDetails">

  <w:docPr><xsl:call-template name="NewLine"/>
    <w:view w:val="print"/><xsl:call-template name="NewLine"/>
    <w:zoom w:precent="100"/><xsl:call-template name="NewLine"/>
    <w:doNotEmbedSystemFonts/><xsl:call-template name="NewLine"/>
    <w:proofState w:spelling="clean" w:grammar="clean"/><xsl:call-template name="NewLine"/>
    <w:attachedTemplate w:val=""/><xsl:call-template name="NewLine"/>
    <w:defaultTabStop w:val="720"/><xsl:call-template name="NewLine"/>
    <w:punctuationKerning/><xsl:call-template name="NewLine"/>
    <w:characterSpacingControl w:val="DontCompress"/><xsl:call-template name="NewLine"/>
    <w:optimizeForBrowser/><xsl:call-template name="NewLine"/>
    <w:validateAgainstSchema/><xsl:call-template name="NewLine"/>
    <w:saveInvalidXML w:val="off"/><xsl:call-template name="NewLine"/>
    <w:ignoreMixedContent w:val="off"/><xsl:call-template name="NewLine"/>
    <w:alwaysShowPlaceholderText w:val="off"/><xsl:call-template name="NewLine"/>
    <w:compat><xsl:call-template name="NewLine"/>
      <w:breakWrappedTables/><xsl:call-template name="NewLine"/>
      <w:snapToGridInCell/><xsl:call-template name="NewLine"/>
      <w:wrapTextWithPunct/><xsl:call-template name="NewLine"/>
      <w:useAsianBreakRules/><xsl:call-template name="NewLine"/>
      <w:dontGrowAutofit/><xsl:call-template name="NewLine"/>
    </w:compat><xsl:call-template name="NewLine"/>
  </w:docPr><xsl:call-template name="NewLine"/>

</xsl:template>


<!-- **************************************************************** -->
<!-- ******************* Output Page Settings Details *************** -->
<!-- **************************************************************** -->
<xsl:template name="OutputPageSettings">
  <w:sectPr><xsl:call-template name="NewLine"/>
    <w:hdr w:type="odd"><xsl:call-template name="NewLine"/>
      <w:p><xsl:call-template name="NewLine"/>
        <w:pPr><xsl:call-template name="NewLine"/>
          <w:pStyle w:val="Header"/><xsl:call-template name="NewLine"/>
          <w:jc w:val="right"/><xsl:call-template name="NewLine"/>
        </w:pPr><xsl:call-template name="NewLine"/>
        <w:r><xsl:call-template name="NewLine"/>
          <w:pict><xsl:call-template name="NewLine"/>
            <v:shape id="_x0000_i1026" type="#_x0000_t75" style="width:94.5pt;height:22.5pt"><xsl:call-template name="NewLine"/>
              <v:imagedata src="wordml://03000001.png" o:title="TrimbleLogo"/><xsl:call-template name="NewLine"/>
            </v:shape><xsl:call-template name="NewLine"/>
          </w:pict><xsl:call-template name="NewLine"/>
        </w:r><xsl:call-template name="NewLine"/>
      </w:p><xsl:call-template name="NewLine"/>
    </w:hdr><xsl:call-template name="NewLine"/>

    <w:pgSz w:w="15840" w:h="12240" w:orient="landscape"/><xsl:call-template name="NewLine"/>
    <w:pgMar w:top="800" w:right="800" w:bottom="800" w:left="800" w:header="300" w:footer="300" w:gutter="0"/><xsl:call-template name="NewLine"/>
    <w:cols w:space="708"/><xsl:call-template name="NewLine"/>
    <w:titlePg/><xsl:call-template name="NewLine"/>
    <w:docGrid w:line-pitch="360"/><xsl:call-template name="NewLine"/>
  </w:sectPr>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************* Start a new Table Row ******************** -->
<!-- **************************************************************** -->
<xsl:template name="StartTableRow">
  <xsl:param name="setAsRepeatedHeaderLine" select="'No'"/>

  <xsl:value-of disable-output-escaping="yes" select="'&lt;w:tr&gt;'"/> <!-- <w:tr> -->

  <xsl:if test="$setAsRepeatedHeaderLine != 'No'">
    <xsl:element name="w:trPr">
      <xsl:element name="w:tblHeader"/>
    </xsl:element>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************************ End a Table Row *********************** -->
<!-- **************************************************************** -->
<xsl:template name="EndTableRow">

  <xsl:value-of disable-output-escaping="yes" select="'&lt;/w:tr&gt;'"/> <!-- </w:tr> -->

</xsl:template>


<!-- **************************************************************** -->
<!-- ******************** Start a new Table Cell ******************** -->
<!-- **************************************************************** -->
<xsl:template name="StartTableCell">
  <xsl:param name="cellWidth"/>

  <xsl:value-of disable-output-escaping="yes" select="'&lt;w:tc&gt;'"/> <!-- <w:tc> -->
  <xsl:element name="w:tcPr">
    <xsl:element name="w:tcW">
      <xsl:attribute name="w:w">
        <xsl:value-of select="$cellWidth"/>
      </xsl:attribute>
      <xsl:attribute name="w:type">dxa</xsl:attribute>
    </xsl:element>
  </xsl:element>

</xsl:template>


<!-- **************************************************************** -->
<!-- ************************ End a Table Cell ********************** -->
<!-- **************************************************************** -->
<xsl:template name="EndTableCell">

  <xsl:value-of disable-output-escaping="yes" select="'&lt;/w:tc&gt;'"/> <!-- </w:tc> -->

</xsl:template>


<!-- **************************************************************** -->
<!-- ***************** Return Formatted Date String ***************** -->
<!-- **************************************************************** -->
<xsl:template name="FormattedDate">
  <xsl:param name="timeStamp"/>

  <xsl:variable name="date" select="substring($timeStamp, 9, 2)"/>

  <xsl:variable name="month">
    <xsl:variable name="monthNbr" select="substring($timeStamp, 6, 2)"/>
    <xsl:choose>
      <xsl:when test="number($monthNbr) = 1">Oca</xsl:when>
      <xsl:when test="number($monthNbr) = 2">Şub</xsl:when>
      <xsl:when test="number($monthNbr) = 3">Mar</xsl:when>
      <xsl:when test="number($monthNbr) = 4">Nis</xsl:when>
      <xsl:when test="number($monthNbr) = 5">May</xsl:when>
      <xsl:when test="number($monthNbr) = 6">Haz</xsl:when>
      <xsl:when test="number($monthNbr) = 7">Tem</xsl:when>
      <xsl:when test="number($monthNbr) = 8">Aug</xsl:when>
      <xsl:when test="number($monthNbr) = 9">Eyl</xsl:when>
      <xsl:when test="number($monthNbr) = 10">Eki</xsl:when>
      <xsl:when test="number($monthNbr) = 11">Kas</xsl:when>
      <xsl:when test="number($monthNbr) = 12">Ara</xsl:when>
    </xsl:choose>
  </xsl:variable>

  <xsl:value-of select="concat($date, ' ', $month, ' ', substring($timeStamp, 1, 4))"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Writes out a Trimble Logo ******************* -->
<!-- **************************************************************** -->
<xsl:template name="OutputLogo">
  <w:p>
    <w:r>
      <w:pict>
        <xsl:call-template name="NewLine"/>
        <w:binData w:name="wordml://03000001.png">
iVBORw0KGgoAAAANSUhEUgAAAZAAAABgCAMAAAAEhNRTAAAAAXNSR0IArs4c6QAAAjdQTFRFF1GS
GFWXHlaWFFSVElOTH1eXFlWWHFWVJVmYJVubMV+dK12cIViYLF6dJlycJFqaKVybMF+cN2KfO2Sf
NWGeMmCeOmOePWahPGWgOGOgW3ivUXOrR22nVnWtQGehU3KqX3qwWneuV3WrVXSsUnSsQmqlQ2qk
Sm+nXnmvSG6oQGmkS2+oRmymTXCpQWiiTnGrT3CpXXiuWXasXHitYn2zYHuxZH6zZX+0YXyyb4a4
f5C9Z4C1fo+8dou6cYe3bYS2dIq6boW3eY69aoK1cIe5a4O2c4m5aYG0eI28eo++fI69gJG+gpK+
g5O/gZK/j53GhpjEjp7HjZ3GhpbCiJjEipnDi5rFjJzFipvGhJTAkp/GhZXBkZ7FjZvEiJnDm6nN
narMmKTKm6bKk6DInKfLnqnOmaXLl6PJkqLJlqLIrrbVtL3YpLDRsLfVoqzPsrnXtrzYrLTToKrN
qrPSqbLRtr/ao6zNtLrWpq/RpK3Ot73ZprHSqbLTtbvXuL7aoavOr7bUsbjWrbXUu8Pdv8bfucLe
vcXfvMTet8Dcvsbg0tfq1dnq1trrxs3j0dXp3N7s0NTnytDl297u2t3txczi2dzrw8vjwcjhztPo
y9HmxMvhx87k1Njpyc/mztPm3d/twMfg3uDu8/L2+vv87Oz18PD2+fn7/v7++/z+9vf79fb6+Pj6
7+/19vT56+v08vT48vH39/X65+jy4+Xx4eLu4OHt6ury7u706enx5ufx5Oby5ebw////RuO/GAAA
EcZJREFUeNrtnflDE8cXwIdcJJwCARQjCCjhRjmqgAjK17aoiNaDCq2IV62AYKX6rRf2i0jBBDkE
5KqFAAkk4ZbDzh/33dndJLuT3c0GQk0x8wPszs7Ozr7P7ntv3sxsAPQlr0rAJwIfEF8SA6Qz5t6E
TxxeBOSNEuytM/gE4jVAdCoA/GL0Pol4ExAAJPldPpl4ExAAVGfe+qTiTUAACKiY9MnFm4AAEF4/
5ZOMNwEBQNMw7ZONNwEB0n11RjLfNDMxhdKs2eh25eYpN5PFKnAR8/2a68xU2+1JQcxgLZkVvl3j
hIV9gmGbgQAgy23V9dwryNUEyoOCgiSxcYXnG7vm3Kr8gh861Y2k2D/PX9ukAmvhd54Ecl7BagnI
nREsPh7BKi9RNW07EBBwsUKCZflrjtUtiK/8EnA37V34XEDOYJXHLwoW7w1mF5fe22YgIUWtS3Dm
VYKTyBSxx0R3VS67DSRx4nMBOYsDEX5D3uJAGrYVSETFMpU7XZeocJKaJL/T5APyDwIJvrJkP27o
OQAOJsmw1sqPv/EB+aeAyPL7bHnmB3kBSnlgebyz5AIrzT4g/wgQNdM6vSuIDS3uN64UhHDY304f
kH8ASMJH9nHzOHW0JMhJeAGtPiDbDqSE2+2cnukv8gvWBrNFIv/FB2R7gSjO093T1YHBQX3/mr2z
uhIDJEBZoOu/kbyL2YxyH5DtBKKopbcXkkm7nXLGbrjfFyJpHKyZgH3fRzLacdUHZNuAhIIqenM+
j75KAUNp3VOjnNSHBrhyguEFVxt8QLYHyBtJsW2znL5ILDLwuuNtVC9wPJfkoCVMeTOjNZUClV90
G0jcgg8InbqPr9Jbv9puvBrtFQJQ+J7MX7xJhbZiBuCQ2tGSB/yVP0pKYaa0cCcAyjRWidSTsz4g
dHpsc2ItcfQ1ggaJPT2Sgvy8hUIViPL9C/+bK3c0JYw/tDW7vspMhhonIMnTrBLrUwJBb8PwICu9
XtnJQHTpw/TWA9s1opE+z6e20/SkpHq02kvtU7Pzj+MZT2uC6PjvQycgX0FvSV4GxHhEQs8AMtjj
JIloL82mW34grfcCbcNNf+x1NKbKB8TjQBpA0AjcGCW2eu3a6ASxNx7FJ3ZTY7TtiKrfB8TDQNYy
gKoHVrQRmw49X0LsdYbR1zvwm2MqirV37Mmt203Lt21G+rgPiIeBEHZD1T2SiuJWR+zXKCX2NmLR
liKviRHbbUujKL2Cy1eooGPIn9sIxLjU3fT08WbmHU8ONT5rfqhfdaqx99WD5uZ7+nURQNb095qf
NQ5NbQ6IoVff0PzwYXNHp9ktIDPpAOzSJ2Si7Sz7NTKQYsoAQJbQZrMcM8i092odOuy1hOyc/Ger
QIx9w3pGeqe30HfU9WNiVKAChPUSV+9ildEPfkIlpgZYme96aMfZ8iB39y7keqiiSjsYvpuxq/JQ
AIqUykKj9j83CwIxtJ+KCCVuUBqS+fWgyV0gaw0n0iNVUtJhDT5YWL8uHkgjcdHwY0CLakm1XyMC
Kal8oHlM45hvLYxFSg0uJ5HHTxH5G+rwXOLu1P1bBGL4BigYSSZ/QerGZ1m0NxfYRzjRWlYZBWXV
XrEzZWHIEMKJWmaAR1poG+IxDZX6Ma+/d4wXiBm2ZTFCErL9Y0Y3gJhGy7ESILigVywQFLqSB4Is
9Jpn2iuQtxP7+lradvxdm0HADkZ5cIi8VpyV8LoOgSf6wwDUbxHIdC52f2gSx6sMx80gIAe5Ooav
sUwV6ha1arHciEHyMrPl+LQNeQMPkLyNr7Fx0qALBtFAPp1RcsQhVNcWRAHpD6DKIyBzsY7zLzJe
v4oIKk9NdgOf+6O+yTzxJB4Ah+DMi8zsmS2+ITiQJ9B4myE8EkiSKCCd0NjiPHizG81Y/sgx9Kkc
5gYSrnEue2JGJJDWWJ7QUJpODJAbqGhUAAnE4lBZQLNBF5q64wiVZJL94wpk9IkHZj0VyDsIWdXc
sHgWyAtYxXrdxQPRcc8+yodwRcN1AL3oHEA4U/6iKCC3/XhriNS7BmIqJApKrgYAjZFl1EH+GiWs
ByxJJKNGGb6i5PGWeBbPov3d6S9NngTSrldsDkhg/3VOSchHzRpuGb0UDwT8KAaIYExVPeYSyAf0
+AcMBIPdaLJJqV1l3qJdkEqsym8Rt/FwMIDeTUQIlTsJFAntRo8B8X8UBzYHJKwikFsSv+TziCjH
DSCKVtdAfpEJVpH50RWQYdJlGg0Eocjy/USfl2onORrBrlF2nRRuKVKoZcT+HuRiPUcHSrtNHgKi
jJNsEoicT12EK/ie2VXxQMChGVdAfpW7qKLQ7AJICyp1e3wX8RAhD8qfOou0Hwby3PEUTCsMEZlm
pM8syB2QI7WoI29XUdTvIZWFSU88EPeTsocPSKiG7gMz0l0XQD5FubzgdRdAilChgb+JTncZ8gxJ
B+EyScJ4M2kE/Z/LZ7+F+2yMa8ndP4itJdoZCDk76QkgeNpOIJJWbiD+x7om1z5+hz0amklhIGVO
1QTJMR0WsSwMJBHJcXxFBUA6MiLfEXW0kMeWCGsfTfppxudaKbNK2iEepZwv1JbZ/XYN8NPkZwfi
L+GzARz6RP6aE4iaNhdXsPyngkAGMY87+IrOuvRyHzuzShgIUjupa+NoGhBq2qhC0kwe6iH7iBE9
VDf9YbKjqxP8AxWdyAZ2INR7Rj9E96c+K5DUH9pe303lqCXi+xcdNenigITZ/NMPmAk9ahYCcoqd
HUD1cgxFbNYWQSCIaS7sRUBQ2NZU8Tt5pJn2VkLoMdqZ/mdlOdo0bV75kxXKneqh63+Odq4xzX7a
E9PnA1JC3q7OuW+WR6qK1TRRQA7bl5AdwYqvCAAZZLsUsmd0HRa209jiEsgp2IeAKFEAzIjEbaq0
605ZgT0sZjCbzY74wWIy1cJ3aOc6u4E5euNnApJHS/IH/ICGvo0WUUAc4fcq7Ei9ABCslix7R/IG
WzougZRSQMBlOtt8jnl+1O01zpOp6RDqUQ4gwK+0e8tA/DO1MblpuxV0cFEUEL8eusqXmCmVjdAH
uiTuAfldwdFmbiBr4XzGoo/lrgV0iwUSMEpZjFKsedE/fmAqIfPAV+itM5KWPH6WCwhhQItXtwQk
9vroxpzVMLn8viU+VnxPfZSusg2Tu8L2nnfK3QMyiJUPN/MCaWVnSt477p1t0+6LBaIg6zVwdGqV
OTcG+8hZJH2DVRkykIlWAzZK7W+Vx4FUMzwD08aMG8FFKg0F8gDpchNIfwjHFbiBnMMULSM8nMw6
clKkUQdXSc1v+pZbkwema1NSUuh1CzVEwWnCcipHOJTk1lXWNaezPxeQvl2Y7vuNFwjmL2gZdrSY
dSTOIgAEubNps6Tbe5RuxbwLG0u2GBmsHwE4RJ1S7lmjnmz1GiD4G0JGGDmBrKqxOhitZ3cYg98K
AEFB0Oj1jwSQcHIxCJKkZb9LIArkYvcpwGOyHmMJ8xlKqduq21sGvRfIKT4gw1ivMFHXr6PTB2yV
75AAkBxkfnTLKuBPdkCePkJ/F5JdEkFrEaxZeZSenGCM/XiiY1jkxUCO8gFpxhw7SYjKlkIwF6NJ
AMhpVGDwkwqN4UA4EiQnO3prX7kCEom+ItBOTzj5ZHf4PBM68WYgcbM8QKqA6HRLAEg9KnCzVxmM
AvVzWgBCSTM9Xa5wUekrRj3v6TxPBRe9GsgiD5DT4oGUCwAhIyAJ3fIL9nZFklMCjA1q8ZVS3V+P
hd+9GohmlQfISfFAigSALKEbDWnMRoZ/mIrFKEmtBT+WSoUqjWXUg4aBPThA5dVAwvt4gBz3DBCI
eh2KYuQtGWyf0pD/TNpqY2uWQKV5pGs6gYJts2og2+fBIVyvBqLWcQMxJ3sIyFPyKuhG/rC/EdIS
qpu92JzD85aE15BNtpxFY+svFdpm1x8o2iFAose5gRhzPQRkCUX8VSj+H8NUSO20HIbLgp0rjL5J
zxH6HfV+Zi/VilkkskOAZEzwqKwiDwGBJ9CNjOD3oDhtW6K09qQsTW0fn/IPSynrsH/XanQQLtZp
GiH8coBkWbdu1P8jCKRHQQG5i50VVWWbKgcNK4MPqy5dvnz+u/o/dCzlZHx9GKRZviQg8UYeIHgd
mdeuXeZO1W2CQNBUOQTE2UvYU8k/Z9tUh3yxrlwJNV3lywGC1mlwArmDFUyG7idqfcg7KQJiSeR4
t0JOD3KOTlla88A1+OYk0mRJi18UkIt8QBow/2efcbNAjN8gIOsp3PpOc+73D+yPlG40VaOyZ2up
tjbDnQzEKfxezwekG/tMYrpps0Bgj1I+wjGnyH4zkenFFc8GR/R6/cjzO6fjo1BURapWUsG0xMUd
DWQMW1lATqzjBGLFJsntmt40EHhNSbi962mCngG9JIbei3j6K7UR9AruaCBPsMmp6gU+IGTgnJEk
7CX8H+/+aRYNZOoUil91hYt12wK+34BfU5vX4E4EEmOXXQsWVM+DvEDwcG8N6wYqQNDhW+MigUA9
ORgyECwKR9DZXgiXKd2abd6RQFLs7uUx7MgdfiDdQm7WHJrnIAs42mQRBaQ7jRwD7whwjUNeOIq8
XuoWwvvhjgSitK+sOYyJ/g0/kHlsKZ1qhNH+C7bcyDMja0aXQHRyaiLZSLQrHnkjqDZrPunjqVrh
zgRin6LWg7lO2bP8QODP+Cvi+JjOc+b4br7VNRAVyCVHXvsSBHFo20gV1UfNjQx6AXcqEMkAWdqE
T4miFhPwANHhRrjA5vm2sLh+DcUAAbnk8vyFq0G8OA42k86H8R41EU/p3hfP/1VAgPLWsmV+HLcg
Ub1CQJyXs8W3r89P/d3KXm4aSKgyKznJbd1qmFxdR++RZX19HgcCEqhw4l88oyBRP1P26G0htR/y
GO5gIISyz8p2cnLor+zxAVlxWuEjTc1O3IPloa+W3FInpaSkR9eOxyRFV0H4ITn1YJUTEJBKWaGF
p0nOzQusphaafDxDXzSiB+5sIFyMxoWBwJsiKglEsxcuAcKdloHyLqLfmbQEbwNypbDTd3tD/0vZ
f+v9DPbEFeVx8u2xDh2zKcOYZbgzgQiNW9+BLoAsHnANhFyNYDbo5dKORdipDFOAIVgMYknL4vyp
8VJ6laipvUDrb7+b48jTtQxfOGC7G0ml+9+D+ZcAOXyEV5SHZ1wBgf17XPEoon3eTrl0iPgblLQP
3P8UHlvMAwRE/mLr6q39+ezb7ChVKMh6oO96dDk31mHt43sg3KlAmqxJPKJ0dLoElkW3BwnzOGKb
RkgAIaTYKYm7DpIbwNUiPiAAHGpzuM9G+KEISIIlrElaqc2b+oWffweQpA34hvvTGMo6KAIIbFIJ
8dhvH+y2AUnUS/yTQfs5fiBAmthi+3Gj2Uf4ojxp9m9rEO5cIJeIvVEuIoEMJ1/w0xod/CFB6WlH
l9AGJGMuB4DY5WMCQAjzH3W8dcIIF/6HS0FdNmaFcAcD2UWqpf4Mp7amMbW08Mdnxvfz8FDVM1SL
DYgGrXwugSWCQBCTsNzGMqamku+JO9e2ADefBD7PdBQ7UOJ8tjVTDBClLeQ9FsIHBJv3TK1TL7Dt
5tFXq2CLfFe1hdkY/DeoZP9jtdVQz7UKOCj/A7NQl0Q6Rvz1S4cdfuApPE6uuRUAAuT5I/1NLefL
T31T+s2p8orfXm8Y4ZZSa3QKO0XbvgBlqE5lHYi963y2uZj9Xebdz8gXIZOVmR5ju2ddzkHWgSyb
nn2bmM48kJRILg2ooSrXaN7ZJXLF/n0PyaFKLIb6KZlde9pfWGvX7udg4KNOY2sQdOHBfxJ/I+ON
8+m738Iz0jOCQGSlQ3QcxogS9EAysz+svLq6bn/fFtiH1jl+Ps9owcqQA5XTWJ2TNp1gmGQfmbPd
gmGOXc0cOa5ntZVmDLtOdT6+czG/uuZJtwVvjAmrfdV5EGJm9GH+oUCJQqHwl6sPV77+hMvQ3Kcj
bsHcP26E48RjtDS6BEX8sKQvbSEZzdaNsXfDuimraK/U99OrXpZ8P07s/UB8P9/tVUB8P3DvVUAk
+V1fsjS8DYhfjP5LloV3AXmjBHvrDF+yKLwMSGfMvYkvWRBeB8SXfEB8yQfE+9P/AX8d0hScr6bE
AAAAAElFTkSuQmCC</w:binData>
        <v:shape type="#_bitmapID" style="width:300pt;height:72pt">
          <v:imagedata src="wordml://03000001.png" o:title="TrimbleLogo"/>
        </v:shape>
      </w:pict>
    </w:r>
  </w:p>
  <xsl:call-template name="NewLine"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******************** Math script references ******************** -->
<!-- **************************************************************** -->
<msxsl:script language="JavaScript" implements-prefix="math">
  function E(){ return Math.E;}
  function LN2(){ return Math.LN2;}
  function LN10(){ return Math.LN10;}
  function LOG2E(){ return Math.LOG2E;}
  function LOG10E(){ return Math.LOG10E;}
  function PI(){ return Math.PI;}
  function SQRT1_2(){ return Math.SQRT1_2;}
  function SQRT2(){ return Math.SQRT2;}

  function abs(arg){ return Math.abs(arg);}
  function acos(arg){ return Math.acos(arg);}
  function asin(arg){ return Math.asin(arg);}
  function atan(arg){ return Math.atan(arg);}
  function atan2(arg1, arg2){ return Math.atan2(arg1, arg2);}
  function ceil(arg){ return Math.ceil(arg);}
  function cos(arg){ return Math.cos(arg);}
  function exp(arg){ return Math.exp(arg);}
  function floor(arg){ return Math.floor(arg);}
  function log(arg){ return Math.log(arg);}
  function pow(arg1, arg2){ return Math.pow(arg1, arg2);}
  function random(){ return Math.random();}
  function round(arg){ return Math.round(arg);}
  function sin(arg){ return Math.sin(arg);}
  function sqrt(arg){ return Math.sqrt(arg);}
  function tan(arg){ return Math.tan(arg);}
  function log10(arg) {return Math.log(arg) / Math.log(10);}
</msxsl:script>


<msxsl:script language="JavaScript" implements-prefix="file">
  function CheckFileExists(fileName)
  {
    var fileSys
    fileSys = new ActiveXObject("Scripting.FileSystemObject");
    if (fileSys.FileExists(fileName))
    {
      return(true)
    }
    else
    {
      return(false);
    }
  }
</msxsl:script>


<msxsl:script language="JavaScript" implements-prefix="str">
  function LowerCase(stringVal)
  {
    return(stringVal.toLowerCase())
  }
</msxsl:script>


<msxsl:script language="JavaScript" implements-prefix="select">
  function DisplayOptionsDialog(surfacesList, defaultProfilePtsToDisplay, defaultVerticalDisplay, defaultAnnotation,
                                defaultAnnotateEvery, defaultShowGridLines, defaultCompProfileOffsets, defaultClosedScans)
  {
    var fileSys = new ActiveXObject("Scripting.FileSystemObject"); // Create file system object
    var shellObj = new ActiveXObject("WScript.Shell");             // Create script shell object
    var tempFolder = shellObj.ExpandEnvironmentStrings("%TEMP%");  // Get Windows temp folder

    // Create a HTML Application file that can be executed to bring up a form allowing the
    // selection of a surface.
    var htaFile = fileSys.CreateTextFile(tempFolder + "\\OptionsDialog.hta", true);  // Create temporary hta file
    htaFile.WriteLine("&lt;!doctype html&gt;");
    htaFile.WriteLine("");
    htaFile.WriteLine("&lt;html&gt;");
    htaFile.WriteLine("&lt;head&gt;");
    htaFile.WriteLine("&lt;title&gt;Seçenekler&lt;/title&gt;");
    htaFile.WriteLine("&lt;HTA:APPLICATION");
    htaFile.WriteLine("     ID=\"objTest\"");
    htaFile.WriteLine("     APPLICATIONNAME=\"OptionsDialog\"");
    htaFile.WriteLine("     SCROLL=\"no\"");
    htaFile.WriteLine("     SINGLEINSTANCE=\"yes\"");
    htaFile.WriteLine("     maximizeButton=\"no\"");
    htaFile.WriteLine("     showInTaskbar=\"no\"");
    htaFile.WriteLine("/&gt;");
    htaFile.WriteLine("&lt;/head&gt;");
    htaFile.WriteLine("");

    htaFile.WriteLine("&lt;SCRIPT LANGUAGE=\"VBScript\"&gt;");
    htaFile.WriteLine("");
    htaFile.WriteLine("  dim fso, shellObj, tempFolder, result, surfNames(50), surfaceCount");
    htaFile.WriteLine("  Set shellObj = CreateObject(\"WScript.Shell\")");
    htaFile.WriteLine("  tempFolder = shellObj.ExpandEnvironmentStrings(\"%TEMP%\")");
    htaFile.WriteLine("  Set fso = CreateObject(\"Scripting.FileSystemObject\")");
    htaFile.WriteLine("");
    htaFile.WriteLine("  Sub Window_onLoad");
    htaFile.WriteLine("    window.resizeTo 610,490");
    htaFile.WriteLine("");
    htaFile.WriteLine("    strComputer = \".\"");
    htaFile.WriteLine("    Set objWMIService = GetObject(\"Winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")");
    htaFile.WriteLine("    Set colItems = objWMIService.ExecQuery(\"Select * From Win32_DesktopMonitor\")");
    htaFile.WriteLine("    For Each objItem in colItems");
    htaFile.WriteLine("        If objItem.Availability = 3 then");
    htaFile.WriteLine("            intHorizontal = objItem.ScreenWidth");
    htaFile.WriteLine("            intVertical = objItem.ScreenHeight");
    htaFile.WriteLine("        End If");
    htaFile.WriteLine("    Next");
    htaFile.WriteLine("    intLeft = (intHorizontal - 610) / 2");
    htaFile.WriteLine("    intTop = (intVertical - 490) / 2");
    htaFile.WriteLine("    window.moveTo intLeft, intTop");
    htaFile.WriteLine("  End Sub");
    htaFile.WriteLine("");
    htaFile.WriteLine("  Function CloseWindow");
    htaFile.WriteLine("    dim file");
    htaFile.WriteLine("    Set file = fso.OpenTextFile(tempFolder &amp; \"\\result.txt\", 2, True)");
    htaFile.WriteLine("    file.Write -1");
    htaFile.WriteLine("    file.Close");
    htaFile.WriteLine("    window.Close");
    htaFile.WriteLine("  End Function");
    htaFile.WriteLine("");
    htaFile.WriteLine("  Function ReturnResult");
    htaFile.WriteLine("    dim file");
    htaFile.WriteLine("    Set file = fso.OpenTextFile(tempFolder &amp; \"\\result.txt\", 2, True)");

    htaFile.WriteLine("    file.Write txlFileName.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write surfNames(SurfaceChooser.selectedIndex)");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write startStation.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write endStation.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write profilePointsToDisplay.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write outputVerticalValuesAs.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write annotateWithChooser.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write annotateEveryChooser.Value");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write showGridLinesOption.checked");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write computeProfileOffsetsOption.checked");
    htaFile.WriteLine("    file.Write \"|\"");

    htaFile.WriteLine("    file.Write closedScansOption.checked");

    htaFile.WriteLine("    file.Close");
    htaFile.WriteLine("    window.Close");
    htaFile.WriteLine("  End Function");

    htaFile.WriteLine("");
    htaFile.WriteLine("  Function TxlFileChanged");
    htaFile.WriteLine("    ReadSurfaceNames");
    htaFile.WriteLine("    count = SurfaceChooser.length");
    htaFile.WriteLine("    For i = count - 1 To 0 Step -1");
    htaFile.WriteLine("      SurfaceChooser.remove(i)");
    htaFile.WriteLine("    Next");
    htaFile.WriteLine("    For j = 0 to surfaceCount");
    htaFile.WriteLine("      Set opt = document.CreateElement(\"option\")");
    htaFile.WriteLine("      opt.text = surfNames(j)");
    htaFile.WriteLine("      SurfaceChooser.Add opt, j");
    htaFile.WriteLine("    Next");
    htaFile.WriteLine("  End Function");

    htaFile.WriteLine("");
    htaFile.WriteLine("  Function ReadSurfaceNames");
    htaFile.WriteLine("    dim file, line, surfPending, haveSurface");
    htaFile.WriteLine("    surfaceCount = 0");
    htaFile.WriteLine("    surfPending = False");
    htaFile.WriteLine("    Set file = fso.OpenTextFile(txlFileName.Value, 1, True)");
    htaFile.WriteLine("      Do While not file.AtEndOfStream");
    htaFile.WriteLine("        line = file.Readline");
    htaFile.WriteLine("        line = Trim(line)");
    htaFile.WriteLine("");
    htaFile.WriteLine("        If surfPending Then");
    htaFile.WriteLine("          If InStr(line, \"&lt;Name&gt;\") > 0 Then");
    htaFile.WriteLine("            line = Replace(line, \"&lt;Name&gt;\", \"\")");
    htaFile.WriteLine("            line = Replace(line, \"&lt;/Name&gt;\", \"\")");
    htaFile.WriteLine("            haveSurface = False");
    htaFile.WriteLine("            If surfaceCount > 0 Then");
    htaFile.WriteLine("              For i = 0 To surfaceCount - 1");
    htaFile.WriteLine("                If StrComp(surfNames(i), line, 1) = 0 Then");
    htaFile.WriteLine("                  haveSurface = True");
    htaFile.WriteLine("                End If");
    htaFile.WriteLine("              Next");
    htaFile.WriteLine("            End If");
    htaFile.WriteLine("            If not haveSurface Then");
    htaFile.WriteLine("              surfNames(surfaceCount) = line");
    htaFile.WriteLine("              surfaceCount = surfaceCount + 1");
    htaFile.WriteLine("            End If");
    htaFile.WriteLine("          End If");
    htaFile.WriteLine("        End If");
    htaFile.WriteLine("");
    htaFile.WriteLine("        If InStr(line, \"&lt;TemplateSurface&gt;\") > 0 Then");
    htaFile.WriteLine("          surfPending = True");
    htaFile.WriteLine("        Else");
    htaFile.WriteLine("          surfPending = False");
    htaFile.WriteLine("        End If");
    htaFile.WriteLine("      Loop");
    htaFile.WriteLine("    file.Close");
    htaFile.WriteLine("");
    htaFile.WriteLine("    surfaceCount = surfaceCount - 1");
    htaFile.WriteLine("  End Function");
    htaFile.WriteLine("&lt;/SCRIPT&gt;");

    htaFile.WriteLine("");
    htaFile.WriteLine("&lt;body&gt;");
    htaFile.WriteLine("");
    htaFile.WriteLine("&lt;font face=\"Arial\"&gt;");
    htaFile.WriteLine("&lt;small&gt;")

    htaFile.WriteLine("&lt;table borders=\"0\" width=\"100%\" cellspacing=\"8\"&gt;");

    // Input field for txl file name
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.Write("Trimble tünel dosyası (*.txl):");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.WriteLine("&lt;input type=\"file\" name=\"txlFileName\" size=\"40\" onChange=\"TxlFileChanged\"&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Drop-down list for selecting surface - will be updated based on the txl file selected
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.Write("Tabaka:");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    // Add the surface names from the passed in node set as select element option elements
    htaFile.WriteLine("&lt;select size=\"1\" name=\"SurfaceChooser\"&gt;");
    for (var i = 0; i &lt; surfacesList.length; i++)
    {
      htaFile.Write("  &lt;option value=\"");
      htaFile.Write(i);
      htaFile.Write("\"&gt;");
      htaFile.Write(surfacesList.item(i).firstChild.nodeValue);
      htaFile.WriteLine("&lt;/option&gt;");
    }
    htaFile.WriteLine("&lt;/select&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Input field for optional start station
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.Write("Başlangıç istasyonu (opsiyonel):");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.Write("&lt;input type=\"text\" name=\"startStation\"&gt;&lt;/input&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Input field for optional end station
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.Write("Bitiş istasyonu (opsiyonel):");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.Write("&lt;input type=\"text\" name=\"endStation\"&gt;&lt;/input&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Drop-down list for selecting which profile points to display
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.WriteLine("&lt;label&gt;Gösterilecek kesit noktaları:&lt;/label&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    // Add the 'Profile points to display' selection option elements
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.WriteLine("&lt;select size=\"1\" name=\"profilePointsToDisplay\"&gt;");
      // First option
      htaFile.Write("  &lt;option value=\"0\"");
      if ( defaultProfilePtsToDisplay == 1 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kesitteki tüm ölçülen noktalar&lt;/option&gt;");
      // Second option
      htaFile.Write("  &lt;option value=\"1\"");
      if ( defaultProfilePtsToDisplay == 2 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kesitteki son ölçülen noktalar&lt;/option&gt;");

    htaFile.WriteLine("&lt;/select&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Drop-down list for selecting what to display for vertical values
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.WriteLine("&lt;label&gt;Düşey değerlerin gösterimi:&lt;/label&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    // Add the 'Output vertical values as' selection option elements
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.WriteLine("&lt;select size=\"1\" name=\"outputVerticalValuesAs\"&gt;");
      // First option
      htaFile.Write("  &lt;option value=\"0\"");
      if ( defaultVerticalDisplay == 1 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kotlar&lt;/option&gt;");
      // Second option
      htaFile.Write("  &lt;option value=\"1\"");
      if ( defaultVerticalDisplay == 2 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Ofsetler&lt;/option&gt;");

    htaFile.WriteLine("&lt;/select&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Drop-down list for selecting what points should be annotated with
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.WriteLine("&lt;label&gt;Kesitteki nokta gösterimi:&lt;/label&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    // Add the 'Annotate profile points with' selection option elements
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.WriteLine("&lt;select size=\"1\" name=\"annotateWithChooser\"&gt;");
      // First option
      htaFile.Write("  &lt;option value=\"0\"");
      if ( defaultAnnotation == 1 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Boş&lt;/option&gt;");
      // Second option
      htaFile.Write("  &lt;option value=\"1\"");
      if ( defaultAnnotation == 2 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kazı/Dolgu&lt;/option&gt;");
      // Third option
      htaFile.Write("  &lt;option value=\"2\"");
      if ( defaultAnnotation == 3 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Nokta no&lt;/option&gt;");
    htaFile.WriteLine("&lt;/select&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Drop-down list for selecting which points should be annotated
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td&gt;");
    htaFile.WriteLine("&lt;label&gt;Gösterim:&lt;/label&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    // Add the 'Annotate' selection option elements
    htaFile.WriteLine("&lt;td align=\"right\"&gt;");
    htaFile.WriteLine("&lt;select size=\"1\" name=\"annotateEveryChooser\"&gt;");
      // First option
      htaFile.Write("  &lt;option value=\"0\"");
      if ( defaultAnnotateEvery == 1 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Tüm kesit noktaları&lt;/option&gt;");
      // Second option
      htaFile.Write("  &lt;option value=\"1\"");
      if ( defaultAnnotateEvery == 2 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kesitteki 2 noktada bir&lt;/option&gt;");
      // Third option
      htaFile.Write("  &lt;option value=\"2\"");
      if ( defaultAnnotateEvery == 3 )
      {
        htaFile.Write(" selected");
      }
      htaFile.WriteLine("&gt;Kesitteki 5 noktada bir&lt;/option&gt;");
    htaFile.WriteLine("&lt;/select&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Checkbox option for 'Show grid lines'
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td colspan=\"2\"&gt;");
    htaFile.Write("&lt;input type=\"checkbox\" name=\"showGridLinesOption\"");
    if ( defaultShowGridLines )
      htaFile.Write(" checked");
    htaFile.WriteLine("&gt;");
    htaFile.Write("Karelaj göster");
    htaFile.WriteLine("&lt;/input&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Checkbox option for 'Compute profile offsets'
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td colspan=\"2\"&gt;");
    htaFile.Write("&lt;input type=\"checkbox\" name=\"computeProfileOffsetsOption\"");
    if ( defaultCompProfileOffsets )
      htaFile.Write(" checked");
    htaFile.WriteLine("&gt;");
    htaFile.Write("As-built güzergah ofsetlerini hesapla (dairesel kesitler için)");
    htaFile.WriteLine("&lt;/input&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    // Checkbox option for 'Tunnel scans are closed'
    htaFile.WriteLine("&lt;tr&gt;");
    htaFile.WriteLine("&lt;td colspan=\"2\"&gt;");
    htaFile.Write("&lt;input type=\"checkbox\" name=\"closedScansOption\"");
    if ( defaultClosedScans )
      htaFile.Write(" checked");
    htaFile.WriteLine("&gt;");
    htaFile.Write("Her tünel kesitini kapalı kesit yap");
    htaFile.WriteLine("&lt;/input&gt;");
    htaFile.WriteLine("&lt;/td&gt;");
    htaFile.WriteLine("&lt;/tr&gt;");
    htaFile.WriteLine("");

    htaFile.WriteLine("&lt;/table&gt;");

    htaFile.WriteLine("&lt;/small&gt;")
    htaFile.WriteLine("&lt;/font&gt;")

    htaFile.WriteLine("&lt;br/&gt;");
    htaFile.WriteLine("&lt;center&gt;");
    htaFile.WriteLine("  &lt;input type=\"button\" value=\"     OK     \" name=\"btnOK\" onClick=\"ReturnResult\" style=\"margin-right: 30px\"&gt;");
    htaFile.WriteLine("  &lt;input type=\"button\" value=\"Cancel\" name=\"btnCancel\" onClick=\"CloseWindow\"&gt;");
    htaFile.WriteLine("&lt;/center&gt;");
    htaFile.WriteLine("");
    htaFile.WriteLine("&lt;/body&gt;");
    htaFile.WriteLine("");
    htaFile.WriteLine("&lt;/html&gt;");
    htaFile.Close();

    // Run the hta file
    shellObj.Run(tempFolder + "\\OptionsDialog.hta", 1, true);

    // Fetch the returned result from the file result.txt in the Windows temp folder
    var result = -1;
    if ( fileSys.FileExists(tempFolder + "\\result.txt") )
    {
      var resultFile = fileSys.OpenTextFile(tempFolder + "\\result.txt");
      result = resultFile.ReadLine();
      resultFile.Close();
      // Clean up by deleting the result file created in the Windows temp folder
      fileSys.DeleteFile(tempFolder + "\\result.txt", true);
    }

    // Clean up by deleting the hta file created in the Windows temp folder
    fileSys.DeleteFile(tempFolder + "\\OptionsDialog.hta", true);

    return(result);
  }
</msxsl:script>


<!-- **************************************************************** -->
<!-- *************** Return Formatted Station Value ***************** -->
<!-- **************************************************************** -->
<xsl:template name="FormatStationVal">
  <xsl:param name="stationVal"/>
  <xsl:param name="zoneVal" select="''"/>
  <xsl:param name="definedFmt" select="''"/>
  <xsl:param name="stationIndexIncrement" select="''"/>
  <xsl:param name="decPlDefnStr" select="''"/>
  <xsl:param name="includeUnitsAbbrev" select="'false'"/>
  <xsl:param name="distUnitAbbrev" select="''"/>

  <xsl:variable name="decPl">
    <xsl:choose>
      <xsl:when test="$decPlDefnStr != ''">
        <xsl:value-of select="$decPlDefnStr"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$DecPl3"/>  <!-- Default to 3 decimal places -->
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="string(number($stationVal)) = 'NaN'">
      <xsl:value-of select="format-number($stationVal, $decPl, 'Standard')"/>  <!-- Return appropriate formatted null value -->
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="formatStyle">
        <xsl:choose>
          <xsl:when test="$definedFmt = ''">
            <xsl:value-of select="/JOBFile/Environment/DisplaySettings/StationingFormat"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$definedFmt"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="stnIndexIncrement">
        <xsl:choose>
          <xsl:when test="string(number($stationIndexIncrement)) = 'NaN'">
            <xsl:value-of select="/JOBFile/Environment/DisplaySettings/StationIndexIncrement"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$stationIndexIncrement"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="stnVal" select="format-number($stationVal * $DistConvFactor, $decPl, 'Standard')"/>
      <xsl:variable name="signChar">
        <xsl:if test="$stnVal &lt; 0.0">-</xsl:if>
      </xsl:variable>

      <xsl:variable name="absStnVal" select="concat(substring('-',2 - ($stnVal &lt; 0)), '1') * $stnVal"/>

      <xsl:variable name="intPart" select="substring-before(format-number($absStnVal, $DecPl3, 'Standard'), '.')"/>
      <xsl:variable name="decPart" select="substring-after($stnVal, '.')"/>

      <xsl:if test="$formatStyle = '1000.0'">
        <xsl:value-of select="$stnVal"/>
      </xsl:if>

      <xsl:if test="$formatStyle = '10+00.0'">
        <xsl:choose>
          <xsl:when test="string-length($intPart) &gt; 2">
            <xsl:value-of select="concat($signChar, substring($intPart, 1, string-length($intPart) - 2),
                                         '+', substring($intPart, string-length($intPart) - 1, 2))"/>
            <xsl:if test="$decPart != ''">
              <xsl:text>.</xsl:text>
              <xsl:value-of select="$decPart"/>
            </xsl:if>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat($signChar, '0+', substring('00', 1, 2 - string-length($intPart)), $intPart)"/>
            <xsl:if test="$decPart != ''">
              <xsl:text>.</xsl:text>
              <xsl:value-of select="$decPart"/>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>

      <xsl:if test="$formatStyle = '1+000.0'">
        <xsl:choose>
          <xsl:when test="string-length($intPart) &gt; 3">
            <xsl:value-of select="concat($signChar, substring($intPart, 1, string-length($intPart) - 3),
                                         '+', substring($intPart, string-length($intPart) - 2, 3))"/>
            <xsl:if test="$decPart != ''">
              <xsl:text>.</xsl:text>
              <xsl:value-of select="$decPart"/>
            </xsl:if>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat($signChar, '0+', substring('000', 1, 3 - string-length($intPart)), $intPart)"/>
            <xsl:if test="$decPart != ''">
              <xsl:text>.</xsl:text>
              <xsl:value-of select="$decPart"/>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>

      <xsl:if test="$formatStyle = 'StationIndex'">
        <xsl:variable name="intIncrement" select="format-number($stnIndexIncrement * $DistConvFactor, $DecPl0, 'Standard')"/>

        <xsl:variable name="afterPlusDigits" select="string-length($intIncrement)"/>
        <xsl:variable name="afterPlusZeros" select="substring('000000000000', 1, $afterPlusDigits)"/>
        <xsl:variable name="afterPlusFmt" select="concat($afterPlusZeros, '.', substring-after($decPl, '.'))"/>

        <xsl:variable name="beforePlus" select="floor($absStnVal div ($stnIndexIncrement * $DistConvFactor))"/>
        <xsl:variable name="afterPlus" select="$absStnVal - $beforePlus * ($stnIndexIncrement * $DistConvFactor)"/>
        <xsl:value-of select="concat($signChar, format-number($beforePlus, '#0'), '+', format-number($afterPlus, $afterPlusFmt, 'Standard'))"/>
      </xsl:if>

      <xsl:if test="$includeUnitsAbbrev != 'false'">
        <xsl:value-of select="$distUnitAbbrev"/>
      </xsl:if>

      <xsl:if test="$zoneVal != ''">
        <xsl:value-of select="':'"/>
        <xsl:value-of select="format-number($zoneVal,'0')"/>
      </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************** New Line Output ************************* -->
<!-- **************************************************************** -->
<xsl:template name="NewLine">
  <xsl:text>&#10;</xsl:text>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Determine if 2 line segments cross each other ********* -->
<!-- **************************************************************** -->
<xsl:template name="LinesCross">
  <xsl:param name="x1"/>
  <xsl:param name="y1"/>
  <xsl:param name="x2"/>
  <xsl:param name="y2"/>
  <xsl:param name="x3"/>
  <xsl:param name="y3"/>
  <xsl:param name="x4"/>
  <xsl:param name="y4"/>

  <xsl:variable name="param1" select="(($x4 - $x3) * ($y1 - $y3) - ($y4 - $y3) * ($x1 - $x3)) div
                                      (($y4 - $y3) * ($x2 - $x1) - ($x4 - $x3) * ($y2 - $y1))"/>

  <xsl:variable name="param2" select="(($x2 - $x1) * ($y1 - $y3) - ($y2 - $y1) * ($x1 - $x3)) div
                                      (($y4 - $y3) * ($x2 - $x1) - ($x4 - $x3) * ($y2 - $y1))"/>

  <xsl:choose>
    <xsl:when test="($param1 &gt;= 0) and ($param1 &lt;= 1) and
                    ($param2 &gt;= 0) and ($param2 &lt;= 1)">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Intersection point for 2 lines ***************** -->
<!-- **************************************************************** -->
<xsl:template name="IntersectionPointForTwoLines">
  <xsl:param name="x1"/>
  <xsl:param name="y1"/>
  <xsl:param name="x2"/>
  <xsl:param name="y2"/>
  <xsl:param name="x3"/>
  <xsl:param name="y3"/>
  <xsl:param name="x4"/>
  <xsl:param name="y4"/>

  <!-- Return a node set with the x (east) and y (north) values of the intersection point -->
  
  <xsl:variable name="param1" select="(($x4 - $x3) * ($y1 - $y3) - ($y4 - $y3) * ($x1 - $x3)) div
                                      (($y4 - $y3) * ($x2 - $x1) - ($x4 - $x3) * ($y2 - $y1))"/>

  <xsl:element name="x" namespace="">
    <xsl:value-of select="$x1 + $param1 * ($x2 - $x1)"/>
  </xsl:element>
  
  <xsl:element name="y" namespace="">
    <xsl:value-of select="$y1 + $param1 * ($y2 - $y1)"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Computes the position of a point projected onto a line **** -->
<!-- **************************************************************** -->
<xsl:template name="PointToLineProjectionPoint">
  <xsl:param name="x1"/>
  <xsl:param name="y1"/>
  <xsl:param name="x2"/>
  <xsl:param name="y2"/>
  <xsl:param name="xPt"/>
  <xsl:param name="yPt"/>

  <xsl:variable name="sqrdLineLength" select="($x2 - $x1) * ($x2 - $x1) + ($y2 - $y1) * ($y2 - $y1)"/>

  <xsl:choose>
    <xsl:when test="$sqrdLineLength &gt; 0.000000001">
      <xsl:variable name="u" select="(($xPt - $x1) * ($x2 - $x1) + ($yPt - $y1) * ($y2 - $y1)) div $sqrdLineLength"/>

      <xsl:element name="x" namespace="">
        <xsl:value-of select="$x1 + $u * ($x2 - $x1)"/>
      </xsl:element>

      <xsl:element name="y" namespace="">
        <xsl:value-of select="$y1 + $u * ($y2 - $y1)"/>
      </xsl:element>
    </xsl:when>

    <xsl:otherwise>  <!-- Return null coordinates for projected point -->
      <xsl:element name="x" namespace=""></xsl:element>
      <xsl:element name="y" namespace=""></xsl:element>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>


<!-- **************************************************************** -->
<!-- **** Compute the dot product for the supplied point and line *** -->
<!-- **************************************************************** -->
<xsl:template name="CrossProduct">
  <xsl:param name="pointX"/>
  <xsl:param name="pointY"/>
  <xsl:param name="startX"/>
  <xsl:param name="startY"/>
  <xsl:param name="endX"/>
  <xsl:param name="endY"/>

  <!-- Use the cross product to determine if the point is left of, right of or on    -->
  <!-- the line:                                                                     -->
  <!-- Less than 0 indicates a point on the left (of line start to end)              -->
  <!-- Greater than 0 indicates a point on the right (of line start to end)          -->
  <!-- Equal to 0 indicates a point on the line                                      -->

  <xsl:value-of select="($endY - $startY) * ($pointX - $startX) - ($endX - $startX) * ($pointY - $startY)"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Determine if 2 rectangles overlap each other ********* -->
<!-- **************************************************************** -->
<xsl:template name="RectanglesOverlap1">
  <xsl:param name="rect1"/>
  <xsl:param name="rect2"/>

  <!-- The rect1 and rect2 parameters must be node-set variables consisting -->
  <!-- of 4 vertices with the following element structure.                  -->
  <!--   <vertex> -->
  <!--     <x> -->
  <!--     <y> -->
  <!--   </vertex> -->

  <!-- This routine will determine if the 2 rectangles (boundaries of two text elements) -->
  <!-- overlap by checking whether each of the lines in rect1 crosses each of the lines  -->
  <!-- in rect2.  If any lines cross each other the function will return true.           -->
  <xsl:variable name="test">
    <xsl:for-each select="msxsl:node-set($rect1)/vertex">
      <xsl:variable name="rect1X1">
        <xsl:choose>
          <xsl:when test="position() = 1">  <!-- On first point grab the last point for other end of line -->
            <xsl:value-of select="msxsl:node-set($rect1)/vertex[last()]/x"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::*[1]/x"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="rect1Y1">
        <xsl:choose>
          <xsl:when test="position() = 1">  <!-- On first point grab the last point for other end of line -->
            <xsl:value-of select="msxsl:node-set($rect1)/vertex[last()]/y"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::*[1]/y"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="rect1X2" select="x"/>
      <xsl:variable name="rect1Y2" select="y"/>

      <xsl:for-each select="msxsl:node-set($rect2)/vertex">
        <xsl:variable name="rect2X1">
          <xsl:choose>
            <xsl:when test="position() = 1">  <!-- On first point grab the last point for other end of line -->
              <xsl:value-of select="msxsl:node-set($rect2)/vertex[last()]/x"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="preceding-sibling::*[1]/x"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="rect2Y1">
          <xsl:choose>
            <xsl:when test="position() = 1">  <!-- On first point grab the last point for other end of line -->
              <xsl:value-of select="msxsl:node-set($rect2)/vertex[last()]/y"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="preceding-sibling::*[1]/y"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="rect2X2" select="x"/>
        <xsl:variable name="rect2Y2" select="y"/>

        <xsl:variable name="crossTest">
          <xsl:call-template name="LinesCross">
            <xsl:with-param name="x1" select="$rect1X1"/>
            <xsl:with-param name="y1" select="$rect1Y1"/>
            <xsl:with-param name="x2" select="$rect1X2"/>
            <xsl:with-param name="y2" select="$rect1Y2"/>
            <xsl:with-param name="x3" select="$rect2X1"/>
            <xsl:with-param name="y3" select="$rect2Y1"/>
            <xsl:with-param name="x4" select="$rect2X2"/>
            <xsl:with-param name="y4" select="$rect2Y2"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:if test="$crossTest = 'true'">x</xsl:if>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="string-length($test) != 0">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Returns node set containing min and max values ******** -->
<!-- **************************************************************** -->
<xsl:template name="GetProfilesMinMaxVals">
  <xsl:param name="showDesignLines">Yes</xsl:param>

  <xsl:variable name="pointsHzSort">
    <xsl:for-each select="JOBFile/FieldBook/TunnelCrossSectionRecord/TunnelPointDeltaRecord">
      <xsl:sort order="ascending" data-type="number" select="HorizontalOffset"/>
      <!-- Check that the referenced observation is not deleted -->
      <xsl:variable name="deleted">
        <xsl:for-each select="key('obsPointID-search', ObservationID)">
          <xsl:value-of select="Deleted"/>
        </xsl:for-each>
      </xsl:variable>
      <xsl:if test="$deleted = 'false'">
        <xsl:copy>
          <xsl:copy-of select="*"/>
        </xsl:copy>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="pointsVtSort">
    <xsl:for-each select="JOBFile/FieldBook/TunnelCrossSectionRecord/TunnelPointDeltaRecord">
      <xsl:sort order="ascending" data-type="number" select="VerticalOffset"/>
      <!-- Check that the referenced observation is not deleted -->
      <xsl:variable name="deleted">
        <xsl:for-each select="key('obsPointID-search', ObservationID)">
          <xsl:value-of select="Deleted"/>
        </xsl:for-each>
      </xsl:variable>
      <xsl:if test="$deleted = 'false'">
        <xsl:copy>
          <xsl:copy-of select="*"/>
        </xsl:copy>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="templatePoints">   <!-- Allow for design template points as well -->
    <xsl:if test="$showDesignLines = 'Yes'">
      <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord">
        <xsl:call-template name="GetTemplateElements">
          <xsl:with-param name="templateName" select="Name"/>
        </xsl:call-template>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>

  <xsl:variable name="offsetLimits">
    <xsl:call-template name="GetAlignmentOffsetLimits"/>
  </xsl:variable>

  <xsl:variable name="templateHzValues">
    <xsl:for-each select="msxsl:node-set($templatePoints)/templateSurface/element">
      <xsl:element name="hzVal">
        <xsl:value-of select="startHz"/>
      </xsl:element>
      <xsl:element name="hzVal">
        <xsl:value-of select="endHz"/>
      </xsl:element>
      <xsl:if test="string(number(midPtHz)) != 'NaN'">
        <xsl:element name="hzVal">
          <xsl:value-of select="midPtHz"/>
        </xsl:element>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="templateHzValuesSort">
    <xsl:for-each select="msxsl:node-set($templateHzValues)/hzVal">
      <xsl:sort order="ascending" data-type="number" select="."/>
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="templateVtValues">
    <xsl:for-each select="msxsl:node-set($templatePoints)/templateSurface/element">
      <xsl:element name="vtVal">
        <xsl:value-of select="startVt"/>
      </xsl:element>
      <xsl:element name="vtVal">
        <xsl:value-of select="endVt"/>
      </xsl:element>
      <xsl:if test="string(number(midPtVt)) != 'NaN'">
        <xsl:element name="vtVal">
          <xsl:value-of select="midPtVt"/>
        </xsl:element>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="templateVtValuesSort">
    <xsl:for-each select="msxsl:node-set($templateVtValues)/vtVal">
      <xsl:sort order="ascending" data-type="number" select="."/>
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </xsl:variable>

  <xsl:element name="minX">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($templateHzValuesSort)/hzVal) = 0">
        <xsl:value-of select="msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[1]/HorizontalOffset"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="(msxsl:node-set($templateHzValuesSort)/hzVal[1] + msxsl:node-set($offsetLimits)/maxLeftOffset ) &lt; msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[1]/HorizontalOffset">
            <xsl:value-of select="msxsl:node-set($templateHzValuesSort)/hzVal[1] + msxsl:node-set($offsetLimits)/maxLeftOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[1]/HorizontalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>

  <xsl:element name="maxX">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($templateHzValuesSort)/hzVal) = 0">
        <xsl:value-of select="msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[last()]/HorizontalOffset"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="(msxsl:node-set($templateHzValuesSort)/hzVal[last()] + msxsl:node-set($offsetLimits)/maxRightOffset) &gt; msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[last()]/HorizontalOffset">
            <xsl:value-of select="msxsl:node-set($templateHzValuesSort)/hzVal[last()] + msxsl:node-set($offsetLimits)/maxRightOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($pointsHzSort)/TunnelPointDeltaRecord[last()]/HorizontalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>

  <xsl:element name="minY">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($templateVtValuesSort)/vtVal) = 0">
        <xsl:value-of select="msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[1]/VerticalOffset"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="(msxsl:node-set($templateVtValuesSort)/vtVal[1] + msxsl:node-set($offsetLimits)/maxDownOffset) &lt; msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[1]/VerticalOffset">
            <xsl:value-of select="msxsl:node-set($templateVtValuesSort)/vtVal[1] + msxsl:node-set($offsetLimits)/maxDownOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[1]/VerticalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>

  <xsl:element name="maxY">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($templateVtValuesSort)/vtVal) = 0">
        <xsl:value-of select="msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[last()]/VerticalOffset"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="(msxsl:node-set($templateVtValuesSort)/vtVal[last()] + msxsl:node-set($offsetLimits)/maxUpOffset) &gt; msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[last()]/VerticalOffset">
            <xsl:value-of select="msxsl:node-set($templateVtValuesSort)/vtVal[last()] + msxsl:node-set($offsetLimits)/maxUpOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($pointsVtSort)/TunnelPointDeltaRecord[last()]/VerticalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Returns node set containing the tunnel profiles ******* -->
<!-- **************************************************************** -->
<xsl:template name="BuildTunnelProfiles">
  <xsl:param name="allProfilesMinMax"/>
  <xsl:param name="gridSizeX">0</xsl:param>
  <xsl:param name="gridSizeY">0</xsl:param>
  <xsl:param name="startStn">0</xsl:param>
  <xsl:param name="endStn">0</xsl:param>
  <xsl:param name="annotatePoints">true</xsl:param>
  <xsl:param name="showDesignLines">Yes</xsl:param>
  <xsl:param name="includePtCodes">false</xsl:param>
  <xsl:param name="computeProfileOffsets">No</xsl:param>
  <xsl:param name="specifiedSurface" select="''"/>

  <xsl:for-each select="JOBFile/FieldBook/TunnelCrossSectionRecord">
    <xsl:sort order="ascending" data-type="number" select="Station"/>
    <xsl:variable name="stn" select="Station"/>
    <xsl:variable name="templateSurface">
      <xsl:choose>
        <xsl:when test="$specifiedSurface != ''">
          <xsl:value-of select="$specifiedSurface"/>
        </xsl:when>
        <xsl:when test="string(TemplateSurface) != ''">
          <xsl:value-of select="TemplateSurface"/>
        </xsl:when>
        <xsl:otherwise>DefaultXSLSurface</xsl:otherwise>  <!-- No surface defined so from pre multiple surface support - set to internal default surface -->
      </xsl:choose>
    </xsl:variable>

    <xsl:if test="(Station &gt;= number($startStn)) and (Station &lt;= number($endStn))">
      <xsl:variable name="stnTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/StationTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/StationTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanStationTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="overbreakTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/OverbreakTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/OverbreakTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanOverbreakTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="underbreakTolerance">
        <xsl:choose>
          <xsl:when test="preceding-sibling::TunnelSettingsRecord[1]/UnderbreakTolerance">
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/UnderbreakTolerance"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="preceding-sibling::TunnelSettingsRecord[1]/ScanUnderbreakTolerance"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="profileDeltas">
        <!-- Ensure we have the first TunnelCrossSectionRecord for a given station and template surface (either   -->
        <!-- the template surface specified in the TunnelCrossSectionRecord or, if there is no template surface   -->
        <!-- specified (an older format file) then the template surface will use the internal 'DefaultXSLSurface' -->
        <!-- name.                                                                                                -->
        <xsl:if test="count(preceding-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                        ((TemplateSurface = $templateSurface) or
                                                                         ((string(TemplateSurface) = '') and
                                                                          ($templateSurface = 'DefaultXSLSurface')))]) = 0">
          <!-- Add the points from the first profile scan at this station if:  -->
          <!-- 1. Outputting all scanned points at this station or             -->
          <!-- 2. Only outputting last scanned points and this is the one and  -->
          <!--    only scan at this station                                    -->
          <xsl:if test="($profilePointsToUse = 'All measured points on profile') or
                        (($profilePointsToUse = 'Last measured points on profile') and
                         (count(following-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                            ((TemplateSurface = $templateSurface) or
                                                                             ((string(TemplateSurface) = '') and
                                                                              ($templateSurface = 'DefaultXSLSurface')))]) = 0))">
            <xsl:for-each select="TunnelPointDeltaRecord">
              <!-- Only add deltas for non-deleted points -->
              <xsl:variable name="obsID" select="ObservationID"/>
              <xsl:if test="/JOBFile/FieldBook/PointRecord[(@ID = $obsID) and (Deleted = 'false')]">
                <xsl:element name="TunnelPointDeltaRecord" namespace="">
                  <xsl:copy-of select="./*"/>
                  <xsl:element name="obsPtName">
                    <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Name"/>
                  </xsl:element>
                  <xsl:if test="$includePtCodes != 'false'">
                    <xsl:element name="obsPtCode">
                      <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Code"/>
                    </xsl:element>
                  </xsl:if>
                </xsl:element>
              </xsl:if>
            </xsl:for-each>
          </xsl:if>

          <xsl:for-each select="following-sibling::TunnelCrossSectionRecord[(Station = $stn) and
                                                                            ((TemplateSurface = $templateSurface) or
                                                                             ((string(TemplateSurface) = '') and
                                                                              ($templateSurface = 'DefaultXSLSurface')))]">
            <!-- Use the same test for each subsequent TunnelCrossSectionRecord -->
            <!-- encountered with the same station value and template surface.  -->
            <xsl:if test="($profilePointsToUse = 'All measured points on profile') or
                          (($profilePointsToUse = 'Last measured points on profile') and
                           (count(following-sibling::TunnelCrossSectionRecord[(Station = $stn) and ((TemplateSurface = $templateSurface) or
                                                                              ((string(TemplateSurface) = '') and ($templateSurface = 'DefaultXSLSurface')))]) = 0))">
              <xsl:for-each select="TunnelPointDeltaRecord">
                <!-- Only add deltas for non-deleted points -->
                <xsl:variable name="obsID" select="ObservationID"/>
                <xsl:if test="/JOBFile/FieldBook/PointRecord[(@ID = $obsID) and (Deleted = 'false')]">
                  <xsl:element name="TunnelPointDeltaRecord" namespace="">
                    <xsl:copy-of select="./*"/>
                    <xsl:element name="obsPtName">
                      <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Name"/>
                    </xsl:element>
                    <xsl:if test="$includePtCodes != 'false'">
                      <xsl:element name="obsPtCode">
                        <xsl:value-of select="/JOBFile/FieldBook/PointRecord[@ID = $obsID]/Code"/>
                      </xsl:element>
                    </xsl:if>
                  </xsl:element>
                </xsl:if>
              </xsl:for-each>
            </xsl:if>
          </xsl:for-each>
        </xsl:if>
      </xsl:variable>

      <xsl:if test="count(msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord) != 0"> <!-- There are some deltas to output -->
        <xsl:variable name="rangeX" select="(msxsl:node-set($allProfilesMinMax)/maxX - msxsl:node-set($allProfilesMinMax)/minX)"/>
        <xsl:variable name="rangeY" select="(msxsl:node-set($allProfilesMinMax)/maxY - msxsl:node-set($allProfilesMinMax)/minY)"/>

        <xsl:variable name="extentXY">
          <xsl:choose>
            <xsl:when test="$rangeX &gt; $rangeY">
              <xsl:value-of select="$rangeX"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$rangeY"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:element name="profile">
          <xsl:element name="tunnelName" namespace="">
            <xsl:value-of select="TunnelName"/>
          </xsl:element>
          <xsl:copy-of select="Station"/>
          <xsl:copy-of select="EquatedStation"/>
          <xsl:element name="TemplateSurface" namespace="">
            <xsl:value-of select="$templateSurface"/>
          </xsl:element>
          <xsl:element name="stationTolerance" namespace="">
            <xsl:value-of select="$stnTolerance"/>
          </xsl:element>
          <xsl:element name="overbreakTolerance" namespace="">
            <xsl:value-of select="$overbreakTolerance"/>
          </xsl:element>
          <xsl:element name="underbreakTolerance" namespace="">
            <xsl:value-of select="$underbreakTolerance"/>
          </xsl:element>

          <xsl:element name="extentXY" namespace="">
            <xsl:value-of select="$extentXY"/>
          </xsl:element>

          <xsl:element name="minX" namespace="">
            <xsl:value-of select="msxsl:node-set($allProfilesMinMax)/minX"/>
          </xsl:element>

          <xsl:element name="minY" namespace="">
            <xsl:value-of select="msxsl:node-set($allProfilesMinMax)/minY"/>
          </xsl:element>

          <xsl:variable name="scaleRatio">
            <xsl:variable name="fractionOfGridUsed">
              <xsl:choose>
                <xsl:when test="$annotatePoints = 'true'">0.75</xsl:when>
                <xsl:otherwise>0.9</xsl:otherwise>
              </xsl:choose>
            </xsl:variable>
            <xsl:variable name="scaleRatioX"><xsl:value-of select="$gridSizeX * $fractionOfGridUsed div $rangeX"/></xsl:variable>
            <xsl:variable name="scaleRatioY"><xsl:value-of select="$gridSizeY * $fractionOfGridUsed div $rangeY"/></xsl:variable>
            <xsl:choose>
              <xsl:when test="$scaleRatioX &lt; $scaleRatioY">
                <xsl:value-of select="$scaleRatioX"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="$scaleRatioY"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:element name="scaleRatio" namespace="">
            <xsl:value-of select="$scaleRatio"/>
          </xsl:element>

          <xsl:element name="borderX" namespace="">
            <xsl:value-of select="($gridSizeX - $scaleRatio * $rangeX) div 2"/>
          </xsl:element>

          <xsl:element name="borderY" namespace="">
            <xsl:value-of select="($gridSizeY - $scaleRatio * $rangeY) div 2"/>
          </xsl:element>

          <!-- Now include the design definition at this station -->
          <!-- Put into a node-set variable so that it can be used in the sorting of the measured points -->
          <xsl:variable name="designTemplate">
            <xsl:if test="$showDesignLines = 'Yes'">
              <!-- Get the rotation values that apply at this station -->
              <xsl:variable name="templateRotationVals">
                <xsl:call-template name="GetTemplateRotationValues">
                  <xsl:with-param name="station" select="Station"/>
                </xsl:call-template>
              </xsl:variable>

              <!-- Get the alignment offset values that apply at this station -->
              <xsl:variable name="templateOffsetVals">
                <xsl:call-template name="GetTemplateOffsetValues">
                  <xsl:with-param name="station" select="Station"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="templateWithoutOffsets">
                <xsl:choose>
                  <xsl:when test="msxsl:node-set($templateRotationVals)/rotationAngle != 0">
                    <xsl:variable name="unrotatedTemplate">
                      <xsl:call-template name="ExtractDesignElements">
                        <xsl:with-param name="station" select="Station"/>
                      </xsl:call-template>
                    </xsl:variable>

                    <xsl:call-template name="ComputeRotatedTemplate">
                      <xsl:with-param name="unrotatedTemplate" select="$unrotatedTemplate"/>
                      <xsl:with-param name="templateRotationVals" select="$templateRotationVals"/>
                    </xsl:call-template>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:call-template name="ExtractDesignElements">
                      <xsl:with-param name="station" select="Station"/>
                    </xsl:call-template>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>

              <xsl:call-template name="ApplyAlignmentOffsets">
                <xsl:with-param name="template" select="$templateWithoutOffsets"/>
                <xsl:with-param name="templateOffsetVals" select="$templateOffsetVals"/>
              </xsl:call-template>
            </xsl:if>
          </xsl:variable>

          <xsl:variable name="hzOffsets">
            <xsl:for-each select="msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord">
              <xsl:sort data-type="number" order="ascending" select="HorizontalOffset"/>
              <xsl:element name="offset">
                <xsl:value-of select="HorizontalOffset"/>
              </xsl:element>
            </xsl:for-each>
          </xsl:variable>

          <xsl:variable name="vtOffsets">
            <xsl:for-each select="msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord">
              <xsl:sort data-type="number" order="ascending" select="VerticalOffset"/>
              <xsl:element name="offset">
                <xsl:value-of select="VerticalOffset"/>
              </xsl:element>
            </xsl:for-each>
          </xsl:variable>

          <xsl:variable name="hzCentroid" select="(msxsl:node-set($hzOffsets)/offset[1] + msxsl:node-set($hzOffsets)/offset[last()]) div 2.0"/>
          <xsl:variable name="vtCentroid" select="(msxsl:node-set($vtOffsets)/offset[1] + msxsl:node-set($vtOffsets)/offset[last()]) div 2.0"/>

          <!-- Hold all the tunnel deltas in a variable so that the distance around the design  -->
          <!-- or the direction from the centroid position to each delta position can be        -->
          <!-- computed for use in sorting the positions.                                       -->
          <xsl:variable name="tunnelDeltas">
            <xsl:for-each select="msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord">
              <xsl:copy>
                <xsl:copy-of select="* | @*"/>
                <xsl:element name="name">
                  <xsl:value-of select="obsPtName"/>
                </xsl:element>

                <xsl:choose>
                  <xsl:when test="$showDesignLines = 'Yes'"> <!-- Sort by distance around the design template -->
                    <xsl:variable name="distAroundAndCalcdDelta">
                      <xsl:call-template name="CalcDistAroundTemplate">
                        <xsl:with-param name="designTemplate" select="$designTemplate"/>
                        <xsl:with-param name="templateSurface" select="$templateSurface"/>
                        <xsl:with-param name="ptHz" select="HorizontalOffset"/>
                        <xsl:with-param name="ptVt" select="VerticalOffset"/>
                      </xsl:call-template>
                    </xsl:variable>
                    <xsl:element name="sortVal">
                      <xsl:value-of select="msxsl:node-set($distAroundAndCalcdDelta)/distAround"/>
                    </xsl:element>
                    <xsl:element name="calcDelta">
                      <xsl:value-of select="msxsl:node-set($distAroundAndCalcdDelta)/calcdDelta"/>
                    </xsl:element>
                  </xsl:when>
                  <xsl:otherwise>  <!-- Compute angle around cross-section from 0° down to use for sorting -->
                    <xsl:variable name="rawDir">
                      <xsl:call-template name="InverseAzimuth">
                        <xsl:with-param name="deltaN" select="VerticalOffset - $vtCentroid"/>
                        <xsl:with-param name="deltaE" select="HorizontalOffset - $hzCentroid"/>
                        <xsl:with-param name="returnInRadians">true</xsl:with-param>
                      </xsl:call-template>
                    </xsl:variable>
                    <!-- Now add 180° (Pi) to the rawDir to end up with angles based on 0° down -->
                    <xsl:element name="sortVal">
                      <xsl:call-template name="RadianAngleBetweenLimits">
                        <xsl:with-param name="anAngle" select="$rawDir + math:PI()"/>
                      </xsl:call-template>
                    </xsl:element>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:copy>
            </xsl:for-each>
          </xsl:variable>

          <!-- Add the tunnel deltas (sorted by distance around design or direction) -->
          <xsl:for-each select="msxsl:node-set($tunnelDeltas)/*">
            <xsl:sort data-type="number" order="ascending" select="sortVal"/>
            <xsl:copy>
              <xsl:copy-of select="* | @*"/>
            </xsl:copy>
          </xsl:for-each>

          <!-- Now include the design definition at this station -->
          <xsl:element name="design">
            <xsl:copy-of select="$designTemplate"/>
          </xsl:element>

          <!-- Output details relating to the position on the alignment                 -->
          <!-- Provides these elements if $computeProfileOffsets = 'Yes':               -->
          <!--   <alignDetails>                                                         -->
          <!--     <templateApplyMethod>Perpendicular or Vertical</templateApplyMethod> -->
          <!--     <grade></grade>                                                      -->
          <!--     <azimuth></azimuth>  (Decimal degrees)                               -->
          <!--     <clCoordinates>                                                      -->
          <!--       <north></north>                                                    -->
          <!--       <east></east>                                                      -->
          <!--       <elevation></elevation>                                            -->
          <!--     </clCoordinates>                                                     -->
          <!--     <meanStn></meanStn>                                                  -->
          <!--   </alignDetails>                                                        -->
          <!-- Otherwise provides these elements:                                       -->
          <!--   <alignDetails>                                                         -->
          <!--     <clCoordinates>                                                      -->
          <!--       <elevation></elevation>                                            -->
          <!--     </clCoordinates>                                                     -->
          <!--   </alignDetails>                                                        -->

          <xsl:variable name="vertAlignment">
            <xsl:copy-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/VerticalAlignment/*"/>
          </xsl:variable>

          <xsl:element name="alignDetails">
            <xsl:choose>
              <xsl:when test="$computeProfileOffsets = 'Yes'"> <!-- Only add these elements if required as the computation is quite intensive -->
                <xsl:element name="templateApplyMethod">  <!-- Either Perpendicular or Vertical -->
                  <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/@templateApplyMethod"/>
                </xsl:element>

                <xsl:element name="grade">
                  <xsl:call-template name="GradeAtStationAsPercentage">
                    <xsl:with-param name="theStation" select="$stn"/>
                    <xsl:with-param name="vertAlignment" select="$vertAlignment"/>
                  </xsl:call-template>
                </xsl:element>

                <xsl:element name="azimuth">
                  <xsl:call-template name="InstantaneousAzimuth">
                    <xsl:with-param name="horizAlignment" select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/HorizontalAlignment"/>
                    <xsl:with-param name="station" select="$stn"/>
                  </xsl:call-template>
                </xsl:element>

                <!-- Compute the centreline coordinates at the average station of the scanned -->
                <!-- cross-section = $stn (design station) + mean DeltaStation                -->
                <xsl:variable name="meanStn" select="$stn + sum(msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord/DeltaStation) div
                                                            count(msxsl:node-set($profileDeltas)/TunnelPointDeltaRecord/DeltaStation)"/>
                
                <xsl:element name="clCoordinates">
                  <xsl:variable name="coords">
                    <xsl:call-template name="PositionAtStation">
                      <xsl:with-param name="horizAlignment" select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/HorizontalAlignment"/>
                      <xsl:with-param name="station" select="$meanStn"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <!-- We only want the north and east components -->
                  <xsl:element name="north">
                    <xsl:value-of select="msxsl:node-set($coords)/north"/>
                  </xsl:element>

                  <xsl:element name="east">
                    <xsl:value-of select="msxsl:node-set($coords)/east"/>
                  </xsl:element>

                  <xsl:element name="elevation">
                    <xsl:call-template name="ElevationAtStation">
                      <xsl:with-param name="theStation" select="$meanStn"/>
                      <xsl:with-param name="vertAlignment" select="$vertAlignment"/>
                    </xsl:call-template>
                  </xsl:element>
                </xsl:element>
                <xsl:element name="meanStn">
                  <xsl:value-of select="$meanStn"/>
                </xsl:element>
              </xsl:when>

              <xsl:otherwise>  <!-- Only need elevation value -->
                <xsl:element name="clCoordinates">
                  <xsl:element name="elevation">
                    <xsl:call-template name="ElevationAtStation">
                      <xsl:with-param name="theStation" select="$stn"/>  <!-- Simply use the design station in this case -->
                      <xsl:with-param name="vertAlignment" select="$vertAlignment"/>
                    </xsl:call-template>
                  </xsl:element>
                </xsl:element>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:element>

          <xsl:if test="$computeProfileOffsets = 'Yes'">
            <!-- Output details relating to the design and computed profile centre        -->
            <!-- Provides elements:                                                       -->
            <!--   <profileOffsets>                                                       -->
            <!--     <hzOffsetComputed></hzOffsetComputed>                                -->
            <!--     <vtOffsetComputed></vtOffsetComputed>                                -->
            <!--     <hzOffsetDesign></hzOffsetDesign>                                    -->
            <!--     <vtOffsetDesign></vtOffsetDesign>                                    -->
            <!--     <hzOffsetDelta></hzOffsetDelta>                                      -->
            <!--     <vtOffsetDelta></vtOffsetDelta>                                      -->
            <!--     <polarDelta></polarDelta>                                            -->
            <!--     <computedRadius></computedRadius>                                    -->
            <!--   </profileOffsets>                                                      -->

            <!-- Also provides a set of elements giving the deltas to the circle formed   -->
            <!-- by the computed radius applied to the computed centre position           -->
            <!--   <calcCircleDeltas>                                                     -->
            <!--     <delta name=""></delta>                                              -->
            <!--   </calcCircleDeltas>                                                    -->

            <!-- Build the points element from the TunnelPointDeltaRecord elements -->
            <xsl:variable name="points">
              <xsl:for-each select="msxsl:node-set($tunnelDeltas)/TunnelPointDeltaRecord">
                <xsl:element name="point">
                  <xsl:element name="x">
                    <xsl:value-of select="HorizontalOffset"/>
                  </xsl:element>
                  <xsl:element name="y">
                    <xsl:value-of select="VerticalOffset"/>
                  </xsl:element>
                </xsl:element>
              </xsl:for-each>
            </xsl:variable>

            <xsl:variable name="computedProfileCentre">
              <xsl:call-template name="LeastSquaresCircleFit">
                <xsl:with-param name="points" select="$points"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:variable name="designProfileCentre">
              <!-- Since this is designed to work with circular profiles only find    -->
              <!-- the centre point of the first arc in the design profile definition -->
              <!-- and use it as the design centre point.                             -->
              <xsl:for-each select="msxsl:node-set($designTemplate)/templateSurface[@name = $templateSurface]/element[centreHz][1]">
                <xsl:element name="x">
                  <xsl:value-of select="centreHz"/>
                </xsl:element>
                <xsl:element name="y">
                  <xsl:value-of select="centreVt"/>
                </xsl:element>
              </xsl:for-each>
            </xsl:variable>

            <xsl:element name="profileOffsets">
              <xsl:variable name="hzOffsetDelta" select="msxsl:node-set($designProfileCentre)/x - msxsl:node-set($computedProfileCentre)/centreX"/>
              <xsl:variable name="vtOffsetDelta" select="msxsl:node-set($designProfileCentre)/y - msxsl:node-set($computedProfileCentre)/centreY"/>
              <xsl:element name="hzOffsetComputed">
                <xsl:value-of select="msxsl:node-set($computedProfileCentre)/centreX"/>
              </xsl:element>
              <xsl:element name="vtOffsetComputed">
                <xsl:value-of select="msxsl:node-set($computedProfileCentre)/centreY"/>
              </xsl:element>
              <xsl:element name="hzOffsetDesign">
                <xsl:value-of select="msxsl:node-set($designProfileCentre)/x"/>
              </xsl:element>
              <xsl:element name="vtOffsetDesign">
                <xsl:value-of select="msxsl:node-set($designProfileCentre)/y"/>
              </xsl:element>
              <xsl:element name="hzOffsetDelta">
                <xsl:value-of select="$hzOffsetDelta"/>
              </xsl:element>
              <xsl:element name="vtOffsetDelta">
                <xsl:value-of select="$vtOffsetDelta"/>
              </xsl:element>
              <xsl:element name="polarDelta">
                <xsl:value-of select="math:sqrt(number($hzOffsetDelta * $hzOffsetDelta + $vtOffsetDelta * $vtOffsetDelta))"/>
              </xsl:element>
              <xsl:element name="computedRadius">
                <xsl:value-of select="msxsl:node-set($computedProfileCentre)/radius"/>
              </xsl:element>
            </xsl:element>
            
            <!-- Create the calcCircleDeltas element -->
            <xsl:element name="calcCircleDeltas">
              <xsl:for-each select="msxsl:node-set($tunnelDeltas)/TunnelPointDeltaRecord">
                <xsl:variable name="calcRadialDist">
                  <xsl:call-template name="InverseDistance">
                    <xsl:with-param name="deltaN" select="VerticalOffset   - msxsl:node-set($computedProfileCentre)/centreY"/>
                    <xsl:with-param name="deltaE" select="HorizontalOffset - msxsl:node-set($computedProfileCentre)/centreX"/>
                  </xsl:call-template>
                </xsl:variable>
                
                <xsl:element name="delta">
                  <xsl:attribute name="name">  <!-- Set up name attribute to match deltas up based on name -->
                    <xsl:value-of select="name"/>
                  </xsl:attribute>
                  <xsl:value-of select="$calcRadialDist - msxsl:node-set($computedProfileCentre)/radius"/>
                </xsl:element>
              </xsl:for-each>
            </xsl:element>
          </xsl:if>
        </xsl:element>   <!-- profile element -->
      </xsl:if>
    </xsl:if>  <!-- In station range -->
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Returns distance around template for point ********** -->
<!-- **************************************************************** -->
<xsl:template name="CalcDistAroundTemplate">
  <xsl:param name="designTemplate"/>
  <xsl:param name="templateSurface"/>  <!-- The surface in the template that the scan was carried out with respect to. -->
  <xsl:param name="ptHz"/>
  <xsl:param name="ptVt"/>

  <xsl:variable name="templateElementIndexVar">
    <xsl:call-template name="TemplateElementForPoint">
      <xsl:with-param name="designTemplate" select="$designTemplate"/>
      <xsl:with-param name="templateSurface" select="$templateSurface"/>
      <xsl:with-param name="ptHz" select="$ptHz"/>
      <xsl:with-param name="ptVt" select="$ptVt"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="templateElementIndex" select="msxsl:node-set($templateElementIndexVar)/index"/>
  <xsl:choose>
    <xsl:when test="string(number($templateElementIndex)) != 'NaN'">
      <xsl:variable name="distToStartOfElement">  <!-- The sum of the lengths of the template elements preceding this element -->
        <xsl:call-template name="TemplateDistPriorToIndex">
          <xsl:with-param name="index" select="$templateElementIndex"/>
          <xsl:with-param name="designTemplate" select="$designTemplate"/>
          <xsl:with-param name="templateSurface" select="$templateSurface"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="distAlongElement">  <!-- The distance along this element -->
        <xsl:call-template name="TemplateDistAlongElement">
          <xsl:with-param name="element" select="msxsl:node-set($designTemplate)/templateSurface[@name = $templateSurface]/element[number($templateElementIndex)]"/>
          <xsl:with-param name="ptHz" select="$ptHz"/>
          <xsl:with-param name="ptVt" select="$ptVt"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:element name="distAround">
        <xsl:value-of select="$distToStartOfElement + $distAlongElement"/> <!-- Return computed distance -->
      </xsl:element>

      <xsl:element name="calcdDelta">
        <xsl:value-of select="msxsl:node-set($templateElementIndexVar)/delta"/> <!-- Return computed delta value -->
      </xsl:element>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Return index of template element adjacent to point ****** -->
<!-- **************************************************************** -->
<xsl:template name="TemplateElementForPoint">
  <xsl:param name="designTemplate"/>
  <xsl:param name="templateSurface"/>  <!-- The surface in the template that the scan was carried out with respect to. -->
  <xsl:param name="ptHz"/>
  <xsl:param name="ptVt"/>

  <xsl:variable name="distToElement">  <!-- A node set holding the shortest distance from point to each template element -->
    <xsl:for-each select="msxsl:node-set($designTemplate)/templateSurface[@name = $templateSurface]/element">
      <xsl:variable name="distToStartPt">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="startVt - $ptVt"/>
          <xsl:with-param name="deltaE" select="startHz - $ptHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="distToEndPt">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="endVt - $ptVt"/>
          <xsl:with-param name="deltaE" select="endHz - $ptHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="shortestDist">
        <xsl:choose>
          <xsl:when test="$distToStartPt &lt; $distToEndPt">
            <xsl:value-of select="$distToStartPt"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$distToEndPt"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="math:abs(number($shortestDist)) &lt; 0.0001">
          <!-- Position is essentially at one of end points so we have a position on the template -->
          <xsl:element name="element">
            <xsl:element name="distance">
              <xsl:value-of select="$shortestDist"/>
            </xsl:element>
            <xsl:element name="index">
              <xsl:value-of select="position()"/>
            </xsl:element>
          </xsl:element>
        </xsl:when>

        <xsl:otherwise>
          <!-- Need to determine if the point will project onto the template element -->
          <xsl:variable name="startToPtDir">
            <xsl:call-template name="InverseAzimuth">
              <xsl:with-param name="deltaN" select="$ptVt - startVt"/>
              <xsl:with-param name="deltaE" select="$ptHz - startHz"/>
              <xsl:with-param name="returnInRadians">true</xsl:with-param>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="endToPtDir">
            <xsl:call-template name="InverseAzimuth">
              <xsl:with-param name="deltaN" select="$ptVt - endVt"/>
              <xsl:with-param name="deltaE" select="$ptHz - endHz"/>
              <xsl:with-param name="returnInRadians">true</xsl:with-param>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="centreToPtDir">
            <xsl:call-template name="InverseAzimuth">
              <xsl:with-param name="deltaN" select="$ptVt - centreVt"/>
              <xsl:with-param name="deltaE" select="$ptHz - centreHz"/>
              <xsl:with-param name="returnInRadians">true</xsl:with-param>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="startDir">
            <xsl:choose>
              <xsl:when test="radius">  <!-- Arc element -->
                <xsl:call-template name="InverseAzimuth">
                  <xsl:with-param name="deltaN" select="startVt - centreVt"/>
                  <xsl:with-param name="deltaE" select="startHz - centreHz"/>
                  <xsl:with-param name="returnInRadians">true</xsl:with-param>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>  <!-- Line element -->
                <xsl:call-template name="InverseAzimuth">
                  <xsl:with-param name="deltaN" select="endVt - startVt"/>
                  <xsl:with-param name="deltaE" select="endHz - startHz"/>
                  <xsl:with-param name="returnInRadians">true</xsl:with-param>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:variable name="endDir">
            <xsl:choose>
              <xsl:when test="radius">  <!-- Arc element -->
                <xsl:call-template name="InverseAzimuth">
                  <xsl:with-param name="deltaN" select="endVt - centreVt"/>
                  <xsl:with-param name="deltaE" select="endHz - centreHz"/>
                  <xsl:with-param name="returnInRadians">true</xsl:with-param>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>  <!-- Line element -->
                <xsl:call-template name="InverseAzimuth">
                  <xsl:with-param name="deltaN" select="endVt - startVt"/>
                  <xsl:with-param name="deltaE" select="endHz - startHz"/>
                  <xsl:with-param name="returnInRadians">true</xsl:with-param>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <xsl:variable name="arcAngle">
            <xsl:call-template name="RadiansClockwiseAngle">
              <xsl:with-param name="fromDir" select="$startDir"/>
              <xsl:with-param name="toDir" select="$endDir"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="arcPointAngle">
            <xsl:call-template name="RadiansClockwiseAngle">
              <xsl:with-param name="fromDir" select="$startDir"/>
              <xsl:with-param name="toDir" select="$centreToPtDir"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:variable name="deltaToStartDir">
            <xsl:call-template name="NormalisedAngleBetweenPlusMinusPi">
              <xsl:with-param name="inAngle" select="$startDir - $startToPtDir"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="absDeltaToStartDir" select="math:abs(number($deltaToStartDir))"/>

          <xsl:variable name="deltaToEndDir">
            <xsl:call-template name="NormalisedAngleBetweenPlusMinusPi">
              <xsl:with-param name="inAngle" select="$endDir - $endToPtDir"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:variable name="absDeltaToEndDir" select="math:abs(number($deltaToEndDir))"/>

          <xsl:choose>
            <xsl:when test="(not(radius) and ($absDeltaToStartDir &lt;= $halfPi) and ($absDeltaToEndDir &gt;= $halfPi)) or
                            (radius and ($arcPointAngle &lt;= $arcAngle))">
              <xsl:element name="element">
                <xsl:choose>
                  <xsl:when test="radius">  <!-- Arc element - the distance to the arc will be the difference between the radius and the distance from the centre point to the point -->
                    <xsl:variable name="distCentreToPt">
                      <xsl:call-template name="InverseDistance">
                        <xsl:with-param name="deltaN" select="centreVt - $ptVt"/>
                        <xsl:with-param name="deltaE" select="centreHz - $ptHz"/>
                      </xsl:call-template>
                    </xsl:variable>
                    <xsl:element name="distance">
                      <xsl:value-of select="math:abs(number($distCentreToPt - radius))"/>
                    </xsl:element>
                    <xsl:element name="deltaDist">  <!-- Retain the signed calculated delta value -->
                      <xsl:value-of select="number($distCentreToPt - radius)"/>
                    </xsl:element>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:element name="distance">
                      <xsl:value-of select="math:sin(number($absDeltaToStartDir)) * $distToStartPt"/>
                    </xsl:element>
                    <xsl:element name="deltaDist">  <!-- Retain the signed calculated delta value -->
                      <xsl:value-of select="math:sin(number($deltaToStartDir)) * $distToStartPt"/>
                    </xsl:element>
                  </xsl:otherwise>
                </xsl:choose>
                <xsl:element name="index">
                  <xsl:value-of select="position()"/>
                </xsl:element>
              </xsl:element>
            </xsl:when>
            <xsl:otherwise>
              <xsl:element name="element">
                <xsl:element name="distance">
                  <xsl:value-of select="$shortestDist"/>
                </xsl:element>
                <xsl:element name="deltaDist">  <!-- Retain the calculated delta value (will always be +ve in this situation) -->
                  <xsl:value-of select="$shortestDist"/>
                </xsl:element>
                <xsl:element name="index">
                  <xsl:value-of select="position()"/>
                </xsl:element>
              </xsl:element>
            </xsl:otherwise>
          </xsl:choose>

        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:variable>

  <xsl:if test="count(msxsl:node-set($distToElement)/element) != 0">
    <xsl:variable name="sortedDists">
      <xsl:for-each select="msxsl:node-set($distToElement)/element">
        <xsl:sort order="ascending" data-type="number" select="distance"/>
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </xsl:variable>

    <xsl:element name="index">
      <xsl:value-of select="msxsl:node-set($sortedDists)/element[1]/index"/>  <!-- Return the element index -->
    </xsl:element>

    <xsl:element name="delta">
      <xsl:value-of select="msxsl:node-set($sortedDists)/element[1]/deltaDist"/>
    </xsl:element>

    <xsl:element name="extCornerPt">
      <xsl:variable name="shortestDist" select="msxsl:node-set($sortedDists)/element[1]/distance"/>
      <xsl:choose>
        <xsl:when test="count(msxsl:node-set($sortedDists)/element[distance = $shortestDist]) &gt; 1">true</xsl:when>
        <xsl:otherwise>false</xsl:otherwise>
      </xsl:choose>
    </xsl:element>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Returns whether this is an underbreak point ********* -->
<!-- **************************************************************** -->
<xsl:template name="IsUnderBreakPoint">
  <xsl:param name="underbreakTol"/>
  <xsl:param name="delta"/>

  <xsl:choose>
    <xsl:when test="$delta &lt; 0">
      <xsl:variable name="absDelta" select="math:abs(number($delta))"/>
      <xsl:choose>
        <xsl:when test="$absDelta &gt; $underbreakTol">
          <xsl:value-of select="'true'"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'false'"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="'false'"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Returns whether this is an overbreak point ********** -->
<!-- **************************************************************** -->
<xsl:template name="IsOverBreakPoint">
  <xsl:param name="overbreakTol"/>
  <xsl:param name="delta"/>

  <xsl:choose>
    <xsl:when test="$delta &gt; 0">
      <xsl:choose>
        <xsl:when test="$delta &gt; $overbreakTol">
          <xsl:value-of select="'true'"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'false'"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="'false'"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ** Returns whether this point is outside the station tolerance * -->
<!-- **************************************************************** -->
<xsl:template name="IsOutsideStnTolPoint">
  <xsl:param name="stnTol"/>

  <xsl:variable name="absStnDelta" select="math:abs(number(DeltaStation))"/>
  <xsl:choose>
    <xsl:when test="$absStnDelta &gt; $stnTol">
      <xsl:value-of select="'true'"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="'false'"/>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Return a node set of grid step values ************* -->
<!-- **************************************************************** -->
<xsl:template name="GridSteps">
  <xsl:param name="fromVal"/>
  <xsl:param name="toVal"/>
  <xsl:param name="increment" select="1"/>
  <xsl:param name="first" select="'true'"/>

  <xsl:if test="$first = 'true'">
    <xsl:element name="value">
      <xsl:value-of select="$fromVal"/>
    </xsl:element>
  </xsl:if>

  <xsl:if test="math:abs(number($fromVal + $increment)) &lt;= math:abs(number($toVal))">
    <xsl:element name="value">
      <xsl:value-of select="$fromVal + $increment"/>
    </xsl:element>
    <xsl:call-template name="GridSteps">   <!-- Recurse the function -->
      <xsl:with-param name="fromVal" select="$fromVal + $increment"/>
      <xsl:with-param name="toVal" select="$toVal"/>
      <xsl:with-param name="increment" select="$increment"/>
      <xsl:with-param name="first" select="'false'"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Return a node set of grid step values ************* -->
<!-- **************************************************************** -->
<xsl:template name="GridStepIncrement">
  <xsl:param name="nbrGridSteps"/>
  <xsl:param name="maxGridSteps"/>
  <xsl:param name="increment" select="1"/>

  <xsl:choose>
    <xsl:when test="$nbrGridSteps div $increment &gt; $maxGridSteps">
      <xsl:call-template name="GridStepIncrement">
        <xsl:with-param name="nbrGridSteps" select="$nbrGridSteps"/>
        <xsl:with-param name="maxGridSteps" select="$maxGridSteps"/>
        <xsl:with-param name="increment" select="$increment + 1"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$increment"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Apply the rotation to the template elements ********** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeRotatedTemplate">
  <xsl:param name="unrotatedTemplate"/>
  <xsl:param name="templateRotationVals"/>

  <!-- Compute and return the rotated coordinates for all the points in $unrotatedTemplate -->
  <xsl:for-each select="msxsl:node-set($unrotatedTemplate)/templateSurface">
    <xsl:element name="templateSurface">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
      <xsl:for-each select="element">
        <xsl:element name="element">
          <!-- Rotate the start point -->
          <xsl:variable name="startPt">
            <xsl:call-template name="ComputeRotatedPoint">
              <xsl:with-param name="rotationAngle" select="msxsl:node-set($templateRotationVals)/rotationAngle"/>
              <xsl:with-param name="hzOrigin" select="msxsl:node-set($templateRotationVals)/hzOrigin"/>
              <xsl:with-param name="vtOrigin" select="msxsl:node-set($templateRotationVals)/vtOrigin"/>
              <xsl:with-param name="hzOffset" select="startHz"/>
              <xsl:with-param name="vtOffset" select="startVt"/>
            </xsl:call-template>
          </xsl:variable>

          <!-- Add rotated start point elements -->
          <xsl:element name="startHz">
            <xsl:value-of select="msxsl:node-set($startPt)/horizOffset"/>
          </xsl:element>

          <xsl:element name="startVt">
            <xsl:value-of select="msxsl:node-set($startPt)/vertOffset"/>
          </xsl:element>

          <!-- Rotate the end point -->
          <xsl:variable name="endPt">
            <xsl:call-template name="ComputeRotatedPoint">
              <xsl:with-param name="rotationAngle" select="msxsl:node-set($templateRotationVals)/rotationAngle"/>
              <xsl:with-param name="hzOrigin" select="msxsl:node-set($templateRotationVals)/hzOrigin"/>
              <xsl:with-param name="vtOrigin" select="msxsl:node-set($templateRotationVals)/vtOrigin"/>
              <xsl:with-param name="hzOffset" select="endHz"/>
              <xsl:with-param name="vtOffset" select="endVt"/>
            </xsl:call-template>
          </xsl:variable>

          <xsl:element name="endHz">
            <xsl:value-of select="msxsl:node-set($endPt)/horizOffset"/>
          </xsl:element>

          <xsl:element name="endVt">
            <xsl:value-of select="msxsl:node-set($endPt)/vertOffset"/>
          </xsl:element>

          <xsl:copy-of select="radius"/>
          <xsl:copy-of select="largeArc"/>
          <xsl:copy-of select="deltaAngle"/>

          <xsl:if test="centreHz">
            <!-- There is a centre point defined so rotate it -->
            <xsl:variable name="centrePt">
              <xsl:call-template name="ComputeRotatedPoint">
                <xsl:with-param name="rotationAngle" select="msxsl:node-set($templateRotationVals)/rotationAngle"/>
                <xsl:with-param name="hzOrigin" select="msxsl:node-set($templateRotationVals)/hzOrigin"/>
                <xsl:with-param name="vtOrigin" select="msxsl:node-set($templateRotationVals)/vtOrigin"/>
                <xsl:with-param name="hzOffset" select="centreHz"/>
                <xsl:with-param name="vtOffset" select="centreVt"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:element name="centreHz">
              <xsl:value-of select="msxsl:node-set($centrePt)/horizOffset"/>
            </xsl:element>

            <xsl:element name="centreVt">
              <xsl:value-of select="msxsl:node-set($centrePt)/vertOffset"/>
            </xsl:element>
          </xsl:if>

          <xsl:copy-of select="code"/>
        </xsl:element>   <!-- element -->
      </xsl:for-each>
    </xsl:element>     <!-- templateSurface -->
  </xsl:for-each>

</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Apply the alignment offsets to the template elements ***** -->
<!-- **************************************************************** -->
<xsl:template name="ApplyAlignmentOffsets">
  <xsl:param name="template"/>
  <xsl:param name="templateOffsetVals"/>

  <!-- Apply the alignment offsets to each point in $template -->
  <xsl:for-each select="msxsl:node-set($template)/templateSurface">
    <xsl:element name="templateSurface">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
      <xsl:for-each select="element">
        <xsl:element name="element">
          <xsl:element name="startHz">
            <xsl:value-of select="startHz + msxsl:node-set($templateOffsetVals)/hzOffset"/>
          </xsl:element>

          <xsl:element name="startVt">
            <xsl:value-of select="startVt + msxsl:node-set($templateOffsetVals)/vtOffset"/>
          </xsl:element>

          <xsl:element name="endHz">
            <xsl:value-of select="endHz + msxsl:node-set($templateOffsetVals)/hzOffset"/>
          </xsl:element>

          <xsl:element name="endVt">
            <xsl:value-of select="endVt + msxsl:node-set($templateOffsetVals)/vtOffset"/>
          </xsl:element>

          <xsl:copy-of select="radius"/>
          <xsl:copy-of select="largeArc"/>
          <xsl:copy-of select="deltaAngle"/>
          <xsl:copy-of select="length"/>

          <xsl:if test="centreHz">
            <xsl:element name="centreHz">
              <xsl:value-of select="centreHz + msxsl:node-set($templateOffsetVals)/hzOffset"/>
            </xsl:element>

            <xsl:element name="centreVt">
              <xsl:value-of select="centreVt + msxsl:node-set($templateOffsetVals)/vtOffset"/>
            </xsl:element>
          </xsl:if>

          <xsl:copy-of select="code"/>
        </xsl:element>  <!-- element -->
      </xsl:for-each>
    </xsl:element>      <!-- templateSurface -->
  </xsl:for-each>

</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Recursive function to add the template elements ******* -->
<!-- **************************************************************** -->
<xsl:template name="AddTemplateElements">
  <xsl:param name="templateDeltas"/>
  <xsl:param name="startHz"/>
  <xsl:param name="startVt"/>
  <xsl:param name="count" select="1"/>

  <!-- The template elements node set has the following structure       -->
  <!--   <element>                                                      -->
  <!--      <startHz>                                                   -->
  <!--      <startVt>                                                   -->
  <!--      <endHz>                                                     -->
  <!--      <endVt>                                                     -->
  <!--      <radius>     optional - indicates arc element               -->
  <!--      <largeArc>   optional - only on an arc element (true/false) -->
  <!--      <deltaAngle> optional - only on some arc elements           -->
  <!--      <centreHz>   optional - only on an arc element              -->
  <!--      <centreVt>   optional - only on an arc element              -->
  <!--      <code>                                                      -->
  <!--   </element>                                                     -->

  <xsl:if test="$count &lt;= count(msxsl:node-set($templateDeltas)/delta)">
    <xsl:variable name="deltaHz" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/hz"/>
    <xsl:variable name="deltaVt" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/vt"/>
    <xsl:variable name="endHz" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/endHz"/>
    <xsl:variable name="endVt" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/endVt"/>
    <xsl:variable name="radius" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/radius"/>
    <xsl:variable name="largeArc" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/largeArc"/>
    <xsl:variable name="centreHz" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/centreHz"/>
    <xsl:variable name="centreVt" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/centreVt"/>
    <xsl:variable name="deltaAngle" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/deltaAngle"/>
    <xsl:variable name="code" select="msxsl:node-set($templateDeltas)/delta[position() = $count]/Code"/>

    <xsl:variable name="radiusVal">
      <xsl:choose>
        <xsl:when test="string(number($radius)) != 'NaN'">
          <xsl:value-of select="$radius"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:if test="(string(number($centreHz)) != 'NaN') and (string(number($centreVt)) != 'NaN') and
                        (string(number($deltaAngle)) != 'NaN')">
            <xsl:value-of select="math:sqrt(number(($startHz - $centreHz) * ($startHz - $centreHz) + ($startVt - $centreVt) * ($startVt - $centreVt)))"/>
          </xsl:if>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="arcEndPt">
      <xsl:if test="(string(number($centreHz)) != 'NaN') and (string(number($centreVt)) != 'NaN') and
                    (string(number($deltaAngle)) != 'NaN')">
        <xsl:call-template name="CalcArcEndPoint">
          <xsl:with-param name="radius" select="$radiusVal"/>
          <xsl:with-param name="deltaAngle" select="$deltaAngle"/>
          <xsl:with-param name="startHz" select="$startHz"/>
          <xsl:with-param name="startVt" select="$startVt"/>
          <xsl:with-param name="centreHz" select="$centreHz"/>
          <xsl:with-param name="centreVt" select="$centreVt"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>

    <xsl:variable name="elementEndHz">
      <xsl:choose>
        <xsl:when test="string(number($endHz)) != 'NaN'">  <!-- Already directly have the end position -->
          <xsl:value-of select="$endHz"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="string(number($deltaHz)) != 'NaN'">  <!-- There is a deltaHz value -->
              <xsl:value-of select="$startHz + $deltaHz"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="msxsl:node-set($arcEndPt)/horizOffset"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="elementEndVt">
      <xsl:choose>
        <xsl:when test="string(number($endVt)) != 'NaN'">  <!-- Already directly have the end position -->
          <xsl:value-of select="$endVt"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="string(number($deltaVt)) != 'NaN'">  <!-- There is a deltaVt value -->
              <xsl:value-of select="$startVt + $deltaVt"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="msxsl:node-set($arcEndPt)/vertOffset"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:element name="element">
      <xsl:element name="startHz">
        <xsl:value-of select="$startHz"/>
      </xsl:element>

      <xsl:element name="startVt">
        <xsl:value-of select="$startVt"/>
      </xsl:element>

      <xsl:element name="endHz">
        <xsl:value-of select="$elementEndHz"/>
      </xsl:element>

      <xsl:element name="endVt">
        <xsl:value-of select="$elementEndVt"/>
      </xsl:element>

      <xsl:if test="string(number($radiusVal)) != 'NaN'">
        <xsl:element name="radius">
          <xsl:value-of select="$radiusVal"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="$largeArc != ''">
        <xsl:element name="largeArc">
          <xsl:value-of select="$largeArc"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="string(number($deltaAngle)) != 'NaN'">
        <xsl:element name="largeArc">
          <xsl:choose>
            <xsl:when test="$deltaAngle &gt; 180.0">true</xsl:when>
            <xsl:otherwise>false</xsl:otherwise>
          </xsl:choose>
        </xsl:element>
      </xsl:if>

      <xsl:if test="string(number($deltaAngle)) != 'NaN'">
        <xsl:element name="deltaAngle">
          <xsl:value-of select="$deltaAngle"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="string(number($centreHz)) != 'NaN'">
        <xsl:element name="centreHz">
          <xsl:value-of select="$centreHz"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="string(number($centreVt)) != 'NaN'">
        <xsl:element name="centreVt">
          <xsl:value-of select="$centreVt"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="(string(number($radiusVal)) != 'NaN') and (string(number($centreHz)) = 'NaN')">
        <!-- We have the radius but no centre point - compute the centre point -->
        <xsl:variable name="centrePt">
          <xsl:call-template name="CalcArcCentrePointAndDeltaAngle">
            <xsl:with-param name="radius" select="$radiusVal"/>
            <xsl:with-param name="startHz" select="$startHz"/>
            <xsl:with-param name="startVt" select="$startVt"/>
            <xsl:with-param name="endHz" select="$endHz"/>
            <xsl:with-param name="endVt" select="$endVt"/>
            <xsl:with-param name="largeArc" select="$largeArc"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:element name="centreHz">
          <xsl:value-of select="msxsl:node-set($centrePt)/horizOffset"/>
        </xsl:element>
        <xsl:element name="centreVt">
          <xsl:value-of select="msxsl:node-set($centrePt)/vertOffset"/>
        </xsl:element>
        <xsl:if test="string(number($deltaAngle)) = 'NaN'">
          <xsl:element name="deltaAngle">
            <xsl:value-of select="msxsl:node-set($centrePt)/deltaAngle"/>
          </xsl:element>
        </xsl:if>
        <xsl:element name="length">
          <xsl:value-of select="msxsl:node-set($centrePt)/deltaAngle * math:PI() div 180.0 * $radiusVal"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="(string(number($radiusVal)) != 'NaN') and (string(number($deltaAngle)) != 'NaN')and (string(number($centreHz)) != 'NaN')">
        <!-- Have a radius and a delta angle and the length has not been added   -->
        <!-- when the centre point was computed so compute the length of the arc -->
        <xsl:element name="length">
          <xsl:value-of select="$deltaAngle * math:PI() div 180.0 * $radiusVal"/>
        </xsl:element>
      </xsl:if>

      <xsl:if test="string(number($radiusVal)) = 'NaN'">  <!-- No radius - must be a line element -->
        <xsl:element name="length">
          <xsl:call-template name="InverseDistance">
            <xsl:with-param name="deltaN" select="$startVt - $elementEndVt"/>
            <xsl:with-param name="deltaE" select="$startHz - $elementEndHz"/>
          </xsl:call-template>
        </xsl:element>
      </xsl:if>

      <xsl:element name="code">
        <xsl:value-of select="$code"/>
      </xsl:element>
    </xsl:element>

    <!-- Recurse the function to build all the design template elements -->
    <xsl:call-template name="AddTemplateElements">
      <xsl:with-param name="templateDeltas" select="$templateDeltas"/>
      <xsl:with-param name="startHz" select="$elementEndHz"/>
      <xsl:with-param name="startVt" select="$elementEndVt"/>
      <xsl:with-param name="count" select="$count + 1"/>
    </xsl:call-template>
  </xsl:if>

</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Get names of surfaces switched on in each template ****** -->
<!-- **************************************************************** -->
<xsl:template name="GetCommonTemplateSurfaces">
  <xsl:param name="templateNames"/>

  <!-- Determine which surfaces are switched on in both the prevTemplate and nextTemplate -->
  <xsl:choose>
    <xsl:when test="(msxsl:node-set($templateNames)/prevTemplateSurfaces = '') and
                    (msxsl:node-set($templateNames)/nextTemplateSurfaces = '')">
      <!-- No surfaces defined (old format txl file) so use internal default surface name -->
      <surface>DefaultXSLSurface</surface>
    </xsl:when>
    <xsl:otherwise>
      <xsl:for-each select="msxsl:node-set($templateNames)/prevTemplateSurfaces/Surface[Used = 'true']">
        <xsl:variable name="surfaceName" select="Name"/>
        <xsl:if test="msxsl:node-set($templateNames)/nextTemplateSurfaces/Surface[Name = $surfaceName]/Used = 'true'">
          <surface>
            <xsl:value-of select="$surfaceName"/>
          </surface>
        </xsl:if>
      </xsl:for-each>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Compute the template elements by standard interpolation **** -->
<!-- **************************************************************** -->
<xsl:template name="StandardInterpolatedElements">
  <xsl:param name="prevTemplateSurf"/>
  <xsl:param name="nextTemplateSurf"/>
  <xsl:param name="ratio"/>

  <xsl:for-each select="msxsl:node-set($prevTemplateSurf)/element">
    <xsl:variable name="posn" select="position()"/>
    <xsl:element name="element">
      <xsl:variable name="startHz">
        <xsl:value-of select="startHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startHz - startHz) * $ratio"/>
      </xsl:variable>
      <xsl:element name="startHz">
        <xsl:value-of select="$startHz"/>
      </xsl:element>

      <xsl:variable name="startVt">
        <xsl:value-of select="startVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startVt - startVt) * $ratio"/>
      </xsl:variable>
      <xsl:element name="startVt">
        <xsl:value-of select="$startVt"/>
      </xsl:element>

      <xsl:variable name="endHz">
        <xsl:value-of select="endHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endHz - endHz) * $ratio"/>
      </xsl:variable>
      <xsl:element name="endHz">
        <xsl:value-of select="$endHz"/>
      </xsl:element>

      <xsl:variable name="endVt">
        <xsl:value-of select="endVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endVt - endVt) * $ratio"/>
      </xsl:variable>
      <xsl:element name="endVt">
        <xsl:value-of select="$endVt"/>
      </xsl:element>

      <xsl:choose>
        <xsl:when test="radius and msxsl:node-set($nextTemplateSurf)/element[$posn]/radius">  <!-- Matching arc elements -->
          <xsl:variable name="radius">
            <xsl:value-of select="radius + (msxsl:node-set($nextTemplateSurf)/element[$posn]/radius - radius) * $ratio"/>
          </xsl:variable>
          <xsl:element name="radius">
            <xsl:value-of select="$radius"/>
          </xsl:element>
          <xsl:variable name="centrePtAndDeltaAngle">
            <xsl:call-template name="CalcArcCentrePointAndDeltaAngle">
              <xsl:with-param name="radius" select="$radius"/>
              <xsl:with-param name="startHz" select="$startHz"/>
              <xsl:with-param name="startVt" select="$startVt"/>
              <xsl:with-param name="endHz" select="$endHz"/>
              <xsl:with-param name="endVt" select="$endVt"/>
              <xsl:with-param name="largeArc" select="largeArc"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:element name="centreHz">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/horizOffset"/>
          </xsl:element>
          <xsl:element name="centreVt">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/vertOffset"/>
          </xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle"/>
          </xsl:element>
          <xsl:element name="largeArc">
            <xsl:value-of select="largeArc"/>
          </xsl:element>
          <xsl:element name="length">
            <xsl:value-of select="math:abs(number($radius * (msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle * math:PI() div 180.0)))"/>
          </xsl:element>
        </xsl:when>

        <xsl:when test="radius and not(msxsl:node-set($nextTemplateSurf)/element[$posn]/radius)">  <!-- Arc changing to line -->
          <xsl:variable name="radius">
            <xsl:variable name="startRadConst" select="math:log10(number(radius))"/>
            <xsl:variable name="endRadConst" select="math:log10(1000)"/>
            <xsl:value-of select="math:pow(10, number($startRadConst + ($endRadConst - $startRadConst) * $ratio))"/>
          </xsl:variable>
          <xsl:element name="radius">
            <xsl:value-of select="$radius"/>
          </xsl:element>
          <xsl:variable name="centrePtAndDeltaAngle">
            <xsl:call-template name="CalcArcCentrePointAndDeltaAngle">
              <xsl:with-param name="radius" select="$radius"/>
              <xsl:with-param name="startHz" select="$startHz"/>
              <xsl:with-param name="startVt" select="$startVt"/>
              <xsl:with-param name="endHz" select="$endHz"/>
              <xsl:with-param name="endVt" select="$endVt"/>
              <xsl:with-param name="largeArc" select="largeArc"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:element name="centreHz">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/horizOffset"/>
          </xsl:element>
          <xsl:element name="centreVt">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/vertOffset"/>
          </xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle"/>
          </xsl:element>
          <xsl:element name="largeArc">
            <xsl:value-of select="largeArc"/>
          </xsl:element>
          <xsl:element name="length">
            <xsl:value-of select="math:abs(number($radius * (msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle * math:PI() div 180.0)))"/>
          </xsl:element>
        </xsl:when>

        <xsl:when test="not(radius) and msxsl:node-set($nextTemplateSurf)/element[$posn]/radius">  <!-- Line changing to arc -->
          <xsl:variable name="radius">
            <xsl:variable name="startRadConst" select="math:log10(1000)"/>
            <xsl:variable name="endRadConst" select="math:log10(number(msxsl:node-set($nextTemplateSurf)/element[$posn]/radius))"/>
            <xsl:value-of select="math:pow(10, number($startRadConst + ($endRadConst - $startRadConst) * $ratio))"/>
          </xsl:variable>
          <xsl:element name="radius">
            <xsl:value-of select="$radius"/>
          </xsl:element>
          <xsl:variable name="centrePtAndDeltaAngle">
            <xsl:call-template name="CalcArcCentrePointAndDeltaAngle">
              <xsl:with-param name="radius" select="$radius"/>
              <xsl:with-param name="startHz" select="$startHz"/>
              <xsl:with-param name="startVt" select="$startVt"/>
              <xsl:with-param name="endHz" select="$endHz"/>
              <xsl:with-param name="endVt" select="$endVt"/>
              <xsl:with-param name="largeArc" select="largeArc"/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:element name="centreHz">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/horizOffset"/>
          </xsl:element>
          <xsl:element name="centreVt">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/vertOffset"/>
          </xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle"/>
          </xsl:element>
          <xsl:element name="largeArc">
            <xsl:value-of select="largeArc"/>
          </xsl:element>
          <xsl:element name="length">
            <xsl:value-of select="math:abs(number($radius * (msxsl:node-set($centrePtAndDeltaAngle)/deltaAngle * math:PI() div 180.0)))"/>
          </xsl:element>
        </xsl:when>
        <xsl:when test="not(radius) and not(msxsl:node-set($nextTemplateSurf)/element[$posn]/radius)">  <!-- No arcs involved -->
          <xsl:element name="length">
            <xsl:call-template name="InverseDistance">
              <xsl:with-param name="deltaN" select="$startVt - $endVt"/>
              <xsl:with-param name="deltaE" select="$startHz - $endHz"/>
            </xsl:call-template>
          </xsl:element>
        </xsl:when>
      </xsl:choose>
      <xsl:copy-of select="code"/>
    </xsl:element>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Check if this is a Norwegian style section ********** -->
<!-- **************************************************************** -->
<xsl:template name="NorwegianStyleSection">
  <xsl:param name="templateSurf"/>

  <xsl:variable name="sequentialArcIndices">
    <xsl:call-template name="SequentialArcCount">
      <xsl:with-param name="templateSurf" select="$templateSurf"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:if test="string(number(msxsl:node-set($sequentialArcIndices)/firstArcIndex)) != 'NaN'">
    <!-- We have a template with 3 or 5 sequential arc elements -->
    <xsl:variable name="firstArcIndex" select="msxsl:node-set($sequentialArcIndices)/firstArcIndex"/>
    <xsl:variable name="lastArcIndex" select="msxsl:node-set($sequentialArcIndices)/lastArcIndex"/>
    <xsl:variable name="centreIdx" select="$firstArcIndex + ($lastArcIndex - $firstArcIndex) div 2"/>
    <xsl:variable name="deltaTol">0.005</xsl:variable>
    <xsl:variable name="centreArcPtsVtDelta" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/startVt - msxsl:node-set($templateSurf)/element[number($centreIdx)]/endVt"/>
    <xsl:if test="math:abs(number($centreArcPtsVtDelta)) &lt; $deltaTol">
      <!-- The template is not tilted -->
      <xsl:variable name="deltaRadius" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex)]/radius - msxsl:node-set($templateSurf)/element[number($lastArcIndex)]/radius"/>
      <xsl:if test="math:abs(number($deltaRadius)) &lt; 0.002">
        <!-- The radii of the first and third arcs are equal -->
        <xsl:choose>
          <xsl:when test="$lastArcIndex - $firstArcIndex + 1 = 3">
            <xsl:variable name="tangentialFirstArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex)]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex)]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/startHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/startVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialFirstArcTest" select="math:abs(number($tangentialFirstArcTest))"/>

            <xsl:variable name="tangentialLastArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex)]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex)]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/endHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/endVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialLastArcTest" select="math:abs(number($tangentialLastArcTest))"/>

            <xsl:if test="($absTangentialFirstArcTest &lt; $deltaTol) and ($absTangentialLastArcTest &lt; $deltaTol)">
              <xsl:value-of select="'true'"/>
            </xsl:if>
          </xsl:when>

          <xsl:otherwise>
            <xsl:variable name="tangentialFirstArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex)]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex)]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/startHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/startVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialFirstArcTest" select="math:abs(number($tangentialFirstArcTest))"/>

            <xsl:variable name="tangentialFirstTransArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($firstArcIndex) + 1]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/startHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/startVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialFirstTransArcTest" select="math:abs(number($tangentialFirstTransArcTest))"/>

            <xsl:variable name="tangentialSecondTransArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/endHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($centreIdx)]/endVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialSecondTransArcTest" select="math:abs(number($tangentialSecondTransArcTest))"/>

            <xsl:variable name="tangentialLastArcTest">
              <xsl:call-template name="CrossProduct">
                <xsl:with-param name="pointX" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex)]/centreHz"/>
                <xsl:with-param name="pointY" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex)]/centreVt"/>
                <xsl:with-param name="startX" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/centreHz"/>
                <xsl:with-param name="startY" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/centreVt"/>
                <xsl:with-param name="endX" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/endHz"/>
                <xsl:with-param name="endY" select="msxsl:node-set($templateSurf)/element[number($lastArcIndex) - 1]/endVt"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="absTangentialLastArcTest" select="math:abs(number($tangentialLastArcTest))"/>

            <xsl:if test="($absTangentialFirstArcTest &lt; $deltaTol) and ($absTangentialLastArcTest &lt; $deltaTol) and
                          ($absTangentialFirstTransArcTest &lt; $deltaTol) and ($absTangentialSecondTransArcTest &lt; $deltaTol)">
              <xsl:value-of select="'true'"/>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:if>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Check for appropriate sequential arc count (3 or 5) ****** -->
<!-- **************************************************************** -->
<xsl:template name="SequentialArcCount">
  <xsl:param name="templateSurf"/>

  <xsl:variable name="arcs">
    <xsl:if test="(count(msxsl:node-set($templateSurf)/element/radius) = 3) or (count(msxsl:node-set($templateSurf)/element/radius) = 5)">
      <!-- There are an appropriate number of arcs in the template -->
      <xsl:for-each select="msxsl:node-set($templateSurf)/element">
        <xsl:if test="radius">   <!-- This is an arc -->
          <xsl:if test="(count(preceding-sibling::*/radius) = 0) or (preceding-sibling::*[1]/radius)">
            <xsl:element name="arc">
              <xsl:value-of select="position()"/>
            </xsl:element>
          </xsl:if>
        </xsl:if>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>

  <xsl:if test="(count(msxsl:node-set($arcs)/arc) = 3) or (count(msxsl:node-set($arcs)/arc) = 5)">
    <xsl:variable name="seqentialTest">
      <xsl:for-each select="msxsl:node-set($arcs)/arc[position() != 1]">
        <xsl:element name="test">
          <xsl:choose>
            <xsl:when test=". - preceding-sibling::arc[1] = 1">true</xsl:when>
            <xsl:otherwise>false</xsl:otherwise>
          </xsl:choose>
        </xsl:element>
      </xsl:for-each>
    </xsl:variable>

    <xsl:if test="count(msxsl:node-set($seqentialTest)/test[. = 'false']) = 0">
      <xsl:element name="firstArcIndex">
        <xsl:value-of select="msxsl:node-set($arcs)/arc[1]"/>
      </xsl:element>

      <xsl:element name="lastArcIndex">
        <xsl:value-of select="msxsl:node-set($arcs)/arc[last()]"/>
      </xsl:element>
    </xsl:if>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Compute template arcs by Norwegian type interpolation **** -->
<!-- **************************************************************** -->
<xsl:template name="NorwegianInterpolatedArcs">
  <xsl:param name="prevTemplateSurf"/>
  <xsl:param name="nextTemplateSurf"/>
  <xsl:param name="ratio"/>

  <!-- The Norwegian method of interpolation only applies when working with cross-section consisting of three
       or five tangential arcs.  The method maintains the radii of the first and last arcs (referred to as wall
       arcs) as well as the radii of the second and fourth 'transition' arcs when present, and computes a new
       radius for the central (or roof) arc.  It interpolates the angles (Ø) between horizontal and the radial
       lines to the upper points of the wall arcs (with the radius Rv).  The interpolation is:
         Ø' = Ø1 + (Ø2 - Ø1) * (station - startStation) / (endStation - startStation)
       The angle ß can then be resolved and the distance AB interpolated.  Using these values the radius Rh at
       the interpolated section can be computed.  The diagram below shows a typical 3 arc section.

                                                   .    .
                                              .              .
                                          .                      .
                                      .                              .
                                    .                                  .
                                 A .                                    . B
                                 .    .                               .   .
                                .       .                           .      .
                               .          .Rh                  Rh .         .
                              .             .                   .            .
                              .            Rv .               . Rv           .
                             .                  .           .                 .
                             .                Ø   .   ß   .  Ø                .
                             x~~~~~~~~~~~~~~~~~~~~~~x   x~~~~~~~~~~~~~~~~~~~~~x
                             .              |         x                       .
                              .             |Yv       Centre                 .
                               .            |                               .
  -->

  <xsl:variable name="arcIndices">
    <xsl:call-template name="SequentialArcCount">
      <xsl:with-param name="templateSurf" select="$prevTemplateSurf"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="firstArcIdx" select="msxsl:node-set($arcIndices)/firstArcIndex"/>
  <xsl:variable name="lastArcIdx" select="msxsl:node-set($arcIndices)/lastArcIndex"/>

  <!-- Compute Ø for the prevTemplate -->
  <xsl:variable name="phiPrev">
    <xsl:call-template name="ScribedAngle">
      <xsl:with-param name="startHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/centreHz - 50"/>  <!-- Point left of centre point -->
      <xsl:with-param name="startVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/centreVt"/>
      <xsl:with-param name="endHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/endHz"/>
      <xsl:with-param name="endVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/endVt"/>
      <xsl:with-param name="centreHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/centreHz"/>
      <xsl:with-param name="centreVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/centreVt"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- Compute Ø for the nextTemplate -->
  <xsl:variable name="phiNext">
    <xsl:call-template name="ScribedAngle">
      <xsl:with-param name="startHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/centreHz - 50"/>  <!-- Point left of centre point -->
      <xsl:with-param name="startVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/centreVt"/>
      <xsl:with-param name="endHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/endHz"/>
      <xsl:with-param name="endVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/endVt"/>
      <xsl:with-param name="centreHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/centreHz"/>
      <xsl:with-param name="centreVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/centreVt"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- Compute interpolated Ø -->
  <xsl:variable name="interpPhi" select="$phiPrev + ($phiNext - $phiPrev) * $ratio"/>

  <!-- As the left and right wall arcs may be different lengths retain separate Yv value for the first and last arcs -->
  <xsl:variable name="prevYvLeft" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/centreVt - msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/startVt"/>
  <xsl:variable name="prevYvRight" select="msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx)]/centreVt - msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx)]/endVt"/>

  <xsl:variable name="nextYvLeft" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/centreVt - msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/startVt"/>
  <xsl:variable name="nextYvRight" select="msxsl:node-set($nextTemplateSurf)/element[number($lastArcIdx)]/centreVt - msxsl:node-set($nextTemplateSurf)/element[number($lastArcIdx)]/endVt"/>

  <!-- Compute interpolated Yv values -->
  <xsl:variable name="interpYvLeft" select="$prevYvLeft + ($nextYvLeft - $prevYvLeft) * $ratio"/>
  <xsl:variable name="interpYvRight" select="$prevYvRight + ($nextYvRight - $prevYvRight) * $ratio"/>

  <!-- Compute interpolated start vertical position (to use in later vertical adjustment of cross-section) -->
  <xsl:variable name="interpStartVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/startVt + (msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/startVt - msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/startVt) * $ratio"/>

  <xsl:variable name="centreIdx" select="$firstArcIdx + ($lastArcIdx - $firstArcIdx) div 2"/>
  <!-- Compute the interpolated A and B positions -->
  <xsl:variable name="interpA">
    <xsl:element name="hz">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/startHz + (msxsl:node-set($nextTemplateSurf)/element[number($centreIdx)]/startHz - msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/startHz) * $ratio"/>
    </xsl:element>

    <xsl:element name="vt">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/startVt + (msxsl:node-set($nextTemplateSurf)/element[number($centreIdx)]/startVt - msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/startVt) * $ratio"/>
    </xsl:element>
  </xsl:variable>

  <xsl:variable name="interpB">
    <xsl:element name="hz">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/endHz + (msxsl:node-set($nextTemplateSurf)/element[number($centreIdx)]/endHz - msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/endHz) * $ratio"/>
    </xsl:element>

    <xsl:element name="vt">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/endVt + (msxsl:node-set($nextTemplateSurf)/element[number($centreIdx)]/endVt - msxsl:node-set($prevTemplateSurf)/element[number($centreIdx)]/endVt) * $ratio"/>
    </xsl:element>
  </xsl:variable>

  <!-- Compute the distance between the interpolated A and B positions -->
  <xsl:variable name="interpAB">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="msxsl:node-set($interpA)/vt - msxsl:node-set($interpB)/vt"/>
      <xsl:with-param name="deltaE" select="msxsl:node-set($interpA)/hz - msxsl:node-set($interpB)/hz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="interpTransAngle">
    <xsl:choose>
      <xsl:when test="$lastArcIdx - $firstArcIdx + 1 = 5">
        <xsl:variable name="prevTransAngle">
          <xsl:call-template name="ScribedAngle">
            <xsl:with-param name="startHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/startHz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/startVt"/>
            <xsl:with-param name="endHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/endHz"/>
            <xsl:with-param name="endVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/endVt"/>
            <xsl:with-param name="centreHz" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/centreHz"/>
            <xsl:with-param name="centreVt" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="nextTransAngle">
          <xsl:call-template name="ScribedAngle">
            <xsl:with-param name="startHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/startHz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/startVt"/>
            <xsl:with-param name="endHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/endHz"/>
            <xsl:with-param name="endVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/endVt"/>
            <xsl:with-param name="centreHz" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/centreHz"/>
            <xsl:with-param name="centreVt" select="msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:value-of select="$prevTransAngle + ($nextTransAngle - $prevTransAngle) * $ratio"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Compute interpolated transition arc radius -->
  <xsl:variable name="radiusT">
    <xsl:if test="$lastArcIdx - $firstArcIdx + 1 = 5">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/radius + (msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx) + 1]/radius - msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/radius) * $ratio"/>
    </xsl:if>
  </xsl:variable>

  <!-- Compute interpolated wall arc radius -->
  <xsl:variable name="radiusV" select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/radius + (msxsl:node-set($nextTemplateSurf)/element[number($firstArcIdx)]/radius - msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/radius) * $ratio"/>

  <xsl:variable name="radiusH" select="($interpAB div 2.0) div math:sin(number($halfPi - ($interpPhi + $interpTransAngle)))"/>

  <xsl:call-template name="BuildNorwegianInterpolatedArcs">
    <xsl:with-param name="radiusH" select="$radiusH"/>
    <xsl:with-param name="radiusT" select="$radiusT"/>
    <xsl:with-param name="radiusV" select="$radiusV"/>
    <xsl:with-param name="interpStartVt" select="$interpStartVt"/>
    <xsl:with-param name="interpPhi" select="$interpPhi"/>
    <xsl:with-param name="interpYvLeft" select="$interpYvLeft"/>
    <xsl:with-param name="interpYvRight" select="$interpYvRight"/>
    <xsl:with-param name="interpTransAngle" select="$interpTransAngle"/>
    <xsl:with-param name="interpA" select="$interpA"/>
    <xsl:with-param name="interpB" select="$interpB"/>
    <xsl:with-param name="prevTemplateSurf" select="$prevTemplateSurf"/>
    <xsl:with-param name="firstArcIdx" select="$firstArcIdx"/>
    <xsl:with-param name="lastArcIdx" select="$lastArcIdx"/>
  </xsl:call-template>

</xsl:template>


<!-- **************************************************************** -->
<!-- **Integrate the Norwegian interp arcs with any other elements ** -->
<!-- **************************************************************** -->
<xsl:template name="AssembleCompleteNorwegianTemplate">
  <xsl:param name="prevTemplateSurf"/>
  <xsl:param name="nextTemplateSurf"/>
  <xsl:param name="norwegianInterpArcs"/>
  <xsl:param name="ratio"/>

  <xsl:for-each select="msxsl:node-set($prevTemplateSurf)/element">
    <xsl:variable name="posn" select="position()"/>
    <xsl:choose>
      <xsl:when test="radius">
        <xsl:variable name="arcIndex" select="count(preceding-sibling::element[radius]) + 1"/>
        <xsl:copy-of select="msxsl:node-set($norwegianInterpArcs)/element[$arcIndex]"/>
      </xsl:when>

      <xsl:otherwise>  <!-- This is a line element -->
        <xsl:choose>
          <xsl:when test="following-sibling::element[1]/radius">  <!-- next element is first arc - this line needs to end on the first arc's start point -->
            <xsl:element name="element">
              <xsl:variable name="startHz" select="startHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startHz - startHz) * $ratio"/>
              <xsl:element name="startHz">
                <xsl:value-of select="$startHz"/>
              </xsl:element>

              <xsl:variable name="startVt" select="startVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startVt - startVt) * $ratio"/>
              <xsl:element name="startVt">
                <xsl:value-of select="$startVt"/>
              </xsl:element>

              <xsl:element name="endHz">
                <xsl:value-of select="msxsl:node-set($norwegianInterpArcs)/element[1]/startHz"/>
              </xsl:element>

              <xsl:element name="endVt">
                <xsl:value-of select="msxsl:node-set($norwegianInterpArcs)/element[1]/startVt"/>
              </xsl:element>

              <xsl:element name="length">
                <xsl:call-template name="InverseDistance">
                  <xsl:with-param name="deltaN" select="$startVt - msxsl:node-set($norwegianInterpArcs)/element[1]/startVt"/>
                  <xsl:with-param name="deltaE" select="$startHz - msxsl:node-set($norwegianInterpArcs)/element[1]/startHz"/>
                </xsl:call-template>
              </xsl:element>
            </xsl:element>
          </xsl:when>

          <xsl:when test="preceding-sibling::element[1]/radius">  <!-- previous element is last arc - this line needs to start on the last arc's end point -->
            <xsl:element name="element">
              <xsl:element name="startHz">
                <xsl:value-of select="msxsl:node-set($norwegianInterpArcs)/element[last()]/endHz"/>
              </xsl:element>

              <xsl:element name="startVt">
                <xsl:value-of select="msxsl:node-set($norwegianInterpArcs)/element[last()]/endVt"/>
              </xsl:element>

              <xsl:variable name="endHz" select="endHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endHz - endHz) * $ratio"/>
              <xsl:element name="endHz">
                <xsl:value-of select="$endHz"/>
              </xsl:element>

              <xsl:variable name="endVt" select="endVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endVt - endVt) * $ratio"/>
              <xsl:element name="endVt">
                <xsl:value-of select="$endVt"/>
              </xsl:element>

              <xsl:element name="length">
                <xsl:call-template name="InverseDistance">
                  <xsl:with-param name="deltaN" select="msxsl:node-set($norwegianInterpArcs)/element[last()]/endVt - $endVt"/>
                  <xsl:with-param name="deltaE" select="msxsl:node-set($norwegianInterpArcs)/element[last()]/endHz - $endHz"/>
                </xsl:call-template>
              </xsl:element>
            </xsl:element>
          </xsl:when>

          <xsl:otherwise>   <!-- Standard line interpolation -->
            <xsl:element name="element">
              <xsl:variable name="startHz" select="startHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startHz - startHz) * $ratio"/>
              <xsl:element name="startHz">
                <xsl:value-of select="$startHz"/>
              </xsl:element>

              <xsl:variable name="startVt" select="startVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/startVt - startVt) * $ratio"/>
              <xsl:element name="startVt">
                <xsl:value-of select="$startVt"/>
              </xsl:element>

              <xsl:variable name="endHz" select="endHz + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endHz - endHz) * $ratio"/>
              <xsl:element name="endHz">
                <xsl:value-of select="$endHz"/>
              </xsl:element>

              <xsl:variable name="endVt" select="endVt + (msxsl:node-set($nextTemplateSurf)/element[$posn]/endVt - endVt) * $ratio"/>
              <xsl:element name="endVt">
                <xsl:value-of select="$endVt"/>
              </xsl:element>

              <xsl:element name="length">
                <xsl:call-template name="InverseDistance">
                  <xsl:with-param name="deltaN" select="$startVt - $endVt"/>
                  <xsl:with-param name="deltaE" select="$startHz - $endHz"/>
                </xsl:call-template>
              </xsl:element>
            </xsl:element>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:copy-of select="code"/>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Compute the scribed angle ******************* -->
<!-- **************************************************************** -->
<xsl:template name="ScribedAngle">
  <xsl:param name="startHz"/>
  <xsl:param name="startVt"/>
  <xsl:param name="endHz"/>
  <xsl:param name="endVt"/>
  <xsl:param name="centreHz"/>
  <xsl:param name="centreVt"/>

  <xsl:variable name="startDir">
    <xsl:call-template name="InverseAzimuth">
      <xsl:with-param name="deltaN" select="$startVt - $centreVt"/>
      <xsl:with-param name="deltaE" select="$startHz - $centreHz"/>
      <xsl:with-param name="returnInRadians">true</xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="endDir">
    <xsl:call-template name="InverseAzimuth">
      <xsl:with-param name="deltaN" select="$endVt - $centreVt"/>
      <xsl:with-param name="deltaE" select="$endHz - $centreHz"/>
      <xsl:with-param name="returnInRadians">true</xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="$startDir &lt; $endDir">  <!-- Regular clockwise arc -->
      <xsl:value-of select="$endDir - $startDir"/>
    </xsl:when>
    <xsl:otherwise>  <!-- This arc is cutting the 0 axis -->
      <xsl:value-of select="$endDir + (math:PI() * 2.0 - $startDir)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Check if 2 templates have the same elements ********* -->
<!-- **************************************************************** -->
<xsl:template name="TemplatesAreEquivalent">
  <xsl:param name="prevTemplate"/>
  <xsl:param name="nextTemplate"/>

  <xsl:variable name="testVar">
    <xsl:for-each select="msxsl:node-set($prevTemplate)/templateSurface">
      <xsl:variable name="surfaceName" select="@name"/>
      <xsl:for-each select="element">
        <xsl:variable name="posn" select="position()"/>
        <xsl:if test=". != msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]/element[number($posn)]">x</xsl:if>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="$testVar = ''">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Return the template name for the current station ******* -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateNames">
  <xsl:param name="station"/>

  <!-- Returns a node set with the following elements: -->
  <!--   <prevTemplateName> -->
  <!--   <prevTemplateStation> -->
  <!--   <prevTemplateSurfaces> -->
  <!--   <nextTemplateName> -->
  <!--   <nextTemplateStation> -->
  <!--   <nextTemplateSurfaces> -->

  <xsl:element name="prevTemplateName">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Name"/>
  </xsl:element>

  <xsl:element name="prevTemplateStation">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Station"/>
  </xsl:element>

  <xsl:element name="prevTemplateSurfaces">
    <xsl:if test="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Station">
      <xsl:choose>
        <xsl:when test="count(msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Surface) != 0">
          <!-- <xsl:copy-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Surface"/> -->
          <!-- Treat all surfaces as able to be used regardless of their setting in the TunnelXML file -->
          <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &gt;= Station][last()]/Surface">
            <xsl:element name="Surface" namespace="">
              <xsl:element name="Name" namespace=""><xsl:value-of select="Name"/></xsl:element>
              <xsl:element name="Used" namespace="">true</xsl:element>
            </xsl:element>
          </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>  <!-- TunnelXML file prior to multiple surfaces - set up default surface -->
          <xsl:element name="Surface" namespace="">
            <xsl:element name="Name" namespace="">DefaultXSLSurface</xsl:element>
            <xsl:element name="Used" namespace="">true</xsl:element>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </xsl:element>

  <xsl:element name="nextTemplateName">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Name"/>
  </xsl:element>

  <xsl:element name="nextTemplateStation">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Station"/>
  </xsl:element>

  <xsl:element name="nextTemplateSurfaces">
    <xsl:if test="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Station">
      <xsl:choose>
        <xsl:when test="count(msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Surface) != 0">
          <!-- <xsl:copy-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Surface"/> -->
          <!-- Treat all surfaces as able to be used regardless of their setting in the TunnelXML file -->
          <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplatePositioning/ApplyTemplate[$station &lt;= Station][1]/Surface">
            <xsl:element name="Surface" namespace="">
              <xsl:element name="Name" namespace=""><xsl:value-of select="Name"/></xsl:element>
              <xsl:element name="Used" namespace="">true</xsl:element>
            </xsl:element>
          </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>  <!-- TunnelXML file prior to multiple surfaces - set up default surface -->
          <xsl:element name="Surface" namespace="">
            <xsl:element name="Name" namespace="">DefaultXSLSurface</xsl:element>
            <xsl:element name="Used" namespace="">true</xsl:element>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Return template rotation details for the current station *** -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateRotationValues">
  <xsl:param name="station"/>

  <!-- Returns a node set with the following elements: -->
  <!--   <rotationAngle> holds interpolated rotation angle in radians (converted from percentage grade) -->
  <!--   <hzOrigin> holds interpolated rotation origin point horizontal value -->
  <!--   <vtOrigin> holds interpolated rotation origin point vertical value -->

  <xsl:variable name="prevRotationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &gt;= Station][last()]/Rotation"/>
  </xsl:variable>

  <xsl:variable name="prevStationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &gt;= Station][last()]/Station"/>
  </xsl:variable>

  <xsl:variable name="prevHzOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &gt;= Station][last()]/HorizontalOffset"/>
  </xsl:variable>

  <xsl:variable name="prevVtOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &gt;= Station][last()]/VerticalOffset"/>
  </xsl:variable>

  <xsl:variable name="nextRotationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &lt;= Station][1]/Rotation"/>
  </xsl:variable>

  <xsl:variable name="nextStationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &lt;= Station][1]/Station"/>
  </xsl:variable>

  <xsl:variable name="nextHzOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &lt;= Station][1]/HorizontalOffset"/>
  </xsl:variable>

  <xsl:variable name="nextVtOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/Rotations/ApplyRotation[$station &lt;= Station][1]/VerticalOffset"/>
  </xsl:variable>

  <xsl:choose>
    <!-- If any of the previous ApplyRotation element values cannot be determined we must -->
    <!-- have a station prior to the first ApplyRotation element so set the rotationAngle -->
    <!-- hzOrigin and vtOrigin elements to 0.                                             -->
    <xsl:when test="(string(number($prevRotationVal)) = 'NaN') or (string(number($prevStationVal)) = 'NaN') or
                    (string(number($prevHzOffsetVal)) = 'NaN') or (string(number($prevVtOffsetVal)) = 'NaN')">
      <xsl:element name="rotationAngle">0</xsl:element>
      <xsl:element name="hzOrigin">0</xsl:element>
      <xsl:element name="vtOrigin">0</xsl:element>
    </xsl:when>

    <!-- If any of the next ApplyRotation element values cannot be determined we must have -->
    <!-- a station after the last ApplyRotation element so set the rotationAngle, hzOrigin -->
    <!-- and vtOrigin element values to those of the previous ApplyRotation element.  If   -->
    <!-- the previous and next stations are the same just return the prev values.          -->
    <xsl:when test="(string(number($nextRotationVal)) = 'NaN') or (string(number($nextStationVal)) = 'NaN') or
                    (string(number($nextHzOffsetVal)) = 'NaN') or (string(number($nextVtOffsetVal)) = 'NaN') or
                    ($prevStationVal = $nextStationVal)">
      <xsl:element name="rotationAngle">
        <!-- Convert from percentage grade value to angle in radians - change the sign to get a clockwise rotation -->
        <xsl:value-of select="math:atan(number($prevRotationVal) div -100)"/>
      </xsl:element>
      <xsl:element name="hzOrigin">
        <xsl:value-of select="$prevHzOffsetVal"/>
      </xsl:element>
      <xsl:element name="vtOrigin">
        <xsl:value-of select="$prevVtOffsetVal"/>
      </xsl:element>
    </xsl:when>

    <xsl:otherwise>
      <!-- We need to interpolate the rotation, hzOrigin and vtOrigin values -->
      <xsl:variable name="rotation" select="$prevRotationVal + ($station - $prevStationVal) div ($nextStationVal - $prevStationVal) * ($nextRotationVal - $prevRotationVal)"/>
      <xsl:element name="rotationAngle">
        <!-- Convert from interpolated percentage grade value to angle in radians - change the sign to get a clockwise rotation -->
        <xsl:value-of select="math:atan(number($rotation) div -100)"/>
      </xsl:element>
      <xsl:element name="hzOrigin">
        <xsl:value-of select="$prevHzOffsetVal + ($station - $prevStationVal) div ($nextStationVal - $prevStationVal) * ($nextHzOffsetVal - $prevHzOffsetVal)"/>
      </xsl:element>
      <xsl:element name="vtOrigin">
        <xsl:value-of select="$prevVtOffsetVal + ($station - $prevStationVal) div ($nextStationVal - $prevStationVal) * ($nextVtOffsetVal - $prevVtOffsetVal)"/>
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Return template offset values for the current station ***** -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateOffsetValues">
  <xsl:param name="station"/>

  <!-- Returns a node set with the following elements: -->
  <!--   <hzOffset> holds interpolated horizontal alignment offset value -->
  <!--   <vtOffset> holds interpolated vertical alignment offset value -->

  <xsl:variable name="prevStationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &gt;= Station][last()]/Station"/>
  </xsl:variable>

  <xsl:variable name="prevHzOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &gt;= Station][last()]/HorizontalOffset"/>
  </xsl:variable>

  <xsl:variable name="prevVtOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &gt;= Station][last()]/VerticalOffset"/>
  </xsl:variable>

  <xsl:variable name="nextStationVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &lt;= Station][1]/Station"/>
  </xsl:variable>

  <xsl:variable name="nextHzOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &lt;= Station][1]/HorizontalOffset"/>
  </xsl:variable>

  <xsl:variable name="nextVtOffsetVal">
    <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets[$station &lt;= Station][1]/VerticalOffset"/>
  </xsl:variable>

  <xsl:choose>
    <!-- If any of the previous ApplyOffsets element values cannot be determined we must  -->
    <!-- have a station prior to the first ApplyOffsets element so set the hzOffset and   -->
    <!-- vtOffset elements to 0.                                                          -->
    <xsl:when test="(string(number($prevStationVal)) = 'NaN') or
                    (string(number($prevHzOffsetVal)) = 'NaN') or (string(number($prevVtOffsetVal)) = 'NaN')">
      <xsl:element name="hzOffset">0</xsl:element>
      <xsl:element name="vtOffset">0</xsl:element>
    </xsl:when>

    <!-- If any of the next ApplyOffsets element values cannot be determined we must have -->
    <!-- a station after the last ApplyOffsets element so set the hzOffset and vtOffset   -->
    <!-- element values to those of the previous ApplyOffsets element.  If the previous   -->
    <!-- and next stations are the same just return the prev values.                      -->
    <xsl:when test="(string(number($nextStationVal)) = 'NaN') or (string(number($nextHzOffsetVal)) = 'NaN') or
                    (string(number($nextVtOffsetVal)) = 'NaN') or ($prevStationVal = $nextStationVal)">
      <xsl:element name="hzOffset">
        <xsl:value-of select="$prevHzOffsetVal"/>
      </xsl:element>
      <xsl:element name="vtOffset">
        <xsl:value-of select="$prevVtOffsetVal"/>
      </xsl:element>
    </xsl:when>

    <xsl:otherwise>
      <!-- We need to interpolate the hzOffset and vtOffset values -->
      <xsl:element name="hzOffset">
        <xsl:value-of select="$prevHzOffsetVal + ($station - $prevStationVal) div ($nextStationVal - $prevStationVal) * ($nextHzOffsetVal - $prevHzOffsetVal)"/>
      </xsl:element>
      <xsl:element name="vtOffset">
        <xsl:value-of select="$prevVtOffsetVal + ($station - $prevStationVal) div ($nextStationVal - $prevStationVal) * ($nextVtOffsetVal - $prevVtOffsetVal)"/>
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Follow Direction to Compute New Point Coords ********* -->
<!-- **************************************************************** -->
<xsl:template name="FollowDirection">
  <xsl:param name="direction"/>
  <xsl:param name="distance"/>
  <xsl:param name="startVt"/>
  <xsl:param name="startHz"/>

  <xsl:element name="vertOffset">
    <xsl:value-of select="$startVt + math:cos(number($direction)) * $distance"/>
  </xsl:element>

  <xsl:element name="horizOffset">
    <xsl:value-of select="$startHz + math:sin(number($direction)) * $distance"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Compute rectangle corner points **************** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeRectangleCoords">
  <xsl:param name="centreX"/>
  <xsl:param name="centreY"/>
  <xsl:param name="dirn"/>
  <xsl:param name="textHeight"/>
  <xsl:param name="textWidth"/>

  <xsl:variable name="tempEnd1">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn"/>
      <xsl:with-param name="distance" select="$textWidth div 2"/>
      <xsl:with-param name="startVt" select="$centreY"/>
      <xsl:with-param name="startHz" select="$centreX"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="tempEnd2">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn + math:PI()"/>
      <xsl:with-param name="distance" select="$textWidth div 2"/>
      <xsl:with-param name="startVt" select="$centreY"/>
      <xsl:with-param name="startHz" select="$centreX"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="vertex1">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn - math:PI() div 2"/>
      <xsl:with-param name="distance" select="$textHeight div 2"/>
      <xsl:with-param name="startVt" select="msxsl:node-set($tempEnd1)/vertOffset"/>
      <xsl:with-param name="startHz" select="msxsl:node-set($tempEnd1)/horizOffset"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:element name="vertex">
    <xsl:element name="x">
      <xsl:value-of select="msxsl:node-set($vertex1)/horizOffset"/>
    </xsl:element>
    <xsl:element name="y">
      <xsl:value-of select="msxsl:node-set($vertex1)/vertOffset"/>
    </xsl:element>
  </xsl:element>

  <xsl:variable name="vertex2">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn + math:PI() div 2"/>
      <xsl:with-param name="distance" select="$textHeight div 2"/>
      <xsl:with-param name="startVt" select="msxsl:node-set($tempEnd1)/vertOffset"/>
      <xsl:with-param name="startHz" select="msxsl:node-set($tempEnd1)/horizOffset"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:element name="vertex">
    <xsl:element name="x">
      <xsl:value-of select="msxsl:node-set($vertex2)/horizOffset"/>
    </xsl:element>
    <xsl:element name="y">
      <xsl:value-of select="msxsl:node-set($vertex2)/vertOffset"/>
    </xsl:element>
  </xsl:element>

  <xsl:variable name="vertex3">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn + math:PI() div 2"/>
      <xsl:with-param name="distance" select="$textHeight div 2"/>
      <xsl:with-param name="startVt" select="msxsl:node-set($tempEnd2)/vertOffset"/>
      <xsl:with-param name="startHz" select="msxsl:node-set($tempEnd2)/horizOffset"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:element name="vertex">
    <xsl:element name="x">
      <xsl:value-of select="msxsl:node-set($vertex3)/horizOffset"/>
    </xsl:element>
    <xsl:element name="y">
      <xsl:value-of select="msxsl:node-set($vertex3)/vertOffset"/>
    </xsl:element>
  </xsl:element>

  <xsl:variable name="vertex4">
    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$dirn - math:PI() div 2"/>
      <xsl:with-param name="distance" select="$textHeight div 2"/>
      <xsl:with-param name="startVt" select="msxsl:node-set($tempEnd2)/vertOffset"/>
      <xsl:with-param name="startHz" select="msxsl:node-set($tempEnd2)/horizOffset"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:element name="vertex">
    <xsl:element name="x">
      <xsl:value-of select="msxsl:node-set($vertex4)/horizOffset"/>
    </xsl:element>
    <xsl:element name="y">
      <xsl:value-of select="msxsl:node-set($vertex4)/vertOffset"/>
    </xsl:element>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Compute Inverse Distance ******************** -->
<!-- **************************************************************** -->
<xsl:template name="InverseDistance">
  <xsl:param name="deltaN"/>
  <xsl:param name="deltaE"/>

  <!-- Compute the inverse distance from the deltas -->
  <xsl:choose>  <!-- If delta values are both effectively 0 return 0 -->
    <xsl:when test="(math:abs(number($deltaN)) &lt; 0.000001) and
                    (math:abs(number($deltaE)) &lt; 0.000001)">0</xsl:when>
    <xsl:otherwise>
      <!-- Return hypotenuse distance -->
      <xsl:value-of select="math:sqrt(number($deltaN * $deltaN + $deltaE * $deltaE))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******************* Compute Inverse Azimuth ******************** -->
<!-- **************************************************************** -->
<xsl:template name="InverseAzimuth">
  <xsl:param name="deltaN"/>
  <xsl:param name="deltaE"/>
  <xsl:param name="returnInRadians" select="'false'"/>

  <!-- Compute the inverse azimuth from the deltas -->
  <xsl:variable name="absDeltaN" select="math:abs(number($deltaN))"/>
  <xsl:variable name="absDeltaE" select="math:abs(number($deltaE))"/>

  <xsl:variable name="flag">
    <xsl:choose>
      <xsl:when test="$absDeltaE &gt; $absDeltaN">1</xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="adjDeltaN">
    <xsl:choose>
      <xsl:when test="$flag"><xsl:value-of select="$absDeltaE"/></xsl:when>
      <xsl:otherwise><xsl:value-of select="$absDeltaN"/></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="adjDeltaE">
    <xsl:choose>
      <xsl:when test="$flag"><xsl:value-of select="$absDeltaN"/></xsl:when>
      <xsl:otherwise><xsl:value-of select="$absDeltaE"/></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Compute the raw angle value -->
  <xsl:variable name="angle">
    <xsl:choose>
      <xsl:when test="$adjDeltaN &lt; 0.000001">
        <xsl:value-of select="0"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="arcTanAngle" select="math:atan(number($adjDeltaE div $adjDeltaN))"/>
        <xsl:choose>
          <xsl:when test="$flag">
            <xsl:value-of select="math:PI() div 2.0 - $arcTanAngle"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$arcTanAngle"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Assemble the raw angle value into an azimuth -->
  <xsl:variable name="azimuth">
    <xsl:choose>
      <xsl:when test="$deltaE &lt; 0">
        <xsl:choose>
          <xsl:when test="$deltaN &lt; 0">
            <xsl:value-of select="math:PI() + $angle"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="math:PI() * 2 - $angle"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="$deltaN &lt; 0">
            <xsl:value-of select="math:PI() - $angle"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$angle"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Return the azimuth value in radians or decimal degrees as requested -->
  <xsl:choose>
    <xsl:when test="$returnInRadians = 'true'">
      <xsl:value-of select="$azimuth"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$azimuth * 180.0 div math:PI()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Follow Azimuth to Compute New Point Coords *********** -->
<!-- **************************************************************** -->
<xsl:template name="FollowAzimuth">
  <xsl:param name="azimuth"/>  <!-- in degrees -->
  <xsl:param name="distance"/>
  <xsl:param name="startN"/>
  <xsl:param name="startE"/>
  <xsl:param name="startElev" select="''"/>
  <xsl:param name="endElev" select="''"/>
  <xsl:param name="elevInterpLength" select="''"/>
  <xsl:param name="grade"/>

  <xsl:variable name="newElev">
    <xsl:choose>
      <xsl:when test="(string(number($startElev)) != 'NaN') and (string(number($endElev)) != 'NaN')">
        <xsl:value-of select="($startElev + $endElev) div 2.0"/> <!-- Return average elevation -->
      </xsl:when>
      <xsl:when test="(string(number($startElev)) != 'NaN') and (string(number($grade)) != 'NaN') and
                      (string(number($elevInterpLength)) != 'NaN')">
        <xsl:value-of select="$startElev + $elevInterpLength * $grade"/> <!-- Apply the grade over the interpolation length to the startElev -->
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="$startElev"/></xsl:otherwise> <!-- Return startElev elevation -->
    </xsl:choose>
  </xsl:variable>

  <!-- Return the coords as a node-set variable -->
  <xsl:element name="north" namespace="">
    <xsl:value-of select="$startN + math:cos(number($azimuth * math:PI() div 180.0)) * $distance"/>
  </xsl:element>
  <xsl:element name="east" namespace="">
    <xsl:value-of select="$startE + math:sin(number($azimuth * math:PI() div 180.0)) * $distance"/>
  </xsl:element>
  <xsl:element name="elevation" namespace="">
    <xsl:value-of select="$newElev"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Returns clockwise angle between 2 azimuths ********** -->
<!-- **************************************************************** -->
<xsl:template name="ClockwiseAngle">
  <xsl:param name="fromAzimuth"/>    <!-- Azimuths in decimal degrees -->
  <xsl:param name="toAzimuth"/>

  <!-- returns the angle from the fromAzimuth direction to the toAzimuth direction in clockwise direction -->
  <xsl:choose>
    <xsl:when test="(string(number($fromAzimuth)) = 'NaN') or (string(number($toAzimuth)) = 'NaN')"/>
    <xsl:otherwise>
      <xsl:variable name="tempAngle" select="$toAzimuth - $fromAzimuth"/>
      <xsl:call-template name="NormalisedAngle">
        <xsl:with-param name="angle" select="$tempAngle"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Return equated station value for a given station ******* -->
<!-- **************************************************************** -->
<xsl:template name="EquatedStationValue">
  <xsl:param name="station"/>
  <xsl:param name="stationEquations"/>

  <!-- Returns a node-set variable with the elements:                                                  -->
  <!--   stnValue - the equated station value                                                          -->
  <!--   zone - the equated station zone                                                               -->
  <!--   aheadStation - the ahead station for the zone (only present when equated station found)       -->
  <!--   direction - the direction (Increasing or Decreasing, only present when equated station found) -->

  <xsl:choose>
    <xsl:when test="count(msxsl:node-set($stationEquations)/ApplyStationEquation) = 0">
      <!-- No station equations defined - just return the passed in station -->
      <xsl:element name="stnValue" namespace="">
        <xsl:value-of select="$station"/>
      </xsl:element>
      <xsl:element name="zone" namespace=""></xsl:element>
    </xsl:when>

    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$station &lt; msxsl:node-set($stationEquations)/ApplyStationEquation[1]/BackStation">
          <!-- Passed in station is before the first station equation (zone 1) -->
          <xsl:element name="stnValue" namespace="">
            <xsl:value-of select="$station"/>
          </xsl:element>
          <xsl:element name="zone" namespace="">1</xsl:element>
          <xsl:element name="direction" namespace="">Increasing</xsl:element>
        </xsl:when>

        <xsl:otherwise>  <!-- Must be a station beyond the first station equation zone -->
          <xsl:variable name="equatedStns">
            <xsl:for-each select="msxsl:node-set($stationEquations)/ApplyStationEquation">
              <xsl:choose>
                <xsl:when test="($station &lt; following-sibling::*[1]/InternalStation) or (position() = last())">
                  <xsl:variable name="deltaStn" select="$station - InternalStation"/>
                  <xsl:element name="item" namespace="">
                    <xsl:element name="stnValue" namespace="">
                      <xsl:choose>
                        <xsl:when test="Direction = 'Increasing'">
                          <xsl:value-of select="AheadStation + $deltaStn"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="AheadStation - $deltaStn"/>
                        </xsl:otherwise>
                      </xsl:choose>
                    </xsl:element>
                    <xsl:element name="zone" namespace="">
                      <xsl:value-of select="position() + 1"/>
                    </xsl:element>
                    <xsl:element name="aheadStation" namespace="">
                      <xsl:value-of select="AheadStation"/>
                    </xsl:element>
                    <xsl:element name="direction" namespace="">
                      <xsl:value-of select="Direction"/>
                    </xsl:element>
                  </xsl:element>
                </xsl:when>
              </xsl:choose>
            </xsl:for-each>
          </xsl:variable>

          <xsl:element name="stnValue" namespace="">
            <xsl:value-of select="msxsl:node-set($equatedStns)/item[1]/stnValue"/>
          </xsl:element>
          <xsl:element name="zone" namespace="">
            <xsl:value-of select="msxsl:node-set($equatedStns)/item[1]/zone"/>
          </xsl:element>
          <xsl:element name="aheadStation" namespace="">
            <xsl:value-of select="msxsl:node-set($equatedStns)/item[1]/aheadStation"/>
          </xsl:element>
          <xsl:element name="direction" namespace="">
            <xsl:value-of select="msxsl:node-set($equatedStns)/item[1]/direction"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Return true station for a given equated station and zone *** -->
<!-- **************************************************************** -->
<xsl:template name="TrueStationValue">
  <xsl:param name="equatedStation"/>
  <xsl:param name="zone"/>
  <xsl:param name="stationEquations"/>

  <xsl:choose>
    <xsl:when test="count(msxsl:node-set($stationEquations)/ApplyStationEquation) = 0">
      <!-- No station equations defined - just return the passed in equated station -->
      <xsl:value-of select="$equatedStation"/>
    </xsl:when>

    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$zone = 1">  <!-- Equated station is in the first zone - return the passed in equated station -->
          <xsl:if test="$equatedStation &lt; msxsl:node-set($stationEquations)/ApplyStationEquation[1]/BackStation">
            <!-- The passed in equatedStation is before the first specified BackStation -->
            <xsl:value-of select="$equatedStation"/>
          </xsl:if>
        </xsl:when>

        <xsl:otherwise>
          <xsl:for-each select="msxsl:node-set($stationEquations)/ApplyStationEquation[number($zone - 1)]">
            <xsl:if test="((Direction = 'Increasing') and ($equatedStation &gt;= AheadStation)) or
                          ((Direction = 'Decreasing') and ($equatedStation &lt;= AheadStation))">
              <!-- The passed in equatedStation is in the correct relationship to the AheadStation -->
              <!-- Now check that if this is not the last zone the equatedStation is before the start of the next one -->
              <xsl:variable name="validValue">
                <xsl:choose>
                  <xsl:when test="$zone &lt; count(msxsl:node-set($stationEquations)/ApplyStationEquation) + 1">
                    <xsl:if test="((Direction = 'Increasing') and ($equatedStation &lt;= following-sibling::*[1]/BackStation)) or
                                  ((Direction = 'Decreasing') and ($equatedStation &gt;= following-sibling::*[1]/BackStation))">
                      <xsl:value-of select="'true'"/>
                    </xsl:if>
                  </xsl:when>
                  <xsl:otherwise>true</xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:if test="$validValue = 'true'">
                <xsl:variable name="deltaStn" select="concat(substring('-',2 - (($equatedStation - AheadStation) &lt; 0)), '1') * ($equatedStation - AheadStation)"/>
                <xsl:value-of select="InternalStation + $deltaStn"/>
              </xsl:if>
            </xsl:if>
          </xsl:for-each>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Determine centre point and radius for best fit circle **** -->
<!-- **************************************************************** -->
<xsl:template name="LeastSquaresCircleFit">
  <xsl:param name="points"/>

  <!-- This routine expects the points node-set variable to have the structure: -->
  <!--   <point>         -->
  <!--     <x>value</x>  -->
  <!--     <y>value</y>  -->
  <!--   </point>        -->
  <!-- The routine will return a node-set variable with the following elements: -->
  <!--   centreX -->
  <!--   centreY -->
  <!--   radius  -->
  
  <!-- The algorithm is based on the 'Least-Squares Circle Fit' pdf document located at -->
  <!-- http://www.dtcenter.org/met/users/docs/write_ups/circle_fit.pdf                  -->
  <!-- Written by R. Bullock                                                            -->
  
  <xsl:variable name="avgX" select="sum(msxsl:node-set($points)/point/x) div count(msxsl:node-set($points)/point)"/>
  <xsl:variable name="avgY" select="sum(msxsl:node-set($points)/point/y) div count(msxsl:node-set($points)/point)"/>

  <xsl:variable name="uvPoints">
    <xsl:for-each select="msxsl:node-set($points)/point">
      <xsl:element name="point">
        <xsl:variable name="u" select="x - $avgX"/>
        <xsl:variable name="v" select="y - $avgY"/>

        <xsl:element name="uu">
          <xsl:value-of select="$u * $u"/>
        </xsl:element>

        <xsl:element name="uv">
          <xsl:value-of select="$u * $v"/>
        </xsl:element>

        <xsl:element name="vv">
          <xsl:value-of select="$v * $v"/>
        </xsl:element>

        <xsl:element name="uuu">
          <xsl:value-of select="$u * $u * $u"/>
        </xsl:element>

        <xsl:element name="vvv">
          <xsl:value-of select="$v * $v * $v"/>
        </xsl:element>

        <xsl:element name="uvv">
          <xsl:value-of select="$u * $v * $v"/>
        </xsl:element>

        <xsl:element name="vuu">
          <xsl:value-of select="$v * $u * $u"/>
        </xsl:element>
      </xsl:element>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="uuSum"  select="sum(msxsl:node-set($uvPoints)/point/uu)"/>
  <xsl:variable name="uvSum"  select="sum(msxsl:node-set($uvPoints)/point/uv)"/>
  <xsl:variable name="vvSum"  select="sum(msxsl:node-set($uvPoints)/point/vv)"/>
  <xsl:variable name="uuuSum" select="sum(msxsl:node-set($uvPoints)/point/uuu)"/>
  <xsl:variable name="vvvSum" select="sum(msxsl:node-set($uvPoints)/point/vvv)"/>
  <xsl:variable name="uvvSum" select="sum(msxsl:node-set($uvPoints)/point/uvv)"/>
  <xsl:variable name="vuuSum" select="sum(msxsl:node-set($uvPoints)/point/vuu)"/>

  <xsl:variable name="k1" select="($uuuSum + $uvvSum) div 2.0"/>
  <xsl:variable name="k2" select="($vvvSum + $vuuSum) div 2.0"/>

  <xsl:variable name="vc" select="($k2 * $uuSum - $k1 * $uvSum) div ($vvSum * $uuSum - $uvSum * $uvSum)"/>
  <xsl:variable name="uc" select="($k1 - $vc * $uvSum) div $uuSum"/>

  <xsl:variable name="radius">
    <xsl:call-template name="Sqrt">
      <xsl:with-param name="num" select="$uc * $uc + $vc * $vc + ($uuSum + $vvSum) div count(msxsl:node-set($points)/point)"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:element name="centreX">
    <xsl:value-of select="$uc + $avgX"/>
  </xsl:element>

  <xsl:element name="centreY">
    <xsl:value-of select="$vc + $avgY"/>
  </xsl:element>
  
  <xsl:element name="radius">
    <xsl:value-of select="$radius"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Return Angle between 0 and 360 or -180 to 180 degrees **** -->
<!-- **************************************************************** -->
<xsl:template name="NormalisedAngle">
  <xsl:param name="angle"/>
  <xsl:param name="plusMinus180" select="'false'"/>

  <xsl:variable name="fullCircleAngle">
    <xsl:choose>
      <xsl:when test="$angle &lt; 0">
        <xsl:variable name="newAngle">
          <xsl:value-of select="$angle + 360.0"/>
        </xsl:variable>
        <xsl:call-template name="NormalisedAngle">
          <xsl:with-param name="angle" select="$newAngle"/>
        </xsl:call-template>
      </xsl:when>

      <xsl:when test="$angle &gt;= 360.0">
        <xsl:variable name="newAngle">
          <xsl:value-of select="$angle - 360.0"/>
        </xsl:variable>
        <xsl:call-template name="NormalisedAngle">
          <xsl:with-param name="angle" select="$newAngle"/>
        </xsl:call-template>
      </xsl:when>

      <xsl:otherwise>
        <xsl:value-of select="$angle"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="$plusMinus180 = 'false'">
      <xsl:value-of select="$fullCircleAngle"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$fullCircleAngle &lt;= 180.0">
          <xsl:value-of select="$fullCircleAngle"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$fullCircleAngle - 360.0"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Return radians angle between Specified Limits ******** -->
<!-- **************************************************************** -->
<xsl:template name="RadianAngleBetweenLimits">
  <xsl:param name="anAngle"/>
  <xsl:param name="minVal" select="0.0"/>
  <xsl:param name="maxVal" select="$Pi * 2.0"/>
  <xsl:param name="incVal" select="$Pi * 2.0"/>

  <xsl:variable name="angle1">
    <xsl:call-template name="AngleValueLessThanMax">
      <xsl:with-param name="inAngle" select="$anAngle"/>
      <xsl:with-param name="maxVal" select="$maxVal"/>
      <xsl:with-param name="incVal" select="$incVal"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="angle2">
    <xsl:call-template name="AngleValueGreaterThanMin">
      <xsl:with-param name="inAngle" select="$angle1"/>
      <xsl:with-param name="minVal" select="$minVal"/>
      <xsl:with-param name="incVal" select="$incVal"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:value-of select="$angle2"/>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Returns node set containing the alignment offset limits **** -->
<!-- **************************************************************** -->
<xsl:template name="GetAlignmentOffsetLimits">
  <xsl:param name="showDesignLines">Yes</xsl:param>

  <xsl:choose>
    <xsl:when test="($showDesignLines = 'Yes') and (count(msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets) != 0)">
      <xsl:variable name="hzOffsets">
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets">
          <xsl:element name="offset">
            <xsl:value-of select="HorizontalOffset"/>
          </xsl:element>
        </xsl:for-each>
      </xsl:variable>

      <xsl:variable name="sortedHzOffsets">
        <xsl:for-each select="msxsl:node-set($hzOffsets)/offset">
          <xsl:sort order="ascending" data-type="number" select="."/>
          <xsl:copy-of select="."/>
        </xsl:for-each>
      </xsl:variable>

      <xsl:element name="maxLeftOffset">
        <xsl:choose>
          <xsl:when test="msxsl:node-set($sortedHzOffsets)/offset[1] &gt;= 0.0">0</xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedHzOffsets)/offset[1]"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:element>

      <xsl:element name="maxRightOffset">
        <xsl:choose>
          <xsl:when test="msxsl:node-set($sortedHzOffsets)/offset[last()] &lt;= 0.0">0</xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedHzOffsets)/offset[last()]"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:element>

      <xsl:variable name="vtOffsets">
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/AlignmentOffsets/ApplyOffsets">
          <xsl:element name="offset">
            <xsl:value-of select="VerticalOffset"/>
          </xsl:element>
        </xsl:for-each>
      </xsl:variable>

      <xsl:variable name="sortedVtOffsets">
        <xsl:for-each select="msxsl:node-set($vtOffsets)/offset">
          <xsl:sort order="ascending" data-type="number" select="."/>
          <xsl:copy-of select="."/>
        </xsl:for-each>
      </xsl:variable>

      <xsl:element name="maxDownOffset">
        <xsl:choose>
          <xsl:when test="msxsl:node-set($sortedVtOffsets)/offset[1] &gt;= 0.0">0</xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedVtOffsets)/offset[1]"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:element>

      <xsl:element name="maxUpOffset">
        <xsl:choose>
          <xsl:when test="msxsl:node-set($sortedVtOffsets)/offset[last()] &lt;= 0.0">0</xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($sortedVtOffsets)/offset[last()]"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:element>
    </xsl:when>

    <xsl:otherwise>
      <xsl:element name="maxLeftOffset">0</xsl:element>
      <xsl:element name="maxRightOffset">0</xsl:element>
      <xsl:element name="maxUpOffset">0</xsl:element>
      <xsl:element name="maxDownOffset">0</xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Return the arc centre point and delta angle ********** -->
<!-- **************************************************************** -->
<xsl:template name="CalcArcCentrePointAndDeltaAngle">
  <xsl:param name="startHz"/>
  <xsl:param name="startVt"/>
  <xsl:param name="endHz"/>
  <xsl:param name="endVt"/>
  <xsl:param name="radius"/>
  <xsl:param name="largeArc"/>

  <xsl:variable name="chordLen">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$endVt - $startVt"/>
      <xsl:with-param name="deltaE" select="$endHz - $startHz"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:if test="($radius != 0.0) and ($chordLen != 0.0) and ($radius &gt;= $chordLen div 2.0)">
    <xsl:variable name="scribedAngle">  <!-- Cosine rule -->
      <xsl:value-of select="math:acos(number(($radius * $radius + $radius * $radius - $chordLen * $chordLen) div (2.0 * $radius * $radius)))"/>
    </xsl:variable>

    <xsl:element name="deltaAngle">  <!-- Degree value -->
      <xsl:choose>
        <xsl:when test="$largeArc = 'true'">
          <xsl:value-of select="(math:PI() * 2.0 - $scribedAngle) * 180.0 div math:PI()"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$scribedAngle * 180.0 div math:PI()"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:element>

    <xsl:variable name="chordDir">
      <xsl:call-template name="InverseAzimuth">
        <xsl:with-param name="deltaN" select="$endVt - $startVt"/>
        <xsl:with-param name="deltaE" select="$endHz - $startHz"/>
        <xsl:with-param name="returnInRadians">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="internalAngle" select="(math:PI() - $scribedAngle) div 2.0"/>

    <xsl:variable name="centreDir">
      <xsl:call-template name="NormalisedAngle">
        <xsl:with-param name="angle">
          <xsl:choose>
            <xsl:when test="$largeArc = 'true'">
              <xsl:value-of select="$chordDir - $internalAngle"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$chordDir + $internalAngle"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:variable>

    <xsl:call-template name="FollowDirection">
      <xsl:with-param name="direction" select="$centreDir"/>
      <xsl:with-param name="distance" select="$radius"/>
      <xsl:with-param name="startVt" select="$startVt"/>
      <xsl:with-param name="startHz" select="$startHz"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Compute end point for arc defined by delta angle ******* -->
<!-- **************************************************************** -->
<xsl:template name="CalcArcEndPoint">
  <xsl:param name="radius"/>
  <xsl:param name="deltaAngle"/>
  <xsl:param name="startHz"/>
  <xsl:param name="startVt"/>
  <xsl:param name="centreHz"/>
  <xsl:param name="centreVt"/>

  <xsl:variable name="dirnToStart">
    <xsl:call-template name="InverseAzimuth">
      <xsl:with-param name="deltaN" select="$startVt - $centreVt"/>
      <xsl:with-param name="deltaE" select="$startHz - $centreHz"/>
      <xsl:with-param name="returnInRadians">true</xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="dirnToEnd">
    <xsl:call-template name="RadianAngleBetweenLimits">
      <xsl:with-param name="anAngle" select="$dirnToStart + $deltaAngle * math:PI() div 180.0"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:call-template name="FollowDirection">
    <xsl:with-param name="direction" select="$dirnToEnd"/>
    <xsl:with-param name="distance" select="$radius"/>
    <xsl:with-param name="startVt" select="$centreVt"/>
    <xsl:with-param name="startHz" select="$centreHz"/>
  </xsl:call-template>

</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Compute rotated point coordinates ************** -->
<!-- **************************************************************** -->
<xsl:template name="ComputeRotatedPoint">
  <xsl:param name="rotationAngle"/>
  <xsl:param name="hzOrigin"/>
  <xsl:param name="vtOrigin"/>
  <xsl:param name="hzOffset"/>
  <xsl:param name="vtOffset"/>

  <!-- First need to translate the point such that the rotation origin is at 0,0 -->
  <xsl:variable name="transHzOffset" select="$hzOffset - $hzOrigin"/>
  <xsl:variable name="transVtOffset" select="$vtOffset - $vtOrigin"/>
  
  <!-- Now apply the rotation to the translated point -->
  <xsl:variable name="rotHzOffset" select="$transHzOffset * math:cos(number($rotationAngle)) - $transVtOffset * math:sin(number($rotationAngle))"/>
  <xsl:variable name="rotVtOffset" select="$transHzOffset * math:sin(number($rotationAngle)) + $transVtOffset * math:cos(number($rotationAngle))"/>

  <!-- Now translate the rotated point back into the original terms and return in horizOffset and vertOffset elements -->
  <xsl:element name="horizOffset">
    <xsl:value-of select="$rotHzOffset + $hzOrigin"/>
  </xsl:element>

  <xsl:element name="vertOffset">
    <xsl:value-of select="$rotVtOffset + $vtOrigin"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Return sum of template element lengths prior to index ***** -->
<!-- **************************************************************** -->
<xsl:template name="TemplateDistPriorToIndex">
  <xsl:param name="index"/>
  <xsl:param name="designTemplate"/>
  <xsl:param name="templateSurface"/>

  <xsl:choose>
    <xsl:when test="$index - 1 &gt; 0">
      <xsl:variable name="lengths">
        <xsl:for-each select="msxsl:node-set($designTemplate)/templateSurface[@name = $templateSurface]/element[position() &lt; $index]">
          <xsl:element name="length">
            <xsl:value-of select="length"/>
          </xsl:element>
        </xsl:for-each>
      </xsl:variable>

      <xsl:value-of select="sum(msxsl:node-set($lengths)/length)"/>  <!-- Return sum of the element lengths -->
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******** Return the distance along the template element ******** -->
<!-- **************************************************************** -->
<xsl:template name="TemplateDistAlongElement">
  <xsl:param name="element"/>
  <xsl:param name="ptHz"/>
  <xsl:param name="ptVt"/>

  <xsl:choose>
    <xsl:when test="msxsl:node-set($element)/radius">  <!-- Arc element -->
      <xsl:variable name="centreTostartPtDir">
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="msxsl:node-set($element)/startVt - msxsl:node-set($element)/centreVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($element)/startHz - msxsl:node-set($element)/centreHz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="centreToPtDir">
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="$ptVt - msxsl:node-set($element)/centreVt"/>
          <xsl:with-param name="deltaE" select="$ptHz - msxsl:node-set($element)/centreHz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="angleToPt">
        <xsl:call-template name="RadiansClockwiseAngle">
          <xsl:with-param name="fromDir" select="$centreTostartPtDir"/>
          <xsl:with-param name="toDir" select="$centreToPtDir"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:value-of select="$angleToPt * msxsl:node-set($element)/radius"/>  <!-- Return arc length for given angle -->
    </xsl:when>

    <xsl:otherwise>  <!-- Line element -->
      <xsl:variable name="lineDir">
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="msxsl:node-set($element)/endVt - msxsl:node-set($element)/startVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($element)/endHz - msxsl:node-set($element)/startHz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="lineLen">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="msxsl:node-set($element)/endVt - msxsl:node-set($element)/startVt"/>
          <xsl:with-param name="deltaE" select="msxsl:node-set($element)/endHz - msxsl:node-set($element)/startHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="startToPtDir">
        <xsl:call-template name="InverseAzimuth">
          <xsl:with-param name="deltaN" select="$ptVt - msxsl:node-set($element)/startVt"/>
          <xsl:with-param name="deltaE" select="$ptHz - msxsl:node-set($element)/startHz"/>
          <xsl:with-param name="returnInRadians">true</xsl:with-param>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="distFromStartPt">
        <xsl:call-template name="InverseDistance">
          <xsl:with-param name="deltaN" select="$ptVt - msxsl:node-set($element)/startVt"/>
          <xsl:with-param name="deltaE" select="$ptHz - msxsl:node-set($element)/startHz"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="deltaAngle" select="$startToPtDir - $lineDir"/>

      <xsl:variable name="calcDist" select="math:cos(number($deltaAngle)) * $distFromStartPt"/> <!-- Return projected distance onto line -->

      <xsl:choose>
        <xsl:when test="$calcDist &lt; $lineLen">
          <xsl:value-of select="$calcDist"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$lineLen"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Extract design template elements *************** -->
<!-- **************************************************************** -->
<xsl:template name="ExtractDesignElements">
  <xsl:param name="station"/>

  <xsl:variable name="templateNames">
    <xsl:call-template name="GetTemplateNames">
      <xsl:with-param name="station" select="$station"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:if test="msxsl:node-set($templateNames)/prevTemplateName != ''">
    <xsl:variable name="prevTemplate">
      <xsl:call-template name="GetTemplateElements">
        <xsl:with-param name="templateName" select="msxsl:node-set($templateNames)/prevTemplateName"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="nextTemplate">
      <xsl:call-template name="GetTemplateElements">
        <xsl:with-param name="templateName" select="msxsl:node-set($templateNames)/nextTemplateName"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="templatesAreEquivalent">
      <xsl:choose>
        <xsl:when test="msxsl:node-set($templateNames)/nextTemplateName = ''">true</xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="TemplatesAreEquivalent">
            <xsl:with-param name="prevTemplate" select="$prevTemplate"/>
            <xsl:with-param name="nextTemplate" select="$nextTemplate"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="(msxsl:node-set($templateNames)/prevTemplateName = msxsl:node-set($templateNames)/nextTemplateName) or
                      (msxsl:node-set($templateNames)/nextTemplateName = '') or ($templatesAreEquivalent = 'true')">
        <!-- Both templates are the same or there is no next template - return the active surfaces for prevTemplate -->
        <xsl:for-each select="msxsl:node-set($templateNames)/prevTemplateSurfaces/Surface[Used = 'true']">
          <xsl:variable name="surfName" select="Name"/>
          <xsl:for-each select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfName]">
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </xsl:for-each>
      </xsl:when>

      <xsl:otherwise>
        <xsl:variable name="templateSurfacesToUse">
          <xsl:call-template name="GetCommonTemplateSurfaces">
            <xsl:with-param name="templateNames" select="$templateNames"/>
          </xsl:call-template>
        </xsl:variable>
        
        <!-- Work through the common template surfaces determining whether they can be interpolated -->
        <xsl:for-each select="msxsl:node-set($templateSurfacesToUse)/surface">
          <xsl:variable name="surfaceName" select="."/>

          <!-- Need to compute an interpolated template if both template surfaces have same number of elements -->
          <xsl:if test="count(msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]/element) = count(msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]/element)">
            <xsl:variable name="deltaStation" select="msxsl:node-set($templateNames)/nextTemplateStation - msxsl:node-set($templateNames)/prevTemplateStation"/>
            <xsl:variable name="ratio" select="($station - msxsl:node-set($templateNames)/prevTemplateStation) div $deltaStation"/>

            <xsl:element name="templateSurface">
              <xsl:attribute name="name">
                <xsl:value-of select="$surfaceName"/>
              </xsl:attribute>

              <!-- Use a special Norwegian interpolation method if the previous and next templates each contain -->
              <!-- 3 or 5 sequential tangential arc elements and the template elements are not inclined.        -->
              <xsl:variable name="useNorwegianInterpolation">
                <xsl:variable name="prevNorwegianStyleSection">
                  <xsl:call-template name="NorwegianStyleSection">
                    <xsl:with-param name="templateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="nextNorwegianStyleSection">
                  <xsl:call-template name="NorwegianStyleSection">
                    <xsl:with-param name="templateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="matchingArcIndices">
                  <xsl:variable name="prevArcIndices">
                    <xsl:call-template name="SequentialArcCount">
                      <xsl:with-param name="templateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:variable name="nextArcIndices">
                    <xsl:call-template name="SequentialArcCount">
                      <xsl:with-param name="templateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:if test="(msxsl:node-set($prevArcIndices)/firstArcIndex = msxsl:node-set($nextArcIndices)/firstArcIndex) and
                                (msxsl:node-set($prevArcIndices)/lastArcIndex = msxsl:node-set($nextArcIndices)/lastArcIndex)">true</xsl:if>
                </xsl:variable>

                <xsl:if test="($prevNorwegianStyleSection = 'true') and ($nextNorwegianStyleSection = 'true') and
                              ($matchingArcIndices = 'true')">
                  <xsl:value-of select="'true'"/>
                </xsl:if>
              </xsl:variable>

              <xsl:choose>
                <xsl:when test="$useNorwegianInterpolation = 'true'">
                  <xsl:variable name="norwegianInterpArcs">
                    <xsl:call-template name="NorwegianInterpolatedArcs">
                      <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                      <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                      <xsl:with-param name="ratio" select="$ratio"/>
                    </xsl:call-template>
                  </xsl:variable>

                  <xsl:call-template name="AssembleCompleteNorwegianTemplate">
                    <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="norwegianInterpArcs" select="$norwegianInterpArcs"/>
                    <xsl:with-param name="ratio" select="$ratio"/>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>  <!-- Use standard interpolation -->
                  <xsl:call-template name="StandardInterpolatedElements">
                    <xsl:with-param name="prevTemplateSurf" select="msxsl:node-set($prevTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="nextTemplateSurf" select="msxsl:node-set($nextTemplate)/templateSurface[@name = $surfaceName]"/>
                    <xsl:with-param name="ratio" select="$ratio"/>
                  </xsl:call-template>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:element>   <!-- templateSurface -->
          </xsl:if>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Get the design template elements *************** -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateElements">
  <xsl:param name="templateName"/>

  <!-- Build up a node set of the template element components -->
  <xsl:variable name="templateDeltas">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface) != 0">
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface">
          <xsl:element name="templateSurface">
            <xsl:attribute name="name">
              <xsl:value-of select="Name"/>
            </xsl:attribute>

            <xsl:call-template name="GetTemplateDeltas"/>
          </xsl:element>  <!-- templateSurface element -->
        </xsl:for-each>
      </xsl:when>

      <xsl:otherwise>  <!-- An old txl file with no surfaces defined in it -->
        <xsl:for-each select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]">
          <xsl:element name="templateSurface">
            <xsl:attribute name="name">
              <xsl:value-of select="'DefaultXSLSurface'"/>  <!-- Unique default name for surface -->
            </xsl:attribute>

            <xsl:call-template name="GetTemplateDeltas"/>
          </xsl:element>  <!-- templateSurface element -->
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>   <!-- templateDeltas -->

  <xsl:for-each select="msxsl:node-set($templateDeltas)/templateSurface">
    <xsl:variable name="surfaceName" select="@name"/>
    <xsl:element name="templateSurface">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
      <xsl:variable name="deltas">   <!-- Get the deltas into an appropriate node-set form to pass to AddTemplateElements function -->
        <xsl:copy-of select="*"/>
      </xsl:variable>

      <xsl:variable name="startHz">
        <xsl:choose>
          <xsl:when test="$surfaceName = 'DefaultXSLSurface'">
            <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateStartPoint/HorizontalOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface[Name = $surfaceName]/TemplateSurfaceStartPoint/HorizontalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="startVt">
        <xsl:choose>
          <xsl:when test="$surfaceName = 'DefaultXSLSurface'">
            <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateStartPoint/VerticalOffset"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="msxsl:node-set($tunnelDefinition)/TrimbleTunnel/TemplateRecord[Name = $templateName]/TemplateSurface[Name = $surfaceName]/TemplateSurfaceStartPoint/VerticalOffset"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:call-template name="AddTemplateElements">
        <xsl:with-param name="templateDeltas" select="$deltas"/>
        <xsl:with-param name="startHz" select="$startHz"/>
        <xsl:with-param name="startVt" select="$startVt"/>
      </xsl:call-template>
    </xsl:element>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ** Compute template elements by Norwegian type interpolation *** -->
<!-- **************************************************************** -->
<xsl:template name="BuildNorwegianInterpolatedArcs">
  <xsl:param name="radiusH"/>
  <xsl:param name="radiusT"/>
  <xsl:param name="radiusV"/>
  <xsl:param name="interpStartVt"/>
  <xsl:param name="interpPhi"/>
  <xsl:param name="interpYvLeft"/>
  <xsl:param name="interpYvRight"/>
  <xsl:param name="interpTransAngle"/>
  <xsl:param name="interpA"/>
  <xsl:param name="interpB"/>
  <xsl:param name="prevTemplateSurf"/>
  <xsl:param name="firstArcIdx"/>
  <xsl:param name="lastArcIdx"/>

  <xsl:variable name="centreArcIdx" select="$firstArcIdx + ($lastArcIdx - $firstArcIdx) div 2"/>

  <!-- First establish the central arc -->
  <xsl:variable name="centralArc">
    <xsl:element name="startHz">
      <xsl:value-of select="msxsl:node-set($interpA)/hz"/>
    </xsl:element>

    <xsl:element name="startVt">
      <xsl:value-of select="msxsl:node-set($interpA)/vt"/>
    </xsl:element>

    <xsl:element name="endHz">
      <xsl:value-of select="msxsl:node-set($interpB)/hz"/>
    </xsl:element>

    <xsl:element name="endVt">
      <xsl:value-of select="msxsl:node-set($interpB)/vt"/>
    </xsl:element>

    <xsl:element name="radius">
      <xsl:value-of select="$radiusH"/>
    </xsl:element>

    <xsl:element name="largeArc">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($centreArcIdx)]/largeArc"/>
    </xsl:element>

    <xsl:variable name="arcVals">
      <xsl:call-template name="CalcArcCentrePointAndDeltaAngle">
        <xsl:with-param name="radius" select="$radiusH"/>
        <xsl:with-param name="startHz" select="msxsl:node-set($interpA)/hz"/>
        <xsl:with-param name="startVt" select="msxsl:node-set($interpA)/vt"/>
        <xsl:with-param name="endHz" select="msxsl:node-set($interpB)/hz"/>
        <xsl:with-param name="endVt" select="msxsl:node-set($interpB)/vt"/>
        <xsl:with-param name="largeArc" select="msxsl:node-set($prevTemplateSurf)/element[number($centreArcIdx)]/largeArc"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:element name="centreHz">
      <xsl:value-of select="msxsl:node-set($arcVals)/horizOffset"/>
    </xsl:element>

    <xsl:element name="centreVt">
      <xsl:value-of select="msxsl:node-set($arcVals)/vertOffset"/>
    </xsl:element>

    <xsl:element name="deltaAngle">
      <xsl:value-of select="msxsl:node-set($arcVals)/deltaAngle"/>
    </xsl:element>

    <xsl:element name="length">
      <xsl:value-of select="math:abs(number($radiusH * (msxsl:node-set($arcVals)/deltaAngle * math:PI() div 180.0)))"/>
    </xsl:element>
  </xsl:variable>

  <!-- The extra portion of the first and last (wall) angles is determined by the interpYv value which specifies -->
  <!-- the vertical distance below the firstArc centre point to the lowest point of the arc.  This extra angle   -->
  <!-- in addition to the interpPhi angle is computed from extraAngle =ArcSine(interpYv / radiusV)               -->
  <xsl:variable name="extraAngleLeft" select="math:asin(number($interpYvLeft div $radiusV))"/>
  <xsl:variable name="extraAngleRight" select="math:asin(number($interpYvRight div $radiusV))"/>

  <!-- Potential transition arc -->
  <xsl:variable name="transArc1">
    <xsl:if test="$lastArcIdx - $firstArcIdx + 1 = 5">
      <xsl:element name="endHz">
        <xsl:value-of select="msxsl:node-set($interpA)/hz"/>
      </xsl:element>

      <xsl:element name="endVt">
        <xsl:value-of select="msxsl:node-set($interpA)/vt"/>
      </xsl:element>

      <xsl:variable name="centreHz">
        <xsl:value-of select="msxsl:node-set($centralArc)/startHz + (msxsl:node-set($centralArc)/centreHz - msxsl:node-set($centralArc)/startHz) * $radiusT div $radiusH"/>
      </xsl:variable>

      <xsl:element name="centreHz">
        <xsl:value-of select="$centreHz"/>
      </xsl:element>

      <xsl:variable name="centreVt">
        <xsl:value-of select="msxsl:node-set($centralArc)/startVt + (msxsl:node-set($centralArc)/centreVt - msxsl:node-set($centralArc)/startVt) * $radiusT div $radiusH"/>
      </xsl:variable>

      <xsl:element name="centreVt">
        <xsl:value-of select="$centreVt"/>
      </xsl:element>

      <xsl:element name="radius">
        <xsl:value-of select="$radiusT"/>
      </xsl:element>

      <xsl:variable name="startPt">
        <xsl:call-template name="CalcArcEndPoint">
          <xsl:with-param name="radius" select="$radiusT"/>
          <xsl:with-param name="deltaAngle" select="$interpTransAngle * -180.0 div math:PI()"/>  <!-- Degrees value reqd and needs to be negated -->
          <xsl:with-param name="startHz" select="msxsl:node-set($interpA)/hz"/>
          <xsl:with-param name="startVt" select="msxsl:node-set($interpA)/vt"/>
          <xsl:with-param name="centreHz" select="$centreHz"/>
          <xsl:with-param name="centreVt" select="$centreVt"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:element name="startHz">
        <xsl:value-of select="msxsl:node-set($startPt)/horizOffset"/>
      </xsl:element>

      <xsl:element name="startVt">
        <xsl:value-of select="msxsl:node-set($startPt)/vertOffset"/>
      </xsl:element>

      <xsl:element name="largeArc">
        <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx) + 1]/largeArc"/>
      </xsl:element>

      <xsl:element name="deltaAngle">
        <xsl:value-of select="$interpTransAngle * 180.0 div math:PI()"/>  <!-- In degrees -->
      </xsl:element>

      <xsl:element name="length">
        <xsl:value-of select="math:abs(number($radiusT * $interpTransAngle))"/>
      </xsl:element>
    </xsl:if>
  </xsl:variable>

  <!-- Now build the first arc -->
  <xsl:variable name="firstArc">
    <xsl:choose>
      <xsl:when test="$lastArcIdx - $firstArcIdx + 1 = 5"> <!-- There is a transition arc - join on to it -->
        <xsl:element name="endHz">
          <xsl:value-of select="msxsl:node-set($transArc1)/startHz"/>
        </xsl:element>

        <xsl:element name="endVt">
          <xsl:value-of select="msxsl:node-set($transArc1)/startVt"/>
        </xsl:element>

        <xsl:variable name="centreHz">
          <xsl:value-of select="msxsl:node-set($transArc1)/startHz + (msxsl:node-set($transArc1)/centreHz - msxsl:node-set($transArc1)/startHz) *
                                $radiusV div $radiusT"/>
        </xsl:variable>

        <xsl:element name="centreHz">
          <xsl:value-of select="$centreHz"/>
        </xsl:element>

        <xsl:variable name="centreVt">
          <xsl:value-of select="msxsl:node-set($transArc1)/startVt + (msxsl:node-set($transArc1)/centreVt - msxsl:node-set($transArc1)/startVt) *
                                $radiusV div $radiusT"/>
        </xsl:variable>

        <xsl:element name="centreVt">
          <xsl:value-of select="$centreVt"/>
        </xsl:element>

        <xsl:variable name="startPt">
          <xsl:call-template name="CalcArcEndPoint">
            <xsl:with-param name="radius" select="$radiusV"/>
            <xsl:with-param name="deltaAngle" select="($interpPhi + $extraAngleLeft) * -180.0 div math:PI()"/>  <!-- Degrees value reqd and needs to be negated -->
            <xsl:with-param name="startHz" select="msxsl:node-set($transArc1)/startHz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($transArc1)/startVt"/>
            <xsl:with-param name="centreHz" select="$centreHz"/>
            <xsl:with-param name="centreVt" select="$centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:element name="startHz">
          <xsl:value-of select="msxsl:node-set($startPt)/horizOffset"/>
        </xsl:element>

        <xsl:element name="startVt">
          <xsl:value-of select="msxsl:node-set($startPt)/vertOffset"/>
        </xsl:element>
      </xsl:when>

      <xsl:otherwise>  <!-- There is no transition arc - join on to central (roof) arc -->
        <xsl:element name="endHz">
          <xsl:value-of select="msxsl:node-set($interpA)/hz"/>
        </xsl:element>

        <xsl:element name="endVt">
          <xsl:value-of select="msxsl:node-set($interpA)/vt"/>
        </xsl:element>

        <xsl:variable name="centreHz">
          <xsl:value-of select="msxsl:node-set($centralArc)/startHz + (msxsl:node-set($centralArc)/centreHz - msxsl:node-set($centralArc)/startHz) *
                                $radiusV div $radiusH"/>
        </xsl:variable>

        <xsl:element name="centreHz">
          <xsl:value-of select="$centreHz"/>
        </xsl:element>

        <xsl:variable name="centreVt">
          <xsl:value-of select="msxsl:node-set($centralArc)/startVt + (msxsl:node-set($centralArc)/centreVt - msxsl:node-set($centralArc)/startVt) *
                                $radiusV div $radiusH"/>
        </xsl:variable>

        <xsl:element name="centreVt">
          <xsl:value-of select="$centreVt"/>
        </xsl:element>

        <xsl:variable name="startPt">
          <xsl:call-template name="CalcArcEndPoint">
            <xsl:with-param name="radius" select="$radiusV"/>
            <xsl:with-param name="deltaAngle" select="($interpPhi + $extraAngleLeft) * -180.0 div math:PI()"/>  <!-- Degrees value reqd and needs to be negated -->
            <xsl:with-param name="startHz" select="msxsl:node-set($interpA)/hz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($interpA)/vt"/>
            <xsl:with-param name="centreHz" select="$centreHz"/>
            <xsl:with-param name="centreVt" select="$centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:element name="startHz">
          <xsl:value-of select="msxsl:node-set($startPt)/horizOffset"/>
        </xsl:element>

        <xsl:element name="startVt">
          <xsl:value-of select="msxsl:node-set($startPt)/vertOffset"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>

    <xsl:element name="radius">
      <xsl:value-of select="$radiusV"/>
    </xsl:element>

    <xsl:element name="largeArc">
      <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($firstArcIdx)]/largeArc"/>
    </xsl:element>

    <xsl:element name="deltaAngle">
      <xsl:value-of select="($interpPhi + $extraAngleLeft) * 180.0 div math:PI()"/>  <!-- In degrees -->
    </xsl:element>

    <xsl:element name="length">
      <xsl:value-of select="math:abs(number($radiusV * ($interpPhi + $extraAngleLeft)))"/>
    </xsl:element>
  </xsl:variable>

  <!-- Build the second transition arc if required -->
  <xsl:variable name="transArc2">
    <xsl:if test="$lastArcIdx - $firstArcIdx + 1 = 5">
      <xsl:element name="startHz">
        <xsl:value-of select="msxsl:node-set($interpB)/hz"/>
      </xsl:element>

      <xsl:element name="startVt">
        <xsl:value-of select="msxsl:node-set($interpB)/vt"/>
      </xsl:element>

      <xsl:variable name="centreHz">
        <xsl:value-of select="msxsl:node-set($centralArc)/endHz + (msxsl:node-set($centralArc)/centreHz - msxsl:node-set($centralArc)/endHz) *$radiusT div $radiusH"/>
      </xsl:variable>

      <xsl:element name="centreHz">
        <xsl:value-of select="$centreHz"/>
      </xsl:element>

      <xsl:variable name="centreVt">
        <xsl:value-of select="msxsl:node-set($centralArc)/endVt + (msxsl:node-set($centralArc)/centreVt - msxsl:node-set($centralArc)/endVt) * $radiusT div $radiusH"/>
      </xsl:variable>

      <xsl:element name="centreVt">
        <xsl:value-of select="$centreVt"/>
      </xsl:element>

      <xsl:element name="radius">
        <xsl:value-of select="$radiusT"/>
      </xsl:element>

      <xsl:variable name="endPt">
        <xsl:call-template name="CalcArcEndPoint">
          <xsl:with-param name="radius" select="$radiusT"/>
          <xsl:with-param name="deltaAngle" select="$interpTransAngle * 180.0 div math:PI()"/>  <!-- Degrees value reqd -->
          <xsl:with-param name="startHz" select="msxsl:node-set($interpB)/hz"/>
          <xsl:with-param name="startVt" select="msxsl:node-set($interpB)/vt"/>
          <xsl:with-param name="centreHz" select="$centreHz"/>
          <xsl:with-param name="centreVt" select="$centreVt"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:element name="endHz">
        <xsl:value-of select="msxsl:node-set($endPt)/horizOffset"/>
      </xsl:element>

      <xsl:element name="endVt">
        <xsl:value-of select="msxsl:node-set($endPt)/vertOffset"/>
      </xsl:element>

      <xsl:element name="largeArc">
        <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx) - 1]/largeArc"/>
      </xsl:element>

      <xsl:element name="deltaAngle">
        <xsl:value-of select="$interpTransAngle * 180.0 div math:PI()"/>  <!-- In degrees -->
      </xsl:element>

      <xsl:element name="length">
        <xsl:value-of select="math:abs(number($radiusT * $interpTransAngle))"/>
      </xsl:element>
    </xsl:if>
  </xsl:variable>

  <!-- And finally build the last (wall) arc -->
  <xsl:variable name="lastArc">
    <xsl:choose>
      <xsl:when test="$lastArcIdx - $firstArcIdx + 1 = 5"> <!-- There is a transition arc - join on to it -->
        <xsl:element name="startHz">
          <xsl:value-of select="msxsl:node-set($transArc2)/endHz"/>
        </xsl:element>

        <xsl:element name="startVt">
          <xsl:value-of select="msxsl:node-set($transArc2)/endVt"/>
        </xsl:element>

        <xsl:variable name="centreHz">
          <xsl:value-of select="msxsl:node-set($transArc2)/endHz + (msxsl:node-set($transArc2)/centreHz - msxsl:node-set($transArc2)/endHz) *
                                $radiusV div $radiusT"/>
        </xsl:variable>

        <xsl:element name="centreHz">
          <xsl:value-of select="$centreHz"/>
        </xsl:element>

        <xsl:variable name="centreVt">
          <xsl:value-of select="msxsl:node-set($transArc2)/endVt + (msxsl:node-set($transArc2)/centreVt - msxsl:node-set($transArc2)/endVt) *
                                $radiusV div $radiusT"/>
        </xsl:variable>

        <xsl:element name="centreVt">
          <xsl:value-of select="$centreVt"/>
        </xsl:element>

        <xsl:variable name="endPt">
          <xsl:call-template name="CalcArcEndPoint">
            <xsl:with-param name="radius" select="$radiusV"/>
            <xsl:with-param name="deltaAngle" select="($interpPhi + $extraAngleRight) * 180.0 div math:PI()"/>  <!-- Degrees value reqd -->
            <xsl:with-param name="startHz" select="msxsl:node-set($transArc2)/endHz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($transArc2)/endVt"/>
            <xsl:with-param name="centreHz" select="$centreHz"/>
            <xsl:with-param name="centreVt" select="$centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:element name="endHz">
          <xsl:value-of select="msxsl:node-set($endPt)/horizOffset"/>
        </xsl:element>

        <xsl:element name="endVt">
          <xsl:value-of select="msxsl:node-set($endPt)/vertOffset"/>
        </xsl:element>

        <xsl:element name="radius">
          <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx)]/radius"/>
        </xsl:element>

        <xsl:element name="largeArc">
          <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx)]/largeArc"/>
        </xsl:element>
      </xsl:when>

      <xsl:otherwise>  <!-- There is no transition arc - join on to central (roof) arc -->
        <xsl:element name="startHz">
          <xsl:value-of select="msxsl:node-set($interpB)/hz"/>
        </xsl:element>

        <xsl:element name="startVt">
          <xsl:value-of select="msxsl:node-set($interpB)/vt"/>
        </xsl:element>

        <xsl:variable name="centreHz">
          <xsl:value-of select="msxsl:node-set($centralArc)/endHz + (msxsl:node-set($centralArc)/centreHz - msxsl:node-set($centralArc)/endHz) *
                                $radiusV div $radiusH"/>
        </xsl:variable>

        <xsl:element name="centreHz">
          <xsl:value-of select="$centreHz"/>
        </xsl:element>

        <xsl:variable name="centreVt">
          <xsl:value-of select="msxsl:node-set($centralArc)/endVt + (msxsl:node-set($centralArc)/centreVt - msxsl:node-set($centralArc)/endVt) *
                                $radiusV div $radiusH"/>
        </xsl:variable>

        <xsl:element name="centreVt">
          <xsl:value-of select="$centreVt"/>
        </xsl:element>

        <xsl:variable name="endPt">
          <xsl:call-template name="CalcArcEndPoint">
            <xsl:with-param name="radius" select="$radiusV"/>
            <xsl:with-param name="deltaAngle" select="($interpPhi + $extraAngleRight) * 180.0 div math:PI()"/>  <!-- Degrees value reqd -->
            <xsl:with-param name="startHz" select="msxsl:node-set($interpB)/hz"/>
            <xsl:with-param name="startVt" select="msxsl:node-set($interpB)/vt"/>
            <xsl:with-param name="centreHz" select="$centreHz"/>
            <xsl:with-param name="centreVt" select="$centreVt"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:element name="endHz">
          <xsl:value-of select="msxsl:node-set($endPt)/horizOffset"/>
        </xsl:element>

        <xsl:element name="endVt">
          <xsl:value-of select="msxsl:node-set($endPt)/vertOffset"/>
        </xsl:element>

        <xsl:element name="radius">
          <xsl:value-of select="$radiusV"/>
        </xsl:element>

        <xsl:element name="largeArc">
          <xsl:value-of select="msxsl:node-set($prevTemplateSurf)/element[number($lastArcIdx)]/largeArc"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>

    <xsl:element name="deltaAngle">
      <xsl:value-of select="($interpPhi + $extraAngleRight) * 180.0 div math:PI()"/>  <!-- In degrees -->
    </xsl:element>

    <xsl:element name="length">
      <xsl:value-of select="math:abs(number($radiusV * ($interpPhi + $extraAngleRight)))"/>
    </xsl:element>
  </xsl:variable>

  <!-- At this point the interpolated cross-section is lined up horizontally and vertically based on the    -->
  <!-- interpolated positions of the A and B points.  It seems reasonable that the cross-sections should    -->
  <!-- line up at the bottom so determine the vertical offset, if any, between the computed arc1 start      -->
  <!-- point y value and interpStartY then apply it to the y values of the points defining the interpolated -->
  <!-- cross-section.                                                                                       -->
  <!-- However if the first (left) and last (right) arcs were not the same length (interpYvLeft and         -->
  <!-- interpYvRight are not be equal) then skip this step as we do not have a level base to work from      -->
  <xsl:variable name="compare" select="concat(substring('-',2 - (($interpYvLeft - $interpYvRight) &lt; 0)), '1') * ($interpYvLeft - $interpYvRight)"/>
  <xsl:variable name="vertAdj">
    <xsl:choose>
      <xsl:when test="compare &lt; 0.005">
        <xsl:value-of select="$interpStartVt - msxsl:node-set($firstArc)/startVt"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- Now create the section elements with the vertical adjustment applied -->
  <xsl:element name="element">
    <xsl:copy-of select="msxsl:node-set($firstArc)/startHz"/>
    <xsl:element name="startVt">
      <xsl:value-of select="msxsl:node-set($firstArc)/startVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($firstArc)/endHz"/>
    <xsl:element name="endVt">
      <xsl:value-of select="msxsl:node-set($firstArc)/endVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($firstArc)/radius"/>
    <xsl:copy-of select="msxsl:node-set($firstArc)/largeArc"/>
    <xsl:copy-of select="msxsl:node-set($firstArc)/centreHz"/>
    <xsl:element name="centreVt">
      <xsl:value-of select="msxsl:node-set($firstArc)/centreVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($firstArc)/deltaAngle"/>
    <xsl:copy-of select="msxsl:node-set($firstArc)/length"/>
  </xsl:element>

  <xsl:if test="count(msxsl:node-set($transArc1)/*) != 0">  <!-- We have a transition arc -->
    <xsl:element name="element">
      <xsl:copy-of select="msxsl:node-set($transArc1)/startHz"/>
      <xsl:element name="startVt">
        <xsl:value-of select="msxsl:node-set($transArc1)/startVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc1)/endHz"/>
      <xsl:element name="endVt">
        <xsl:value-of select="msxsl:node-set($transArc1)/endVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc1)/radius"/>
      <xsl:copy-of select="msxsl:node-set($transArc1)/largeArc"/>
      <xsl:copy-of select="msxsl:node-set($transArc1)/centreHz"/>
      <xsl:element name="centreVt">
        <xsl:value-of select="msxsl:node-set($transArc1)/centreVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc1)/deltaAngle"/>
      <xsl:copy-of select="msxsl:node-set($transArc1)/length"/>
    </xsl:element>
  </xsl:if>

  <xsl:element name="element">
    <xsl:copy-of select="msxsl:node-set($centralArc)/startHz"/>
    <xsl:element name="startVt">
      <xsl:value-of select="msxsl:node-set($centralArc)/startVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($centralArc)/endHz"/>
    <xsl:element name="endVt">
      <xsl:value-of select="msxsl:node-set($centralArc)/endVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($centralArc)/radius"/>
    <xsl:copy-of select="msxsl:node-set($centralArc)/largeArc"/>
    <xsl:copy-of select="msxsl:node-set($centralArc)/centreHz"/>
    <xsl:element name="centreVt">
      <xsl:value-of select="msxsl:node-set($centralArc)/centreVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($centralArc)/deltaAngle"/>
    <xsl:copy-of select="msxsl:node-set($centralArc)/length"/>
  </xsl:element>

  <xsl:if test="count(msxsl:node-set($transArc2)/*) != 0">  <!-- We have a transition arc -->
    <xsl:element name="element">
      <xsl:copy-of select="msxsl:node-set($transArc2)/startHz"/>
      <xsl:element name="startVt">
        <xsl:value-of select="msxsl:node-set($transArc2)/startVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc2)/endHz"/>
      <xsl:element name="endVt">
        <xsl:value-of select="msxsl:node-set($transArc2)/endVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc2)/radius"/>
      <xsl:copy-of select="msxsl:node-set($transArc2)/largeArc"/>
      <xsl:copy-of select="msxsl:node-set($transArc2)/centreHz"/>
      <xsl:element name="centreVt">
        <xsl:value-of select="msxsl:node-set($transArc2)/centreVt + $vertAdj"/>
      </xsl:element>
      <xsl:copy-of select="msxsl:node-set($transArc2)/deltaAngle"/>
      <xsl:copy-of select="msxsl:node-set($transArc2)/length"/>
    </xsl:element>
  </xsl:if>

  <xsl:element name="element">
    <xsl:copy-of select="msxsl:node-set($lastArc)/startHz"/>
    <xsl:element name="startVt">
      <xsl:value-of select="msxsl:node-set($lastArc)/startVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($lastArc)/endHz"/>
    <xsl:element name="endVt">
      <xsl:value-of select="msxsl:node-set($lastArc)/endVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($lastArc)/radius"/>
    <xsl:copy-of select="msxsl:node-set($lastArc)/largeArc"/>
    <xsl:copy-of select="msxsl:node-set($lastArc)/centreHz"/>
    <xsl:element name="centreVt">
      <xsl:value-of select="msxsl:node-set($lastArc)/centreVt + $vertAdj"/>
    </xsl:element>
    <xsl:copy-of select="msxsl:node-set($lastArc)/deltaAngle"/>
    <xsl:copy-of select="msxsl:node-set($lastArc)/length"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Return angle normalised between -Pi and Pi radians ****** -->
<!-- **************************************************************** -->
<xsl:template name="NormalisedAngleBetweenPlusMinusPi">
  <xsl:param name="inAngle"/>

  <xsl:choose>
    <xsl:when test="$inAngle &lt; math:PI() * -1.0">
      <xsl:call-template name="NormalisedAngleBetweenPlusMinusPi">
        <xsl:with-param name="inAngle" select="$inAngle + 2.0 * math:PI()"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:when test="$inAngle &gt; math:PI()">
      <xsl:call-template name="NormalisedAngleBetweenPlusMinusPi">
        <xsl:with-param name="inAngle" select="$inAngle - math:PI() * 2.0"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$inAngle"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Returns clockwise angle between 2 directions ********* -->
<!-- **************************************************************** -->
<xsl:template name="RadiansClockwiseAngle">
  <xsl:param name="fromDir"/>    <!-- Directions in radians -->
  <xsl:param name="toDir"/>

  <!-- returns the angle from the fromDir direction to the toDir direction in clockwise direction -->
  <xsl:choose>
    <xsl:when test="(string(number($fromDir)) = 'NaN') or (string(number($toDir)) = 'NaN')"/>
    <xsl:otherwise>
      <xsl:variable name="tempAngle" select="$toDir - $fromDir"/>

      <xsl:call-template name="RadianAngleBetweenLimits">
        <xsl:with-param name="anAngle" select="$tempAngle"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *********** Return The Elevation At Specified Station ********** -->
<!-- **************************************************************** -->
<xsl:template name="ElevationAtStation">
  <xsl:param name="theStation"/>
  <xsl:param name="vertAlignment"/>

  <xsl:variable name="station">  <!-- Check for the passed in station value being within 0.0005 of the vertical alignment start or end station -->
    <xsl:variable name="startDelta" select="math:abs(number($theStation - msxsl:node-set($vertAlignment)/StartStation))"/>
    <xsl:variable name="endDelta" select="math:abs(number($theStation - msxsl:node-set($vertAlignment)/EndStation))"/>
    <xsl:choose>
      <xsl:when test="$startDelta &lt; 0.0005">
        <xsl:value-of select="msxsl:node-set($vertAlignment)/StartStation"/>
      </xsl:when>
      <xsl:when test="$endDelta &lt; 0.0005">
        <xsl:value-of select="msxsl:node-set($vertAlignment)/EndStation"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$theStation"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="($station &lt; msxsl:node-set($vertAlignment)/StartStation) or
                    ($station &gt; msxsl:node-set($vertAlignment)/EndStation)">
      <xsl:value-of select="''"/>  <!-- Return null -->
    </xsl:when>

    <xsl:otherwise>
      <xsl:for-each select="msxsl:node-set($vertAlignment)/*[(name(.) != 'StartStation') and (name(.) != 'EndStation')]">
        <xsl:variable name="stationIP" select="number(IntersectionPoint/Station)"/>
        <xsl:variable name="nextStnIP" select="number(following-sibling::*[1]/IntersectionPoint/Station)"/>
        <xsl:if test="($station &gt;= $stationIP) and (($station &lt; $nextStnIP) or (string(number($nextStnIP)) = 'NaN'))">
        <xsl:variable name="elevIP" select="IntersectionPoint/Elevation"/>
        <xsl:variable name="endStn">
          <xsl:choose>
            <xsl:when test="name(.) = 'VerticalPoint'">
              <xsl:value-of select="$stationIP"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="EndPoint/Station"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="nextStartStn">
          <xsl:choose>
            <xsl:when test="name(following-sibling::*[1]) = 'VerticalPoint'">
              <xsl:value-of select="following-sibling::*[1]/IntersectionPoint/Station"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="following-sibling::*[1]/StartPoint/Station"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <!-- We have located the vertical IP before or equal to the required station -->
        <xsl:choose>
          <!-- When at a vertical point simply return its elevation -->
          <xsl:when test="($station = $stationIP) and (name(.) = 'VerticalPoint')">
            <xsl:value-of select="$elevIP"/>
          </xsl:when>

          <!-- When on a grade compute the elevation along the grade -->
          <xsl:when test="($station &gt;= $endStn) and ($station &lt;= $nextStartStn)">
            <!-- In case the grade value recorded in the rxl file is incorrect (due to non-tangential -->
            <!-- vertical curves entered by start and end station and elevation values for example)   -->
            <!-- compute the grade based on the previous and next elevations and stations.            -->
            <xsl:variable name="endElev">
              <xsl:choose>
                <xsl:when test="name(.) = 'VerticalPoint'">
                  <xsl:value-of select="IntersectionPoint/Elevation"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="EndPoint/Elevation"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

            <xsl:variable name="nextElev">
              <xsl:choose>
                <xsl:when test="name(following-sibling::*[1]) = 'VerticalPoint'">
                  <xsl:value-of select="following-sibling::*[1]/IntersectionPoint/Elevation"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="following-sibling::*[1]/StartPoint/Elevation"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

            <xsl:variable name="grade">
              <xsl:variable name="computedGrade" select="($nextElev - $endElev) div ($nextStartStn - $endStn)"/>
              <xsl:choose>
                <xsl:when test="string(number($computedGrade)) != 'NaN'">
                  <xsl:value-of select="$computedGrade"/>
                </xsl:when>
                <xsl:otherwise>  <!-- Unable to compute grade - use value from file -->
                  <xsl:value-of select="GradeOut div 100.0"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

            <xsl:value-of select="$endElev + ($station - $endStn) * $grade"/>
          </xsl:when>

        <!-- When on the lead out section of this parabolic vertical curve compute the elevation on the curve -->
        <xsl:when test="((name(.) = 'VerticalParabola') or (name(.) = 'VerticalAsymmetricParabola')) and
                        ($station &lt;= $endStn)">
          <xsl:call-template name="ParabolaPointElevation">
            <xsl:with-param name="stationIP" select="$stationIP"/>
            <xsl:with-param name="gradeIn" select="GradeIn div 100.0"/>
            <xsl:with-param name="gradeOut" select="GradeOut div 100.0"/>
            <xsl:with-param name="startStn" select="StartPoint/Station"/>
            <xsl:with-param name="endStn" select="EndPoint/Station"/>
            <xsl:with-param name="startElev" select="StartPoint/Elevation"/>
            <xsl:with-param name="endElev" select="EndPoint/Elevation"/>
            <xsl:with-param name="lenIn" select="$stationIP - StartPoint/Station"/>
            <xsl:with-param name="lenOut" select="EndPoint/Station - $stationIP"/>
            <xsl:with-param name="ptStn" select="$station"/>
          </xsl:call-template>
        </xsl:when>

        <!-- When on the lead in section of next parabolic vertical curve compute the elevation on the curve -->
        <xsl:when test="((name(following-sibling::*[1]) = 'VerticalParabola') or
                         (name(following-sibling::*[1]) = 'VerticalAsymmetricParabola')) and
                        ($station &gt;= following-sibling::*[1]/StartPoint/Station)">
          <xsl:call-template name="ParabolaPointElevation">
            <xsl:with-param name="stationIP" select="$nextStnIP"/>
            <xsl:with-param name="gradeIn" select="following-sibling::*[1]/GradeIn div 100.0"/>
            <xsl:with-param name="gradeOut" select="following-sibling::*[1]/GradeOut div 100.0"/>
            <xsl:with-param name="startStn" select="following-sibling::*[1]/StartPoint/Station"/>
            <xsl:with-param name="endStn" select="following-sibling::*[1]/EndPoint/Station"/>
            <xsl:with-param name="startElev" select="following-sibling::*[1]/StartPoint/Elevation"/>
            <xsl:with-param name="endElev" select="following-sibling::*[1]/EndPoint/Elevation"/>
            <xsl:with-param name="lenIn" select="$nextStnIP - following-sibling::*[1]/StartPoint/Station"/>
            <xsl:with-param name="lenOut" select="following-sibling::*[1]/EndPoint/Station - $nextStnIP"/>
            <xsl:with-param name="ptStn" select="$station"/>
          </xsl:call-template>
        </xsl:when>

        <!-- When on the lead out section of this circular vertical curve compute the elevation on the curve -->
        <xsl:when test="(name(.) = 'VerticalArc') and ($station &lt;= $endStn)">
          <xsl:call-template name="CircularVertCurvePointElevation">
            <xsl:with-param name="centreStn" select="CentrePoint/Station"/>
            <xsl:with-param name="centreElev" select="CentrePoint/Elevation"/>
            <xsl:with-param name="intersectElev" select="IntersectionPoint/Elevation"/>
            <xsl:with-param name="radius" select="Radius"/>
            <xsl:with-param name="ptStn" select="$station"/>
          </xsl:call-template>
        </xsl:when>

        <!-- When on the lead in section of next circular vertical curve compute the elevation on the curve -->
        <xsl:when test="(name(following-sibling::*[1]) = 'VerticalArc') and
                        ($station &gt;= following-sibling::*[1]/StartPoint/Station)">
          <xsl:call-template name="CircularVertCurvePointElevation">
            <xsl:with-param name="centreStn" select="following-sibling::*[1]/CentrePoint/Station"/>
            <xsl:with-param name="centreElev" select="following-sibling::*[1]/CentrePoint/Elevation"/>
            <xsl:with-param name="intersectElev" select="following-sibling::*[1]/IntersectionPoint/Elevation"/>
            <xsl:with-param name="radius" select="following-sibling::*[1]/Radius"/>
            <xsl:with-param name="ptStn" select="$station"/>
          </xsl:call-template>
        </xsl:when>

      </xsl:choose>
    </xsl:if>
  </xsl:for-each>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Return The Percentage Grade At Specified Station ******* -->
<!-- **************************************************************** -->
<xsl:template name="GradeAtStationAsPercentage">
  <xsl:param name="theStation"/>
  <xsl:param name="vertAlignment"/>

  <xsl:variable name="station">  <!-- Check for the passed in station value being within 0.0005 of the vertical alignment start or end station -->
    <xsl:variable name="startDelta" select="math:abs(number($theStation - msxsl:node-set($vertAlignment)/StartStation))"/>
    <xsl:variable name="endDelta" select="math:abs(number($theStation - msxsl:node-set($vertAlignment)/EndStation))"/>
    <xsl:choose>
      <xsl:when test="$startDelta &lt; 0.0005">
        <xsl:value-of select="msxsl:node-set($vertAlignment)/StartStation"/>
      </xsl:when>
      <xsl:when test="$endDelta &lt; 0.0005">
        <xsl:value-of select="msxsl:node-set($vertAlignment)/EndStation"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$theStation"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="($station &lt; msxsl:node-set($vertAlignment)/StartStation) or
                    ($station &gt; msxsl:node-set($vertAlignment)/EndStation)">
      <xsl:value-of select="''"/>  <!-- Return null -->
    </xsl:when>

    <xsl:otherwise>
      <xsl:for-each select="msxsl:node-set($vertAlignment)/*[(name(.) != 'StartStation') and (name(.) != 'EndStation')]">
        <xsl:variable name="stationIP" select="number(IntersectionPoint/Station)"/>
        <xsl:variable name="nextStnIP" select="number(following-sibling::*[1]/IntersectionPoint/Station)"/>
        <xsl:if test="($station &gt;= $stationIP) and (($station &lt; $nextStnIP) or (string(number($nextStnIP)) = 'NaN'))">
          <xsl:variable name="endStn">
            <xsl:choose>
              <xsl:when test="name(.) = 'VerticalPoint'">
                <xsl:value-of select="$stationIP"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="EndPoint/Station"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="nextStartStn">
            <xsl:choose>
              <xsl:when test="name(following-sibling::*[1]) = 'VerticalPoint'">
                <xsl:value-of select="following-sibling::*[1]/IntersectionPoint/Station"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="following-sibling::*[1]/StartPoint/Station"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>

          <!-- We have located the vertical IP before or equal to the required station -->
          <xsl:choose>
            <!-- When at or very close to a vertical point simply return the grade in (or grade out if grade in is null -->
            <xsl:when test="(math:abs(number($station - $stationIP)) &lt; 0.00001) and (name(.) = 'VerticalPoint')">
              <xsl:variable name="grade">
                <xsl:choose>
                  <xsl:when test="string(number(GradeIn)) != 'NaN'">
                    <xsl:value-of select="GradeIn"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="GradeOut"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:value-of select="$grade"/>
            </xsl:when>

            <!-- When on a straight grade return it (the GradeOut) -->
            <xsl:when test="($station &gt;= $endStn) and ($station &lt;= $nextStartStn)">
              <xsl:value-of select="GradeOut"/>
            </xsl:when>

            <!-- When on the lead out section of this parabolic vertical curve compute the elevation on the curve -->
            <xsl:when test="((name(.) = 'VerticalParabola') or (name(.) = 'VerticalAsymmetricParabola')) and
                            ($station &lt; $endStn)">
              <xsl:call-template name="ParabolaGradeAtStationAsPercentage">
                <xsl:with-param name="startStn" select="StartPoint/Station"/>
                <xsl:with-param name="stationIP" select="IntersectionPoint/Station"/>
                <xsl:with-param name="endStn" select="EndPoint/Station"/>
                <xsl:with-param name="gradeIn" select="GradeIn div 100.0"/>
                <xsl:with-param name="gradeOut" select="GradeOut div 100.0"/>
                <xsl:with-param name="lenIn" select="IntersectionPoint/Station - StartPoint/Station"/>
                <xsl:with-param name="lenOut" select="EndPoint/Station - IntersectionPoint/Station"/>
                <xsl:with-param name="ptStn" select="$station"/>
              </xsl:call-template>
            </xsl:when>

            <!-- When on the lead in section of next parabolic vertical curve compute the elevation on the curve -->
            <xsl:when test="((name(following-sibling::*[1]) = 'VerticalParabola') or
                             (name(following-sibling::*[1]) = 'VerticalAsymmetricParabola')) and
                            ($station &gt; following-sibling::*[1]/StartPoint/Station)">
              <xsl:call-template name="ParabolaGradeAtStationAsPercentage">
                <xsl:with-param name="startStn" select="following-sibling::*[1]/StartPoint/Station"/>
                <xsl:with-param name="stationIP" select="$nextStnIP"/>
                <xsl:with-param name="endStn" select="following-sibling::*[1]/EndPoint/Station"/>
                <xsl:with-param name="gradeIn" select="following-sibling::*[1]/GradeIn div 100.0"/>
                <xsl:with-param name="gradeOut" select="following-sibling::*[1]/GradeOut div 100.0"/>
                <xsl:with-param name="lenIn" select="$nextStnIP - following-sibling::*[1]/StartPoint/Station"/>
                <xsl:with-param name="lenOut" select="following-sibling::*[1]/EndPoint/Station - $nextStnIP"/>
                <xsl:with-param name="ptStn" select="$station"/>
              </xsl:call-template>
            </xsl:when>

            <!-- When on the lead out section of this circular vertical curve compute the elevation on the curve -->
            <xsl:when test="(name(.) = 'VerticalArc') and ($station &lt; $endStn)">
              <xsl:variable name="elev">
                <xsl:call-template name="CircularVertCurvePointElevation">
                  <xsl:with-param name="centreStn" select="CentrePoint/Station"/>
                  <xsl:with-param name="centreElev" select="CentrePoint/Elevation"/>
                  <xsl:with-param name="intersectElev" select="IntersectionPoint/Elevation"/>
                  <xsl:with-param name="radius" select="Radius"/>
                  <xsl:with-param name="ptStn" select="$station"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:value-of select="(CentrePoint/Station - $station) div ($elev - CentrePoint/Elevation) * 100.0"/>
            </xsl:when>

            <!-- When on the lead in section of next circular vertical curve compute the elevation on the curve -->
            <xsl:when test="(name(following-sibling::*[1]) = 'VerticalArc') and
                            ($station &gt; following-sibling::*[1]/StartPoint/Station)">
              <xsl:variable name="elev">
                <xsl:call-template name="CircularVertCurvePointElevation">
                  <xsl:with-param name="centreStn" select="following-sibling::*[1]/CentrePoint/Station"/>
                  <xsl:with-param name="centreElev" select="following-sibling::*[1]/CentrePoint/Elevation"/>
                  <xsl:with-param name="intersectElev" select="following-sibling::*[1]/IntersectionPoint/Elevation"/>
                  <xsl:with-param name="radius" select="following-sibling::*[1]/Radius"/>
                  <xsl:with-param name="ptStn" select="$station"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:value-of select="(following-sibling::*[1]/CentrePoint/Station - $station) div ($elev - following-sibling::*[1]/CentrePoint/Elevation) * 100.0"/>
            </xsl:when>
          </xsl:choose>
        </xsl:if>
      </xsl:for-each>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *********** Return the position at the given station *********** -->
<!-- **************************************************************** -->
<xsl:template name="PositionAtStation">
  <xsl:param name="horizAlignment"/>
  <xsl:param name="station"/>

  <!-- This function returns a node set with north and east elements -->
  <!-- It uses the global $roadScaleFactor variable.                 -->
  <xsl:choose>
    <xsl:when test="$station &lt; msxsl:node-set($horizAlignment)/StartStation">Out of range</xsl:when>
    <xsl:when test="$station &gt; msxsl:node-set($horizAlignment)/EndStation">Out of range</xsl:when>
    <xsl:otherwise>
      <xsl:for-each select="msxsl:node-set($horizAlignment)/*[(name(.) != 'StartStation') and (name(.) != 'EndStation') and (name(.) != 'StartPoint')]">
        <xsl:if test="(($station &gt;= StartStation) and ($station &lt; EndStation) and (position() != last())) or
                      (($station &gt;= StartStation) and ($station &lt;= EndStation) and (position() = last()))">
          <xsl:choose>
            <xsl:when test="name(.) = 'Straight'">
              <xsl:call-template name="InterpolatedCoordinates">
                <xsl:with-param name="startN" select="StartCoordinate/North"/>
                <xsl:with-param name="startE" select="StartCoordinate/East"/>
                <xsl:with-param name="endN" select="EndCoordinate/North"/>
                <xsl:with-param name="endE" select="EndCoordinate/East"/>
                <xsl:with-param name="distAlong" select="($station - StartStation) * $roadScaleFactor"/>
              </xsl:call-template>
            </xsl:when>

            <xsl:when test="name(.) = 'Arc'">
              <xsl:variable name="distAlong" select="($station - StartStation) * $roadScaleFactor"/>
              <xsl:variable name="deflectionAngle" select="($distAlong div (Radius * $roadScaleFactor)) div 2.0"/>
              <xsl:variable name="chordLen" select="2.0 * Radius * $roadScaleFactor * math:sin(number($deflectionAngle))"/>
              <xsl:variable name="azimuth">
                <xsl:choose>
                  <xsl:when test="Direction = 'Right'">
                    <xsl:value-of select="StartAzimuth + $deflectionAngle * 180.0 div math:PI()"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="StartAzimuth - $deflectionAngle * 180.0 div math:PI()"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:call-template name="FollowAzimuth">
                <xsl:with-param name="azimuth" select="$azimuth"/>
                <xsl:with-param name="distance" select="$chordLen"/>
                <xsl:with-param name="startN" select="StartCoordinate/North"/>
                <xsl:with-param name="startE" select="StartCoordinate/East"/>
              </xsl:call-template>
            </xsl:when>

            <xsl:when test="name(.) = 'EntrySpiral'">
              <xsl:variable name="offsets">
                <xsl:call-template name="CalcSpiral">
                  <xsl:with-param name="smallRadius" select="EndRadius * $roadScaleFactor"/>
                  <xsl:with-param name="largeRadius" select="StartRadius * $roadScaleFactor"/>
                  <xsl:with-param name="length" select="Length * $roadScaleFactor"/>
                  <xsl:with-param name="spiralDist" select="($station - StartStation) * $roadScaleFactor"/>
                  <xsl:with-param name="spiralType" select="$spiralType"/>
                </xsl:call-template>
              </xsl:variable>
              
              <xsl:variable name="tempPos">
                <xsl:call-template name="FollowAzimuth">
                  <xsl:with-param name="azimuth" select="StartAzimuth"/>
                  <xsl:with-param name="distance" select="msxsl:node-set($offsets)/along"/>
                  <xsl:with-param name="startN" select="StartCoordinate/North"/>
                  <xsl:with-param name="startE" select="StartCoordinate/East"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="across">
                <xsl:choose>
                  <xsl:when test="Direction = 'Right'">
                    <xsl:value-of select="msxsl:node-set($offsets)/across"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="msxsl:node-set($offsets)/across * -1.0"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              
              <xsl:call-template name="FollowAzimuth">
                <xsl:with-param name="azimuth" select="StartAzimuth + 90.0"/>
                <xsl:with-param name="distance" select="$across"/>
                <xsl:with-param name="startN" select="msxsl:node-set($tempPos)/north"/>
                <xsl:with-param name="startE" select="msxsl:node-set($tempPos)/east"/>
              </xsl:call-template>
            </xsl:when>

            <xsl:when test="name(.) = 'ExitSpiral'">
              <xsl:variable name="offsets">
                <xsl:call-template name="CalcSpiral">
                  <xsl:with-param name="smallRadius" select="StartRadius * $roadScaleFactor"/>
                  <xsl:with-param name="largeRadius" select="EndRadius * $roadScaleFactor"/>
                  <xsl:with-param name="length" select="Length * $roadScaleFactor"/>
                  <xsl:with-param name="spiralDist" select="(Length - ($station - StartStation)) * $roadScaleFactor"/>
                  <xsl:with-param name="spiralType" select="$spiralType"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="tempPos">
                <xsl:call-template name="FollowAzimuth">
                  <xsl:with-param name="azimuth" select="EndAzimuth + 180.0"/>
                  <xsl:with-param name="distance" select="msxsl:node-set($offsets)/along"/>
                  <xsl:with-param name="startN" select="EndCoordinate/North"/>
                  <xsl:with-param name="startE" select="EndCoordinate/East"/>
                </xsl:call-template>
              </xsl:variable>

              <xsl:variable name="across">
                <xsl:choose>
                  <xsl:when test="Direction = 'Right'">
                    <xsl:value-of select="msxsl:node-set($offsets)/across * -1.0"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="msxsl:node-set($offsets)/across"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>

              <xsl:call-template name="FollowAzimuth">
                <xsl:with-param name="azimuth" select="EndAzimuth - 90.0"/>
                <xsl:with-param name="distance" select="$across"/>
                <xsl:with-param name="startN" select="msxsl:node-set($tempPos)/north"/>
                <xsl:with-param name="startE" select="msxsl:node-set($tempPos)/east"/>
              </xsl:call-template>
            </xsl:when>
          </xsl:choose>
        </xsl:if>
      </xsl:for-each>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ****** Return the instantaneous azimuth given the station ****** -->
<!-- **************************************************************** -->
<xsl:template name="InstantaneousAzimuth">
  <xsl:param name="horizAlignment"/>
  <xsl:param name="station"/>

  <xsl:variable name="retAzimuth">
    <xsl:choose>
      <xsl:when test="$station &lt; msxsl:node-set($horizAlignment)/StartStation">Out of range</xsl:when>
      <xsl:when test="$station &gt; msxsl:node-set($horizAlignment)/EndStation">Out of range</xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="msxsl:node-set($horizAlignment)/*[(name(.) != 'StartStation') and (name(.) != 'EndStation') and (name(.) != 'StartPoint')]">
          <xsl:variable name="isStartStn">
            <xsl:choose>
              <xsl:when test="math:abs(number($station - StartStation)) &lt; 0.001">true</xsl:when>
              <xsl:otherwise>false</xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="isEndStn">
            <xsl:choose>
              <xsl:when test="math:abs(number($station - EndStation)) &lt; 0.001">true</xsl:when>
              <xsl:otherwise>false</xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="rndStartStn" select="format-number(StartStation, $DecPl5, 'Standard')"/>
          <xsl:variable name="rndEndStn" select="format-number(EndStation, $DecPl5, 'Standard')"/>
          <xsl:if test="($isStartStn = 'true') or (($isEndStn = 'true') and (position() = last())) or
                        (($station &gt; $rndStartStn) and ($station &lt;= $rndEndStn) and (position() != last())) or
                        (($station &gt; $rndStartStn) and ($station &lt;= $rndEndStn))">
            <xsl:choose>
              <xsl:when test="name(.) = 'Straight'">
                <xsl:element name="azimuth">
                  <xsl:value-of select="StartAzimuth"/>
                </xsl:element>
              </xsl:when>

              <xsl:when test="name(.) = 'Arc'">
                <xsl:variable name="deltaAngle" select="(($station - StartStation) div Radius) * 180.0 div math:PI()"/>
                <xsl:element name="azimuth">
                  <xsl:choose>
                    <xsl:when test="Direction = 'Right'">
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="StartAzimuth + $deltaAngle"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="StartAzimuth - $deltaAngle"/>
                      </xsl:call-template>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:when>

              <xsl:when test="name(.) = 'EntrySpiral'">
                <xsl:variable name="deflection">
                  <xsl:choose>
                    <xsl:when test="$spiralType = 'NSWCubicParabola'">
                      <xsl:variable name="transitionXc">
                        <xsl:call-template name="CalcNSWTransitionXc">
                          <xsl:with-param name="length" select="Length"/>
                          <xsl:with-param name="smallRadius" select="EndRadius"/>
                          <xsl:with-param name="largeRadius" select="StartRadius"/>
                        </xsl:call-template>
                      </xsl:variable>

                      <xsl:call-template name="CalcNSWDeflectionAtDistance">
                        <xsl:with-param name="smallRadius" select="EndRadius"/>
                        <xsl:with-param name="largeRadius" select="StartRadius"/>
                        <xsl:with-param name="length" select="Length"/>
                        <xsl:with-param name="spiralDist" select="$station - StartStation"/>
                        <xsl:with-param name="transitionXc" select="$transitionXc"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise> <!-- Clothoid spiral, Cubic spiral, Bloss spiral, CubicParabola or KoreanCubicParabola -->
                      <xsl:variable name="spiralVals">
                        <xsl:call-template name="CalcSpiral">
                          <xsl:with-param name="smallRadius" select="EndRadius"/>
                          <xsl:with-param name="largeRadius" select="StartRadius"/>
                          <xsl:with-param name="length" select="Length"/>
                          <xsl:with-param name="spiralDist" select="$station - StartStation"/>
                          <xsl:with-param name="spiralType" select="$spiralType"/>
                        </xsl:call-template>
                      </xsl:variable>
                      <xsl:value-of select="msxsl:node-set($spiralVals)/deflection"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>
                <xsl:element name="azimuth">
                  <xsl:choose>
                    <xsl:when test="Direction = 'Right'">
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="StartAzimuth + $deflection"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="StartAzimuth - $deflection"/>
                      </xsl:call-template>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:when>

              <xsl:when test="name(.) = 'ExitSpiral'">
                <xsl:variable name="deflection">
                  <xsl:choose>
                    <xsl:when test="$spiralType = 'NSWCubicParabola'">
                      <xsl:variable name="transitionXc">
                        <xsl:call-template name="CalcNSWTransitionXc">
                          <xsl:with-param name="length" select="Length"/>
                          <xsl:with-param name="smallRadius" select="StartRadius"/>
                          <xsl:with-param name="largeRadius" select="EndRadius"/>
                        </xsl:call-template>
                      </xsl:variable>

                      <xsl:call-template name="CalcNSWDeflectionAtDistance">
                        <xsl:with-param name="smallRadius" select="StartRadius"/>
                        <xsl:with-param name="largeRadius" select="EndRadius"/>
                        <xsl:with-param name="length" select="Length"/>
                        <xsl:with-param name="spiralDist" select="Length - ($station - StartStation)"/>
                        <xsl:with-param name="transitionXc" select="$transitionXc"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise> <!-- Clothoid spiral, Cubic spiral, Bloss spiral, CubicParabola or KoreanCubicParabola -->
                      <xsl:variable name="spiralVals">
                        <xsl:call-template name="CalcSpiral">
                          <xsl:with-param name="smallRadius" select="StartRadius"/>
                          <xsl:with-param name="largeRadius" select="EndRadius"/>
                          <xsl:with-param name="length" select="Length"/>
                          <xsl:with-param name="spiralDist" select="Length - ($station - StartStation)"/>
                          <xsl:with-param name="spiralType" select="$spiralType"/>
                        </xsl:call-template>
                      </xsl:variable>
                      <xsl:value-of select="msxsl:node-set($spiralVals)/deflection"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>
                <xsl:element name="azimuth">
                  <xsl:choose>
                    <xsl:when test="Direction = 'Right'">
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="EndAzimuth - $deflection"/>
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:call-template name="NormalisedAngle">
                        <xsl:with-param name="angle" select="EndAzimuth + $deflection"/>
                      </xsl:call-template>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:when>
            </xsl:choose>
          </xsl:if>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  
  <xsl:value-of select="msxsl:node-set($retAzimuth)/azimuth[1]"/>  <!-- Return only first azimuth value in case of an IP point very close to specified station -->
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Return the square root of a value ************** -->
<!-- **************************************************************** -->
<xsl:template name="Sqrt">
  <xsl:param name="num" select="0"/>       <!-- The number you want to find the square root of -->
  <xsl:param name="try" select="1"/>       <!-- The current 'try'.  This is used internally. -->
  <xsl:param name="iter" select="1"/>      <!-- The current iteration, checked against maxiter to limit loop count - used internally -->
  <xsl:param name="maxiter" select="40"/>  <!-- Set this up to insure against infinite loops - used internally -->

  <!-- This template uses Sir Isaac Newton's method of finding roots -->

  <xsl:choose>
    <xsl:when test="$num &lt; 0"></xsl:when>  <!-- Invalid input - no square root of a negative number so return null -->
    <xsl:when test="$try * $try = $num or $iter &gt; $maxiter">
      <xsl:value-of select="$try"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="Sqrt">
        <xsl:with-param name="num" select="$num"/>
        <xsl:with-param name="try" select="$try - (($try * $try - $num) div (2 * $try))"/>
        <xsl:with-param name="iter" select="$iter + 1"/>
        <xsl:with-param name="maxiter" select="$maxiter"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Return radians angle less than Specificed Maximum ****** -->
<!-- **************************************************************** -->
<xsl:template name="AngleValueLessThanMax">
  <xsl:param name="inAngle"/>
  <xsl:param name="maxVal"/>
  <xsl:param name="incVal"/>

  <xsl:choose>
    <xsl:when test="$inAngle &gt; $maxVal">
      <xsl:variable name="newAngle">
        <xsl:value-of select="$inAngle - $incVal"/>
      </xsl:variable>
      <xsl:call-template name="AngleValueLessThanMax">
        <xsl:with-param name="inAngle" select="$newAngle"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$inAngle"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************* Return radians angle greater than Zero *********** -->
<!-- **************************************************************** -->
<xsl:template name="AngleValueGreaterThanMin">
  <xsl:param name="inAngle"/>
  <xsl:param name="minVal"/>
  <xsl:param name="incVal"/>

  <xsl:choose>
    <xsl:when test="$inAngle &lt; $minVal">
      <xsl:variable name="newAngle">
        <xsl:value-of select="$inAngle + $incVal"/>
      </xsl:variable>
      <xsl:call-template name="AngleValueGreaterThanMin">
        <xsl:with-param name="inAngle" select="$newAngle"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$inAngle"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************ Get the design template element deltas ************ -->
<!-- **************************************************************** -->
<xsl:template name="GetTemplateDeltas">

  <xsl:for-each select="*">
    <xsl:choose>
      <xsl:when test="name(.) = 'LineDistanceAndVerticalDistance'">
        <xsl:element name="delta">
          <xsl:element name="hz">
            <xsl:value-of select="HorizontalDistance"/>
          </xsl:element>
          <xsl:element name="vt">
            <xsl:value-of select="VerticalDistance"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'LineDistanceAndGrade'">
        <xsl:element name="delta">
          <xsl:element name="hz">
            <xsl:value-of select="HorizontalDistance"/>
          </xsl:element>
          <xsl:element name="vt">
            <xsl:value-of select="HorizontalDistance * (Grade div 100.0)"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'LineEndpoint'">
        <xsl:element name="delta">
          <xsl:element name="endHz">
            <xsl:value-of select="HorizontalEnd"/>
          </xsl:element>
          <xsl:element name="endVt">
            <xsl:value-of select="VerticalEnd"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcEndPointAndRadius'">
        <xsl:element name="delta">
          <xsl:element name="endHz">
            <xsl:value-of select="HorizontalEnd"/>
          </xsl:element>
          <xsl:element name="endVt">
            <xsl:value-of select="VerticalEnd"/>
          </xsl:element>
          <xsl:element name="radius">
            <xsl:value-of select="Radius"/>
          </xsl:element>
          <xsl:element name="largeArc">
            <xsl:value-of select="LargeArc"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcAlignmentAndAngle'">
        <xsl:element name="delta">
          <!-- Always centred on 0,0 -->
          <xsl:element name="centreHz">0.0</xsl:element>
          <xsl:element name="centreVt">0.0</xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="DeltaAngle"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>

      <xsl:when test="name(.) = 'ArcCenterAndAngle'">
        <xsl:element name="delta">
          <xsl:element name="centreHz">
            <xsl:value-of select="HorizontalCenter"/>
          </xsl:element>
          <xsl:element name="centreVt">
            <xsl:value-of select="VerticalCenter"/>
          </xsl:element>
          <xsl:element name="deltaAngle">
            <xsl:value-of select="DeltaAngle"/>
          </xsl:element>
          <xsl:copy-of select="Code"/>
        </xsl:element>
      </xsl:when>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Return The Elevation Of A Point On A Parabola ******** -->
<!-- **************************************************************** -->
<xsl:template name="ParabolaPointElevation">
  <xsl:param name="stationIP"/>
  <xsl:param name="gradeIn"/>
  <xsl:param name="gradeOut"/>
  <xsl:param name="startStn"/>
  <xsl:param name="endStn"/>
  <xsl:param name="startElev"/>
  <xsl:param name="endElev"/>
  <xsl:param name="lenIn"/>
  <xsl:param name="lenOut"/>
  <xsl:param name="ptStn"/>

  <xsl:variable name="aOne">
    <xsl:choose>
      <xsl:when test="$lenIn + $lenOut &gt; 0.0">
        <xsl:value-of select="($gradeOut - $gradeIn) * $lenOut div ($lenIn + $lenOut)"/>
      </xsl:when>
      <xsl:otherwise>0.0</xsl:otherwise>  <!-- avoid divide by zero -->
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="aTwo">
    <xsl:choose>
      <xsl:when test="$lenIn + $lenOut &gt; 0.0">
        <xsl:value-of select="($gradeOut - $gradeIn) * $lenIn div ($lenIn + $lenOut)"/>
      </xsl:when>
      <xsl:otherwise>0.0</xsl:otherwise>  <!-- avoid divide by zero -->
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="xE" select="$ptStn - $startStn"/>
  <xsl:variable name="xX" select="$ptStn - $endStn"/>

  <xsl:choose>
    <xsl:when test="$ptStn &lt; $stationIP">
      <xsl:choose>
        <xsl:when test="$lenIn != 0.0">
          <xsl:value-of select="$startElev + $gradeIn * $xE + $aOne * $xE * $xE div (2.0 * $lenIn)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$startElev + $gradeIn * $xE"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>

    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$lenOut != 0.0">
          <xsl:value-of select="$endElev + $gradeOut * $xX + $aTwo * $xX * $xX div (2.0 * $lenOut)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$endElev + $gradeOut * $xX"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Return The Elevation Of A Point On A Circular Vert Curve *** -->
<!-- **************************************************************** -->
<xsl:template name="CircularVertCurvePointElevation">
  <xsl:param name="centreStn"/>
  <xsl:param name="centreElev"/>
  <xsl:param name="intersectElev"/>
  <xsl:param name="radius"/>
  <xsl:param name="ptStn"/>

  <xsl:variable name="dist" select="$ptStn - $centreStn"/>

  <xsl:variable name="deltaElev" select="math:sqrt(number($radius * $radius - $dist * $dist))"/>

  <xsl:choose>
    <xsl:when test="$intersectElev &lt; $centreElev">
      <xsl:value-of select="$centreElev - $deltaElev"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$centreElev + $deltaElev"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- *** Return Percentage Grade At Specified Station On Parabola *** -->
<!-- **************************************************************** -->
<xsl:template name="ParabolaGradeAtStationAsPercentage">
  <xsl:param name="startStn"/>
  <xsl:param name="stationIP"/>
  <xsl:param name="endStn"/>
  <xsl:param name="gradeIn"/>
  <xsl:param name="gradeOut"/>
  <xsl:param name="lenIn"/>
  <xsl:param name="lenOut"/>
  <xsl:param name="ptStn"/>

  <xsl:variable name="aOne">
    <xsl:choose>
      <xsl:when test="$lenIn + $lenOut &gt; 0.0">
        <xsl:value-of select="($gradeOut - $gradeIn) * $lenOut div ($lenIn + $lenOut)"/>
      </xsl:when>
      <xsl:otherwise>0.0</xsl:otherwise>  <!-- avoid divide by zero -->
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="aTwo">
    <xsl:choose>
      <xsl:when test="$lenIn + $lenOut &gt; 0.0">
        <xsl:value-of select="($gradeOut - $gradeIn) * $lenIn div ($lenIn + $lenOut)"/>
      </xsl:when>
      <xsl:otherwise>0.0</xsl:otherwise>  <!-- avoid divide by zero -->
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="xE" select="$ptStn - $startStn"/>
  <xsl:variable name="xX" select="$ptStn - $endStn"/>

  <xsl:choose>
    <xsl:when test="$ptStn &lt; $stationIP">
      <xsl:choose>
        <xsl:when test="$lenIn != 0.0">
          <xsl:value-of select="(($aOne div $lenIn) * $xE + $gradeIn) * 100.0"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="0.0"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>

    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$lenOut != 0.0">
          <xsl:value-of select="(($aTwo div $lenOut) * $xX + $gradeOut) * 100.0"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="0.0"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ** Calculate NSWCubicParabola deflection at dist along spiral ** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWDeflectionAtDistance">
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>
  <xsl:param name="length"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="transitionXc"/>

  <xsl:variable name="deflectionAtLargeRadius">
    <xsl:choose>
      <xsl:when test="string(number($largeRadius)) = 'NaN'">0</xsl:when>  <!-- Standard spiral to infinity -->
      <xsl:otherwise>
        <xsl:variable name="largeRadiusVals">  <!-- Get the along value at the large radius (spiralDist = 0) -->
          <xsl:call-template name="CalcNSWRadiusAtDistance">
            <xsl:with-param name="smallRadius" select="$smallRadius"/>
            <xsl:with-param name="largeRadius" select="$largeRadius"/>
            <xsl:with-param name="length" select="$length"/>
            <xsl:with-param name="spiralDist" select="0"/>
            <xsl:with-param name="transitionXc" select="$transitionXc"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:call-template name="CalcNSWSpiralDeflection">  <!-- Returned in degrees -->
          <xsl:with-param name="smallRadius" select="$largeRadius"/>
          <xsl:with-param name="transitionXc" select="msxsl:node-set($largeRadiusVals)/along"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="$spiralDist &lt; 0.00005">0</xsl:when>

    <xsl:when test="math:abs(number($length - $spiralDist)) &lt; 0.00005">
      <!-- At the smallest radius for the spiral -->
      <xsl:variable name="deflection">
        <xsl:call-template name="CalcNSWSpiralDeflection">  <!-- Returned in degrees -->
          <xsl:with-param name="smallRadius" select="$smallRadius"/>
          <xsl:with-param name="transitionXc" select="$transitionXc"/>
        </xsl:call-template>
      </xsl:variable>
      
      <!-- Return the deflection less the deflectionAtLargeRadius -->
      <xsl:value-of select="$deflection - $deflectionAtLargeRadius"/>
    </xsl:when>

    <xsl:otherwise>
      <!-- First get the radius at this position -->
      <xsl:variable name="radiusVals">
        <xsl:call-template name="CalcNSWRadiusAtDistance">
          <xsl:with-param name="smallRadius" select="$smallRadius"/>
          <xsl:with-param name="largeRadius" select="$largeRadius"/>
          <xsl:with-param name="length" select="$length"/>
          <xsl:with-param name="spiralDist" select="$spiralDist"/>
          <xsl:with-param name="transitionXc" select="$transitionXc"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="deflection">
        <xsl:call-template name="CalcNSWSpiralDeflection">  <!-- Returned in degrees -->
          <xsl:with-param name="smallRadius" select="msxsl:node-set($radiusVals)/radius"/>
          <xsl:with-param name="transitionXc" select="msxsl:node-set($radiusVals)/along"/>
        </xsl:call-template>
      </xsl:variable>

      <!-- Return the deflection less the deflectionAtLargeRadius -->
      <xsl:value-of select="$deflection - $deflectionAtLargeRadius"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Calculate NSWCubicParabola transitionXc value ******** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWTransitionXc">
  <xsl:param name="length"/>
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>

  <xsl:choose>
    <xsl:when test="string(number($largeRadius)) = 'NaN'">  <!-- Standard fully developed transition -->
      <xsl:call-template name="CalcNSWIterateXcStandard">
        <xsl:with-param name="transitionXc" select="$length * 0.99"/>  <!-- Initial estimate of TransitionXc value -->
        <xsl:with-param name="length" select="$length"/>
        <xsl:with-param name="smallRadius" select="$smallRadius"/>
      </xsl:call-template>
    </xsl:when>
    
    <xsl:otherwise>  <!-- Compound transition between 2 arcs -->
      <xsl:call-template name="CalcNSWIterateXcCompound">
        <xsl:with-param name="transitionXc" select="$smallRadius * 0.68"/>  <!-- Initial estimate of TransitionXc value -->
        <xsl:with-param name="length" select="$length"/>
        <xsl:with-param name="smallRadius" select="$smallRadius"/>
        <xsl:with-param name="largeRadius" select="$largeRadius"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******************** Calculate spiral deltas ******************* -->
<!-- **************************************************************** -->
<xsl:template name="CalcSpiral">
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>
  <xsl:param name="length"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="spiralType" select="'Clothoid'"/>  <!-- Can be 'Clothoid', 'Cubic', 'Bloss', 'KoreanCubicParabola' or 'NSWCubicParabola' -->

  <!-- Returns node-set variable with the elements:  -->
  <!--   along                                       -->
  <!--   across                                      -->
  <!--   deflection                                  -->

  <xsl:if test="(string(number($length)) != 'NaN') and (string(number($smallRadius)) != 'NaN') and
                (string(number($spiralDist)) != 'NaN') and ($spiralDist &gt;= 0) and ($spiralDist &lt;= $length)">
    <!-- We have valid input values -->
    <xsl:choose>
      <xsl:when test="($spiralDist = 0.0) or ($smallRadius = 0.0)">
        <xsl:element name="along" namespace="">0</xsl:element>
        <xsl:element name="across" namespace="">0</xsl:element>
        <xsl:element name="deflection" namespace="">0</xsl:element>
      </xsl:when>

      <xsl:when test="string(number($largeRadius)) = 'NaN'">  <!-- Standard spiral calculation -->
        <xsl:variable name="K" select="$smallRadius * $length"/>

        <xsl:variable name="transitionXc">
          <xsl:if test="$spiralType = 'NSWCubicParabola'">
            <xsl:call-template name="CalcNSWTransitionXc">
              <xsl:with-param name="length" select="$length"/>
              <xsl:with-param name="smallRadius" select="$smallRadius"/>
              <xsl:with-param name="largeRadius" select="$largeRadius"/>
            </xsl:call-template>
          </xsl:if>
        </xsl:variable>

        <xsl:variable name="deflectionNSW">  <!-- Returned in degrees -->
          <xsl:if test="$spiralType = 'NSWCubicParabola'">
            <xsl:call-template name="CalcNSWSpiralDeflection">
              <xsl:with-param name="smallRadius" select="$smallRadius"/>
              <xsl:with-param name="transitionXc" select="$transitionXc"/>
            </xsl:call-template>
          </xsl:if>
        </xsl:variable>

        <xsl:variable name="spiralM">
          <xsl:if test="$spiralType = 'NSWCubicParabola'">
            <xsl:value-of select="math:tan(number($deflectionNSW * math:PI() div 180.0)) div (3.0 * $transitionXc * $transitionXc)"/>
          </xsl:if>
        </xsl:variable>

        <xsl:variable name="spiralVals">
          <xsl:call-template name="CalcSpiralXY">
            <xsl:with-param name="spiralDist" select="$spiralDist"/>
            <xsl:with-param name="K" select="$K"/>
            <xsl:with-param name="spiralM" select="$spiralM"/>
            <xsl:with-param name="spiralType" select="$spiralType"/>
            <xsl:with-param name="smallRadius" select="$smallRadius"/>
            <xsl:with-param name="length" select="$length"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:element name="along" namespace="">
          <xsl:value-of select="msxsl:node-set($spiralVals)/along"/>
        </xsl:element>

        <xsl:element name="across" namespace="">
          <xsl:value-of select="msxsl:node-set($spiralVals)/across"/>
        </xsl:element>

        <!-- Now compute the spiral deflection - returned in decimal degrees -->
        <xsl:element name="deflection" namespace="">
          <xsl:choose>
            <xsl:when test="$spiralType = 'NSWCubicParabola'">
              <xsl:value-of select="$deflectionNSW"/>
            </xsl:when>

            <xsl:otherwise>
              <xsl:call-template name="CalcSpiralDeflection">
                <xsl:with-param name="smallRadius" select="$smallRadius"/>
                <xsl:with-param name="largeRadius" select="$largeRadius"/>
                <xsl:with-param name="length" select="$length"/>
                <xsl:with-param name="spiralDist" select="$spiralDist"/>
                <xsl:with-param name="along" select="msxsl:node-set($spiralVals)/along"/>
                <xsl:with-param name="spiralType" select="$spiralType"/>
              </xsl:call-template>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:element>
      </xsl:when>

      <xsl:otherwise>  <!-- Spiral between 2 arcs (only applies to Clothoid spiral, Cubic spiral and NSWCubicParabola spirals) -->
        <xsl:choose>
          <xsl:when test="$largeRadius != $smallRadius">
            <xsl:choose>
              <xsl:when test="($spiralType = 'Clothoid') or ($spiralType = 'Cubic')">
                <xsl:variable name="K" select="($smallRadius * $largeRadius * $length) div ($largeRadius - $smallRadius)"/>
                <xsl:variable name="prevLength" select="math:abs(number($K div $smallRadius)) - $length"/>
                <xsl:variable name="localDist" select="$prevLength + $spiralDist"/>
                <xsl:variable name="startDeflection" select="($prevLength * $prevLength) div (2.0 * $K)"/>

                <xsl:variable name="startDeflectionX" select="math:cos(number($startDeflection))"/>
                <xsl:variable name="startDeflectionY" select="math:sin(number($startDeflection))"/>

                <xsl:variable name="prevLenVals">
                  <xsl:call-template name="CalcSpiralXY">
                    <xsl:with-param name="spiralDist" select="$prevLength"/>
                    <xsl:with-param name="K" select="$K"/>
                    <xsl:with-param name="spiralType" select="$spiralType"/>
                    <xsl:with-param name="smallRadius" select="$smallRadius"/>
                    <xsl:with-param name="length" select="$length"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="localDistVals">
                  <xsl:call-template name="CalcSpiralXY">
                    <xsl:with-param name="spiralDist" select="$localDist"/>
                    <xsl:with-param name="K" select="$K"/>
                    <xsl:with-param name="spiralType" select="$spiralType"/>
                    <xsl:with-param name="smallRadius" select="$smallRadius"/>
                    <xsl:with-param name="length" select="$length"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="hX" select="msxsl:node-set($localDistVals)/along - msxsl:node-set($prevLenVals)/along"/>
                <xsl:variable name="hY" select="msxsl:node-set($localDistVals)/across - msxsl:node-set($prevLenVals)/across"/>

                <xsl:variable name="along" select="$hX * $startDeflectionX + $hY * $startDeflectionY"/>

                <xsl:variable name="hX2" select="$hX - $along * $startDeflectionX"/>
                <xsl:variable name="hY2" select="$hY - $along * $startDeflectionY"/>

                <xsl:element name="along" namespace="">  <!-- along value to be returned -->
                  <xsl:value-of select="$along"/>
                </xsl:element>

                <xsl:element name="across" namespace=""> <!-- across value to be returned -->
                  <xsl:value-of select="math:sqrt(number($hX2 * $hX2 + $hY2 * $hY2))"/>
                </xsl:element>

                <xsl:element name="deflection" namespace="">
                  <!-- Could call the CalcSpiralDeflection template but we already have all the required values so compute it directly -->
                  <xsl:value-of select="(($localDist * $localDist) div (2.0 * $K) - $startDeflection) * 180.0 div math:PI()"/>
                </xsl:element>
              </xsl:when>
              
              <xsl:when test="$spiralType = 'NSWCubicParabola'">  <!-- NSWCubicParabola type transition -->
                <xsl:variable name="transitionXc">
                  <xsl:call-template name="CalcNSWTransitionXc">
                    <xsl:with-param name="length" select="$length"/>
                    <xsl:with-param name="smallRadius" select="$smallRadius"/>
                    <xsl:with-param name="largeRadius" select="$largeRadius"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="fullDeflection">
                  <xsl:call-template name="CalcNSWSpiralDeflection">  <!-- Returned in degrees -->
                    <xsl:with-param name="smallRadius" select="$smallRadius"/>
                    <xsl:with-param name="transitionXc" select="$transitionXc"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="spiralM">
                  <xsl:value-of select="math:tan(number($fullDeflection * math:PI() div 180.0)) div (3.0 * $transitionXc * $transitionXc)"/>
                </xsl:variable>
                
                <xsl:variable name="deflection">
                  <xsl:call-template name="CalcNSWDeflectionAtDistance">
                    <xsl:with-param name="smallRadius" select="$smallRadius"/>
                    <xsl:with-param name="largeRadius" select="$largeRadius"/>
                    <xsl:with-param name="length" select="$length"/>
                    <xsl:with-param name="spiralDist" select="$spiralDist"/>
                    <xsl:with-param name="transitionXc" select="$transitionXc"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="fullyDevelopedLength">
                  <xsl:call-template name="CalcNSWSpiralLength">
                    <xsl:with-param name="transitionXc" select="$transitionXc"/>
                    <xsl:with-param name="spiralM" select="$spiralM"/>
                  </xsl:call-template>
                </xsl:variable>
                
                <xsl:variable name="prevLength" select="$fullyDevelopedLength - $length"/>
                <xsl:variable name="localDist" select="$prevLength + $spiralDist"/>

                <xsl:variable name="localDistVals">
                  <xsl:call-template name="CalcNSWSpiralXY">
                    <xsl:with-param name="spiralDist" select="$localDist"/>
                    <xsl:with-param name="spiralM" select="$spiralM"/>
                  </xsl:call-template>
                </xsl:variable>

                <xsl:variable name="prevLenVals">
                  <xsl:call-template name="CalcNSWSpiralXY">
                    <xsl:with-param name="spiralDist" select="$prevLength"/>
                    <xsl:with-param name="spiralM" select="$spiralM"/>
                  </xsl:call-template>
                </xsl:variable>
                
                <xsl:variable name="startDeflection" select="math:atan(number(3.0 * $spiralM * msxsl:node-set($prevLenVals)/along * msxsl:node-set($prevLenVals)/along))"/>

                <xsl:variable name="startDeflectionX" select="math:cos(number($startDeflection))"/>
                <xsl:variable name="startDeflectionY" select="math:sin(number($startDeflection))"/>

                <xsl:variable name="hX" select="msxsl:node-set($localDistVals)/along - msxsl:node-set($prevLenVals)/along"/>
                <xsl:variable name="hY" select="msxsl:node-set($localDistVals)/across - msxsl:node-set($prevLenVals)/across"/>

                <xsl:variable name="along" select="$hX * $startDeflectionX + $hY * $startDeflectionY"/>

                <xsl:variable name="hX2" select="$hX - $along * $startDeflectionX"/>
                <xsl:variable name="hY2" select="$hY - $along * $startDeflectionY"/>

                <xsl:element name="along" namespace="">  <!-- along value to be returned -->
                  <xsl:value-of select="$along"/>
                </xsl:element>

                <xsl:element name="across" namespace=""> <!-- across value to be returned -->
                  <xsl:value-of select="math:sqrt(number($hX2 * $hX2 + $hY2 * $hY2))"/>
                </xsl:element>
                
                <xsl:element name="deflection" namespace="">
                  <xsl:value-of select="$deflection - $startDeflection"/>
                </xsl:element>
              </xsl:when>
            </xsl:choose>
          </xsl:when>

          <xsl:otherwise>   <!-- This is a special case of an arc -->
            <xsl:variable name="deflectionAngle" select="$length div $smallRadius"/>

            <xsl:element name="along" namespace="">
              <xsl:value-of select="math:sin(number($deflectionAngle)) * $smallRadius"/>
            </xsl:element>

            <xsl:element name="across" namespace="">
              <xsl:value-of select="$smallRadius - math:cos(number($deflectionAngle)) * $smallRadius"/>
            </xsl:element>

            <xsl:element name="deflection" namespace="">
              <xsl:value-of select="$deflectionAngle * 180.0 div math:PI()"/>
            </xsl:element>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>


<!-- **************************************************************** -->
<!-- *************** Compute Interpolated Coordinates *************** -->
<!-- **************************************************************** -->
<xsl:template name="InterpolatedCoordinates">
  <xsl:param name="startN"/>
  <xsl:param name="startE"/>
  <xsl:param name="endN"/>
  <xsl:param name="endE"/>
  <xsl:param name="distAlong"/>
  
  <xsl:variable name="totalLen">
    <xsl:call-template name="InverseDistance">
      <xsl:with-param name="deltaN" select="$endN - $startN"/>
      <xsl:with-param name="deltaE" select="$endE - $startE"/>
    </xsl:call-template>
  </xsl:variable>
  
  <xsl:element name="north" namespace="">
    <xsl:value-of select="($endN - $startN) * $distAlong div $totalLen + $startN"/>
  </xsl:element>

  <xsl:element name="east" namespace="">
    <xsl:value-of select="($endE - $startE) * $distAlong div $totalLen + $startE"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ************* Calculate a spiral deflection angle ************** -->
<!-- **************************************************************** -->
<xsl:template name="CalcSpiralDeflection">
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>
  <xsl:param name="length"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="along"/>  <!-- Only used for KoreanCubicParabola -->
  <xsl:param name="spiralType" select="'Clothoid'"/>  <!-- Can be 'Clothoid', 'KoreanCubicParabola', 'Cubic' or 'Bloss' -->
  
  <xsl:if test="(string(number($length)) != 'NaN') and (string(number($smallRadius)) != 'NaN') and
                (string(number($spiralDist)) != 'NaN') and ($spiralDist &gt;= 0) and ($spiralDist &lt;= $length)">
    <!-- We have valid input values -->
    <xsl:choose>
      <xsl:when test="($spiralDist = 0.0) or ($smallRadius = 0.0)">
        <xsl:value-of select="0.0"/>  <!-- Return a deflection angle of 0 -->
      </xsl:when>

      <xsl:when test="string(number($largeRadius)) = 'NaN'">  <!-- Standard spiral calculation - Clothoid spiral, Cubic spiral and Cubic parabola -->
        <xsl:choose>
          <xsl:when test="($spiralType = 'Clothoid') or ($spiralType = 'Cubic')">
            <xsl:variable name="K" select="$smallRadius * $length"/>
            <xsl:value-of select="($spiralDist * $spiralDist) div (2.0 * $K) * 180.0 div math:PI()"/>
          </xsl:when>

          <xsl:when test="$spiralType = 'Bloss'">  <!-- Bloss spiral -->
            <xsl:value-of select="(math:pow(number($spiralDist), 3) div ($smallRadius * $length * $length) -
                                   math:pow(number($spiralDist), 4) div (2.0 * $smallRadius * math:pow(number($length), 3))) * 180.0 div math:PI()"/>
          </xsl:when>
          
          <xsl:otherwise>   <!-- KoreanCubicParabola -->
            <xsl:value-of select="math:atan(number($along div (2.0 * $smallRadius))) * 180.0 div math:PI()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>

      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="$largeRadius != $smallRadius">
            <!-- No partial spiral deflection computation for KoreanCubicParabola or Bloss spiral -->
            <xsl:variable name="K" select="($smallRadius * $largeRadius * $length) div ($largeRadius - $smallRadius)"/>
            <xsl:variable name="prevLength" select="math:abs(number($K div $smallRadius)) - $length"/>
            <xsl:variable name="localDist" select="$prevLength + $spiralDist"/>
            <xsl:variable name="startDeflection" select="($prevLength * $prevLength) div (2.0 * $K)"/>
            <xsl:value-of select="(($localDist * $localDist) div (2.0 * $K) - $startDeflection) * 180.0 div math:PI()"/>
          </xsl:when>

          <xsl:otherwise>   <!-- This is a special case of an arc -->
            <xsl:value-of select="($length div $smallRadius) * 180.0 div math:PI()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>

</xsl:template>


<!-- **************************************************************** -->
<!-- *** Calculate spiral deflection angle for NSWCubicParabola ***** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWSpiralDeflection">
  <xsl:param name="smallRadius"/>
  <xsl:param name="transitionXc"/>

  <xsl:variable name="sqRoot3" select="math:sqrt(3.0)"/>
  
  <xsl:variable name="arcCosValInDeg" select="math:acos(number(-3.0 * $sqRoot3 * $transitionXc div (4.0 * $smallRadius))) * (180.0 div math:PI())"/>

  <xsl:variable name="cosVal" select="math:cos(number(($arcCosValInDeg div 3.0 + 240.0) * math:PI() div 180.0))"/>

  <xsl:value-of select="math:sin(number(2.0 div $sqRoot3 * $cosVal)) * 180.0 div math:PI()"/>  <!-- Return deflection value in degrees -->
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Calculate NSWCubicParabola radius at dist along spiral **** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWRadiusAtDistance">
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>
  <xsl:param name="length"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="transitionXc"/>

  <!-- Return a node set variable that provides: -->
  <!--   radius  -->
  <!--   along   -->
  
  <xsl:variable name="deflection">  <!-- Returned in degrees -->
    <xsl:call-template name="CalcNSWSpiralDeflection">
      <xsl:with-param name="smallRadius" select="$smallRadius"/>
      <xsl:with-param name="transitionXc" select="$transitionXc"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="spiralM">
    <xsl:value-of select="math:tan(number($deflection * math:PI() div 180.0)) div (3.0 * $transitionXc * $transitionXc)"/>
  </xsl:variable>

  <xsl:variable name="spiralVals">
    <xsl:choose>
      <xsl:when test="string(number($largeRadius)) = 'NaN'"> <!-- This is a standard spiral to infinity -->
        <xsl:call-template name="CalcNSWSpiralXY">
          <xsl:with-param name="spiralDist" select="$spiralDist"/>
          <xsl:with-param name="spiralM" select="$spiralM"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>  <!-- This is a spiral between 2 arcs -->
        <xsl:variable name="totalLength">  <!-- Spiral length from infinity to smallRadius -->
          <xsl:call-template name="CalcNSWSpiralLength">
            <xsl:with-param name="transitionXc" select="$transitionXc"/>
            <xsl:with-param name="spiralM" select="$spiralM"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="lengthToPoint" select="$totalLength - ($length - $spiralDist)"/>

        <xsl:call-template name="CalcNSWSpiralXY">
          <xsl:with-param name="spiralDist" select="$lengthToPoint"/>
          <xsl:with-param name="spiralM" select="$spiralM"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="x" select="msxsl:node-set($spiralVals)/along"/>
  <xsl:variable name="term" select="1.0 + 9.0 * $spiralM * $spiralM * math:pow(number($x), 4)"/>

  <xsl:element name="radius" namespace="">
    <xsl:value-of select="math:sqrt(number(math:pow(number($term), 3))) div (6.0 * $spiralM * $x)"/>
  </xsl:element>
  
  <xsl:element name="along" namespace="">
    <xsl:value-of select="$x"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Recursive func to calc NSWCubicParabola transitionXc ***** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWIterateXcStandard">  <!-- Standard fully defined case -->
  <xsl:param name="transitionXc"/>
  <xsl:param name="length"/>
  <xsl:param name="smallRadius"/>

  <xsl:variable name="deflection">  <!-- Returned in degrees -->
    <xsl:call-template name="CalcNSWSpiralDeflection">
      <xsl:with-param name="smallRadius" select="$smallRadius"/>
      <xsl:with-param name="transitionXc" select="$transitionXc"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="spiralM">
    <xsl:value-of select="math:tan(number($deflection * math:PI() div 180.0)) div (3.0 * $transitionXc * $transitionXc)"/>
  </xsl:variable>

  <!-- Get the calculated spiral length based on the current Xc value -->
  <xsl:variable name="calcLength">
    <xsl:call-template name="CalcNSWSpiralLength">
      <xsl:with-param name="transitionXc" select="$transitionXc"/>
      <xsl:with-param name="spiralM" select="$spiralM"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="math:abs(number($calcLength - $length)) &gt; 0.0000001">
      <!-- Recurse function adjusting transitionXc value by known length to computed length proportion -->
      <xsl:call-template name="CalcNSWIterateXcStandard">
        <xsl:with-param name="transitionXc" select="$transitionXc * $length div $calcLength"/>
        <xsl:with-param name="length" select="$length"/>
        <xsl:with-param name="smallRadius" select="$smallRadius"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$transitionXc"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Recursive func to calc NSWCubicParabola transitionXc ***** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWIterateXcCompound">  <!-- Compound transition between 2 arcs case -->
  <xsl:param name="transitionXc"/>
  <xsl:param name="length"/>
  <xsl:param name="smallRadius"/>
  <xsl:param name="largeRadius"/>

  <xsl:variable name="deflection">  <!-- Returned in degrees -->
    <xsl:call-template name="CalcNSWSpiralDeflection">
      <xsl:with-param name="smallRadius" select="$smallRadius"/>
      <xsl:with-param name="transitionXc" select="$transitionXc"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="spiralM">
    <xsl:value-of select="math:tan(number($deflection * math:PI() div 180.0)) div (3.0 * $transitionXc * $transitionXc)"/>
  </xsl:variable>

  <xsl:variable name="transitionXl">
    <xsl:call-template name="CalcNSWIterateXl">
      <xsl:with-param name="transitionXl" select="1.0 div (6.0 * $spiralM * $largeRadius)"/>
      <xsl:with-param name="largeRadius" select="$largeRadius"/>
      <xsl:with-param name="spiralM" select="$spiralM"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="lenLargeRad">
    <xsl:call-template name="CalcNSWSpiralLength">
      <xsl:with-param name="transitionXc" select="$transitionXl"/>
      <xsl:with-param name="spiralM" select="$spiralM"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="totalLength">
    <xsl:call-template name="CalcNSWSpiralLength">
      <xsl:with-param name="transitionXc" select="$transitionXc"/>
      <xsl:with-param name="spiralM" select="$spiralM"/>
    </xsl:call-template>
  </xsl:variable>
  
  <xsl:choose>
    <xsl:when test="math:abs(number(($totalLength - $lenLargeRad) - $length)) &gt; 0.0000001">
      <!-- Recurse function adjusting transitionXc value by known length to computed length proportion -->
      <xsl:call-template name="CalcNSWIterateXcCompound">
        <xsl:with-param name="transitionXc" select="$transitionXc * $length div ($totalLength - $lenLargeRad)"/>
        <xsl:with-param name="length" select="$length"/>
        <xsl:with-param name="smallRadius" select="$smallRadius"/>
        <xsl:with-param name="largeRadius" select="$largeRadius"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$transitionXc"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- **************** Calculate spiral X and Y values *************** -->
<!-- **************************************************************** -->
<xsl:template name="CalcSpiralXY">
  <xsl:param name="spiralDist"/>
  <xsl:param name="K"/>           <!-- Used for Clothoid spiral, Cubic spiral and KoreanCubicParabola transitions -->
  <xsl:param name="spiralM"/>     <!-- Used for NSWCubicParabola transition -->
  <xsl:param name="spiralType"/>
  <xsl:param name="smallRadius"/> <!-- Used for Bloss spiral transition -->
  <xsl:param name="length"/>      <!-- Used for Bloss spiral transition -->

  <!-- Returns node-set variable with the elements:  -->
  <!--   along                                       -->
  <!--   across                                      -->

  <xsl:variable name="squaredDist" select="$spiralDist * $spiralDist"/>
  <xsl:variable name="t1" select="($squaredDist div (2.0 * $K)) * ($squaredDist div (2.0 * $K)) * -1.0"/>

  <xsl:choose>
    <xsl:when test="($spiralType = 'Clothoid') or ($spiralType = 'KoreanCubicParabola') or ($spiralType = 'Cubic')"> <!-- Clothoid spiral, KoreanCubicParabola or Cubic spiral -->
      <!-- Calculate displacement along entry azimuth -->
      <!-- Computation of displacement along the entry azimuth is identical for Clothoid spiral, KoreanCubicParabola and Cubic spiral -->
      <xsl:variable name="alongTerm" select="$spiralDist"/>

      <xsl:variable name="along">
        <xsl:call-template name="alongTermIter">
          <xsl:with-param name="count" select="1"/>
          <xsl:with-param name="t1" select="$t1"/>
          <xsl:with-param name="alongTerm" select="$alongTerm"/>
          <xsl:with-param name="along" select="$alongTerm"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:element name="along" namespace="">
        <xsl:value-of select="$along"/>
      </xsl:element>

      <!-- Calculate displacement normal to entry azimuth -->
      <xsl:element name="across" namespace="">
        <xsl:choose>
          <xsl:when test="$spiralType = 'Clothoid'">  <!-- Clothoid spiral -->
            <xsl:variable name="acrossTerm" select="$squaredDist * $spiralDist div (6.0 * $K)"/>

            <xsl:call-template name="acrossTermIter">
              <xsl:with-param name="count" select="1"/>
              <xsl:with-param name="t1" select="$t1"/>
              <xsl:with-param name="acrossTerm" select="$acrossTerm"/>
              <xsl:with-param name="across" select="$acrossTerm"/>
            </xsl:call-template>
          </xsl:when>

          <xsl:when test="$spiralType = 'Cubic'">
            <xsl:value-of select="$squaredDist * $spiralDist div (6.0 * $K)"/>
          </xsl:when>

          <xsl:otherwise>  <!-- KoreanCubicParabola transition -->
            <xsl:value-of select="$along * $along div (6.0 * $K div $spiralDist)"/>  <!-- No iteration required -->
          </xsl:otherwise>
        </xsl:choose>
      </xsl:element>
    </xsl:when>

    <xsl:when test="$spiralType = 'NSWCubicParabola'">  <!-- NSWCubicParabola type transition -->
      <xsl:call-template name="CalcNSWSpiralXY">
        <xsl:with-param name="spiralDist" select="$spiralDist"/>
        <xsl:with-param name="spiralM" select="$spiralM"/>
      </xsl:call-template>
    </xsl:when>
    
    <xsl:when test="$spiralType = 'Bloss'">
      <xsl:call-template name="CalcBlossSpiralXY">
        <xsl:with-param name="spiralDist" select="$spiralDist"/>
        <xsl:with-param name="smallRadius" select="$smallRadius"/>
        <xsl:with-param name="length" select="$length"/>
      </xsl:call-template>
    </xsl:when>
  </xsl:choose>

</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Calculate spiral X and Y values for NSWCubicParabola ***** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWSpiralXY">
  <xsl:param name="spiralDist"/>
  <xsl:param name="spiralM"/>

  <!-- Returns node-set variable with the elements:  -->
  <!--   along                                       -->
  <!--   across                                      -->

  <xsl:variable name="squaredDist" select="$spiralDist * $spiralDist"/>
  <xsl:variable name="t1" select="($spiralM * $squaredDist) * ($spiralM * $squaredDist) * -1"/>

  <xsl:variable name="along">
    <xsl:call-template name="alongNSWTermIter">
      <xsl:with-param name="count" select="1"/>
      <xsl:with-param name="t1" select="$t1"/>
      <xsl:with-param name="t1Start" select="$t1"/>
      <xsl:with-param name="spiralDist" select="$spiralDist"/>
      <xsl:with-param name="alongTerm" select="$spiralDist"/>
      <xsl:with-param name="along" select="$spiralDist"/>
    </xsl:call-template>
  </xsl:variable>
  
  <xsl:element name="along" namespace="">
    <xsl:value-of select="$along"/>
  </xsl:element>
  
  <xsl:element name="across" namespace="">
    <xsl:value-of select="$spiralM * $along * $along * $along"/>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********** Calculate NSWCubicParabola spiral length ************ -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWSpiralLength">
  <xsl:param name="transitionXc"/>
  <xsl:param name="spiralM"/>

  <xsl:variable name="squaredDist" select="$transitionXc * $transitionXc"/>
  <xsl:variable name="t1" select="($spiralM * $squaredDist) * ($spiralM * $squaredDist)"/>

  <xsl:call-template name="lengthNSWTermIter">
    <xsl:with-param name="count" select="1"/>
    <xsl:with-param name="t1" select="$t1"/>
    <xsl:with-param name="t1Start" select="$t1 * -1"/>
    <xsl:with-param name="transitionXc" select="$transitionXc"/>
    <xsl:with-param name="lengthTerm" select="$transitionXc"/>
    <xsl:with-param name="length" select="$transitionXc"/>
  </xsl:call-template>
</xsl:template>


<!-- **************************************************************** -->
<!-- ***** Recursive func to calc NSWCubicParabola transitionXl ***** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWIterateXl">
  <xsl:param name="transitionXl"/>
  <xsl:param name="largeRadius"/>
  <xsl:param name="spiralM"/>

  <xsl:variable name="calcLargeRadius">
    <xsl:call-template name="CalcNSWRadiusAtTangentDistance">
      <xsl:with-param name="transitionXc" select="$transitionXl"/>
      <xsl:with-param name="spiralM" select="$spiralM"/>
    </xsl:call-template>
  </xsl:variable>
  
  <xsl:choose>
    <xsl:when test="math:abs(number($calcLargeRadius - $largeRadius)) &gt; 0.0000001">
      <!-- Recurse function adjusting transitionXl value by computed large radius to known large radius proportion -->
      <xsl:call-template name="CalcNSWIterateXl">
        <xsl:with-param name="transitionXl" select="$transitionXl * $calcLargeRadius div $largeRadius"/>
        <xsl:with-param name="largeRadius" select="$largeRadius"/>
        <xsl:with-param name="spiralM" select="$spiralM"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$transitionXl"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<xsl:template name="acrossTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="30"/>
  <xsl:param name="t1"/>
  <xsl:param name="acrossTerm"/>
  <xsl:param name="across"/>

  <xsl:variable name="resolution" select="0.0000001"/>

  <xsl:choose>
    <xsl:when test="(math:abs(number($acrossTerm)) &gt; $resolution) and
                    ($count &lt; $maxIter)">
      <xsl:variable name="t2" select="((4 * $count + 3) * $count * (4 * $count + 2))"/>
      <xsl:variable name="term" select="$acrossTerm * ($t1 * ((4 * $count - 1) div $t2))"/>
      <!-- Now recurse function -->
      <xsl:call-template name="acrossTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1"/>
        <xsl:with-param name="acrossTerm" select="$term"/>
        <xsl:with-param name="across" select="$across + $term"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$across"/>  <!-- Return the iterated across value -->
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>


<xsl:template name="alongTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="30"/>
  <xsl:param name="t1"/>
  <xsl:param name="alongTerm"/>
  <xsl:param name="along"/>

  <xsl:variable name="resolution" select="0.0000001"/>

  <xsl:choose>
    <xsl:when test="(math:abs(number($alongTerm)) &gt; $resolution) and
                    ($count &lt; $maxIter)">
      <xsl:variable name="t2" select="((4 * $count + 1) * $count * (4 * $count - 2))"/>
      <xsl:variable name="term" select="$alongTerm * ($t1 * ((4 * $count - 3) div $t2))"/>
      <!-- Now recurse function -->
      <xsl:call-template name="alongTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1"/>
        <xsl:with-param name="alongTerm" select="$term"/>
        <xsl:with-param name="along" select="$along + $term"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$along"/>  <!-- Return the iterated along value -->
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>


<xsl:template name="alongNSWTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="5"/>
  <xsl:param name="t1"/>
  <xsl:param name="t1Start"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="alongTerm"/>
  <xsl:param name="along"/>

  <xsl:variable name="resolution" select="0.0000001"/>

  <xsl:choose>
    <xsl:when test="(math:abs(number($alongTerm)) &gt; $resolution) and
                    ($count &lt; $maxIter)">
      <xsl:variable name="t2">
        <xsl:choose>
          <xsl:when test="$count = 1">0.9</xsl:when>
          <xsl:when test="$count = 2">5.175</xsl:when>
          <xsl:when test="$count = 3">43.1948</xsl:when>
          <xsl:when test="$count = 4">426.0564</xsl:when>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="term" select="$t1 * $t2 * $spiralDist"/>

      <!-- Now recurse function -->
      <xsl:call-template name="alongNSWTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1 * $t1Start"/>
        <xsl:with-param name="t1Start" select="$t1Start"/>
        <xsl:with-param name="spiralDist" select="$spiralDist"/>
        <xsl:with-param name="alongTerm" select="$term"/>
        <xsl:with-param name="along" select="$along + $term"/>
      </xsl:call-template>
    </xsl:when>
    
    <xsl:otherwise>
      <xsl:value-of select="$along"/>  <!-- Return the iterated along value -->
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<xsl:template name="lengthNSWTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="5"/>
  <xsl:param name="t1"/>
  <xsl:param name="t1Start"/>
  <xsl:param name="transitionXc"/>
  <xsl:param name="lengthTerm"/>
  <xsl:param name="length"/>

  <xsl:variable name="resolution" select="0.0000001"/>

  <xsl:choose>
    <xsl:when test="(math:abs(number($lengthTerm)) &gt; $resolution) and
                    ($count &lt; $maxIter)">
      <xsl:variable name="t2">
        <xsl:choose>
          <xsl:when test="$count = 1">0.9</xsl:when>
          <xsl:when test="$count = 2">1.125</xsl:when>   <!-- 9.0 / 8.0 -->
          <xsl:when test="$count = 3"><xsl:value-of select="729.0 div 208.0"/></xsl:when>
          <xsl:when test="$count = 4"><xsl:value-of select="32805.0 div 2176.0"/></xsl:when>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="term" select="$t1 * $t2 * $transitionXc"/>

      <!-- Now recurse function -->
      <xsl:call-template name="lengthNSWTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1 * $t1Start"/>
        <xsl:with-param name="t1Start" select="$t1Start"/>
        <xsl:with-param name="transitionXc" select="$transitionXc"/>
        <xsl:with-param name="lengthTerm" select="$term"/>
        <xsl:with-param name="length" select="$length + $term"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$length"/>  <!-- Return the iterated length value -->
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ******* Calculate spiral X and Y values for Bloss spiral ******* -->
<!-- **************************************************************** -->
<xsl:template name="CalcBlossSpiralXY">
  <xsl:param name="spiralDist"/>     <!-- Distance along spiral -->
  <xsl:param name="smallRadius"/>
  <xsl:param name="length"/>         <!-- Total length of spiral -->

  <!-- Returns node-set variable with the elements:  -->
  <!--   along                                       -->
  <!--   across                                      -->

  <xsl:variable name="t1" select="$spiralDist * $spiralDist * $spiralDist div ($smallRadius * $length * $length)"/>
  <xsl:variable name="t2" select="$t1 * $spiralDist div $length"/>
  
  <xsl:element name="along" namespace="">
    <xsl:call-template name="alongBlossTermIter">
      <xsl:with-param name="count">1</xsl:with-param>
      <xsl:with-param name="t1" select="$t1"/>
      <xsl:with-param name="t2" select="$t2"/>
      <xsl:with-param name="spiralDist" select="$spiralDist"/>
      <xsl:with-param name="along">0.0</xsl:with-param>
    </xsl:call-template>
  </xsl:element>

  <xsl:element name="across" namespace="">
    <xsl:call-template name="acrossBlossTermIter">
      <xsl:with-param name="count">1</xsl:with-param>
      <xsl:with-param name="t1" select="$t1"/>
      <xsl:with-param name="t2" select="$t2"/>
      <xsl:with-param name="spiralDist" select="$spiralDist"/>
      <xsl:with-param name="across">0.0</xsl:with-param>
    </xsl:call-template>
  </xsl:element>
</xsl:template>


<!-- **************************************************************** -->
<!-- **** Calculate NSWCubicParabola radius at dist along tangent *** -->
<!-- **************************************************************** -->
<xsl:template name="CalcNSWRadiusAtTangentDistance">
  <xsl:param name="transitionXc"/>
  <xsl:param name="spiralM"/>
  
  <xsl:variable name="param1" select="1.0 + 9.0 * $spiralM * $spiralM * math:pow(number($transitionXc), 4)"/>

  <xsl:value-of select="math:sqrt(math:pow(number($param1), 3)) div (6.0 * $spiralM * $transitionXc)"/>
</xsl:template>


<xsl:template name="alongBlossTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="3"/>
  <xsl:param name="t1"/>
  <xsl:param name="t2"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="along"/>

  <xsl:choose>
    <xsl:when test="$count &lt;= $maxIter">
      <xsl:variable name="t3">
        <xsl:choose>
          <xsl:when test="$count = 1">1.0</xsl:when>
          <xsl:when test="$count = 2">
            <xsl:value-of select="- $t1 * $t1 div 14.0 +
                                    $t1 * $t2 div 16.0 -
                                    $t2 * $t2 div 72.0"/>
          </xsl:when>
          <xsl:when test="$count = 3">
            <xsl:value-of select="$t1 * $t1 * $t1 * $t1 div 312.0 -
                                  $t1 * $t1 * $t1 * $t2 div 168.0 +
                                  $t1 * $t1 * $t2 * $t2 div 240.0 -
                                  $t1 * $t2 * $t2 * $t2 div 768.0 +
                                  $t2 * $t2 * $t2 * $t2 div 6528.0"/>
          </xsl:when>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="term" select="$spiralDist * $t3"/>

      <!-- Now recurse function -->
      <xsl:call-template name="alongBlossTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1"/>
        <xsl:with-param name="t2" select="$t2"/>
        <xsl:with-param name="spiralDist" select="$spiralDist"/>
        <xsl:with-param name="along" select="$along + $term"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$along"/>  <!-- Return the iterated along value -->
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<xsl:template name="acrossBlossTermIter">
  <xsl:param name="count"/>
  <xsl:param name="maxIter" select="2"/>
  <xsl:param name="t1"/>
  <xsl:param name="t2"/>
  <xsl:param name="spiralDist"/>
  <xsl:param name="across"/>

  <xsl:choose>
    <xsl:when test="$count &lt;= $maxIter">
      <xsl:variable name="t3">
        <xsl:choose>
          <xsl:when test="$count = 1">
            <xsl:value-of select="$t1 div 4.0 - $t2 div 10.0"/>
          </xsl:when>
          <xsl:when test="$count = 2">
            <xsl:value-of select="- $t1 * $t1 * $t1 div 60.0 +
                                    $t1 * $t1 * $t2 div 44.0 -
                                    $t1 * $t2 * $t2 div 96.0 +
                                    $t2 * $t2 * $t2 div 624.0"/>
          </xsl:when>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="term" select="$spiralDist * $t3"/>

      <!-- Now recurse function -->
      <xsl:call-template name="acrossBlossTermIter">
        <xsl:with-param name="count" select="$count + 1"/>
        <xsl:with-param name="maxIter" select="$maxIter"/>
        <xsl:with-param name="t1" select="$t1"/>
        <xsl:with-param name="t2" select="$t2"/>
        <xsl:with-param name="spiralDist" select="$spiralDist"/>
        <xsl:with-param name="across" select="$across + $term"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="$across"/>  <!-- Return the iterated across value -->
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


</xsl:stylesheet>
