<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:d="http://cpee.org/ns/description/1.0" xmlns:str="http://exslt.org/strings" version="1.0">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>
  <xsl:variable name="myspacemultiplier">2</xsl:variable>
  <xsl:template match="/">
    <xsl:apply-templates select="//d:description"/>
  </xsl:template>
  <xsl:template match="//d:description">
    <xsl:apply-templates>
      <xsl:with-param name="myspace">
        <xsl:value-of select="-1*$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:apply-templates>
  </xsl:template>
  <xsl:template match="*">
    <xsl:param name="myspace"/>
    <xsl:call-template name="print-space">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="count">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:if test="name()='call' or name()='manipulate'">
      <xsl:value-of select="name()"/>
      <xsl:text> :</xsl:text>
      <xsl:value-of select="@id"/>
    </xsl:if>
    <xsl:if test="name()='call'">
      <xsl:text>, </xsl:text>
      <xsl:choose>
        <xsl:when test="count(str:tokenize(@endpoint,' ')) &gt; 1">
          <xsl:text>[</xsl:text>
          <xsl:for-each select="str:tokenize(@endpoint,' ')">
            <xsl:if test="position() &gt;1">, </xsl:if>
            <xsl:text>:</xsl:text>
            <xsl:value-of select="."/>
          </xsl:for-each>
          <xsl:text>]</xsl:text>
        </xsl:when>
        <xsl:when test="count(str:tokenize(@endpoint,' ')) = 0">
          <xsl:text>nil</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>:</xsl:text>
          <xsl:value-of select="@endpoint"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>, parameters: { </xsl:text>
      <xsl:apply-templates select="d:parameters"/>
      <xsl:text> }</xsl:text>
      <xsl:if test="d:finalize and d:finalize/text()">
        <xsl:text>, finalize: &lt;&lt;-END</xsl:text>
      </xsl:if>
      <xsl:if test="d:update and d:update/text()">
        <xsl:text>, update: &lt;&lt;-END</xsl:text>
      </xsl:if>
      <xsl:apply-templates select="d:finalize" mode="part-of-call">
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:apply-templates select="d:update" mode="part-of-call">
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='manipulate'">
      <xsl:call-template name="print-mcontent">
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='escape'">
      <xsl:text>escape</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='parallel'">
      <xsl:text>parallel</xsl:text>
      <xsl:if test="@wait">
        <xsl:text> :wait =&gt; </xsl:text>
        <xsl:value-of select="@wait"/>
      </xsl:if>
      <xsl:text> do</xsl:text>
      <xsl:call-template name="print-newline"/>
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>end</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='loop'">
      <xsl:text>loop </xsl:text>
      <xsl:if test="@mode='pre_test'">
        <xsl:choose>
          <xsl:when test="not(@language) or @language='application/x-ruby'">
            <xsl:text>pre_test{</xsl:text>
            <xsl:value-of select="@condition"/>
            <xsl:text>} </xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>pre_test("</xsl:text>
            <xsl:value-of select="@condition"/>
            <xsl:text>")</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
      <xsl:if test="@mode='post_test'">
        <xsl:choose>
          <xsl:when test="not(@language) or @language='application/x-ruby'">
            <xsl:text>post_test{</xsl:text>
            <xsl:value-of select="@condition"/>
            <xsl:text>} </xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>post_test("</xsl:text>
            <xsl:value-of select="@condition"/>
            <xsl:text>")</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
      <xsl:for-each select="@*[not(name()='language' or name()='mode' or name()='condition' or name()='svg-label')]">
        <xsl:text>, :</xsl:text>
        <xsl:value-of select="name(.)"/>
        <xsl:text> => "</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
      </xsl:for-each>
      <xsl:text> do</xsl:text>
      <xsl:call-template name="print-newline"/>
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>end</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='choose'">
      <xsl:text>choose </xsl:text>
      <xsl:choose>
        <xsl:when test="@mode='exclusive'">
          <xsl:text>:exclusive</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>:inclusive</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text> do</xsl:text>
      <xsl:call-template name="print-newline"/>
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>end</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='group'">
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
    <xsl:if test="name()='critical'">
      <xsl:text>critical :</xsl:text>
      <xsl:value-of select="@sid"/>
      <xsl:text> do</xsl:text>
      <xsl:call-template name="print-newline"/>
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>end</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
  </xsl:template>
  <xsl:template match="d:alternative">
    <xsl:param name="myspace"/>
    <xsl:call-template name="print-space">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="count">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:text>alternative </xsl:text>
    <xsl:choose>
      <xsl:when test="not(@language) or @language='application/x-ruby'">
        <xsl:text>test{</xsl:text>
        <xsl:value-of select="@condition"/>
        <xsl:text>}</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>test("</xsl:text>
        <xsl:value-of select="@condition"/>
        <xsl:text>")</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:for-each select="@*[not(name()='language' or name()='condition' or name()='svg-label')]">
      <xsl:text>, :</xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:text> => "</xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text> do</xsl:text>
    <xsl:call-template name="print-newline"/>
    <xsl:apply-templates>
      <xsl:with-param name="myspace">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:apply-templates>
    <xsl:call-template name="print-space">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="count">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:text>end</xsl:text>
    <xsl:call-template name="print-newline"/>
  </xsl:template>
  <xsl:template match="d:otherwise">
    <xsl:param name="myspace"/>
    <xsl:if test="*">
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>otherwise </xsl:text>
      <xsl:for-each select="@*[not(name()='language' or name()='condition' or name()='svg-label')]">
        <xsl:if test="position() &gt;1">, </xsl:if>
        <xsl:text>:</xsl:text>
        <xsl:value-of select="name(.)"/>
        <xsl:text> => "</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
      </xsl:for-each>
      <xsl:text> do</xsl:text>
      <xsl:call-template name="print-newline"/>
      <xsl:apply-templates>
        <xsl:with-param name="myspace">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:apply-templates>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>end</xsl:text>
      <xsl:call-template name="print-newline"/>
    </xsl:if>
  </xsl:template>
  <xsl:template match="d:parallel_branch">
    <xsl:param name="myspace"/>
    <xsl:call-template name="print-space">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="count">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:text>parallel_branch</xsl:text>
    <xsl:if test="@pass">
      <xsl:text> </xsl:text>
      <xsl:value-of select="@pass"/>
    </xsl:if>
    <xsl:text> do</xsl:text>
    <xsl:if test="@local">
      <xsl:text> |</xsl:text>
      <xsl:value-of select="@local"/>
      <xsl:text>|</xsl:text>
    </xsl:if>
    <xsl:call-template name="print-newline"/>
    <xsl:apply-templates>
      <xsl:with-param name="myspace">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:apply-templates>
    <xsl:call-template name="print-space">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="count">
        <xsl:value-of select="$myspace+$myspacemultiplier"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:text>end</xsl:text>
    <xsl:call-template name="print-newline"/>
  </xsl:template>
  <xsl:template match="d:parameters">
    <xsl:apply-templates select="d:label" mode="parameter"/>
    <xsl:apply-templates select="d:*[not(name()='label')]" mode="parameter"/>
  </xsl:template>
  <xsl:template match="d:label" mode="parameter">
    <xsl:text>:</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text> =&gt; "</xsl:text>
    <xsl:value-of select="str:replace(str:replace(text(),'\','\\'),'&quot;','\&quot;')"/>
    <xsl:text>"</xsl:text>
  </xsl:template>
  <xsl:template match="d:*[not(name()='label')]" mode="parameter">
    <xsl:if test="count(preceding-sibling::*) &gt; 0">, </xsl:if>
    <xsl:text>:</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text> =&gt; </xsl:text>

    <xsl:choose>
      <xsl:when test="count(*) &gt; 0 and name()='arguments'">
        <xsl:text>[</xsl:text>
        <xsl:apply-templates select="d:*" mode="sub"/>
        <xsl:text>]</xsl:text>
      </xsl:when>
      <xsl:when test="count(*) &gt; 0 and not(name()='arguments')">
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="d:*" mode="parameter"/>
        <xsl:text>}</xsl:text>
      </xsl:when>
      <xsl:when test="not(node())">
        <xsl:text>nil</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="text()"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="d:*" mode="sub">
    <xsl:if test="count(preceding-sibling::*) &gt; 0">, </xsl:if>
    <xsl:text>⭐(</xsl:text>
    <xsl:text>:name =&gt; :</xsl:text>
    <xsl:choose>
      <xsl:when test="contains(name(),'-')">
        <xsl:text>'</xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text>'</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="name()"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>, :value =&gt; </xsl:text>
    <xsl:choose>
      <xsl:when test="not(node())">
        <xsl:text>nil</xsl:text>
      </xsl:when>
      <xsl:when test="child::node()[not(self::text())]">
        <xsl:text>"[</xsl:text>
        <xsl:apply-templates select="*" mode="JSON"/>
        <xsl:text> ]"</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="substring(text(),1,1) = '!'">
            <xsl:value-of select="substring(text(),2)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>"</xsl:text>
            <xsl:value-of select="str:replace(str:replace(text(),'\','\\'),'&quot;','\&quot;')"/>
            <xsl:text>"</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:for-each select="@*">
      <xsl:text>, :</xsl:text>
      <xsl:value-of select="name()"/>
      <xsl:text> =&gt; "</xsl:text>
      <xsl:value-of select="string(.)"/>
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>)</xsl:text>
  </xsl:template>

  <xsl:template match="d:finalize | d:update" mode="part-of-call">
    <xsl:param name="myspace"/>
    <xsl:call-template name="print-content">
      <xsl:with-param name="myspace">
        <xsl:value-of select="$myspace"/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="print-content">
    <xsl:param name="myspace"/>
    <xsl:if test="text()">
      <xsl:for-each select="str:tokenize(text(), '&#x0A;')">
        <xsl:value-of select="concat('&#x0A;',concat(str:padding($myspace+$myspacemultiplier+$myspacemultiplier),string(.)))" />
      </xsl:for-each>
      <xsl:call-template name="print-newline"/>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:text>END</xsl:text>
    </xsl:if>
  </xsl:template>
  <xsl:template name="print-mcontent">
    <xsl:param name="myspace"/>
    <xsl:if test="text()">
      <xsl:choose>
        <xsl:when test="@language='application/x-ruby'">
          <xsl:text> do </xsl:text>
          <xsl:if test="@output">
            <xsl:text>|</xsl:text>
            <xsl:value-of select="@output"/>
            <xsl:text>|</xsl:text>
          </xsl:if>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>, &lt;&lt;-END</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:for-each select="str:tokenize(text(), '&#x0A;')">
        <xsl:value-of select="concat('&#x0A;',concat(str:padding($myspace+$myspacemultiplier+$myspacemultiplier),string(.)))" />
      </xsl:for-each>
      <xsl:call-template name="print-newline"/>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$myspace+$myspacemultiplier"/>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:choose>
        <xsl:when test="@language='application/x-ruby'">
          <xsl:text>end</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>END</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </xsl:template>
  <xsl:template name="print-space">
    <xsl:param name="i"/>
    <xsl:param name="count"/>
    <xsl:if test="$i &lt;= $count">
      <xsl:text> </xsl:text>
      <xsl:call-template name="print-space">
        <xsl:with-param name="i">
          <xsl:value-of select="$i + 1"/>
        </xsl:with-param>
        <xsl:with-param name="count">
          <xsl:value-of select="$count"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
  <xsl:template name="print-newline">
    <xsl:text>
</xsl:text>
  </xsl:template>

  <!-- JSON Element -->
  <xsl:template match="*" mode="JSON">
    <xsl:text> { \"</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text>\": </xsl:text>
    <xsl:call-template name="JSONProperties">
      <xsl:with-param name="parent" select="'Yes'"></xsl:with-param>
    </xsl:call-template>
    <xsl:choose>
      <xsl:when test="following-sibling::*"><xsl:text> </xsl:text></xsl:when>
    </xsl:choose>
    <xsl:text>}</xsl:text>
    <xsl:if test="following-sibling::*">,</xsl:if>
  </xsl:template>

  <xsl:template match="*" mode="JSONSUB">
    <xsl:text> \"</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text>\": </xsl:text>
    <xsl:call-template name="JSONProperties">
      <xsl:with-param name="parent" select="'Yes'"></xsl:with-param>
    </xsl:call-template>
    <xsl:if test="following-sibling::*">,</xsl:if>
  </xsl:template>

  <!-- JSON Array Element -->
  <xsl:template match="*" mode="JSONArrayElement">
    <xsl:call-template name="JSONProperties"/>
  </xsl:template>

  <!-- JSON Object Properties -->
  <xsl:template name="JSONProperties">
    <xsl:param name="parent"></xsl:param>
    <xsl:variable name="childName" select="name(*[1])"/>
    <xsl:choose>
      <xsl:when test="not(*|@*)">
        <xsl:choose>
          <xsl:when test="$parent='Yes'">
            <xsl:choose>
              <xsl:when test="string(number(.)) = .">
                <xsl:value-of select="."/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>\"</xsl:text>
                <xsl:value-of select="str:replace(str:replace(.,'\','\\'),'&quot;','\\\&quot;')"/>
                <xsl:text>\"</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>\"</xsl:text>
            <xsl:value-of select="name()"/>
            <xsl:text>\": </xsl:text>
            <xsl:choose>
              <xsl:when test="string(number(.)) = .">
                <xsl:value-of select="."/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>\"</xsl:text>
                <xsl:value-of select="str:replace(str:replace(.,'\','\\'),'&quot;','\\\&quot;')"/>
                <xsl:text>\"</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:when test="count(*[name()=$childName]) > 1">
        <xsl:text>{ \"</xsl:text>
        <xsl:value-of select="$childName"/>
        <xsl:text>\": [ </xsl:text>
        <xsl:apply-templates select="*" mode="JSONArrayElement"/>
        <xsl:text> ] }</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="text()[normalize-space(.)]">
          <xsl:text>[ </xsl:text>
        </xsl:if>
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="@*" mode="JSON"/>
        <xsl:apply-templates select="*" mode="JSONSUB"/>
        <xsl:text>}</xsl:text>
        <xsl:if test="text()[normalize-space(.)]">
          <xsl:text>, </xsl:text>
          <xsl:text>\"</xsl:text>
          <xsl:value-of select="str:replace(str:replace(.,'\','\\'),'&quot;','\\\&quot;')"/>
          <xsl:text>\"</xsl:text>
          <xsl:text> ]</xsl:text>
        </xsl:if>
        <xsl:choose>
          <xsl:when test="following-sibling::*"></xsl:when>
          <xsl:otherwise><xsl:text> </xsl:text></xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- JSON Attribute Property -->
  <xsl:template match="@*" mode="JSON">
    <xsl:text> \"@</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text>\": </xsl:text>
    <xsl:choose>
      <xsl:when test="number(.) = .">
        <xsl:value-of select="."/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>\"</xsl:text>
        <xsl:value-of select="str:replace(str:replace(.,'\','\\'),'&quot;','\\\&quot;')"/>
        <xsl:text>\"</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:choose>
      <xsl:when test="not(position() = last())">
        <xsl:text>,</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>