changeset 0:d6fb2ee61c2c draft

Uploaded
author fubar
date Thu, 03 Jun 2021 04:43:09 +0000
parents
children 0b622237ddfb
files planemo_test/.shed.yml planemo_test/planemo_test.xml planemo_test/test-data/Input_text_file_to_be_reversed_sample planemo_test/test-data/ToolFactory_toolshed_XML_from_the_history_to_test_sample planemo_test/test-data/input1_sample planemo_test/test-data/new_tested_toolshed_archive_sample planemo_test/test-data/tacrev_reversed_output_sample planemo_test/test-data/tacrev_reversed_sample
diffstat 8 files changed, 2828 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/.shed.yml	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,6 @@
+category: TF Generated Tools
+description: Lints a ToolFactory or other xml using planemo
+name: planemo_lint
+owner: planemo
+synopsis: Lints a ToolFactory or other xml using planemo
+type: unrestricted
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/planemo_test.xml	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,162 @@
+<tool name="planemo_test" id="planemo_test" version="0.01">
+  <!--Source in git at: https://github.com/fubar2/toolfactory-->
+  <!--Created by ross.lazarus@gmail.com at 04/05/2021 03:41:57 using the Galaxy Tool Factory.-->
+  <description>Test and finalise a toolshed archive</description>
+  <requirements>
+    <requirement type="package" version="5.0.1">rpyc</requirement>
+    <requirement type="package" version="3.2.3">rsync</requirement>
+    <requirement type="package" version="4.6.3">lxml</requirement>
+  </requirements>
+  <stdio>
+    <exit_code range="1:" level="fatal"/>
+  </stdio>
+  <version_command><![CDATA[echo "0.01"]]></version_command>
+  <command><![CDATA[python
+$runme
+$ToolFactory_toolshed_XML_from_the_history_to_test
+$new_tested_toolshed_archive]]></command>
+  <configfiles>
+    <configfile name="runme"><![CDATA[#raw
+# script for ToolFactory toolshed archive test tool
+# most of the work is done in the rpyc server function exposed for this purpose
+
+import lxml.etree as ET
+
+import os
+import rpyc
+import shutil
+import subprocess
+import sys
+
+
+def run_rsync(srcf, dstf):
+    src = os.path.abspath(srcf)
+    dst = os.path.abspath(dstf)
+    if os.path.isdir(src):
+        cll = ["rsync", "-r", src, dst]
+    else:
+        cll = ["rsync", src, dst]
+    subprocess.run(
+        cll,
+        capture_output=False,
+        encoding="utf8",
+        shell=False,
+    )
+
+def main():
+    assert len(sys.argv) >= 3, 'Must have input xml and output archive paths on command line'
+    xmlin = sys.argv[1]
+    arcout = sys.argv[2]
+    tree = ET.parse(xmlin)
+    root = tree.getroot()
+    toolname = root.get('id')
+    try:
+        conn = rpyc.connect("planemo-server", port=9999, config={'sync_request_timeout':1200})
+    except ConnectionRefusedError:
+        print('### no remote rpyc server found on port 9999 - this only works in the ToolFactory Appliance with that server running...')
+        sys.exit(1)
+    collection = './testout'
+    abscoll = os.path.abspath(collection)
+    os.mkdir(collection) # for collection
+    pwork = os.path.join("/export", "galaxy", "tested_TF_archives")
+    ptooldir =  os.path.join(pwork,toolname)
+    pworkrep = os.path.join("/export", "galaxy", "tested_TF_reports")
+    prepdir = os.path.join(pworkrep, toolname)
+    galtooldir = os.path.join('/export/galaxy/tools/TFtools', toolname)
+    res = conn.root.planemo_lint_test(xmlin, abscoll)
+    shutil.copy(f"{toolname}_tested.toolshed.gz", arcout)
+
+main()
+#end raw]]></configfile>
+  </configfiles>
+  <inputs>
+    <param name="ToolFactory_toolshed_XML_from_the_history_to_test" type="data" optional="false" label="ToolFactory toolshed XML from the history to test"
+    help="" format="xml" multiple="false"/>
+  </inputs>
+  <outputs>
+    <data name="new_tested_toolshed_archive" format="toolshed.gz" label="${ToolFactory_toolshed_XML_from_the_history_to_test.name}_tested.toolshed.gz" hidden="false"/>
+    <collection name="testout" type="list" label="${ToolFactory_toolshed_XML_from_the_history_to_test.name} Planemo Test Reports">
+      <discover_datasets pattern="__name_and_ext__" directory="testout" visible="false" />
+    </collection>
+  </outputs>
+  <tests>
+    <test>
+      <output name="new_tested_toolshed_archive" value="new_tested_toolshed_archive_sample" compare="sim_size" delta_frac="0.2"/>
+      <param name="ToolFactory_toolshed_XML_from_the_history_to_test" value="ToolFactory_toolshed_XML_from_the_history_to_test_sample"/>
+      <output_collection name="testout"/>
+    </test>
+  </tests>
+  <help><![CDATA[
+
+**What it Does**
+
+Runs planemo test and returns a toolshed archive updated with test outputs and a Planemo test result.
+
+Dogfood demonstration - this tool was generated by the ToolFactory - labels were manually adjusted to include tool names since it's
+not easy to put mako strings into a galaxyxml label.
+
+This script will only work if it can use methods that completely sidestep Galaxy job-runner security inside the
+ToolFactory Appliance. It should not be able to work anywhere else. It expects to find a server on port 9999 of
+a planemo-server container to do most of the more nefarious stuff. Rsync does the rest. This is as insecure as
+can be imagined and one good reason why the
+ToolFactory Appliance should never, ever be exposed on any public network. Private desktop/laptop use only is recommended.
+
+
+------
+
+
+Script::
+
+    # script for ToolFactory toolshed archive test tool
+    # most of the work is done in the rpyc server function exposed for this purpose
+
+    import lxml.etree as ET
+
+    import os
+    import sys
+    import rpyc
+    import shutil
+    import subprocess
+
+    def run_rsync(srcf, dstf):
+        src = os.path.abspath(srcf)
+        dst = os.path.abspath(dstf)
+        if os.path.isdir(src):
+            cll = ["rsync", "-r", src, dst]
+        else:
+            cll = ["rsync", src, dst]
+        subprocess.run(
+            cll,
+            capture_output=False,
+            encoding="utf8",
+            shell=False,
+        )
+
+    def main():
+        assert len(sys.argv) >= 3, 'Must have input xml and output archive paths on command line'
+        xmlin = sys.argv[1]
+        arcout = sys.argv[2]
+        tree = ET.parse(xmlin)
+        root = tree.getroot()
+        toolname = root.get('id')
+        conn = rpyc.connect("planemo-server", port=9999, config={'sync_request_timeout':1200})
+        collection = './testout'
+        abscoll = os.path.abspath(collection)
+        os.mkdir(collection) # for collection
+        pwork = os.path.join("/export", "galaxy", "tested_TF_archives")
+        ptooldir =  os.path.join(pwork,toolname)
+        pworkrep = os.path.join("/export", "galaxy", "tested_TF_reports")
+        prepdir = os.path.join(pworkrep, toolname)
+        galtooldir = os.path.join('/export/galaxy/tools/TFtools', toolname)
+        res = conn.root.planemo_lint_test(xmlin, abscoll)
+        run_rsync(f"{ptooldir}/{toolname}_tested.toolshed.gz", ".")
+        run_rsync(f"{ptooldir}/{toolname}_tested.toolshed.gz", galtooldir)
+        shutil.copy(f"{toolname}_tested.toolshed.gz", arcout)
+
+    main()
+]]></help>
+  <citations>
+    <citation type="doi">10.1093/bioinformatics/bts573</citation>
+  </citations>
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/Input_text_file_to_be_reversed_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,741 @@
+#!/usr/bin/env python
+# rgToolFactory.py
+# see https://github.com/fubar2/toolfactory
+#
+# copyright ross lazarus (ross stop lazarus at gmail stop com) May 2012
+#
+# all rights reserved
+# Licensed under the LGPL
+# suggestions for improvement and bug fixes welcome at https://github.com/fubar2/toolfactory
+#
+# July 2020: BCC was fun and I feel like rip van winkle after 5 years.
+# Decided to
+# 1. Fix the toolfactory so it works - done for simplest case
+# 2. Fix planemo so the toolfactory function works
+# 3. Rewrite bits using galaxyxml functions where that makes sense - done
+#
+# removed all the old complications including making the new tool use this same script
+# galaxyxml now generates the tool xml https://github.com/hexylena/galaxyxml
+# No support for automatic HTML file creation from arbitrary outputs
+# TODO: add option to run that code as a post execution hook
+# TODO: add additional history input parameters - currently only one
+
+
+import argparse
+import logging
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tarfile
+import tempfile
+import time
+
+import galaxyxml.tool as gxt
+import galaxyxml.tool.parameters as gxtp
+
+import lxml
+
+myversion = "V2.1 July 2020"
+verbose = True
+debug = True
+toolFactoryURL = "https://github.com/fubar2/toolfactory"
+ourdelim = "~~~"
+
+# --input_files="$input_files~~~$CL~~~$input_formats~~~$input_label
+# ~~~$input_help"
+IPATHPOS = 0
+ICLPOS = 1
+IFMTPOS = 2
+ILABPOS = 3
+IHELPOS = 4
+IOCLPOS = 5
+
+# --output_files "$otab.history_name~~~$otab.history_format~~~$otab.CL
+ONAMEPOS = 0
+OFMTPOS = 1
+OCLPOS = 2
+OOCLPOS = 3
+
+# --additional_parameters="$i.param_name~~~$i.param_value~~~
+# $i.param_label~~~$i.param_help~~~$i.param_type~~~$i.CL~~~i$.param_CLoverride"
+ANAMEPOS = 0
+AVALPOS = 1
+ALABPOS = 2
+AHELPPOS = 3
+ATYPEPOS = 4
+ACLPOS = 5
+AOVERPOS = 6
+AOCLPOS = 7
+
+
+foo = len(lxml.__version__)  
+# fug you, flake8. Say my name! 
+
+def timenow():
+    """return current time as a string
+    """
+    return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time()))
+
+
+def quote_non_numeric(s):
+    """return a prequoted string for non-numerics
+    useful for perl and Rscript parameter passing?
+    """
+    try:
+        _ = float(s)
+        return s
+    except ValueError:
+        return '"%s"' % s
+
+
+html_escape_table = {"&": "&amp;", ">": "&gt;", "<": "&lt;", "$": r"\$"}
+
+
+def html_escape(text):
+    """Produce entities within text."""
+    return "".join(html_escape_table.get(c, c) for c in text)
+
+
+def html_unescape(text):
+    """Revert entities within text. Multiple character targets so use replace"""
+    t = text.replace("&amp;", "&")
+    t = t.replace("&gt;", ">")
+    t = t.replace("&lt;", "<")
+    t = t.replace("\\$", "$")
+    return t
+
+
+def parse_citations(citations_text):
+    """
+    """
+    citations = [c for c in citations_text.split("**ENTRY**") if c.strip()]
+    citation_tuples = []
+    for citation in citations:
+        if citation.startswith("doi"):
+            citation_tuples.append(("doi", citation[len("doi") :].strip()))
+        else:
+            citation_tuples.append(
+                ("bibtex", citation[len("bibtex") :].strip())
+            )
+    return citation_tuples
+
+
+class ScriptRunner:
+    """Wrapper for an arbitrary script
+    uses galaxyxml
+
+    """
+
+    def __init__(self, args=None):
+        """
+        prepare command line cl for running the tool here
+        and prepare elements needed for galaxyxml tool generation
+        """
+
+        self.infiles = [x.split(ourdelim) for x in args.input_files]
+        self.outfiles = [x.split(ourdelim) for x in args.output_files]
+        self.addpar = [x.split(ourdelim) for x in args.additional_parameters]
+        self.args = args
+        self.cleanuppar()
+        self.lastclredirect = None
+        self.lastxclredirect = None
+        self.cl = []
+        self.xmlcl = []
+        self.is_positional = self.args.parampass == "positional"
+        aCL = self.cl.append
+        assert args.parampass in [
+            "0",
+            "argparse",
+            "positional",
+        ], 'Parameter passing in args.parampass must be "0","positional" or "argparse"'
+        self.tool_name = re.sub("[^a-zA-Z0-9_]+", "", args.tool_name)
+        self.tool_id = self.tool_name
+        if self.args.interpreter_name:
+            exe = "$runMe"
+        else:
+            exe = self.args.exe_package
+        assert (
+            exe is not None
+        ), "No interpeter or executable passed in - nothing to run so cannot build"
+        self.tool = gxt.Tool(
+            self.args.tool_name,
+            self.tool_id,
+            self.args.tool_version,
+            self.args.tool_desc,
+            exe,
+        )
+        self.tinputs = gxtp.Inputs()
+        self.toutputs = gxtp.Outputs()
+        self.testparam = []
+        if (
+            self.args.runmode == "Executable" or self.args.runmode == "system"
+        ):  # binary - no need
+            aCL(self.args.exe_package)  # this little CL will just run
+        else:
+            self.prepScript()
+        self.elog = "%s_error_log.txt" % self.tool_name
+        self.tlog = "%s_runner_log.txt" % self.tool_name
+
+        if self.args.parampass == "0":
+            self.clsimple()
+        else:
+            clsuffix = []
+            xclsuffix = []
+            for i, p in enumerate(self.infiles):
+                if p[IOCLPOS] == "STDIN":
+                    appendme = [
+                        p[IOCLPOS],
+                        p[ICLPOS],
+                        p[IPATHPOS],
+                        "< %s" % p[IPATHPOS],
+                    ]
+                    xappendme = [
+                        p[IOCLPOS],
+                        p[ICLPOS],
+                        p[IPATHPOS],
+                        "< $%s" % p[ICLPOS],
+                    ]
+                else:
+                    appendme = [p[IOCLPOS], p[ICLPOS], p[IPATHPOS], ""]
+                    xappendme = [p[IOCLPOS], p[ICLPOS], "$%s" % p[ICLPOS], ""]
+                clsuffix.append(appendme)
+                xclsuffix.append(xappendme)
+                # print('##infile i=%d, appendme=%s' % (i,appendme))
+            for i, p in enumerate(self.outfiles):
+                if p[OOCLPOS] == "STDOUT":
+                    self.lastclredirect = [">", p[ONAMEPOS]]
+                    self.lastxclredirect = [">", "$%s" % p[OCLPOS]]
+                else:
+                    clsuffix.append([p[OOCLPOS], p[OCLPOS], p[ONAMEPOS], ""])
+                    xclsuffix.append(
+                        [p[OOCLPOS], p[OCLPOS], "$%s" % p[ONAMEPOS], ""]
+                    )
+            for p in self.addpar:
+                clsuffix.append(
+                    [p[AOCLPOS], p[ACLPOS], p[AVALPOS], p[AOVERPOS]]
+                )
+                xclsuffix.append(
+                    [p[AOCLPOS], p[ACLPOS], '"$%s"' % p[ANAMEPOS], p[AOVERPOS]]
+                )
+            clsuffix.sort()
+            xclsuffix.sort()
+            self.xclsuffix = xclsuffix
+            self.clsuffix = clsuffix
+            if self.args.parampass == "positional":
+                self.clpositional()
+            else:
+                self.clargparse()
+
+    def prepScript(self):
+        aCL = self.cl.append
+        rx = open(self.args.script_path, "r").readlines()
+        rx = [x.rstrip() for x in rx]
+        rxcheck = [x.strip() for x in rx if x.strip() > ""]
+        assert len(rxcheck) > 0, "Supplied script is empty. Cannot run"
+        self.script = "\n".join(rx)
+        fhandle, self.sfile = tempfile.mkstemp(
+            prefix=self.tool_name, suffix="_%s" % (self.args.interpreter_name)
+        )
+        tscript = open(self.sfile, "w")
+        tscript.write(self.script)
+        tscript.close()
+        self.indentedScript = "  %s" % "\n".join(
+            [" %s" % html_escape(x) for x in rx]
+        )
+        self.escapedScript = "%s" % "\n".join(
+            [" %s" % html_escape(x) for x in rx]
+        )
+        art = "%s.%s" % (self.tool_name, self.args.interpreter_name)
+        artifact = open(art, "wb")
+        artifact.write(bytes(self.script, "utf8"))
+        artifact.close()
+        aCL(self.args.interpreter_name)
+        aCL(self.sfile)
+
+    def cleanuppar(self):
+        """ positional parameters are complicated by their numeric ordinal"""
+        for i, p in enumerate(self.infiles):
+            if self.args.parampass == "positional":
+                assert p[ICLPOS].isdigit(), (
+                    "Positional parameters must be ordinal integers - got %s for %s"
+                    % (p[ICLPOS], p[ILABPOS])
+                )
+            p.append(p[ICLPOS])
+            if p[ICLPOS].isdigit() or self.args.parampass == "0":
+                scl = "input%d" % (i + 1)
+                p[ICLPOS] = scl
+            self.infiles[i] = p
+        for i, p in enumerate(
+            self.outfiles
+        ):  # trying to automagically gather using extensions
+            if self.args.parampass == "positional" and p[OCLPOS] != "STDOUT":
+                assert p[OCLPOS].isdigit(), (
+                    "Positional parameters must be ordinal integers - got %s for %s"
+                    % (p[OCLPOS], p[ONAMEPOS])
+                )
+            p.append(p[OCLPOS])
+            if p[OCLPOS].isdigit() or p[OCLPOS] == "STDOUT":
+                scl = p[ONAMEPOS]
+                p[OCLPOS] = scl
+            self.outfiles[i] = p
+        for i, p in enumerate(self.addpar):
+            if self.args.parampass == "positional":
+                assert p[ACLPOS].isdigit(), (
+                    "Positional parameters must be ordinal integers - got %s for %s"
+                    % (p[ACLPOS], p[ANAMEPOS])
+                )
+            p.append(p[ACLPOS])
+            if p[ACLPOS].isdigit():
+                scl = "input%s" % p[ACLPOS]
+                p[ACLPOS] = scl
+            self.addpar[i] = p
+
+    def clsimple(self):
+        """ no parameters - uses < and > for i/o
+        """
+        aCL = self.cl.append
+        aCL("<")
+        aCL(self.infiles[0][IPATHPOS])
+        aCL(">")
+        aCL(self.outfiles[0][OCLPOS])
+        aXCL = self.xmlcl.append
+        aXCL("<")
+        aXCL("$%s" % self.infiles[0][ICLPOS])
+        aXCL(">")
+        aXCL("$%s" % self.outfiles[0][ONAMEPOS])
+
+    def clpositional(self):
+        # inputs in order then params
+        aCL = self.cl.append
+        for (o_v, k, v, koverride) in self.clsuffix:
+            if " " in v:
+                aCL("%s" % v)
+            else:
+                aCL(v)
+        aXCL = self.xmlcl.append
+        for (o_v, k, v, koverride) in self.xclsuffix:
+            aXCL(v)
+        if self.lastxclredirect:
+            aXCL(self.lastxclredirect[0])
+            aXCL(self.lastxclredirect[1])
+
+    def clargparse(self):
+        """ argparse style
+        """
+        aCL = self.cl.append
+        aXCL = self.xmlcl.append
+        # inputs then params in argparse named form
+        for (o_v, k, v, koverride) in self.xclsuffix:
+            if koverride > "":
+                k = koverride
+            elif len(k.strip()) == 1:
+                k = "-%s" % k
+            else:
+                k = "--%s" % k
+            aXCL(k)
+            aXCL(v)
+        for (o_v, k, v, koverride) in self.clsuffix:
+            if koverride > "":
+                k = koverride
+            elif len(k.strip()) == 1:
+                k = "-%s" % k
+            else:
+                k = "--%s" % k
+            aCL(k)
+            aCL(v)
+
+    def getNdash(self, newname):
+        if self.is_positional:
+            ndash = 0
+        else:
+            ndash = 2
+            if len(newname) < 2:
+                ndash = 1
+        return ndash
+
+    def doXMLparam(self):
+        """flake8 made me do this..."""
+        for p in self.outfiles:
+            newname, newfmt, newcl, oldcl = p
+            ndash = self.getNdash(newcl)
+            aparm = gxtp.OutputData(newcl, format=newfmt, num_dashes=ndash)
+            aparm.positional = self.is_positional
+            if self.is_positional:
+                if oldcl == "STDOUT":
+                    aparm.positional = 9999999
+                    aparm.command_line_override = "> $%s" % newcl
+                else:
+                    aparm.positional = int(oldcl)
+                    aparm.command_line_override = "$%s" % newcl
+            self.toutputs.append(aparm)
+            tp = gxtp.TestOutput(
+                name=newcl, value="%s_sample" % newcl, format=newfmt
+            )
+            self.testparam.append(tp)
+        for p in self.infiles:
+            newname = p[ICLPOS]
+            newfmt = p[IFMTPOS]
+            ndash = self.getNdash(newname)
+            if not len(p[ILABPOS]) > 0:
+                alab = p[ICLPOS]
+            else:
+                alab = p[ILABPOS]
+            aninput = gxtp.DataParam(
+                newname,
+                optional=False,
+                label=alab,
+                help=p[IHELPOS],
+                format=newfmt,
+                multiple=False,
+                num_dashes=ndash,
+            )
+            aninput.positional = self.is_positional
+            self.tinputs.append(aninput)
+            tparm = gxtp.TestParam(name=newname, value="%s_sample" % newname)
+            self.testparam.append(tparm)
+        for p in self.addpar:
+            newname, newval, newlabel, newhelp, newtype, newcl, override, oldcl = p
+            if not len(newlabel) > 0:
+                newlabel = newname
+            ndash = self.getNdash(newname)
+            if newtype == "text":
+                aparm = gxtp.TextParam(
+                    newname,
+                    label=newlabel,
+                    help=newhelp,
+                    value=newval,
+                    num_dashes=ndash,
+                )
+            elif newtype == "integer":
+                aparm = gxtp.IntegerParam(
+                    newname,
+                    label=newname,
+                    help=newhelp,
+                    value=newval,
+                    num_dashes=ndash,
+                )
+            elif newtype == "float":
+                aparm = gxtp.FloatParam(
+                    newname,
+                    label=newname,
+                    help=newhelp,
+                    value=newval,
+                    num_dashes=ndash,
+                )
+            else:
+                raise ValueError(
+                    'Unrecognised parameter type "%s" for\
+                 additional parameter %s in makeXML'
+                    % (newtype, newname)
+                )
+            aparm.positional = self.is_positional
+            if self.is_positional:
+                aninput.positional = int(oldcl)
+            self.tinputs.append(aparm)
+            self.tparm = gxtp.TestParam(newname, value=newval)
+            self.testparam.append(tparm)
+
+    def doNoXMLparam(self):
+        alab = self.infiles[0][ILABPOS]
+        if len(alab) == 0:
+            alab = self.infiles[0][ICLPOS]
+        max1s = (
+            "Maximum one input if parampass is 0 - more than one input files supplied - %s"
+            % str(self.infiles)
+        )
+        assert len(self.infiles) == 1, max1s
+        newname = self.infiles[0][ICLPOS]
+        aninput = gxtp.DataParam(
+            newname,
+            optional=False,
+            label=alab,
+            help=self.infiles[0][IHELPOS],
+            format=self.infiles[0][IFMTPOS],
+            multiple=False,
+            num_dashes=0,
+        )
+        aninput.command_line_override = "< $%s" % newname
+        aninput.positional = self.is_positional
+        self.tinputs.append(aninput)
+        tp = gxtp.TestParam(name=newname, value="%s_sample" % newname)
+        self.testparam.append(tp)
+        newname = self.outfiles[0][OCLPOS]
+        newfmt = self.outfiles[0][OFMTPOS]
+        anout = gxtp.OutputData(newname, format=newfmt, num_dashes=0)
+        anout.command_line_override = "> $%s" % newname
+        anout.positional = self.is_positional
+        self.toutputs.append(anout)
+        tp = gxtp.TestOutput(
+            name=newname, value="%s_sample" % newname, format=newfmt
+        )
+        self.testparam.append(tp)
+
+    def makeXML(self):
+        """
+        Create a Galaxy xml tool wrapper for the new script
+        Uses galaxyhtml
+        Hmmm. How to get the command line into correct order...
+        """
+        self.tool.command_line_override = self.xmlcl
+        if self.args.interpreter_name:
+            self.tool.interpreter = self.args.interpreter_name
+        if self.args.help_text:
+            helptext = open(self.args.help_text, "r").readlines()
+            helptext = [html_escape(x) for x in helptext]
+            self.tool.help = "".join([x for x in helptext])
+        else:
+            self.tool.help = (
+                "Please ask the tool author (%s) for help \
+              as none was supplied at tool generation\n"
+                % (self.args.user_email)
+            )
+        self.tool.version_command = None  # do not want
+        requirements = gxtp.Requirements()
+
+        if self.args.interpreter_name:
+            if self.args.interpreter_name == "python":
+                requirements.append(
+                    gxtp.Requirement(
+                        "package", "python", self.args.interpreter_version
+                    )
+                )
+            elif self.args.interpreter_name not in ["bash", "sh"]:
+                requirements.append(
+                    gxtp.Requirement(
+                        "package",
+                        self.args.interpreter_name,
+                        self.args.interpreter_version,
+                    )
+                )
+        else:
+            if self.args.exe_package and self.args.parampass != "system":
+                requirements.append(
+                    gxtp.Requirement(
+                        "package",
+                        self.args.exe_package,
+                        self.args.exe_package_version,
+                    )
+                )
+        self.tool.requirements = requirements
+        if self.args.parampass == "0":
+            self.doNoXMLparam()
+        else:
+            self.doXMLparam()
+        self.tool.outputs = self.toutputs
+        self.tool.inputs = self.tinputs
+        if self.args.runmode not in ["Executable", "system"]:
+            configfiles = gxtp.Configfiles()
+            configfiles.append(gxtp.Configfile(name="runMe", text=self.script))
+            self.tool.configfiles = configfiles
+        tests = gxtp.Tests()
+        test_a = gxtp.Test()
+        for tp in self.testparam:
+            test_a.append(tp)
+        tests.append(test_a)
+        self.tool.tests = tests
+        self.tool.add_comment(
+            "Created by %s at %s using the Galaxy Tool Factory."
+            % (self.args.user_email, timenow())
+        )
+        self.tool.add_comment("Source in git at: %s" % (toolFactoryURL))
+        self.tool.add_comment(
+            "Cite: Creating re-usable tools from scripts doi: 10.1093/bioinformatics/bts573"
+        )
+        exml = self.tool.export()
+        xf = open('%s.xml' % self.tool_name, "w")
+        xf.write(exml)
+        xf.write("\n")
+        xf.close()
+        # ready for the tarball
+
+    def makeTooltar(self):
+        """
+        a tool is a gz tarball with eg
+        /toolname/tool.xml /toolname/tool.py /toolname/test-data/test1_in.foo ...
+        NOTE names for test inputs and outputs are munged here so must
+        correspond to actual input and output names used on the generated cl
+        """
+        retval = self.run()
+        if retval:
+            sys.stderr.write(
+                "## Run failed. Cannot build yet. Please fix and retry"
+            )
+            sys.exit(1)
+        tdir = "tfout"
+        if not os.path.exists(tdir):
+            os.mkdir(tdir)
+        self.makeXML()
+        testdir = os.path.join(tdir, "test-data")
+        if not os.path.exists(testdir):
+            os.mkdir(testdir)  # make tests directory
+        for p in self.infiles:
+            pth = p[IPATHPOS]
+            dest = os.path.join(testdir, "%s_sample" % p[ICLPOS])
+            shutil.copyfile(pth, dest)
+        for p in self.outfiles:
+            pth = p[OCLPOS]
+            if p[OOCLPOS] == "STDOUT" or self.args.parampass == "0":
+                pth = p[ONAMEPOS]
+                dest = os.path.join(testdir, "%s_sample" % p[ONAMEPOS])
+                shutil.copyfile(pth, dest)
+                dest = os.path.join(tdir, p[ONAMEPOS])
+                shutil.copyfile(pth, dest)
+            else:
+                pth = p[OCLPOS]
+                dest = os.path.join(testdir, "%s_sample" % p[OCLPOS])
+                shutil.copyfile(pth, dest)
+                dest = os.path.join(tdir, p[OCLPOS])
+                shutil.copyfile(pth, dest)
+
+        if os.path.exists(self.tlog) and os.stat(self.tlog).st_size > 0:
+            shutil.copyfile(self.tlog, os.path.join(testdir, "test1_log_outfiletxt"))
+        if self.args.runmode not in ["Executable", "system"]:
+            stname = os.path.join(tdir, "%s" % (self.sfile))
+            if not os.path.exists(stname):
+                shutil.copyfile(self.sfile, stname)
+        xreal = '%s.xml' % self.tool_name
+        xout = os.path.join(tdir,xreal)
+        shutil.copyfile(xreal, xout)
+        tarpath = "toolfactory_%s.tgz" % self.tool_name
+        tf = tarfile.open(tarpath, "w:gz")
+        tf.add(name=tdir, arcname=self.tool_name)
+        tf.close()
+        shutil.copyfile(tarpath, self.args.new_tool)
+        shutil.copyfile(xreal,"tool_xml.txt")
+        repdir = "TF_run_report_tempdir"
+        if not os.path.exists(repdir):
+            os.mkdir(repdir)
+        repoutnames = [x[OCLPOS] for x in self.outfiles]
+        with os.scandir('.') as outs:
+            for entry in outs:
+                if entry.name.endswith('.tgz') or not entry.is_file():
+                    continue
+                if entry.name in repoutnames:
+                    shutil.copyfile(entry.name,os.path.join(repdir,entry.name))
+                elif entry.name == "%s.xml" % self.tool_name:
+                    shutil.copyfile(entry.name,os.path.join(repdir,"new_tool_xml"))
+        return retval
+
+    def run(self):
+        """
+        Some devteam tools have this defensive stderr read so I'm keeping with the faith
+        Feel free to update.
+        """
+        s = "run cl=%s" % str(self.cl)
+
+        logging.debug(s)
+        scl = " ".join(self.cl)
+        err = None
+        if self.args.parampass != "0":
+            ste = open(self.elog, "wb")
+            if self.lastclredirect:
+                sto = open(
+                    self.lastclredirect[1], "wb"
+                )  # is name of an output file
+            else:
+                sto = open(self.tlog, "wb")
+                sto.write(
+                    bytes(
+                        "## Executing Toolfactory generated command line = %s\n"
+                        % scl,
+                        "utf8",
+                    )
+                )
+            sto.flush()
+            p = subprocess.run(self.cl, shell=False, stdout=sto, stderr=ste)
+            sto.close()
+            ste.close()
+            tmp_stderr = open(self.elog, "rb")
+            err = ""
+            buffsize = 1048576
+            try:
+                while True:
+                    err += str(tmp_stderr.read(buffsize))
+                    if not err or len(err) % buffsize != 0:
+                        break
+            except OverflowError:
+                pass
+            tmp_stderr.close()
+            retval = p.returncode
+        else:  # work around special case of simple scripts that take stdin and write to stdout
+            sti = open(self.infiles[0][IPATHPOS], "rb")
+            sto = open(self.outfiles[0][ONAMEPOS], "wb")
+            # must use shell to redirect
+            p = subprocess.run(self.cl, shell=False, stdout=sto, stdin=sti)
+            retval = p.returncode
+            sto.close()
+            sti.close()
+        if os.path.isfile(self.tlog) and os.stat(self.tlog).st_size == 0:
+            os.unlink(self.tlog)
+        if os.path.isfile(self.elog) and os.stat(self.elog).st_size == 0:
+            os.unlink(self.elog)
+        if p.returncode != 0 and err:  # problem
+            sys.stderr.write(err)
+        logging.debug("run done")
+        return retval
+
+
+def main():
+    """
+    This is a Galaxy wrapper. It expects to be called by a special purpose tool.xml as:
+    <command interpreter="python">rgBaseScriptWrapper.py --script_path "$scriptPath" --tool_name "foo" --interpreter "Rscript"
+    </command>
+    """
+    parser = argparse.ArgumentParser()
+    a = parser.add_argument
+    a("--script_path", default="")
+    a("--tool_name", default=None)
+    a("--interpreter_name", default=None)
+    a("--interpreter_version", default=None)
+    a("--exe_package", default=None)
+    a("--exe_package_version", default=None)
+    a("--input_files", default=[], action="append")
+    a("--output_files", default=[], action="append")
+    a("--user_email", default="Unknown")
+    a("--bad_user", default=None)
+    a("--make_Tool", default=None)
+    a("--help_text", default=None)
+    a("--tool_desc", default=None)
+    a("--tool_version", default=None)
+    a("--citations", default=None)
+    a("--additional_parameters", action="append", default=[])
+    a("--edit_additional_parameters", action="store_true", default=False)
+    a("--parampass", default="positional")
+    a("--tfout", default="./tfout")
+    a("--new_tool", default="new_tool")
+    a("--runmode", default=None)
+    args = parser.parse_args()
+    assert not args.bad_user, (
+        'UNAUTHORISED: %s is NOT authorized to use this tool until Galaxy admin adds %s to "admin_users" in the Galaxy configuration file'
+        % (args.bad_user, args.bad_user)
+    )
+    assert (
+        args.tool_name
+    ), "## Tool Factory expects a tool name - eg --tool_name=DESeq"
+    assert (
+        args.interpreter_name or args.exe_package
+    ), "## Tool Factory wrapper expects an interpreter or an executable package"
+    assert args.exe_package or (
+        len(args.script_path) > 0 and os.path.isfile(args.script_path)
+    ), "## Tool Factory wrapper expects a script path - eg --script_path=foo.R if no executable"
+    args.input_files = [
+        x.replace('"', "").replace("'", "") for x in args.input_files
+    ]
+    # remove quotes we need to deal with spaces in CL params
+    for i, x in enumerate(args.additional_parameters):
+        args.additional_parameters[i] = args.additional_parameters[i].replace(
+            '"', ""
+        )
+    r = ScriptRunner(args)
+    if args.make_Tool:
+        retcode = r.makeTooltar()
+    else:
+        retcode = r.run()
+    if retcode:
+        sys.exit(retcode)  # indicate failure to job runner
+
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/ToolFactory_toolshed_XML_from_the_history_to_test_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,53 @@
+<tool name="tacrev" id="tacrev" version="0.01">
+  <!--Source in git at: https://github.com/fubar2/toolfactory-->
+  <!--Created by admin@galaxy.org at 15/05/2021 06:15:17 using the Galaxy Tool Factory.-->
+  <description></description>
+  <requirements/>
+  <stdio>
+    <exit_code range="1:" level="fatal"/>
+  </stdio>
+  <version_command><![CDATA[echo "0.01"]]></version_command>
+  <command><![CDATA[bash
+$runme
+<
+$Input_text_file_to_be_reversed
+>
+$tacrev_reversed_output]]></command>
+  <configfiles>
+    <configfile name="runme"><![CDATA[#raw
+
+tac | rev
+
+#end raw]]></configfile>
+  </configfiles>
+  <inputs>
+    <param name="Input_text_file_to_be_reversed" type="data" optional="false" label="Input text file to be reversed" help="" format="txt" multiple="false"/>
+  </inputs>
+  <outputs>
+    <data name="tacrev_reversed_output" format="txt" hidden="false"/>
+  </outputs>
+  <tests>
+    <test>
+      <param name="Input_text_file_to_be_reversed" value="Input_text_file_to_be_reversed_sample"/>
+      <output name="tacrev_reversed_output" value="tacrev_reversed_output_sample"/>
+    </test>
+  </tests>
+  <help><![CDATA[
+
+**What it Does**
+
+ 
+
+------
+
+
+Script::
+
+    tac | rev
+
+]]></help>
+  <citations>
+    <citation type="doi">10.1093/bioinformatics/bts573</citation>
+  </citations>
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/input1_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,536 @@
+<tool id="rgtfd" name="toolfactory" version="2.00" profile="16.04" >
+  <description>Scripts into tools v2.0</description>
+  <macros>
+     <xml name="tool_metadata">
+         <param name="tool_version" label="Tool Version - bump this to warn users trying to redo old analyses" type="text" value="0.01"
+            help="If you change your script and regenerate the 'same' tool, you should inform Galaxy (and users) by changing (bumping is traditional) this number"/>
+            <param name="tool_desc" label="Tool Synopsis" type="text" value=""
+             help="Supply a brief tool description for the Galaxy tool menu entry" />
+            <param name="help_text" label="Tool form documentation and help text for users" type="text" area="true"
+            value="**What it Does**"
+             help="Supply user documentation to appear on the new tool form as reStructured text - http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html" >
+                <sanitizer>
+                    <valid initial="string.printable">
+                    </valid>
+                    <mapping initial="none"/>
+                </sanitizer>
+            </param>
+            <repeat name="citations" title="Citation">
+                <conditional name="citation_type">
+                    <param name="type" type="select" display="radio" label="Citation Type">
+                        <option value="doi">DOI</option>
+                        <option value="bibtex">BibTeX</option>
+                    </param>
+                    <when value="doi">
+                        <param name="doi" label="DOI" type="text" value=""
+                        help="Supply a DOI (e.g. doi: 10.1111/j.1740-9713.2007.00258.x) to be cited when this tool is used in published research." />
+                    </when>
+                    <when value="bibtex">
+                        <param name="bibtex" label="BibTex" type="text" area="true"
+                            help="Supply a BibTex entry that should be cited when this tool is used in published research." value="" >
+                            <sanitizer>
+                                <valid initial="string.printable">
+                                </valid>
+                                <mapping initial="none"/>
+                            </sanitizer>
+                        </param>
+                    </when>
+                </conditional>
+            </repeat>
+     </xml>
+     <xml name="io">
+     <section name="io" title="Input and output files" expanded="true">
+        <repeat name="history_inputs" title="zero or more input data files to pass as parameters to the executable."
+             help="USE SMALL SAMPLES for the new tool's test. Prompts will form a history item selector as input for users of this new tool">
+            <param name="input_files" type="data" format="data" label="Select an input file from your history" optional="true" multiple="false"
+               help=""/>
+            <param name="input_formats" type="select" multiple="true" label="Select the datatype(s) that your tool/script accepts as input"
+              help="If your datatype is not listed here, it has to be added in galaxy's datatypes_conf.xml" value="tabular">
+               <options from_parameter="tool.app.datatypes_registry.upload_file_formats">
+                <column name="value" index="0"/>
+               </options>
+            </param>
+            <param name="input_label" type="text" value="" label="This will become the user prompt for the form so please make it informative"
+             help="Note that '~~~' is an internal delimiter so must not appear in this text field - please work around this technical limitation" >
+            <sanitizer invalid_char="">
+              <valid initial="string.printable"> <remove value='~~~'/> </valid>
+              <mapping initial="none"/>
+            </sanitizer>
+            </param>
+            <param name="input_help" type="text" value="" label="This will become help text on the form."
+             help="Note that three consecutive ~ cannot be used in this text field - please work around this technical limitation">
+            <sanitizer invalid_char="">
+              <valid initial="string.printable"> <remove value='~~~'/> </valid>
+              <mapping initial="none"/>
+            </sanitizer>
+            </param>
+            <param name="input_CL" type="text" label="Positional: ordinal integer. Argparse: argument name. STDIN if the executable/script expects it"
+              help="If you will pass positional parameters, enter the integer ordinal for this parameter. If Argparse style, '--' will be prepended or '-' if single character" value="">
+            </param>
+        </repeat>
+        <repeat name="history_outputs" title="one or more new history items output by the executable to appear in the user history after the tool runs"
+             help="The name will become a history item for users of the new tool you are making containing one of it's outputs">
+            <param name="history_name" type="text" label="Name for this output to appear in new history" optional="false"
+              help="No spaces! Argparse will also use this name as --[name]">
+              <sanitizer invalid_char="_">
+                <valid initial="string.letters,string.digits"/>
+                <add value="_" />
+              </sanitizer>
+            </param>
+            <param name="history_format" type="select" multiple="false" label="Select the datatype for this output"
+              help="If your datatype is not listed here, it has to be added in galaxy's datatypes_conf.xml" value="tabular">
+               <options from_parameter="tool.app.datatypes_registry.upload_file_formats">
+                <column name="value" index="0"/>
+               </options>
+            </param>
+            <param name="history_CL" type="text"  label="Positional: ordinal integer. Use STDOUT if '>' required. Otherwise ignored if argparse because name is used"
+              help="If positional parameters, enter the integer ordinal expected for this parameter. If argparse, ignore unless STDOUT needed" value=""/>
+            <param name="history_test" type="text"  label="Test pass decision criterion for this output compared to test generation"
+              help="Available options are diff:[lines], sim_size:[delta (integer) or delta_frac (float)" value="diff:0"/>
+        </repeat>
+        </section>
+     </xml>
+     <xml name="additparam">
+     <section name="addparam" title="Executable or script settings passed on the command line other than I/O files" expanded="true">
+        <param name="edit_params" type="select" display="radio" label="Make these settings on the generated tool form user editable?"
+             help="If no, users will NOT be able to alter any additional parameters. If yes, these will appear on the tool form as text fields with no validation or sanitizing">
+            <option value="yes" selected="true">Yes, allow user to edit all additional parameters on the generated tool form</option>
+            <option value="no">No - use the fixed values for all additional parameters - no user editing</option>
+        </param>
+
+        <repeat name="additional_parameters" title="zero or more settings to be set by the tool user and passed on the command line"
+             help="See examples below to see how these can be parsed by scripts in the various languages">
+          <param name="param_name" type="text" value="" label="Choose the name for this parameter - MUST not be blank!">
+            <sanitizer invalid_char="">
+              <valid initial="string.letters,string.digits"/>
+              <mapping initial="none"/>
+            </sanitizer>
+          </param>
+          <param name="param_type" type="select" label="Select the type for this parameter">
+            <option value="text" selected="true">text</option>
+            <option value="integer">integer</option>
+            <option value="float">float</option>
+          </param>
+          <param name="param_value" type="text" value="" label="Enter this parameter's default value"
+            help="Note that '~~~' is an internal delimiter must not appear in this text field - please work around this technical limitation" >
+            <sanitizer invalid_char="">
+              <valid initial="string.printable"> <remove value='~~~'/> </valid>
+              <mapping initial="none"/>
+            </sanitizer>
+          </param>
+          <param name="param_label" type="text" value="" label="Enter this parameter's label for the form"
+             help="Note that '~~~' is an internal delimiter so must not appear in this text field - please work around this technical limitation" >
+            <sanitizer invalid_char="">
+              <valid initial="string.printable"> <remove value='~~~'/> </valid>
+              <mapping initial="none"/>
+            </sanitizer>
+          </param>
+          <param name="param_help" type="text" value="" label="Help for this parameter"
+             help="Note that three consecutive ~ cannot be used in this text field - please work around this technical limitation" >
+            <sanitizer invalid_char="">
+              <valid initial="string.printable"> <remove value='~~~'/> </valid>
+              <mapping initial="none"/>
+            </sanitizer>
+          </param>
+          <param name="param_CL" type="text" label="Positional ordinal | argparse argument name"
+              help="Using positional parameters, enter the integer ordinal for this parameter on the command line. Using Argparse style, '--' will be prepended on the CL" value="" />
+          <param name="param_CLprefixed" type="text" label="Override the generated default argparse name prefix if not empty - eg ~~--foo if needed"
+              help="Some targets like Planemo expect an unadorned action like 'test' before --galaxy_root." value="" />
+        </repeat>
+        </section>
+     </xml>
+  </macros>
+
+<requirements>
+   <requirement type="package" version="0.4.11">galaxyxml</requirement>
+   <requirement type="package" version="0.14.0">bioblend</requirement>
+   <requirement type="package" version="0.10.6">ephemeris</requirement>
+   <requirement type="package" version="0.72.0">planemo</requirement>
+</requirements>
+
+  <command ><![CDATA[
+#import os
+#set dev_env = os.environ.get('GALAXY_DEVELOPMENT_ENVIRONMENT', '0') == '1'
+#if not $dev_env and ( $__user_email__ not in $__admin_users__ ):
+python3 $__tool_directory__/rgToolFactory2.py --bad_user $__user_email__
+ #else:
+python3 $__tool_directory__/rgToolFactory2.py
+    #if len(str($cl_prefix)) > 3:
+--cl_prefix "$cl_prefix"
+    #end if
+    #if $cover.commover == "yes":
+       #if len(str($cover.command_override)) > 10:
+--command_override "$commandoverride"
+       #end if
+       #if len(str($cover.test_override)) > 10:
+--test_override "$testoverride"
+       #end if
+    #end if
+--packages "$deps.packages"
+   #if $deps.usescript.choosescript == "yes":
+--script_path "$runme"
+--sysexe "$deps.usescript.scriptrunner"
+    #end if
+--tool_name "$tool_name"  --user_email "$__user_email__" --citations "$citeme"  --parampass "$io_param.ppass.parampass"
+
+   #if str($make.makeMode.make_Tool)!="runonly":
+--make_Tool "$make.makeMode.make_Tool"
+--tool_desc "$make.makeMode.tool_desc"
+--tool_version "$make.makeMode.tool_version"
+--help_text "$helpme"
+--new_tool "$new_tool"
+--toolshed_api_key "$make.makeMode.toolshed_apikey"
+--galaxy_api_key "$make.makeMode.galaxy_apikey"
+--toolshed_url "$make.makeMode.toolshed_url"
+--galaxy_url "$make.makeMode.galaxy_url"
+   #end if
+   #if $io_param.ppass.parampass != '0':
+     #if str($io_param.ppass.addparam.edit_params) == "yes":
+--edit_additional_parameters
+     #end if
+     #for apar in $io_param.ppass.addparam.additional_parameters:
+--additional_parameters "$apar.param_name~~~$apar.param_value~~~$apar.param_label~~~$apar.param_help~~~$apar.param_type~~~$apar.param_CL~~~$apar.param_CLprefixed"
+     #end for
+   #end if
+     #for $intab in $io_param.ppass.io.history_inputs:
+--input_files "$intab.input_files~~~$intab.input_CL~~~$intab.input_formats~~~$intab.input_label~~~$intab.input_help"
+     #end for
+     #for $otab in $io_param.ppass.io.history_outputs:
+--output_files "$otab.history_name~~~$otab.history_format~~~$otab.history_CL~~~$otab.history_test"
+     #end for
+--galaxy_root "$__root_dir__"
+--tool_dir "$__tool_directory__"
+ #end if
+]]></command>
+ <configfiles>
+  <configfile name="runme">
+$deps.usescript.dynScript
+ </configfile>
+ <configfile name="commandoverride">
+#if $cover.commover == "yes" and len(str($cover.command_override).strip()) > 1:
+$cover.command_override
+#end if
+ </configfile>
+ <configfile name="testoverride">
+#if $cover.commover == "yes" and len(str($cover.test_override).strip()) > 1:
+$cover.test_override
+#end if
+ </configfile>
+ <configfile name="helpme">
+    #if $make.makeMode.make_Tool != "runonly":
+${make.makeMode.help_text}
+    #else
+$tool_name help goes here
+    #end if
+ </configfile>
+ <configfile name="citeme">
+#if $make.makeMode.make_Tool != "runonly":
+    #for $citation in $make.makeMode.citations:
+        #if $citation.citation_type.type == "bibtex":
+            **ENTRY**bibtex
+            ${citation.citation_type.bibtex}
+        #else
+            **ENTRY**doi
+            ${citation.citation_type.doi}
+        #end if
+    #end for
+#end if
+ </configfile>
+  </configfiles>
+  <inputs>
+   <param name="tool_name" type="text" value="tool1"   label="New tool ID and title for outputs"
+         help="Toolshed repository name. Choose thoughtfully to avoid namespace clashes with other tool writers. Lower case, digits and underscores only">
+        <sanitizer invalid_char="">
+            <valid initial="string.ascii_lowercase,string.digits">
+                <add value="_"/>
+            </valid>
+        </sanitizer>
+    </param>
+
+    <section name="deps" title="Dependencies, optional script and script interpreter" expanded="true">
+
+    <param name="packages" type="text" value="" label="Conda dependencies as package name[:version, name:version...]. These will always be available when this tool executes"
+    optional="false" help="Use =[ver] or :[ver] for specific version - 'bwa=0.17.0'. Default is latest. Will be used every time the tool is (re)run. Only Conda is currently supported"  />
+
+    <conditional name="usescript">
+        <param name="choosescript" type="select" display="radio" label="Supply a script for a dependency (e.g. python/R/bash) or a system executable such as Bash"
+        help = "For script interpreters like Python or bash, parameters and i/o specified below must match script's expectations - if you pass parameters, the script must deal with them">
+            <option value="no">No script required for this tool - just pass parameters on the command line to the first dependency listed above</option>
+            <option value="yes" selected="true">Yes, a script is ready to be pasted below</option>
+        </param>
+        <when value="no">
+            <param name="dynScript" type="hidden"  value="" />
+            <param name="scriptrunner" type="hidden"  value="" />
+        </when>
+        <when value="yes">
+            <param name="scriptrunner" type="text" value=""   label="Interpreter for the script - eg bash or python. Can be one of the dependencies named above or a system executable"
+             help="Scripts are interpreted by the executable named here. Use bash for bash scripts, or a conda dependency such as R or Python for those scripts">
+            <sanitizer invalid_char="">
+                <valid initial="string.letters,string.digits">
+                    <add value="_"/>
+                </valid>
+            </sanitizer>
+            </param>
+            <param name="dynScript" type="text" area="True" value="" label="Script for executable above to interpret. It can be one of the Conda dependency names "
+             help="Script must handle all i/o and parameters as specified below using the parameters and passing method chosen below">
+              <sanitizer>
+                 <valid initial="string.printable">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+             </param>
+        </when>
+    </conditional>
+    </section>
+    <section name="io_param" title="Data file input, output and settings forming the executable or script command line" expanded="true">
+    <conditional name="ppass">
+        <param name="parampass"  type="select" display="radio" label="Command line parameter passing method to use">
+            <option value="argparse" selected="true">Argparse: passed in the form of --clname value</option>
+            <option value="positional">Positional: Passed in the order of positional ordinals ...foo.bam bar.idx zot.xls</option>
+            <option value="0">Tool reads selected input file from STDIN and writes STDOUT with no parameters</option>
+        </param>
+        <when value="argparse">
+            <expand macro="io" />
+            <expand macro="additparam" />
+        </when>
+        <when value="positional">
+            <expand macro="io" />
+            <expand macro="additparam" />
+        </when>
+        <when value="0">
+             <expand macro="io"/>
+        </when>
+    </conditional>
+    </section>
+    <param name="cl_prefix" type="text" value="" label="Prefix for generated command line. Prepends generated i/o and parameter CL. Use override below to replace completely"
+            help="Text will replace generated executable/script elements. Sometimes required before i/o and parameters in the generated command line." />
+    <conditional name="cover">
+        <param name="commover" type="select" display="radio" label="Add Human wrought code to override the generated XML command and/or test section - DIY"
+        help = "For arbitrary and artfull command lines. All i/o and parameters must be passed. Choose No unless needed. Not for the faint of heart">
+            <option value="no" selected="true">No. Use automatically generated command/test XML </option>
+            <option value="yes">Yes. XML needed to override autogenerated command and/or test segments will be pasted below</option>
+        </param>
+        <when value="no">
+            <param name="command_override" type="hidden"  value="" />
+            <param name="test_override" type="hidden"  value="" />
+        </when>
+        <when value="yes">
+            <param name="command_override" type="text" area="True" value="" label="Optional. Human wrought command element override XML/template - e.g. for bwa"
+             help="For arbitrary and artfull command lines. All i/o and parameters must be passed. Leave blank unless needed. Not for the faint of heart">
+              <sanitizer>
+                 <valid initial="string.printable">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+             </param>
+            <param name="test_override" type="text" area="True" value="" label="Optional. Human wrought test element override XML/template - e.g. for bwa"
+             help="For arbitrary and artfull scripts. Leave blank unless needed. Not for the faint of heart">
+              <sanitizer>
+                 <valid initial="string.printable">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+            </param>
+        </when>
+    </conditional>
+     <section name="make" title="Generate, toolshed and local Galaxy installation options" expanded="true">
+    <conditional name="makeMode">
+        <param name="make_Tool" type="select" display="radio" label="Choose the steps you want to run. The TF Docker container is recommended for local installation"
+          help="Installation in this Galaxy is optional" >
+        <option value="generate" >Run to generate tests only. Should fail if dependencies needed.</option>
+        <option value="gentest" selected="true">Test with planemo after generating.</option>
+        <option value="gentestinstall">Install in Galaxy after generation and testing. URLs and matching API keys are required for this step! </option>
+        </param>
+       <when value="generate">
+           <param name="galaxy_apikey" value="" type="hidden"  ></param>
+           <param name="toolshed_apikey" value="" type="hidden"  ></param>
+           <param name="galaxy_url" value="" type="hidden"  ></param>
+           <param name="toolshed_url" value="" type="hidden"  ></param>
+            <expand macro="tool_metadata" />
+        </when>
+       <when value="gentest">
+           <param name="galaxy_apikey" value="" type="hidden"  ></param>
+           <param name="toolshed_apikey" value="" type="hidden"  ></param>
+           <param name="galaxy_url" value="" type="hidden"  ></param>
+           <param name="toolshed_url" value="" type="hidden"  ></param>
+            <expand macro="tool_metadata" />
+        </when>
+       <when value="gentestinstall">
+            <param name="galaxy_url" type="text" value="http://localhost:8080" label="URL for the Galaxy server where the new tool should be installed"
+             help="Default is localhost">
+              <sanitizer>
+                 <valid initial="string.printable">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+            </param>
+          <param name="galaxy_apikey" type="text" value="fakekey" label="API key for the Galaxy to install the new tool"
+             help="Cut and paste from the admin user properties screen">
+              <sanitizer>
+                 <valid initial="string.letters,string.digits">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+            </param>
+           <param name="toolshed_url" type="text" value="http://localhost:9009" label="URL for the Toolshed where the new tool should be installed"
+             help="Default value is localhost:9009">
+              <sanitizer>
+                 <valid initial="string.printable">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+            </param>
+           <param name="toolshed_apikey" type="text" value="fakekey" label="API key for the local toolshed to use when installing the tool"
+             help="Cut and paste from the admin user properties screen">
+              <sanitizer>
+                 <valid initial="string.letters,string.digits">
+                 </valid>
+                 <mapping initial="none"/>
+              </sanitizer>
+            </param>
+            <expand macro="tool_metadata" />
+        </when>
+    </conditional>
+    </section>
+  </inputs>
+  <outputs>
+
+    <data format="tgz" name="new_tool" label="${tool_name}_toolshed.tgz" >
+        <filter>makeMode['make_Tool'] != "runonly"</filter>
+    </data>
+
+  <collection name="TF_run_report" type="list" label="${tool_name} outputs">
+      <discover_datasets pattern="__name_and_ext__" directory="TF_run_report_tempdir" />
+  </collection>
+  </outputs>
+<tests>
+<test>
+    <param name="user_email" value="admin@galaxy.org"/>
+    <param name="input_files" value="input1_sample" />
+    <param name="input_CL" value="1" />
+    <param name="input_formats" value="txt" />
+    <param name="input_label" value="input" />
+    <param name="input_help" value="help" />
+    <param name="tool_name" value="pyrevpos" />
+    <param name="parampass" value="positional" />
+    <param name="make_Tool" value="generate" />
+    <param name="tool_version" value="0.01" />
+    <param name="tool_desc" value="positional reverse" />
+    <param name="help_text" value="help text goes here" />
+    <param name="packages" value="python"/>
+    <param name="history_name" value="output2" />
+    <param name="history_format" value="txt" />
+    <param name="history_CL" value="2" />
+    <param name="dynScript" value="import sys; inp = sys.argv[1]; outp = sys.argv[2]; inlist = open(inp,'r').readlines(); o = open(outp,'w'); rs = [''.join(list(reversed(x.rstrip()))) for x in inlist]; o.write('\n'.join(rs)); o.close()"/>
+    <param name="choosescript" value="yes" />
+    <param name="script_path" value="$runme"/>
+    <output name="new_tool" file="toolfactory_pyrevpos_tgz_sample" compare="sim_size" delta="6000" />
+</test>
+</tests>
+<help>
+
+.. class:: warningmark
+
+**Details and attribution**
+(see GTF_)
+
+**Local Admins ONLY**
+Only users whose IDs found in the local admin_user configuration setting in universe_wsgi.ini can run this tool.
+
+**If you find a bug**
+Please raise an issue, or even better, submit a pull request fixing it, on the github repository GTF_
+
+**What it does**
+This tool optionally generates normal workflow compatible first class Galaxy tools
+
+Generated tools can run existing binary packages that become requirements, existing scripts, or new scripts pasted into this tool form.
+Pasted scripts are written so they are part of the new tool and cannot be adjusted by the downstream user.
+Binary packages are managed by the dependency subsystem - conda usually, so anything in bioconda or conda_forge is available for example.
+
+Any number of parameters can be built into the new tool form for passing in to the script or executable at runtime.
+These can be editable by the downstream user or baked in.
+
+When you run this tool, your executable or script and supplied parameter values will be run to produce a canonical
+set of outputs - these are used to construct a test for the new tool.
+
+If tool generation is required, a new tarball compatible with any Galaxy toolshed is created.
+It can be unpacked in your galaxy/tools directory and manually added to tool_conf.xml, or
+installed into any toolshed from where it can be installed into your Galaxy.
+
+
+.. class:: warningmark
+
+**Note to system administrators**
+This tool offers *NO* built in protection against malicious scripts. It should only be installed on private/personnal Galaxy instances.
+Admin_users will have the power to do anything they want as the Galaxy user if you install this tool.
+
+.. class:: warningmark
+
+**Use on public servers**  is STRONGLY discouraged for obvious reasons
+
+The tools generated by this tool will run just as securely as any other normal installed Galaxy tool but like any other new tools, should always be checked carefully before installation.
+We recommend that you follow the good code hygiene practices associated with safe toolshed practices.
+
+Here's a sample python script that can be cut and pasted into the tool form, suitable for positional parameter passing:
+
+::
+
+    # reverse order of text by row
+    import sys
+    inp = sys.argv[1]
+    outp = sys.argv[2]
+    i = open(inp,'r').readlines()
+    o = open(outp,'w')
+    for row in i:
+      rs = row.rstrip()
+      rs = list(rs)
+      rs.reverse()
+      o.write(''.join(rs))
+      o.write('\n')
+    o.close()
+
+With argparse style parameters:
+
+::
+
+    # reverse order of text by row
+    import argparse
+    parser = argparse.ArgumentParser()
+    a = parser.add_argument
+    a('--infile',default='')
+    a('--outfile',default=None)
+    args = parser.parse_args()
+    inp = args.infile
+    outp = args.outfile
+    i = open(inp,'r').readlines()
+    o = open(outp,'w')
+    for row in i:
+      rs = row.rstrip()
+      rs = list(rs)
+      rs.reverse()
+      o.write(''.join(rs))
+      o.write('\n')
+    o.close()
+
+
+
+Paper_
+
+*Licensing*
+
+Copyright Ross Lazarus (ross period lazarus at gmail period com) May 2012
+All rights reserved.
+Licensed under the LGPL_
+
+.. _LGPL: http://www.gnu.org/copyleft/lesser.html
+.. _GTF:  https://github.com/fubar2/toolfactory
+.. _Paper: http://bioinformatics.oxfordjournals.org/cgi/reprint/bts573
+
+
+</help>
+<citations>
+    <citation type="doi">10.1093/bioinformatics/bts573</citation>
+</citations>
+</tool>
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/new_tested_toolshed_archive_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,53 @@
+<tool name="tacrev" id="tacrev" version="0.01">
+  <!--Source in git at: https://github.com/fubar2/toolfactory-->
+  <!--Created by admin@galaxy.org at 15/05/2021 06:15:17 using the Galaxy Tool Factory.-->
+  <description></description>
+  <requirements/>
+  <stdio>
+    <exit_code range="1:" level="fatal"/>
+  </stdio>
+  <version_command><![CDATA[echo "0.01"]]></version_command>
+  <command><![CDATA[bash
+$runme
+<
+$Input_text_file_to_be_reversed
+>
+$tacrev_reversed_output]]></command>
+  <configfiles>
+    <configfile name="runme"><![CDATA[#raw
+
+tac | rev
+
+#end raw]]></configfile>
+  </configfiles>
+  <inputs>
+    <param name="Input_text_file_to_be_reversed" type="data" optional="false" label="Input text file to be reversed" help="" format="txt" multiple="false"/>
+  </inputs>
+  <outputs>
+    <data name="tacrev_reversed_output" format="txt" hidden="false"/>
+  </outputs>
+  <tests>
+    <test>
+      <param name="Input_text_file_to_be_reversed" value="Input_text_file_to_be_reversed_sample"/>
+      <output name="tacrev_reversed_output" value="tacrev_reversed_output_sample"/>
+    </test>
+  </tests>
+  <help><![CDATA[
+
+**What it Does**
+
+ 
+
+------
+
+
+Script::
+
+    tac | rev
+
+]]></help>
+  <citations>
+    <citation type="doi">10.1093/bioinformatics/bts573</citation>
+  </citations>
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/tacrev_reversed_output_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,741 @@
+)(niam    
+:"__niam__" == __eman__ fi
+
+
+rennur boj ot eruliaf etacidni #  )edocter(tixe.sys        
+:edocter fi    
+)(nur.r = edocter        
+:esle    
+)(ratlooTekam.r = edocter        
+:looT_ekam.sgra fi    
+)sgra(rennuRtpircS = r    
+)        
+"" ,'"'            
+(ecalper.]i[sretemarap_lanoitidda.sgra = ]i[sretemarap_lanoitidda.sgra        
+:)sretemarap_lanoitidda.sgra(etaremune ni x ,i rof    
+smarap LC ni secaps htiw laed ot deen ew setouq evomer #    
+]    
+selif_tupni.sgra ni x rof )"" ,"'"(ecalper.)"" ,'"'(ecalper.x        
+[ = selif_tupni.sgra    
+"elbatucexe on fi R.oof=htap_tpircs-- ge - htap tpircs a stcepxe repparw yrotcaF looT ##" ,)    
+)htap_tpircs.sgra(elifsi.htap.so dna 0 > )htap_tpircs.sgra(nel        
+( ro egakcap_exe.sgra tressa    
+"egakcap elbatucexe na ro reterpretni na stcepxe repparw yrotcaF looT ##" ,)    
+egakcap_exe.sgra ro eman_reterpretni.sgra        
+( tressa    
+"qeSED=eman_loot-- ge - eman loot a stcepxe yrotcaF looT ##" ,)    
+eman_loot.sgra        
+( tressa    
+)    
+)resu_dab.sgra ,resu_dab.sgra( %        
+'elif noitarugifnoc yxalaG eht ni "sresu_nimda" ot s% sdda nimda yxalaG litnu loot siht esu ot dezirohtua TON si s% :DESIROHTUANU'        
+( ,resu_dab.sgra ton tressa    
+)(sgra_esrap.resrap = sgra    
+)enoN=tluafed ,"edomnur--"(a    
+)"loot_wen"=tluafed ,"loot_wen--"(a    
+)"tuoft/."=tluafed ,"tuoft--"(a    
+)"lanoitisop"=tluafed ,"ssapmarap--"(a    
+)eslaF=tluafed ,"eurt_erots"=noitca ,"sretemarap_lanoitidda_tide--"(a    
+)][=tluafed ,"dneppa"=noitca ,"sretemarap_lanoitidda--"(a    
+)enoN=tluafed ,"snoitatic--"(a    
+)enoN=tluafed ,"noisrev_loot--"(a    
+)enoN=tluafed ,"csed_loot--"(a    
+)enoN=tluafed ,"txet_pleh--"(a    
+)enoN=tluafed ,"looT_ekam--"(a    
+)enoN=tluafed ,"resu_dab--"(a    
+)"nwonknU"=tluafed ,"liame_resu--"(a    
+)"dneppa"=noitca ,][=tluafed ,"selif_tuptuo--"(a    
+)"dneppa"=noitca ,][=tluafed ,"selif_tupni--"(a    
+)enoN=tluafed ,"noisrev_egakcap_exe--"(a    
+)enoN=tluafed ,"egakcap_exe--"(a    
+)enoN=tluafed ,"noisrev_reterpretni--"(a    
+)enoN=tluafed ,"eman_reterpretni--"(a    
+)enoN=tluafed ,"eman_loot--"(a    
+)""=tluafed ,"htap_tpircs--"(a    
+tnemugra_dda.resrap = a    
+)(resraPtnemugrA.esrapgra = resrap    
+"""    
+>dnammoc/<    
+"tpircsR" reterpretni-- "oof" eman_loot-- "htaPtpircs$" htap_tpircs-- yp.repparWtpircSesaBgr>"nohtyp"=reterpretni dnammoc<    
+:sa lmx.loot esoprup laiceps a yb dellac eb ot stcepxe tI .repparw yxalaG a si sihT    
+"""    
+:)(niam fed
+
+
+lavter nruter        
+)"enod nur"(gubed.gniggol        
+)rre(etirw.rredts.sys            
+melborp #  :rre dna 0 =! edocnruter.p fi        
+)gole.fles(knilnu.so            
+:0 == ezis_ts.)gole.fles(tats.so dna )gole.fles(elifsi.htap.so fi        
+)golt.fles(knilnu.so            
+:0 == ezis_ts.)golt.fles(tats.so dna )golt.fles(elifsi.htap.so fi        
+)(esolc.its            
+)(esolc.ots            
+edocnruter.p = lavter            
+)its=nidts ,ots=tuodts ,eslaF=llehs ,lc.fles(nur.ssecorpbus = p            
+tcerider ot llehs esu tsum #            
+)"bw" ,]SOPEMANO[]0[seliftuo.fles(nepo = ots            
+)"br" ,]SOPHTAPI[]0[selifni.fles(nepo = its            
+tuodts ot etirw dna nidts ekat taht stpircs elpmis fo esac laiceps dnuora krow #  :esle        
+edocnruter.p = lavter            
+)(esolc.rredts_pmt            
+ssap                
+:rorrEwolfrevO tpecxe            
+kaerb                        
+:0 =! ezisffub % )rre(nel ro rre ton fi                    
+))ezisffub(daer.rredts_pmt(rts =+ rre                    
+:eurT elihw                
+:yrt            
+6758401 = ezisffub            
+"" = rre            
+)"br" ,gole.fles(nepo = rredts_pmt            
+)(esolc.ets            
+)(esolc.ots            
+)ets=rredts ,ots=tuodts ,eslaF=llehs ,lc.fles(nur.ssecorpbus = p            
+)(hsulf.ots            
+)                
+)                    
+,"8ftu"                        
+,lcs %                        
+"n\s% = enil dnammoc detareneg yrotcaflooT gnitucexE ##"                        
+(setyb                    
+(etirw.ots                
+)"bw" ,golt.fles(nepo = ots                
+:esle            
+elif tuptuo na fo eman si #  )                
+"bw" ,]1[tceriderlctsal.fles                    
+(nepo = ots                
+:tceriderlctsal.fles fi            
+)"bw" ,gole.fles(nepo = ets            
+:"0" =! ssapmarap.sgra.fles fi        
+enoN = rre        
+)lc.fles(nioj." " = lcs        
+)s(gubed.gniggol        
+
+)lc.fles(rts % "s%=lc nur" = s        
+"""        
+.etadpu ot eerf leeF        
+htiaf eht htiw gnipeek m'I os daer rredts evisnefed siht evah sloot maetved emoS        
+"""        
+:)fles(nur fed    
+
+lavter nruter        
+))"lmx_loot_wen",ridper(nioj.htap.so,eman.yrtne(elifypoc.lituhs                    
+:eman_loot.fles % "lmx.s%" == eman.yrtne file                
+))eman.yrtne,ridper(nioj.htap.so,eman.yrtne(elifypoc.lituhs                    
+:semantuoper ni eman.yrtne fi                
+eunitnoc                    
+:)(elif_si.yrtne ton ro )'zgt.'(htiwsdne.eman.yrtne fi                
+:stuo ni yrtne rof            
+:stuo sa )'.'(ridnacs.so htiw        
+]seliftuo.fles ni x rof ]SOPLCO[x[ = semantuoper        
+)ridper(ridkm.so            
+:)ridper(stsixe.htap.so ton fi        
+"ridpmet_troper_nur_FT" = ridper        
+)"txt.lmx_loot",laerx(elifypoc.lituhs        
+)loot_wen.sgra.fles ,htaprat(elifypoc.lituhs        
+)(esolc.ft        
+)eman_loot.fles=emancra ,ridt=eman(dda.ft        
+)"zg:w" ,htaprat(nepo.elifrat = ft        
+eman_loot.fles % "zgt.s%_yrotcafloot" = htaprat        
+)tuox ,laerx(elifypoc.lituhs        
+)laerx,ridt(nioj.htap.so = tuox        
+eman_loot.fles % 'lmx.s%' = laerx        
+)emants ,elifs.fles(elifypoc.lituhs                
+:)emants(stsixe.htap.so ton fi            
+))elifs.fles( % "s%" ,ridt(nioj.htap.so = emants            
+:]"metsys" ,"elbatucexE"[ ni ton edomnur.sgra.fles fi        
+))"txteliftuo_gol_1tset" ,ridtset(nioj.htap.so ,golt.fles(elifypoc.lituhs            
+:0 > ezis_ts.)golt.fles(tats.so dna )golt.fles(stsixe.htap.so fi        
+
+)tsed ,htp(elifypoc.lituhs                
+)]SOPLCO[p ,ridt(nioj.htap.so = tsed                
+)tsed ,htp(elifypoc.lituhs                
+)]SOPLCO[p % "elpmas_s%" ,ridtset(nioj.htap.so = tsed                
+]SOPLCO[p = htp                
+:esle            
+)tsed ,htp(elifypoc.lituhs                
+)]SOPEMANO[p ,ridt(nioj.htap.so = tsed                
+)tsed ,htp(elifypoc.lituhs                
+)]SOPEMANO[p % "elpmas_s%" ,ridtset(nioj.htap.so = tsed                
+]SOPEMANO[p = htp                
+:"0" == ssapmarap.sgra.fles ro "TUODTS" == ]SOPLCOO[p fi            
+]SOPLCO[p = htp            
+:seliftuo.fles ni p rof        
+)tsed ,htp(elifypoc.lituhs            
+)]SOPLCI[p % "elpmas_s%" ,ridtset(nioj.htap.so = tsed            
+]SOPHTAPI[p = htp            
+:selifni.fles ni p rof        
+yrotcerid stset ekam #  )ridtset(ridkm.so            
+:)ridtset(stsixe.htap.so ton fi        
+)"atad-tset" ,ridt(nioj.htap.so = ridtset        
+)(LMXekam.fles        
+)ridt(ridkm.so            
+:)ridt(stsixe.htap.so ton fi        
+"tuoft" = ridt        
+)1(tixe.sys            
+)            
+"yrter dna xif esaelP .tey dliub tonnaC .deliaf nuR ##"                
+(etirw.rredts.sys            
+:lavter fi        
+)(nur.fles = lavter        
+"""        
+lc detareneg eht no desu seman tuptuo dna tupni lautca ot dnopserroc        
+tsum os ereh degnum era stuptuo dna stupni tset rof seman ETON        
+... oof.ni_1tset/atad-tset/emanloot/ yp.loot/emanloot/ lmx.loot/emanloot/        
+ge htiw llabrat zg a si loot a        
+"""        
+:)fles(ratlooTekam fed    
+
+llabrat eht rof ydaer #        
+)(esolc.fx        
+)"n\"(etirw.fx        
+)lmxe(etirw.fx        
+)"w" ,eman_loot.fles % 'lmx.s%'(nepo = fx        
+)(tropxe.loot.fles = lmxe        
+)        
+"375stb/scitamrofnioib/3901.01 :iod stpircs morf sloot elbasu-er gnitaerC :etiC"            
+(tnemmoc_dda.loot.fles        
+))LRUyrotcaFloot( % "s% :ta tig ni ecruoS"(tnemmoc_dda.loot.fles        
+)        
+))(wonemit ,liame_resu.sgra.fles( %            
+".yrotcaF looT yxalaG eht gnisu s% ta s% yb detaerC"            
+(tnemmoc_dda.loot.fles        
+stset = stset.loot.fles        
+)a_tset(dneppa.stset        
+)pt(dneppa.a_tset            
+:maraptset.fles ni pt rof        
+)(tseT.ptxg = a_tset        
+)(stseT.ptxg = stset        
+selifgifnoc = selifgifnoc.loot.fles            
+))tpircs.fles=txet ,"eMnur"=eman(elifgifnoC.ptxg(dneppa.selifgifnoc            
+)(selifgifnoC.ptxg = selifgifnoc            
+:]"metsys" ,"elbatucexE"[ ni ton edomnur.sgra.fles fi        
+stupnit.fles = stupni.loot.fles        
+stuptuot.fles = stuptuo.loot.fles        
+)(marapLMXod.fles            
+:esle        
+)(marapLMXoNod.fles            
+:"0" == ssapmarap.sgra.fles fi        
+stnemeriuqer = stnemeriuqer.loot.fles        
+)                
+)                    
+,noisrev_egakcap_exe.sgra.fles                        
+,egakcap_exe.sgra.fles                        
+,"egakcap"                        
+(tnemeriuqeR.ptxg                    
+(dneppa.stnemeriuqer                
+:"metsys" =! ssapmarap.sgra.fles dna egakcap_exe.sgra.fles fi            
+:esle        
+)                
+)                    
+,noisrev_reterpretni.sgra.fles                        
+,eman_reterpretni.sgra.fles                        
+,"egakcap"                        
+(tnemeriuqeR.ptxg                    
+(dneppa.stnemeriuqer                
+:]"hs" ,"hsab"[ ni ton eman_reterpretni.sgra.fles file            
+)                
+)                    
+noisrev_reterpretni.sgra.fles ,"nohtyp" ,"egakcap"                        
+(tnemeriuqeR.ptxg                    
+(dneppa.stnemeriuqer                
+:"nohtyp" == eman_reterpretni.sgra.fles fi            
+:eman_reterpretni.sgra.fles fi        
+
+)(stnemeriuqeR.ptxg = stnemeriuqer        
+tnaw ton od #  enoN = dnammoc_noisrev.loot.fles        
+)            
+)liame_resu.sgra.fles( %                
+"n\noitareneg loot ta deilppus saw enon sa              
+\ pleh rof )s%( rohtua loot eht ksa esaelP"                
+( = pleh.loot.fles            
+:esle        
+)]txetpleh ni x rof x[(nioj."" = pleh.loot.fles            
+]txetpleh ni x rof )x(epacse_lmth[ = txetpleh            
+)(senildaer.)"r" ,txet_pleh.sgra.fles(nepo = txetpleh            
+:txet_pleh.sgra.fles fi        
+eman_reterpretni.sgra.fles = reterpretni.loot.fles            
+:eman_reterpretni.sgra.fles fi        
+lclmx.fles = edirrevo_enil_dnammoc.loot.fles        
+"""        
+...redro tcerroc otni enil dnammoc eht teg ot woH .mmmH        
+lmthyxalag sesU        
+tpircs wen eht rof repparw loot lmx yxalaG a etaerC        
+"""        
+:)fles(LMXekam fed    
+
+)pt(dneppa.maraptset.fles        
+)        
+tmfwen=tamrof ,emanwen % "elpmas_s%"=eulav ,emanwen=eman            
+(tuptuOtseT.ptxg = pt        
+)tuona(dneppa.stuptuot.fles        
+lanoitisop_si.fles = lanoitisop.tuona        
+emanwen % "s%$ >" = edirrevo_enil_dnammoc.tuona        
+)0=sehsad_mun ,tmfwen=tamrof ,emanwen(ataDtuptuO.ptxg = tuona        
+]SOPTMFO[]0[seliftuo.fles = tmfwen        
+]SOPLCO[]0[seliftuo.fles = emanwen        
+)pt(dneppa.maraptset.fles        
+)emanwen % "elpmas_s%"=eulav ,emanwen=eman(maraPtseT.ptxg = pt        
+)tupnina(dneppa.stupnit.fles        
+lanoitisop_si.fles = lanoitisop.tupnina        
+emanwen % "s%$ <" = edirrevo_enil_dnammoc.tupnina        
+)        
+,0=sehsad_mun            
+,eslaF=elpitlum            
+,]SOPTMFI[]0[selifni.fles=tamrof            
+,]SOPLEHI[]0[selifni.fles=pleh            
+,bala=lebal            
+,eslaF=lanoitpo            
+,emanwen            
+(maraPataD.ptxg = tupnina        
+]SOPLCI[]0[selifni.fles = emanwen        
+s1xam ,1 == )selifni.fles(nel tressa        
+)        
+)selifni.fles(rts %            
+"s% - deilppus selif tupni eno naht erom - 0 si ssapmarap fi tupni eno mumixaM"            
+( = s1xam        
+]SOPLCI[]0[selifni.fles = bala            
+:0 == )bala(nel fi        
+]SOPBALI[]0[selifni.fles = bala        
+:)fles(marapLMXoNod fed    
+
+)mrapt(dneppa.maraptset.fles            
+)lavwen=eulav ,emanwen(maraPtseT.ptxg = mrapt.fles            
+)mrapa(dneppa.stupnit.fles            
+)lcdlo(tni = lanoitisop.tupnina                
+:lanoitisop_si.fles fi            
+lanoitisop_si.fles = lanoitisop.mrapa            
+)                
+)emanwen ,epytwen( %                    
+'LMXekam ni s% retemarap lanoitidda                 
+\rof "s%" epyt retemarap desingocernU'                    
+(rorrEeulaV esiar                
+:esle            
+)                
+,hsadn=sehsad_mun                    
+,lavwen=eulav                    
+,plehwen=pleh                    
+,emanwen=lebal                    
+,emanwen                    
+(maraPtaolF.ptxg = mrapa                
+:"taolf" == epytwen file            
+)                
+,hsadn=sehsad_mun                    
+,lavwen=eulav                    
+,plehwen=pleh                    
+,emanwen=lebal                    
+,emanwen                    
+(maraPregetnI.ptxg = mrapa                
+:"regetni" == epytwen file            
+)                
+,hsadn=sehsad_mun                    
+,lavwen=eulav                    
+,plehwen=pleh                    
+,lebalwen=lebal                    
+,emanwen                    
+(maraPtxeT.ptxg = mrapa                
+:"txet" == epytwen fi            
+)emanwen(hsadNteg.fles = hsadn            
+emanwen = lebalwen                
+:0 > )lebalwen(nel ton fi            
+p = lcdlo ,edirrevo ,lcwen ,epytwen ,plehwen ,lebalwen ,lavwen ,emanwen            
+:rapdda.fles ni p rof        
+)mrapt(dneppa.maraptset.fles            
+)emanwen % "elpmas_s%"=eulav ,emanwen=eman(maraPtseT.ptxg = mrapt            
+)tupnina(dneppa.stupnit.fles            
+lanoitisop_si.fles = lanoitisop.tupnina            
+)            
+,hsadn=sehsad_mun                
+,eslaF=elpitlum                
+,tmfwen=tamrof                
+,]SOPLEHI[p=pleh                
+,bala=lebal                
+,eslaF=lanoitpo                
+,emanwen                
+(maraPataD.ptxg = tupnina            
+]SOPBALI[p = bala                
+:esle            
+]SOPLCI[p = bala                
+:0 > )]SOPBALI[p(nel ton fi            
+)emanwen(hsadNteg.fles = hsadn            
+]SOPTMFI[p = tmfwen            
+]SOPLCI[p = emanwen            
+:selifni.fles ni p rof        
+)pt(dneppa.maraptset.fles            
+)            
+tmfwen=tamrof ,lcwen % "elpmas_s%"=eulav ,lcwen=eman                
+(tuptuOtseT.ptxg = pt            
+)mrapa(dneppa.stuptuot.fles            
+lcwen % "s%$" = edirrevo_enil_dnammoc.mrapa                    
+)lcdlo(tni = lanoitisop.mrapa                    
+:esle                
+lcwen % "s%$ >" = edirrevo_enil_dnammoc.mrapa                    
+9999999 = lanoitisop.mrapa                    
+:"TUODTS" == lcdlo fi                
+:lanoitisop_si.fles fi            
+lanoitisop_si.fles = lanoitisop.mrapa            
+)hsadn=sehsad_mun ,tmfwen=tamrof ,lcwen(ataDtuptuO.ptxg = mrapa            
+)lcwen(hsadNteg.fles = hsadn            
+p = lcdlo ,lcwen ,tmfwen ,emanwen            
+:seliftuo.fles ni p rof        
+"""...siht od em edam 8ekalf"""        
+:)fles(marapLMXod fed    
+
+hsadn nruter        
+1 = hsadn                
+:2 < )emanwen(nel fi            
+2 = hsadn            
+:esle        
+0 = hsadn            
+:lanoitisop_si.fles fi        
+:)emanwen ,fles(hsadNteg fed    
+
+)v(LCa            
+)k(LCa            
+k % "s%--" = k                
+:esle            
+k % "s%-" = k                
+:1 == ))(pirts.k(nel file            
+edirrevok = k                
+:"" > edirrevok fi            
+:xiffuslc.fles ni )edirrevok ,v ,k ,v_o( rof        
+)v(LCXa            
+)k(LCXa            
+k % "s%--" = k                
+:esle            
+k % "s%-" = k                
+:1 == ))(pirts.k(nel file            
+edirrevok = k                
+:"" > edirrevok fi            
+:xiffuslcx.fles ni )edirrevok ,v ,k ,v_o( rof        
+mrof deman esrapgra ni smarap neht stupni #        
+dneppa.lclmx.fles = LCXa        
+dneppa.lc.fles = LCa        
+"""        
+elyts esrapgra """        
+:)fles(esrapgralc fed    
+
+)]1[tceriderlcxtsal.fles(LCXa            
+)]0[tceriderlcxtsal.fles(LCXa            
+:tceriderlcxtsal.fles fi        
+)v(LCXa            
+:xiffuslcx.fles ni )edirrevok ,v ,k ,v_o( rof        
+dneppa.lclmx.fles = LCXa        
+)v(LCa                
+:esle            
+)v % "s%"(LCa                
+:v ni " " fi            
+:xiffuslc.fles ni )edirrevok ,v ,k ,v_o( rof        
+dneppa.lc.fles = LCa        
+smarap neht redro ni stupni #        
+:)fles(lanoitisoplc fed    
+
+)]SOPEMANO[]0[seliftuo.fles % "s%$"(LCXa        
+)">"(LCXa        
+)]SOPLCI[]0[selifni.fles % "s%$"(LCXa        
+)"<"(LCXa        
+dneppa.lclmx.fles = LCXa        
+)]SOPLCO[]0[seliftuo.fles(LCa        
+)">"(LCa        
+)]SOPHTAPI[]0[selifni.fles(LCa        
+)"<"(LCa        
+dneppa.lc.fles = LCa        
+"""        
+o/i rof > dna < sesu - sretemarap on """        
+:)fles(elpmislc fed    
+
+p = ]i[rapdda.fles            
+lcs = ]SOPLCA[p                
+]SOPLCA[p % "s%tupni" = lcs                
+:)(tigidsi.]SOPLCA[p fi            
+)]SOPLCA[p(dneppa.p            
+)                
+)]SOPEMANA[p ,]SOPLCA[p( %                    
+"s% rof s% tog - sregetni lanidro eb tsum sretemarap lanoitisoP"                    
+( ,)(tigidsi.]SOPLCA[p tressa                
+:"lanoitisop" == ssapmarap.sgra.fles fi            
+:)rapdda.fles(etaremune ni p ,i rof        
+p = ]i[seliftuo.fles            
+lcs = ]SOPLCO[p                
+]SOPEMANO[p = lcs                
+:"TUODTS" == ]SOPLCO[p ro )(tigidsi.]SOPLCO[p fi            
+)]SOPLCO[p(dneppa.p            
+)                
+)]SOPEMANO[p ,]SOPLCO[p( %                    
+"s% rof s% tog - sregetni lanidro eb tsum sretemarap lanoitisoP"                    
+( ,)(tigidsi.]SOPLCO[p tressa                
+:"TUODTS" =! ]SOPLCO[p dna "lanoitisop" == ssapmarap.sgra.fles fi            
+snoisnetxe gnisu rehtag yllacigamotua ot gniyrt #  :)        
+seliftuo.fles            
+(etaremune ni p ,i rof        
+p = ]i[selifni.fles            
+lcs = ]SOPLCI[p                
+)1 + i( % "d%tupni" = lcs                
+:"0" == ssapmarap.sgra.fles ro )(tigidsi.]SOPLCI[p fi            
+)]SOPLCI[p(dneppa.p            
+)                
+)]SOPBALI[p ,]SOPLCI[p( %                    
+"s% rof s% tog - sregetni lanidro eb tsum sretemarap lanoitisoP"                    
+( ,)(tigidsi.]SOPLCI[p tressa                
+:"lanoitisop" == ssapmarap.sgra.fles fi            
+:)selifni.fles(etaremune ni p ,i rof        
+"""lanidro ciremun rieht yb detacilpmoc era sretemarap lanoitisop """        
+:)fles(rappunaelc fed    
+
+)elifs.fles(LCa        
+)eman_reterpretni.sgra.fles(LCa        
+)(esolc.tcafitra        
+))"8ftu" ,tpircs.fles(setyb(etirw.tcafitra        
+)"bw" ,tra(nepo = tcafitra        
+)eman_reterpretni.sgra.fles ,eman_loot.fles( % "s%.s%" = tra        
+)        
+]xr ni x rof )x(epacse_lmth % "s% "[            
+(nioj."n\" % "s%" = tpircSdepacse.fles        
+)        
+]xr ni x rof )x(epacse_lmth % "s% "[            
+(nioj."n\" % "s%  " = tpircSdetnedni.fles        
+)(esolc.tpircst        
+)tpircs.fles(etirw.tpircst        
+)"w" ,elifs.fles(nepo = tpircst        
+)        
+)eman_reterpretni.sgra.fles( % "s%_"=xiffus ,eman_loot.fles=xiferp            
+(pmetskm.elifpmet = elifs.fles ,eldnahf        
+)xr(nioj."n\" = tpircs.fles        
+"nur tonnaC .ytpme si tpircs deilppuS" ,0 > )kcehcxr(nel tressa        
+]"" > )(pirts.x fi xr ni x rof )(pirts.x[ = kcehcxr        
+]xr ni x rof )(pirtsr.x[ = xr        
+)(senildaer.)"r" ,htap_tpircs.sgra.fles(nepo = xr        
+dneppa.lc.fles = LCa        
+:)fles(tpircSperp fed    
+
+)(esrapgralc.fles                
+:esle            
+)(lanoitisoplc.fles                
+:"lanoitisop" == ssapmarap.sgra.fles fi            
+xiffuslc = xiffuslc.fles            
+xiffuslcx = xiffuslcx.fles            
+)(tros.xiffuslcx            
+)(tros.xiffuslc            
+)                
+]]SOPREVOA[p ,]SOPEMANA[p % '"s%$"' ,]SOPLCA[p ,]SOPLCOA[p[                    
+(dneppa.xiffuslcx                
+)                
+]]SOPREVOA[p ,]SOPLAVA[p ,]SOPLCA[p ,]SOPLCOA[p[                    
+(dneppa.xiffuslc                
+:rapdda.fles ni p rof            
+)                    
+]"" ,]SOPEMANO[p % "s%$" ,]SOPLCO[p ,]SOPLCOO[p[                        
+(dneppa.xiffuslcx                    
+)]"" ,]SOPEMANO[p ,]SOPLCO[p ,]SOPLCOO[p[(dneppa.xiffuslc                    
+:esle                
+]]SOPLCO[p % "s%$" ,">"[ = tceriderlcxtsal.fles                    
+]]SOPEMANO[p ,">"[ = tceriderlctsal.fles                    
+:"TUODTS" == ]SOPLCOO[p fi                
+:)seliftuo.fles(etaremune ni p ,i rof            
+))emdneppa,i( % 's%=emdneppa ,d%=i elifni##'(tnirp #                
+)emdneppax(dneppa.xiffuslcx                
+)emdneppa(dneppa.xiffuslc                
+]"" ,]SOPLCI[p % "s%$" ,]SOPLCI[p ,]SOPLCOI[p[ = emdneppax                    
+]"" ,]SOPHTAPI[p ,]SOPLCI[p ,]SOPLCOI[p[ = emdneppa                    
+:esle                
+]                    
+,]SOPLCI[p % "s%$ <"                        
+,]SOPHTAPI[p                        
+,]SOPLCI[p                        
+,]SOPLCOI[p                        
+[ = emdneppax                    
+]                    
+,]SOPHTAPI[p % "s% <"                        
+,]SOPHTAPI[p                        
+,]SOPLCI[p                        
+,]SOPLCOI[p                        
+[ = emdneppa                    
+:"NIDTS" == ]SOPLCOI[p fi                
+:)selifni.fles(etaremune ni p ,i rof            
+][ = xiffuslcx            
+][ = xiffuslc            
+:esle        
+)(elpmislc.fles            
+:"0" == ssapmarap.sgra.fles fi        
+
+eman_loot.fles % "txt.gol_rennur_s%" = golt.fles        
+eman_loot.fles % "txt.gol_rorre_s%" = gole.fles        
+)(tpircSperp.fles            
+:esle        
+nur tsuj lliw LC elttil siht #  )egakcap_exe.sgra.fles(LCa            
+deen on - yranib #  :)        
+"metsys" == edomnur.sgra.fles ro "elbatucexE" == edomnur.sgra.fles            
+( fi        
+][ = maraptset.fles        
+)(stuptuO.ptxg = stuptuot.fles        
+)(stupnI.ptxg = stupnit.fles        
+)        
+,exe            
+,csed_loot.sgra.fles            
+,noisrev_loot.sgra.fles            
+,di_loot.fles            
+,eman_loot.sgra.fles            
+(looT.txg = loot.fles        
+"dliub tonnac os nur ot gnihton - ni dessap elbatucexe ro retepretni oN" ,)        
+enoN ton si exe            
+( tressa        
+egakcap_exe.sgra.fles = exe            
+:esle        
+"eMnur$" = exe            
+:eman_reterpretni.sgra.fles fi        
+eman_loot.fles = di_loot.fles        
+)eman_loot.sgra ,"" ,"+]_9-0Z-Az-a^["(bus.er = eman_loot.fles        
+'"esrapgra" ro "lanoitisop","0" eb tsum ssapmarap.sgra ni gnissap retemaraP' ,]        
+,"lanoitisop"            
+,"esrapgra"            
+,"0"            
+[ ni ssapmarap.sgra tressa        
+dneppa.lc.fles = LCa        
+"lanoitisop" == ssapmarap.sgra.fles = lanoitisop_si.fles        
+][ = lclmx.fles        
+][ = lc.fles        
+enoN = tceriderlcxtsal.fles        
+enoN = tceriderlctsal.fles        
+)(rappunaelc.fles        
+sgra = sgra.fles        
+]sretemarap_lanoitidda.sgra ni x rof )miledruo(tilps.x[ = rapdda.fles        
+]selif_tuptuo.sgra ni x rof )miledruo(tilps.x[ = seliftuo.fles        
+]selif_tupni.sgra ni x rof )miledruo(tilps.x[ = selifni.fles        
+
+"""        
+noitareneg loot lmxyxalag rof dedeen stnemele eraperp dna        
+ereh loot eht gninnur rof lc enil dnammoc eraperp        
+"""        
+:)enoN=sgra ,fles(__tini__ fed    
+
+"""    
+
+lmxyxalag sesu    
+tpircs yrartibra na rof repparW"""    
+:rennuRtpircS ssalc
+
+
+selput_noitatic nruter    
+)            
+))(pirts.]: )"xetbib"(nel[noitatic ,"xetbib"(                
+(dneppa.selput_noitatic            
+:esle        
+)))(pirts.]: )"iod"(nel[noitatic ,"iod"((dneppa.selput_noitatic            
+:)"iod"(htiwstrats.noitatic fi        
+:snoitatic ni noitatic rof    
+][ = selput_noitatic    
+])(pirts.c fi )"**YRTNE**"(tilps.txet_snoitatic ni c rof c[ = snoitatic    
+"""    
+"""    
+:)txet_snoitatic(snoitatic_esrap fed
+
+
+t nruter    
+)"$" ,"$\\"(ecalper.t = t    
+)"<" ,";tl&"(ecalper.t = t    
+)">" ,";tg&"(ecalper.t = t    
+)"&" ,";pma&"(ecalper.txet = t    
+"""ecalper esu os stegrat retcarahc elpitluM .txet nihtiw seititne treveR"""    
+:)txet(epacsenu_lmth fed
+
+
+)txet ni c rof )c ,c(teg.elbat_epacse_lmth(nioj."" nruter    
+""".txet nihtiw seititne ecudorP"""    
+:)txet(epacse_lmth fed
+
+
+}"$\"r :"$" ,";tl&" :"<" ,";tg&" :">" ,";pma&" :"&"{ = elbat_epacse_lmth
+
+
+s % '"s%"' nruter        
+:rorrEeulaV tpecxe    
+s nruter        
+)s(taolf = _        
+:yrt    
+"""    
+?gnissap retemarap tpircsR dna lrep rof lufesu    
+sciremun-non rof gnirts detouqerp a nruter"""    
+:)s(ciremun_non_etouq fed
+
+
+)))(emit.emit(emitlacol.emit ,"S%:M%:H% Y%/m%/d%"(emitfrts.emit nruter    
+"""    
+gnirts a sa emit tnerruc nruter"""    
+:)(wonemit fed
+
+ !eman ym yaS .8ekalf ,uoy guf #
+  )__noisrev__.lmxl(nel = oof
+
+
+7 = SOPLCOA
+6 = SOPREVOA
+5 = SOPLCA
+4 = SOPEPYTA
+3 = SOPPLEHA
+2 = SOPBALA
+1 = SOPLAVA
+0 = SOPEMANA
+"edirrevoLC_marap.$i~~~LC.i$~~~epyt_marap.i$~~~pleh_marap.i$~~~lebal_marap.i$ #
+~~~eulav_marap.i$~~~eman_marap.i$"=sretemarap_lanoitidda-- #
+
+3 = SOPLCOO
+2 = SOPLCO
+1 = SOPTMFO
+0 = SOPEMANO
+LC.bato$~~~tamrof_yrotsih.bato$~~~eman_yrotsih.bato$" selif_tuptuo-- #
+
+5 = SOPLCOI
+4 = SOPLEHI
+3 = SOPBALI
+2 = SOPTMFI
+1 = SOPLCI
+0 = SOPHTAPI
+"pleh_tupni$~~~ #
+lebal_tupni$~~~stamrof_tupni$~~~LC$~~~selif_tupni$"=selif_tupni-- #
+
+"~~~" = miledruo
+"yrotcafloot/2rabuf/moc.buhtig//:sptth" = LRUyrotcaFloot
+eurT = gubed
+eurT = esobrev
+"0202 yluJ 1.2V" = noisrevym
+
+lmxl tropmi
+
+ptxg sa sretemarap.loot.lmxyxalag tropmi
+txg sa loot.lmxyxalag tropmi
+
+emit tropmi
+elifpmet tropmi
+elifrat tropmi
+sys tropmi
+ssecorpbus tropmi
+lituhs tropmi
+er tropmi
+so tropmi
+gniggol tropmi
+esrapgra tropmi
+
+
+eno ylno yltnerruc - sretemarap tupni yrotsih lanoitidda dda :ODOT #
+kooh noitucexe tsop a sa edoc taht nur ot noitpo dda :ODOT #
+stuptuo yrartibra morf noitaerc elif LMTH citamotua rof troppus oN #
+lmxyxalag/anelyxeh/moc.buhtig//:sptth lmx loot eht setareneg won lmxyxalag #
+tpircs emas siht esu loot wen eht gnikam gnidulcni snoitacilpmoc dlo eht lla devomer #
+#
+enod - esnes sekam taht erehw snoitcnuf lmxyxalag gnisu stib etirweR .3 #
+skrow noitcnuf yrotcafloot eht os omenalp xiF .2 #
+esac tselpmis rof enod - skrow ti os yrotcafloot eht xiF .1 #
+ot dediceD #
+.sraey 5 retfa elkniw nav pir ekil leef I dna nuf saw CCB :0202 yluJ #
+#
+yrotcafloot/2rabuf/moc.buhtig//:sptth ta emoclew sexif gub dna tnemevorpmi rof snoitseggus #
+LPGL eht rednu desneciL #
+devreser sthgir lla #
+#
+2102 yaM )moc pots liamg ta surazal pots ssor( surazal ssor thgirypoc #
+#
+yrotcafloot/2rabuf/moc.buhtig//:sptth ees #
+yp.yrotcaFlooTgr #
+nohtyp vne/nib/rsu/!#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo_test/test-data/tacrev_reversed_sample	Thu Jun 03 04:43:09 2021 +0000
@@ -0,0 +1,536 @@
+
+
+>loot/<
+>snoitatic/<
+>noitatic/<375stb/scitamrofnioib/3901.01>"iod"=epyt noitatic<    
+>snoitatic<
+>pleh/<
+
+
+375stb/tnirper/igc/gro.slanruojdrofxo.scitamrofnioib//:ptth :repaP_ ..
+yrotcafloot/2rabuf/moc.buhtig//:sptth  :FTG_ ..
+lmth.ressel/tfelypoc/gro.ung.www//:ptth :LPGL_ ..
+
+_LPGL eht rednu desneciL
+.devreser sthgir llA
+2102 yaM )moc doirep liamg ta surazal doirep ssor( surazaL ssoR thgirypoC
+
+*gnisneciL*
+
+_repaP
+
+
+
+)(esolc.o    
+)'n\'(etirw.o      
+))sr(nioj.''(etirw.o      
+)(esrever.sr      
+)sr(tsil = sr      
+)(pirtsr.wor = sr      
+:i ni wor rof    
+)'w',ptuo(nepo = o    
+)(senildaer.)'r',pni(nepo = i    
+eliftuo.sgra = ptuo    
+elifni.sgra = pni    
+)(sgra_esrap.resrap = sgra    
+)enoN=tluafed,'eliftuo--'(a    
+)''=tluafed,'elifni--'(a    
+tnemugra_dda.resrap = a    
+)(resraPtnemugrA.esrapgra = resrap    
+esrapgra tropmi    
+wor yb txet fo redro esrever #    
+
+::
+
+:sretemarap elyts esrapgra htiW
+
+)(esolc.o    
+)'n\'(etirw.o      
+))sr(nioj.''(etirw.o      
+)(esrever.sr      
+)sr(tsil = sr      
+)(pirtsr.wor = sr      
+:i ni wor rof    
+)'w',ptuo(nepo = o    
+)(senildaer.)'r',pni(nepo = i    
+]2[vgra.sys = ptuo    
+]1[vgra.sys = pni    
+sys tropmi    
+wor yb txet fo redro esrever #    
+
+::
+
+:gnissap retemarap lanoitisop rof elbatius ,mrof loot eht otni detsap dna tuc eb nac taht tpircs nohtyp elpmas a s'ereH
+
+.secitcarp dehsloot efas htiw detaicossa secitcarp eneigyh edoc doog eht wollof uoy taht dnemmocer eW
+.noitallatsni erofeb ylluferac dekcehc eb syawla dluohs ,sloot wen rehto yna ekil tub loot yxalaG dellatsni lamron rehto yna sa yleruces sa tsuj nur lliw loot siht yb detareneg sloot ehT
+
+snosaer suoivbo rof degaruocsid YLGNORTS si  **srevres cilbup no esU**
+
+kramgninraw ::ssalc ..
+
+.loot siht llatsni uoy fi resu yxalaG eht sa tnaw yeht gnihtyna od ot rewop eht evah lliw sresu_nimdA
+.secnatsni yxalaG lannosrep/etavirp no dellatsni eb ylno dluohs tI .stpircs suoicilam tsniaga noitcetorp ni tliub *ON* sreffo loot sihT
+**srotartsinimda metsys ot etoN**
+
+kramgninraw ::ssalc ..
+
+
+.yxalaG ruoy otni dellatsni eb nac ti erehw morf dehsloot yna otni dellatsni
+ro ,lmx.fnoc_loot ot dedda yllaunam dna yrotcerid sloot/yxalag ruoy ni dekcapnu eb nac tI
+.detaerc si dehsloot yxalaG yna htiw elbitapmoc llabrat wen a ,deriuqer si noitareneg loot fI
+
+.loot wen eht rof tset a tcurtsnoc ot desu era eseht - stuptuo fo tes
+lacinonac a ecudorp ot nur eb lliw seulav retemarap deilppus dna tpircs ro elbatucexe ruoy ,loot siht nur uoy nehW
+
+.ni dekab ro resu maertsnwod eht yb elbatide eb nac esehT
+.emitnur ta elbatucexe ro tpircs eht ot ni gnissap rof mrof loot wen eht otni tliub eb nac sretemarap fo rebmun ynA
+
+.elpmaxe rof elbaliava si egrof_adnoc ro adnocoib ni gnihtyna os ,yllausu adnoc - metsysbus ycnedneped eht yb deganam era segakcap yraniB
+.resu maertsnwod eht yb detsujda eb tonnac dna loot wen eht fo trap era yeht os nettirw era stpircs detsaP
+.mrof loot siht otni detsap stpircs wen ro ,stpircs gnitsixe ,stnemeriuqer emoceb taht segakcap yranib gnitsixe nur nac sloot detareneG
+
+sloot yxalaG ssalc tsrif elbitapmoc wolfkrow lamron setareneg yllanoitpo loot sihT
+**seod ti tahW**
+
+_FTG yrotisoper buhtig eht no ,ti gnixif tseuqer llup a timbus ,retteb neve ro ,eussi na esiar esaelP
+**gub a dnif uoy fI**
+
+.loot siht nur nac ini.igsw_esrevinu ni gnittes noitarugifnoc resu_nimda lacol eht ni dnuof sDI esohw sresu ylnO
+**YLNO snimdA lacoL**
+
+)_FTG ees(
+**noitubirtta dna sliateD**
+
+kramgninraw ::ssalc ..
+
+>pleh<
+>stset/<
+>tset/<
+>/ "0006"=atled "ezis_mis"=erapmoc "elpmas_zgt_sopveryp_yrotcafloot"=elif "loot_wen"=eman tuptuo<    
+>/"emnur$"=eulav "htap_tpircs"=eman marap<    
+>/ "sey"=eulav "tpircsesoohc"=eman marap<    
+>/")(esolc.o ;))sr(nioj.'n\'(etirw.o ;]tsilni ni x rof ))))(pirtsr.x(desrever(tsil(nioj.''[ = sr ;)'w',ptuo(nepo = o ;)(senildaer.)'r',pni(nepo = tsilni ;]2[vgra.sys = ptuo ;]1[vgra.sys = pni ;sys tropmi"=eulav "tpircSnyd"=eman marap<    
+>/ "2"=eulav "LC_yrotsih"=eman marap<    
+>/ "txt"=eulav "tamrof_yrotsih"=eman marap<    
+>/ "2tuptuo"=eulav "eman_yrotsih"=eman marap<    
+>/"nohtyp"=eulav "segakcap"=eman marap<    
+>/ "ereh seog txet pleh"=eulav "txet_pleh"=eman marap<    
+>/ "esrever lanoitisop"=eulav "csed_loot"=eman marap<    
+>/ "10.0"=eulav "noisrev_loot"=eman marap<    
+>/ "etareneg"=eulav "looT_ekam"=eman marap<    
+>/ "lanoitisop"=eulav "ssapmarap"=eman marap<    
+>/ "sopveryp"=eulav "eman_loot"=eman marap<    
+>/ "pleh"=eulav "pleh_tupni"=eman marap<    
+>/ "tupni"=eulav "lebal_tupni"=eman marap<    
+>/ "txt"=eulav "stamrof_tupni"=eman marap<    
+>/ "1"=eulav "LC_tupni"=eman marap<    
+>/ "elpmas_1tupni"=eulav "selif_tupni"=eman marap<    
+>/"gro.yxalag@nimda"=eulav "liame_resu"=eman marap<    
+>tset<
+>stset<
+>stuptuo/<  
+>noitcelloc/<  
+>/ "ridpmet_troper_nur_FT"=yrotcerid "__txe_dna_eman__"=nrettap stesatad_revocsid<      
+>"stuptuo }eman_loot{$"=lebal "tsil"=epyt "troper_nur_FT"=eman noitcelloc<  
+
+>atad/<    
+>retlif/<"ylnonur" =! ]'looT_ekam'[edoMekam>retlif<        
+> "zgt.dehsloot_}eman_loot{$"=lebal "loot_wen"=eman "zgt"=tamrof atad<    
+
+>stuptuo<  
+>stupni/<  
+>noitces/<    
+>lanoitidnoc/<    
+>nehw/<        
+>/ "atadatem_loot"=orcam dnapxe<            
+>marap/<            
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"stigid.gnirts,srettel.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"neercs seitreporp resu nimda eht morf etsap dna tuC"=pleh             
+"loot eht gnillatsni nehw esu ot dehsloot lacol eht rof yek IPA"=lebal "yekekaf"=eulav "txet"=epyt "yekipa_dehsloot"=eman marap<           
+>marap/<            
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"elbatnirp.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"9009:tsohlacol si eulav tluafeD"=pleh             
+"dellatsni eb dluohs loot wen eht erehw dehslooT eht rof LRU"=lebal "9009:tsohlacol//:ptth"=eulav "txet"=epyt "lru_dehsloot"=eman marap<           
+>marap/<            
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"stigid.gnirts,srettel.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"neercs seitreporp resu nimda eht morf etsap dna tuC"=pleh             
+"loot wen eht llatsni ot yxalaG eht rof yek IPA"=lebal "yekekaf"=eulav "txet"=epyt "yekipa_yxalag"=eman marap<          
+>marap/<            
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"elbatnirp.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"tsohlacol si tluafeD"=pleh             
+"dellatsni eb dluohs loot wen eht erehw revres yxalaG eht rof LRU"=lebal "0808:tsohlacol//:ptth"=eulav "txet"=epyt "lru_yxalag"=eman marap<            
+>"llatsnitsetneg"=eulav nehw<       
+>nehw/<        
+>/ "atadatem_loot"=orcam dnapxe<            
+>marap/<>  "neddih"=epyt ""=eulav "lru_dehsloot"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "lru_yxalag"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "yekipa_dehsloot"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "yekipa_yxalag"=eman marap<           
+>"tsetneg"=eulav nehw<       
+>nehw/<        
+>/ "atadatem_loot"=orcam dnapxe<            
+>marap/<>  "neddih"=epyt ""=eulav "lru_dehsloot"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "lru_yxalag"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "yekipa_dehsloot"=eman marap<           
+>marap/<>  "neddih"=epyt ""=eulav "yekipa_yxalag"=eman marap<           
+>"etareneg"=eulav nehw<       
+>marap/<        
+>noitpo/< !pets siht rof deriuqer era syek IPA gnihctam dna sLRU .gnitset dna noitareneg retfa yxalaG ni llatsnI>"llatsnitsetneg"=eulav noitpo<        
+>noitpo/<.gnitareneg retfa omenalp htiw tseT>"eurt"=detceles "tsetneg"=eulav noitpo<        
+>noitpo/<.dedeen seicnedneped fi liaf dluohS .ylno stset etareneg ot nuR> "etareneg"=eulav noitpo<        
+> "lanoitpo si yxalaG siht ni noitallatsnI"=pleh          
+"noitallatsni lacol rof dednemmocer si reniatnoc rekcoD FT ehT .nur ot tnaw uoy spets eht esoohC"=lebal "oidar"=yalpsid "tceles"=epyt "looT_ekam"=eman marap<        
+>"edoMekam"=eman lanoitidnoc<    
+>"eurt"=dednapxe "snoitpo noitallatsni yxalaG lacol dna dehsloot ,etareneG"=eltit "ekam"=eman noitces<     
+>lanoitidnoc/<    
+>nehw/<        
+>marap/<            
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"elbatnirp.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"traeh fo tniaf eht rof toN .dedeen sselnu knalb evaeL .stpircs lluftra dna yrartibra roF"=pleh             
+"awb rof .g.e - etalpmet/LMX edirrevo tnemele tset thguorw namuH .lanoitpO"=lebal ""=eulav "eurT"=aera "txet"=epyt "edirrevo_tset"=eman marap<            
+>marap/<             
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"elbatnirp.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"traeh fo tniaf eht rof toN .dedeen sselnu knalb evaeL .dessap eb tsum sretemarap dna o/i llA .senil dnammoc lluftra dna yrartibra roF"=pleh             
+"awb rof .g.e - etalpmet/LMX edirrevo tnemele dnammoc thguorw namuH .lanoitpO"=lebal ""=eulav "eurT"=aera "txet"=epyt "edirrevo_dnammoc"=eman marap<            
+>"sey"=eulav nehw<        
+>nehw/<        
+>/ ""=eulav  "neddih"=epyt "edirrevo_tset"=eman marap<            
+>/ ""=eulav  "neddih"=epyt "edirrevo_dnammoc"=eman marap<            
+>"on"=eulav nehw<        
+>marap/<        
+>noitpo/<woleb detsap eb lliw stnemges tset ro/dna dnammoc detarenegotua edirrevo ot dedeen LMX .seY>"sey"=eulav noitpo<            
+>noitpo/< LMX tset/dnammoc detareneg yllacitamotua esU .oN>"eurt"=detceles "on"=eulav noitpo<            
+>"traeh fo tniaf eht rof toN .dedeen sselnu oN esoohC .dessap eb tsum sretemarap dna o/i llA .senil dnammoc lluftra dna yrartibra roF" = pleh        
+"YID - noitces tset ro/dna dnammoc LMX detareneg eht edirrevo ot edoc thguorw namuH ddA"=lebal "oidar"=yalpsid "tceles"=epyt "revommoc"=eman marap<        
+>"revoc"=eman lanoitidnoc<    
+>/ ".enil dnammoc detareneg eht ni sretemarap dna o/i erofeb deriuqer semitemoS .stnemele tpircs/elbatucexe detareneg ecalper lliw txeT"=pleh            
+"yletelpmoc ecalper ot woleb edirrevo esU .LC retemarap dna o/i detareneg sdneperP .enil dnammoc detareneg rof xiferP"=lebal ""=eulav "txet"=epyt "xiferp_lc"=eman marap<    
+>noitces/<    
+>lanoitidnoc/<    
+>nehw/<        
+>/"oi"=orcam dnapxe<             
+>"0"=eulav nehw<        
+>nehw/<        
+>/ "maraptidda"=orcam dnapxe<            
+>/ "oi"=orcam dnapxe<            
+>"lanoitisop"=eulav nehw<        
+>nehw/<        
+>/ "maraptidda"=orcam dnapxe<            
+>/ "oi"=orcam dnapxe<            
+>"esrapgra"=eulav nehw<        
+>marap/<        
+>noitpo/<sretemarap on htiw TUODTS setirw dna NIDTS morf elif tupni detceles sdaer looT>"0"=eulav noitpo<            
+>noitpo/<slx.toz xdi.rab mab.oof... slanidro lanoitisop fo redro eht ni dessaP :lanoitisoP>"lanoitisop"=eulav noitpo<            
+>noitpo/<eulav emanlc-- fo mrof eht ni dessap :esrapgrA>"eurt"=detceles "esrapgra"=eulav noitpo<            
+>"esu ot dohtem gnissap retemarap enil dnammoC"=lebal "oidar"=yalpsid "tceles"=epyt  "ssapmarap"=eman marap<        
+>"ssapp"=eman lanoitidnoc<    
+>"eurt"=dednapxe "enil dnammoc tpircs ro elbatucexe eht gnimrof sgnittes dna tuptuo ,tupni elif ataD"=eltit "marap_oi"=eman noitces<    
+>noitces/<    
+>lanoitidnoc/<    
+>nehw/<        
+>marap/<             
+>rezitinas/<              
+>/"enon"=laitini gnippam<                 
+>dilav/<                 
+>"elbatnirp.gnirts"=laitini dilav<                 
+>rezitinas<              
+>"woleb nesohc dohtem gnissap dna sretemarap eht gnisu woleb deificeps sa sretemarap dna o/i lla eldnah tsum tpircS"=pleh             
+" seman ycnedneped adnoC eht fo eno eb nac tI .terpretni ot evoba elbatucexe rof tpircS"=lebal ""=eulav "eurT"=aera "txet"=epyt "tpircSnyd"=eman marap<            
+>marap/<            
+>rezitinas/<            
+>dilav/<                
+>/"_"=eulav dda<                    
+>"stigid.gnirts,srettel.gnirts"=laitini dilav<                
+>""=rahc_dilavni rezitinas<            
+>"stpircs esoht rof nohtyP ro R sa hcus ycnedneped adnoc a ro ,stpircs hsab rof hsab esU .ereh deman elbatucexe eht yb deterpretni era stpircS"=pleh             
+"elbatucexe metsys a ro evoba deman seicnedneped eht fo eno eb naC .nohtyp ro hsab ge - tpircs eht rof reterpretnI"=lebal   ""=eulav "txet"=epyt "rennurtpircs"=eman marap<            
+>"sey"=eulav nehw<        
+>nehw/<        
+>/ ""=eulav  "neddih"=epyt "rennurtpircs"=eman marap<            
+>/ ""=eulav  "neddih"=epyt "tpircSnyd"=eman marap<            
+>"on"=eulav nehw<        
+>marap/<        
+>noitpo/<woleb detsap eb ot ydaer si tpircs a ,seY>"eurt"=detceles "sey"=eulav noitpo<            
+>noitpo/<evoba detsil ycnedneped tsrif eht ot enil dnammoc eht no sretemarap ssap tsuj - loot siht rof deriuqer tpircs oN>"on"=eulav noitpo<            
+>"meht htiw laed tsum tpircs eht ,sretemarap ssap uoy fi - snoitatcepxe s'tpircs hctam tsum woleb deificeps o/i dna sretemarap ,hsab ro nohtyP ekil sreterpretni tpircs roF" = pleh        
+"hsaB sa hcus elbatucexe metsys a ro )hsab/R/nohtyp .g.e( ycnedneped a rof tpircs a ylppuS"=lebal "oidar"=yalpsid "tceles"=epyt "tpircsesoohc"=eman marap<        
+>"tpircsesu"=eman lanoitidnoc<    
+
+>/  "detroppus yltnerruc si adnoC ylnO .nur)er( si loot eht emit yreve desu eb lliW .tsetal si tluafeD .'0.71.0=awb' - noisrev cificeps rof ]rev[: ro ]rev[= esU"=pleh "eslaf"=lanoitpo    
+"setucexe loot siht nehw elbaliava eb syawla lliw esehT .]...noisrev:eman ,noisrev:[eman egakcap sa seicnedneped adnoC"=lebal ""=eulav "txet"=epyt "segakcap"=eman marap<    
+
+>"eurt"=dednapxe "reterpretni tpircs dna tpircs lanoitpo ,seicnednepeD"=eltit "sped"=eman noitces<    
+
+>marap/<    
+>rezitinas/<        
+>dilav/<            
+>/"_"=eulav dda<                
+>"stigid.gnirts,esacrewol_iicsa.gnirts"=laitini dilav<            
+>""=rahc_dilavni rezitinas<        
+>"ylno serocsrednu dna stigid ,esac rewoL .sretirw loot rehto htiw sehsalc ecapseman diova ot yllufthguoht esoohC .eman yrotisoper dehslooT"=pleh         
+"stuptuo rof eltit dna DI loot weN"=lebal   "1loot"=eulav "txet"=epyt "eman_loot"=eman marap<   
+>stupni<  
+>selifgifnoc/<  
+>elifgifnoc/< 
+fi dne#
+rof dne#    
+fi dne#        
+}iod.epyt_noitatic.noitatic{$            
+iod**YRTNE**            
+esle#        
+}xetbib.epyt_noitatic.noitatic{$            
+xetbib**YRTNE**            
+:"xetbib" == epyt.epyt_noitatic.noitatic$ fi#        
+:snoitatic.edoMekam.ekam$ ni noitatic$ rof#    
+:"ylnonur" =! looT_ekam.edoMekam.ekam$ fi#
+>"emetic"=eman elifgifnoc< 
+>elifgifnoc/< 
+fi dne#    
+ereh seog pleh eman_loot$
+esle#    
+}txet_pleh.edoMekam.ekam{$
+:"ylnonur" =! looT_ekam.edoMekam.ekam$ fi#    
+>"empleh"=eman elifgifnoc< 
+>elifgifnoc/< 
+fi dne#
+edirrevo_tset.revoc$
+:1 > ))(pirts.)edirrevo_tset.revoc$(rts(nel dna "sey" == revommoc.revoc$ fi#
+>"edirrevotset"=eman elifgifnoc< 
+>elifgifnoc/< 
+fi dne#
+edirrevo_dnammoc.revoc$
+:1 > ))(pirts.)edirrevo_dnammoc.revoc$(rts(nel dna "sey" == revommoc.revoc$ fi#
+>"edirrevodnammoc"=eman elifgifnoc< 
+>elifgifnoc/< 
+tpircSnyd.tpircsesu.sped$
+>"emnur"=eman elifgifnoc<  
+>selifgifnoc< 
+>dnammoc/<>]]
+fi dne# 
+"__yrotcerid_loot__$" rid_loot--
+"__rid_toor__$" toor_yxalag--
+rof dne#     
+"tset_yrotsih.bato$~~~LC_yrotsih.bato$~~~tamrof_yrotsih.bato$~~~eman_yrotsih.bato$" selif_tuptuo--
+:stuptuo_yrotsih.oi.ssapp.marap_oi$ ni bato$ rof#     
+rof dne#     
+"pleh_tupni.batni$~~~lebal_tupni.batni$~~~stamrof_tupni.batni$~~~LC_tupni.batni$~~~selif_tupni.batni$" selif_tupni--
+:stupni_yrotsih.oi.ssapp.marap_oi$ ni batni$ rof#     
+fi dne#   
+rof dne#     
+"dexiferpLC_marap.rapa$~~~LC_marap.rapa$~~~epyt_marap.rapa$~~~pleh_marap.rapa$~~~lebal_marap.rapa$~~~eulav_marap.rapa$~~~eman_marap.rapa$" sretemarap_lanoitidda--
+:sretemarap_lanoitidda.marapdda.ssapp.marap_oi$ ni rapa rof#     
+fi dne#     
+sretemarap_lanoitidda_tide--
+:"sey" == )smarap_tide.marapdda.ssapp.marap_oi$(rts fi#     
+:'0' =! ssapmarap.ssapp.marap_oi$ fi#   
+fi dne#   
+"lru_yxalag.edoMekam.ekam$" lru_yxalag--
+"lru_dehsloot.edoMekam.ekam$" lru_dehsloot--
+"yekipa_yxalag.edoMekam.ekam$" yek_ipa_yxalag--
+"yekipa_dehsloot.edoMekam.ekam$" yek_ipa_dehsloot--
+"loot_wen$" loot_wen--
+"empleh$" txet_pleh--
+"noisrev_loot.edoMekam.ekam$" noisrev_loot--
+"csed_loot.edoMekam.ekam$" csed_loot--
+"looT_ekam.edoMekam.ekam$" looT_ekam--
+:"ylnonur"=!)looT_ekam.edoMekam.ekam$(rts fi#   
+
+"ssapmarap.ssapp.marap_oi$" ssapmarap--  "emetic$" snoitatic-- "__liame_resu__$" liame_resu--  "eman_loot$" eman_loot--
+fi dne#    
+"rennurtpircs.tpircsesu.sped$" exesys--
+"emnur$" htap_tpircs--
+:"sey" == tpircsesoohc.tpircsesu.sped$ fi#   
+"segakcap.sped$" segakcap--
+fi dne#    
+fi dne#       
+"edirrevotset$" edirrevo_tset--
+:01 > ))edirrevo_tset.revoc$(rts(nel fi#       
+fi dne#       
+"edirrevodnammoc$" edirrevo_dnammoc--
+:01 > ))edirrevo_dnammoc.revoc$(rts(nel fi#       
+:"sey" == revommoc.revoc$ fi#    
+fi dne#    
+"xiferp_lc$" xiferp_lc--
+:3 > ))xiferp_lc$(rts(nel fi#    
+yp.2yrotcaFlooTgr/__yrotcerid_loot__$ 3nohtyp
+:esle# 
+__liame_resu__$ resu_dab-- yp.2yrotcaFlooTgr/__yrotcerid_loot__$ 3nohtyp
+:) __sresu_nimda__$ ni ton __liame_resu__$ ( dna vne_ved$ ton fi#
+'1' == )'0' ,'TNEMNORIVNE_TNEMPOLEVED_YXALAG'(teg.norivne.so = vne_ved tes#
+so tropmi#
+[ATADC[!<> dnammoc<  
+
+>stnemeriuqer/<
+>tnemeriuqer/<omenalp>"0.27.0"=noisrev "egakcap"=epyt tnemeriuqer<   
+>tnemeriuqer/<siremehpe>"6.01.0"=noisrev "egakcap"=epyt tnemeriuqer<   
+>tnemeriuqer/<dnelboib>"0.41.0"=noisrev "egakcap"=epyt tnemeriuqer<   
+>tnemeriuqer/<lmxyxalag>"11.4.0"=noisrev "egakcap"=epyt tnemeriuqer<   
+>stnemeriuqer<
+
+>sorcam/<  
+>lmx/<     
+>noitces/<        
+>taeper/<        
+>/ ""=eulav ".toor_yxalag-- erofeb 'tset' ekil noitca denrodanu na tcepxe omenalP ekil stegrat emoS"=pleh              
+"dedeen fi oof--~~ ge - ytpme ton fi xiferp eman esrapgra tluafed detareneg eht edirrevO"=lebal "txet"=epyt "dexiferpLC_marap"=eman marap<          
+>/ ""=eulav "LC eht no dedneperp eb lliw '--' ,elyts esrapgrA gnisU .enil dnammoc eht no retemarap siht rof lanidro regetni eht retne ,sretemarap lanoitisop gnisU"=pleh              
+"eman tnemugra esrapgra | lanidro lanoitisoP"=lebal "txet"=epyt "LC_marap"=eman marap<          
+>marap/<          
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>dilav/< >/'~~~'=eulav evomer< >"elbatnirp.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+> "noitatimil lacinhcet siht dnuora krow esaelp - dleif txet siht ni desu eb tonnac ~ evitucesnoc eerht taht etoN"=pleh             
+"retemarap siht rof pleH"=lebal ""=eulav "txet"=epyt "pleh_marap"=eman marap<          
+>marap/<          
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>dilav/< >/'~~~'=eulav evomer< >"elbatnirp.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+> "noitatimil lacinhcet siht dnuora krow esaelp - dleif txet siht ni raeppa ton tsum os retimiled lanretni na si '~~~' taht etoN"=pleh             
+"mrof eht rof lebal s'retemarap siht retnE"=lebal ""=eulav "txet"=epyt "lebal_marap"=eman marap<          
+>marap/<          
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>dilav/< >/'~~~'=eulav evomer< >"elbatnirp.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+> "noitatimil lacinhcet siht dnuora krow esaelp - dleif txet siht ni raeppa ton tsum retimiled lanretni na si '~~~' taht etoN"=pleh            
+"eulav tluafed s'retemarap siht retnE"=lebal ""=eulav "txet"=epyt "eulav_marap"=eman marap<          
+>marap/<          
+>noitpo/<taolf>"taolf"=eulav noitpo<            
+>noitpo/<regetni>"regetni"=eulav noitpo<            
+>noitpo/<txet>"eurt"=detceles "txet"=eulav noitpo<            
+>"retemarap siht rof epyt eht tceleS"=lebal "tceles"=epyt "epyt_marap"=eman marap<          
+>marap/<          
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>/"stigid.gnirts,srettel.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+>"!knalb eb ton TSUM - retemarap siht rof eman eht esoohC"=lebal ""=eulav "txet"=epyt "eman_marap"=eman marap<          
+>"segaugnal suoirav eht ni stpircs yb desrap eb nac eseht woh ees ot woleb selpmaxe eeS"=pleh             
+"enil dnammoc eht no dessap dna resu loot eht yb tes eb ot sgnittes erom ro orez"=eltit "sretemarap_lanoitidda"=eman taeper<        
+
+>marap/<        
+>noitpo/<gnitide resu on - sretemarap lanoitidda lla rof seulav dexif eht esu - oN>"on"=eulav noitpo<            
+>noitpo/<mrof loot detareneg eht no sretemarap lanoitidda lla tide ot resu wolla ,seY>"eurt"=detceles "sey"=eulav noitpo<            
+>"gnizitinas ro noitadilav on htiw sdleif txet sa mrof loot eht no raeppa lliw eseht ,sey fI .sretemarap lanoitidda yna retla ot elba eb TON lliw sresu ,on fI"=pleh             
+"?elbatide resu mrof loot detareneg eht no sgnittes eseht ekaM"=lebal "oidar"=yalpsid "tceles"=epyt "smarap_tide"=eman marap<        
+>"eurt"=dednapxe "selif O/I naht rehto enil dnammoc eht no dessap sgnittes tpircs ro elbatucexE"=eltit "marapdda"=eman noitces<     
+>"maraptidda"=eman lmx<     
+>lmx/<     
+>noitces/<        
+>taeper/<        
+>/"0:ffid"=eulav ")taolf( carf_atled ro )regetni( atled[:ezis_mis ,]senil[:ffid era snoitpo elbaliavA"=pleh              
+"noitareneg tset ot derapmoc tuptuo siht rof noiretirc noisiced ssap tseT"=lebal  "txet"=epyt "tset_yrotsih"=eman marap<            
+>/""=eulav "dedeen TUODTS sselnu erongi ,esrapgra fI .retemarap siht rof detcepxe lanidro regetni eht retne ,sretemarap lanoitisop fI"=pleh              
+"desu si eman esuaceb esrapgra fi derongi esiwrehtO .deriuqer '>' fi TUODTS esU .regetni lanidro :lanoitisoP"=lebal  "txet"=epyt "LC_yrotsih"=eman marap<            
+>marap/<            
+>snoitpo/<               
+>/"0"=xedni "eulav"=eman nmuloc<                
+>"stamrof_elif_daolpu.yrtsiger_sepytatad.ppa.loot"=retemarap_morf snoitpo<               
+>"ralubat"=eulav "lmx.fnoc_sepytatad s'yxalag ni dedda eb ot sah ti ,ereh detsil ton si epytatad ruoy fI"=pleh              
+"tuptuo siht rof epytatad eht tceleS"=lebal "eslaf"=elpitlum "tceles"=epyt "tamrof_yrotsih"=eman marap<            
+>marap/<            
+>rezitinas/<              
+>/ "_"=eulav dda<                
+>/"stigid.gnirts,srettel.gnirts"=laitini dilav<                
+>"_"=rahc_dilavni rezitinas<              
+>"]eman[-- sa eman siht esu osla lliw esrapgrA !secaps oN"=pleh              
+"eslaf"=lanoitpo "yrotsih wen ni raeppa ot tuptuo siht rof emaN"=lebal "txet"=epyt "eman_yrotsih"=eman marap<            
+>"stuptuo s'ti fo eno gniniatnoc gnikam era uoy loot wen eht fo sresu rof meti yrotsih a emoceb lliw eman ehT"=pleh             
+"snur loot eht retfa yrotsih resu eht ni raeppa ot elbatucexe eht yb tuptuo smeti yrotsih wen erom ro eno"=eltit "stuptuo_yrotsih"=eman taeper<        
+>taeper/<        
+>marap/<            
+>""=eulav "retcarahc elgnis fi '-' ro dedneperp eb lliw '--' ,elyts esrapgrA fI .retemarap siht rof lanidro regetni eht retne ,sretemarap lanoitisop ssap lliw uoy fI"=pleh              
+"ti stcepxe tpircs/elbatucexe eht fi NIDTS .eman tnemugra :esrapgrA .regetni lanidro :lanoitisoP"=lebal "txet"=epyt "LC_tupni"=eman marap<            
+>marap/<            
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>dilav/< >/'~~~'=eulav evomer< >"elbatnirp.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+>"noitatimil lacinhcet siht dnuora krow esaelp - dleif txet siht ni desu eb tonnac ~ evitucesnoc eerht taht etoN"=pleh             
+".mrof eht no txet pleh emoceb lliw sihT"=lebal ""=eulav "txet"=epyt "pleh_tupni"=eman marap<            
+>marap/<            
+>rezitinas/<            
+>/"enon"=laitini gnippam<              
+>dilav/< >/'~~~'=eulav evomer< >"elbatnirp.gnirts"=laitini dilav<              
+>""=rahc_dilavni rezitinas<            
+> "noitatimil lacinhcet siht dnuora krow esaelp - dleif txet siht ni raeppa ton tsum os retimiled lanretni na si '~~~' taht etoN"=pleh             
+"evitamrofni ti ekam esaelp os mrof eht rof tpmorp resu eht emoceb lliw sihT"=lebal ""=eulav "txet"=epyt "lebal_tupni"=eman marap<            
+>marap/<            
+>snoitpo/<               
+>/"0"=xedni "eulav"=eman nmuloc<                
+>"stamrof_elif_daolpu.yrtsiger_sepytatad.ppa.loot"=retemarap_morf snoitpo<               
+>"ralubat"=eulav "lmx.fnoc_sepytatad s'yxalag ni dedda eb ot sah ti ,ereh detsil ton si epytatad ruoy fI"=pleh              
+"tupni sa stpecca tpircs/loot ruoy taht )s(epytatad eht tceleS"=lebal "eurt"=elpitlum "tceles"=epyt "stamrof_tupni"=eman marap<            
+>/""=pleh               
+"eslaf"=elpitlum "eurt"=lanoitpo "yrotsih ruoy morf elif tupni na tceleS"=lebal "atad"=tamrof "atad"=epyt "selif_tupni"=eman marap<            
+>"loot wen siht fo sresu rof tupni sa rotceles meti yrotsih a mrof lliw stpmorP .tset s'loot wen eht rof SELPMAS LLAMS ESU"=pleh             
+".elbatucexe eht ot sretemarap sa ssap ot selif atad tupni erom ro orez"=eltit "stupni_yrotsih"=eman taeper<        
+>"eurt"=dednapxe "selif tuptuo dna tupnI"=eltit "oi"=eman noitces<     
+>"oi"=eman lmx<     
+>lmx/<     
+>taeper/<            
+>lanoitidnoc/<                
+>nehw/<                    
+>marap/<                        
+>rezitinas/<                            
+>/"enon"=laitini gnippam<                                
+>dilav/<                                
+>"elbatnirp.gnirts"=laitini dilav<                                
+>rezitinas<                            
+> ""=eulav ".hcraeser dehsilbup ni desu si loot siht nehw detic eb dluohs taht yrtne xeTbiB a ylppuS"=pleh                            
+"eurt"=aera "txet"=epyt "xeTbiB"=lebal "xetbib"=eman marap<                        
+>"xetbib"=eulav nehw<                    
+>nehw/<                    
+>/ ".hcraeser dehsilbup ni desu si loot siht nehw detic eb ot )x.85200.7002.3179-0471.j/1111.01 :iod .g.e( IOD a ylppuS"=pleh                        
+""=eulav "txet"=epyt "IOD"=lebal "iod"=eman marap<                        
+>"iod"=eulav nehw<                    
+>marap/<                    
+>noitpo/<XeTbiB>"xetbib"=eulav noitpo<                        
+>noitpo/<IOD>"iod"=eulav noitpo<                        
+>"epyT noitatiC"=lebal "oidar"=yalpsid "tceles"=epyt "epyt"=eman marap<                    
+>"epyt_noitatic"=eman lanoitidnoc<                
+>"noitatiC"=eltit "snoitatic"=eman taeper<            
+>marap/<            
+>rezitinas/<                
+>/"enon"=laitini gnippam<                    
+>dilav/<                    
+>"elbatnirp.gnirts"=laitini dilav<                    
+>rezitinas<                
+> "lmth.txetderutcurtser/tsr/fer/scod/ten.egrofecruos.slitucod//:ptth - txet derutcurtSer sa mrof loot wen eht no raeppa ot noitatnemucod resu ylppuS"=pleh             
+"**seoD ti tahW**"=eulav            
+"eurt"=aera "txet"=epyt "sresu rof txet pleh dna noitatnemucod mrof looT"=lebal "txet_pleh"=eman marap<            
+>/ "yrtne unem loot yxalaG eht rof noitpircsed loot feirb a ylppuS"=pleh             
+""=eulav "txet"=epyt "sisponyS looT"=lebal "csed_loot"=eman marap<            
+>/"rebmun siht )lanoitidart si gnipmub( gnignahc yb )sresu dna( yxalaG mrofni dluohs uoy ,loot 'emas' eht etareneger dna tpircs ruoy egnahc uoy fI"=pleh            
+"10.0"=eulav "txet"=epyt "sesylana dlo oder ot gniyrt sresu nraw ot siht pmub - noisreV looT"=lebal "noisrev_loot"=eman marap<         
+>"atadatem_loot"=eman lmx<     
+>sorcam<  
+>noitpircsed/<0.2v sloot otni stpircS>noitpircsed<  
+> "40.61"=eliforp "00.2"=noisrev "yrotcafloot"=eman "dftgr"=di loot<