Extract mature miRNAs identified with matches to miRBase by ShortStack in 08.2-Peve-sRNAseq-ShortStack-31bp-fastp-merged.Rmd to FastA.


1 Create a Bash variables file

This allows usage of Bash variables across R Markdown chunks.

{
echo "#### Assign Variables ####"
echo ""

echo "# Trimmed FastQ naming pattern"

echo "# Data directories"
echo 'export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive'
echo 'export shortstack_dir="${deep_dive_dir}/E-Peve/output/08.2-Peve-sRNAseq-ShortStack-31bp-fastp-merged/ShortStack_out"'
echo 'export output_dir_top=${deep_dive_dir}/E-Peve/output/08.2.1-Peve-sRNAseq-ShortStack-FastA-extraction'
echo ""

echo "# Input/Output files"
echo 'export output_fasta="mature-miRBase-matches.fasta"'
echo 'export shortstack_fasta="mir.fasta"'
echo 'export shortstack_fasta_index="mir.fasta.fai"'
echo 'export shortstack_fixed_fasta="mir-coords-fixed.fasta"'
echo 'export shortstack_fixed_fasta_index="mir-coords-fixed.fasta.fai"'

echo 'export shortstack_results_file="Results.txt"'
echo 'export regions="mature-miRBase-regions.txt"'

echo ""

echo "# Set number of CPUs to use"
echo 'export threads=40'
echo ""

echo "# Programs"
echo 'export samtools=/home/shared/samtools-1.12/samtools'


} > .bashvars

cat .bashvars
#### Assign Variables ####

# Trimmed FastQ naming pattern
# Data directories
export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive
export shortstack_dir="${deep_dive_dir}/E-Peve/output/08.2-Peve-sRNAseq-ShortStack-31bp-fastp-merged/ShortStack_out"
export output_dir_top=${deep_dive_dir}/E-Peve/output/08.2.1-Peve-sRNAseq-ShortStack-FastA-extraction

# Input/Output files
export output_fasta="mature-miRBase-matches.fasta"
export shortstack_fasta="mir.fasta"
export shortstack_fasta_index="mir.fasta.fai"
export shortstack_fixed_fasta="mir-coords-fixed.fasta"
export shortstack_fixed_fasta_index="mir-coords-fixed.fasta.fai"
export shortstack_results_file="Results.txt"
export regions="mature-miRBase-regions.txt"

# Set number of CPUs to use
export threads=40

# Programs
export samtools=/home/shared/samtools-1.12/samtools

2 Examine Results.txt

2.2 Columns of interest

Column 1: Region of miRNA match

Column 20: ShortStack miRNA? Y/N

Column 21: Match to miRBase? NA or miRBase match

# Load bash variables into memory
source .bashvars

awk '{print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | head | column -t
Locus                                      MIRNA  known_miRNAs
Porites_evermani_scaffold_1:45711-46131    N      NA
Porites_evermani_scaffold_1:201507-201931  N      NA
Porites_evermani_scaffold_1:313446-313846  N      NA
Porites_evermani_scaffold_1:406146-406734  N      NA
Porites_evermani_scaffold_1:409839-410269  N      NA
Porites_evermani_scaffold_1:465244-465668  N      NA
Porites_evermani_scaffold_1:468473-468950  N      NA
Porites_evermani_scaffold_1:476827-477250  N      NA
Porites_evermani_scaffold_1:486441-486868  N      NA

2.3 miRNAs of interest

# Load bash variables into memory
source .bashvars

awk '$20 == "Y" && $21 != "NA" {print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | head | column -t

echo ""
echo "------------------------------------------"
echo ""
echo "Number of miRNAs matching miRBase:"

awk '$20 == "Y" && $21 != "NA" {print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | wc -l 
Porites_evermani_scaffold_49:151587-151681   Y  ami-nve-F-miR-100-5p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-100_5p_Acropora_digitifera_Gajigan_&_Conaco_2017_mir-100;_spi-miR-temp-1;adi-nve-F-miR-100_Acropora_digitifera__Praher_et_al._2021_NA
Porites_evermani_scaffold_430:205865-205960  Y  spi-mir-temp-30_Stylophora_pistillata_Liew_et_al._2014_Close_match_of_nve-miR-2036.;spi-nve-F-miR-2036_Stylophora_pistillata_Praher_et_al._2021_NA;ami-nve-F-miR-2036-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-2036_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2036-3p;_nve-miR-2036-3p;_spi-miR-temp-30;eca-nve-F-miR-2036_Edwardsiella_carnea_Praher_et_al._2021_Transcriptome-level
Porites_evermani_scaffold_502:58948-59038    Y  ami-nve-F-miR-2030-5p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-2030_5p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2030-5p;_nve-miR-2030-5p;_spi-miR-temp-40;adi-nve-F-miR-2030_Acropora_digitifera__Praher_et_al._2021_NA;spi-mir-temp-40_Stylophora_pistillata_Liew_et_al._2014_Close_match_of_nve-miR-2030;eca-nve-F-miR-2030_Edwardsiella_carnea_Praher_et_al._2021_Transcriptome-level;miR-2030_Nematostella_vectensis_Moran_et_al._2014_NA
Porites_evermani_scaffold_594:158176-158270  Y  nve-miR-2023-3p;spi-mir-temp-4_Stylophora_pistillata_Liew_et_al._2014_Exact_match_of_nve-miR-2023.;apa-mir-2023_Exaiptasia_pallida_Baumgarten_et_al._2017_miR-2023;_Nve;_Spis;_Adi;mse-nve-F-miR-2023_Metridium_senile_Praher_et_al._2021_Transcriptome-level;sca-nve-miR-2023-3p_Scolanthus_callimorphus_Praher_et_al._2021_Transcriptome-level;eca-nve-F-miR-2023_Edwardsiella_carnea_Praher_et_al._2021_Transcriptome-level;ami-nve-F-miR-2023-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-2023_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2023-3p;_nve-miR-2023-3p;_spi-miR-temp-4;epa-nve-F-miR-2023_Exaiptasia_pallida_Praher_et_al._2021_NA;miR-2023_Nematostella_vectensis_Moran_et_al._2014_NA;spi-nve-F-miR-2023_Stylophora_pistillata_Praher_et_al._2021_NA;avi-miR-temp-2023_Anemonia_viridis_Urbarova_et_al._2018_NA
Porites_evermani_scaffold_910:99233-99322    Y  adi-miR-P-novel-6-3p_Acropora_digitifera__Praher_et_al._2021_NA
Porites_evermani_scaffold_910:118720-118809  Y  adi-miR-P-novel-6-3p_Acropora_digitifera__Praher_et_al._2021_NA;spi-mir-temp-14_Stylophora_pistillata_Liew_et_al._2014_NA;ami-spi-miR-L-temp-14-5p_Acropora_millepora_Praher_et_al._2021_NA
Porites_evermani_scaffold_910:139331-139420  Y  ami-spi-miR-L-temp-14-5p_Acropora_millepora_Praher_et_al._2021_NA
Porites_evermani_scaffold_1503:47558-47651   Y  spi-mir-temp-15_Stylophora_pistillata_Liew_et_al._2014_NA;spi-miR-L-temp-15_Stylophora_pistillata_Praher_et_al._2021_NA
Porites_evermani_scaffold_3072:29428-29521   Y  ami-nve-F-miR-2025-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-2025_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2025-3p;_nve-miR-2025-3p;adi-nve-F-miR-2025_Acropora_digitifera__Praher_et_al._2021_NA

------------------------------------------

Number of miRNAs matching miRBase:
9

3 Examine ShortStack miRNA FastA

3.1 Head FastA

# Load bash variables into memory
source .bashvars

grep "^>" "${shortstack_dir}/${shortstack_fasta}" | head
>Cluster_29::Porites_evermani_scaffold_1:1404249-1404342(-)
>Cluster_29.mature::Porites_evermani_scaffold_1:1404271-1404293(-)
>Cluster_29.star::Porites_evermani_scaffold_1:1404300-1404322(-)
>Cluster_578::Porites_evermani_scaffold_16:383385-383478(-)
>Cluster_578.mature::Porites_evermani_scaffold_16:383436-383458(-)
>Cluster_578.star::Porites_evermani_scaffold_16:383405-383427(-)
>Cluster_786::Porites_evermani_scaffold_26:382549-382645(-)
>Cluster_786.mature::Porites_evermani_scaffold_26:382571-382593(-)
>Cluster_786.star::Porites_evermani_scaffold_26:382602-382625(-)
>Cluster_1125::Porites_evermani_scaffold_47:475971-476066(-)

4 Fix FastA description starting coordinates

Needed, due to bug in code (GitHub Issue) which incorrectly calculates the starting coordinates in the FastA output. All other files where start/stop coordinates are conveyed are correct.

The incorrect starting coordinates cause an issue in downstream manipulation, because the FastA headers need to match the ShortStack results file.

# Load bash variables into memory
source .bashvars

awk '
/^>/ {
    # Split the line into main parts based on "::" delimiter
    split($0, main_parts, "::")
    
    # Extract the coordinate part and strand information separately
    coordinates_strand = main_parts[2]
    split(coordinates_strand, coord_parts, "[:-]")
    
    # Determine if the strand information is present and extract it
    strand = ""
    if (substr(coordinates_strand, length(coordinates_strand)) ~ /[\(\)\-\+]/) {
        strand = substr(coordinates_strand, length(coordinates_strand) - 1)
        coordinates_strand = substr(coordinates_strand, 1, length(coordinates_strand) - 2)
        split(coordinates_strand, coord_parts, "[:-]")
    }
    
    # Increment the starting coordinate by 1
    new_start = coord_parts[2] + 1
    
    # Reconstruct the description line with the new starting coordinate
    new_description = main_parts[1] "::" coord_parts[1] ":" new_start "-" coord_parts[3] strand
    
    # Print the modified description line
    print new_description
    
    # Skip to the next line to process the sequence line
    next
}

# For sequence lines, print them as-is
{
    print
}
' "${shortstack_dir}/${shortstack_fasta}" \
> "${shortstack_dir}/${shortstack_fixed_fasta}"

diff "${shortstack_dir}/${shortstack_fasta}" \
"${shortstack_dir}/${shortstack_fixed_fasta}" \
| head
1c1
< >Cluster_29::Porites_evermani_scaffold_1:1404249-1404342(-)
---
> >Cluster_29::Porites_evermani_scaffold_1:1404250-1404342(-)
3c3
< >Cluster_29.mature::Porites_evermani_scaffold_1:1404271-1404293(-)
---
> >Cluster_29.mature::Porites_evermani_scaffold_1:1404272-1404293(-)
5c5
< >Cluster_29.star::Porites_evermani_scaffold_1:1404300-1404322(-)

5 Create regions file for use with samtools

5.1 Make FastA index

# Load bash variables into memory
source .bashvars

${samtools} faidx "${shortstack_dir}/${shortstack_fixed_fasta}"


head "${shortstack_dir}/${shortstack_fixed_fasta_index}"
Cluster_29::Porites_evermani_scaffold_1:1404250-1404342(-)  93  60  93  94
Cluster_29.mature::Porites_evermani_scaffold_1:1404272-1404293(-)   22  221 22  23
Cluster_29.star::Porites_evermani_scaffold_1:1404301-1404322(-) 22  309 22  23
Cluster_578::Porites_evermani_scaffold_16:383386-383478(-)  93  392 93  94
Cluster_578.mature::Porites_evermani_scaffold_16:383437-383458(-)   22  553 22  23
Cluster_578.star::Porites_evermani_scaffold_16:383406-383427(-) 22  641 22  23
Cluster_786::Porites_evermani_scaffold_26:382550-382645(-)  96  724 96  97
Cluster_786.mature::Porites_evermani_scaffold_26:382572-382593(-)   22  888 22  23
Cluster_786.star::Porites_evermani_scaffold_26:382603-382625(-) 23  976 23  24
Cluster_1125::Porites_evermani_scaffold_47:475972-476066(-) 95  1061    95  96

5.2 Construct regions of miRBase matches for FastA index

# Load bash variables into memory
source .bashvars

# Make output directory, if it doesn't exist
mkdir --parents "${output_dir_top}"

{
   awk '$20 == "Y" && $21 != "NA" {print $2}' "${shortstack_dir}/${shortstack_results_file}" \
   | grep --fixed-strings --file - "${shortstack_dir}/${shortstack_fixed_fasta_index}" \
   | awk '{print $1}'
} \
> "${output_dir_top}/${regions}"

head "${output_dir_top}/${regions}"
Cluster_1153::Porites_evermani_scaffold_49:151587-151681(-)
Cluster_1153.mature::Porites_evermani_scaffold_49:151640-151661(-)
Cluster_1153.star::Porites_evermani_scaffold_49:151607-151628(-)
Cluster_5540::Porites_evermani_scaffold_430:205865-205960(-)
Cluster_5540.mature::Porites_evermani_scaffold_430:205887-205909(-)
Cluster_5540.star::Porites_evermani_scaffold_430:205917-205940(-)
Cluster_6211::Porites_evermani_scaffold_502:58948-59038(-)
Cluster_6211.mature::Porites_evermani_scaffold_502:58997-59018(-)
Cluster_6211.star::Porites_evermani_scaffold_502:58968-58989(-)
Cluster_6875::Porites_evermani_scaffold_594:158176-158270(+)

6 Extract FastAs

# Load bash variables into memory
source .bashvars

${samtools} faidx "${shortstack_dir}/${shortstack_fixed_fasta}" \
--region-file "${output_dir_top}/${regions}" \
> "${output_dir_top}/${output_fasta}"

head "${output_dir_top}/${output_fasta}"

echo ""
echo ""
echo ""
echo "Number of FastA sequences:"
grep "^>" --count "${output_dir_top}/${output_fasta}"
>Cluster_1153::Porites_evermani_scaffold_49:151587-151681(-)
AATTCTAGCAGCTCATGCGATCCCGTAGATCCGAACTTGTGGGTATTTTCTCCACAGGTT
GGGCTCTACGGTCATATTTGCTGTAATATAACATG
>Cluster_1153.mature::Porites_evermani_scaffold_49:151640-151661(-)
TCCCGTAGATCCGAACTTGTGG
>Cluster_1153.star::Porites_evermani_scaffold_49:151607-151628(-)
ACAGGTTGGGCTCTACGGTCAT
>Cluster_5540::Porites_evermani_scaffold_430:205865-205960(-)
TGAAGTGTTGTTTCTAGAGGCGGTGAAAGTCGTCTCAATACACAGTTGATGTATATTGTA
CGACTCTCATCGTGTTTGTGACAATCTCTTATTTCA



Number of FastA sequences:
27
LS0tCnRpdGxlOiAiMDguMi4xLVBldmUtc1JOQXNlcS1TaG9ydFN0YWNrLUZhc3RBLWV4dHJhY3Rpb24iCmF1dGhvcjogIlNhbSBXaGl0ZSIKZGF0ZTogIjIwMjQtMDUtMjIiCm91dHB1dDogCiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICBnaXRodWJfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliCmxpbmstY2l0YXRpb25zOiB0cnVlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgICAgICAgICAjIERpc3BsYXkgY29kZSBjaHVua3MKICBldmFsID0gRkFMU0UsICAgICAgICAjIEV2YWx1YXRlIGNvZGUgY2h1bmtzCiAgd2FybmluZyA9IEZBTFNFLCAgICAgIyBIaWRlIHdhcm5pbmdzCiAgbWVzc2FnZSA9IEZBTFNFLCAgICAgIyBIaWRlIG1lc3NhZ2VzCiAgY29tbWVudCA9ICIiICAgICAgICAgIyBQcmV2ZW50cyBhcHBlbmRpbmcgJyMjJyB0byBiZWdpbm5pbmcgb2YgbGluZXMgaW4gY29kZSBvdXRwdXQKKQpgYGAKCkV4dHJhY3QgbWF0dXJlIG1pUk5BcyBpZGVudGlmaWVkIHdpdGggbWF0Y2hlcyB0byBtaVJCYXNlIGJ5IFNob3J0U3RhY2sgaW4gWzA4LjItUGV2ZS1zUk5Bc2VxLVNob3J0U3RhY2stMzFicC1mYXN0cC1tZXJnZWQuUm1kXSguLzA4LjItUGV2ZS1zUk5Bc2VxLVNob3J0U3RhY2stMzFicC1mYXN0cC1tZXJnZWQuUm1kKSB0byBGYXN0QS4KCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgojIENyZWF0ZSBhIEJhc2ggdmFyaWFibGVzIGZpbGUKClRoaXMgYWxsb3dzIHVzYWdlIG9mIEJhc2ggdmFyaWFibGVzIGFjcm9zcyBSIE1hcmtkb3duIGNodW5rcy4KCmBgYHtyIHNhdmUtYmFzaC12YXJpYWJsZXMtdG8tcnZhcnMtZmlsZSwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQp7CmVjaG8gIiMjIyMgQXNzaWduIFZhcmlhYmxlcyAjIyMjIgplY2hvICIiCgplY2hvICIjIFRyaW1tZWQgRmFzdFEgbmFtaW5nIHBhdHRlcm4iCgplY2hvICIjIERhdGEgZGlyZWN0b3JpZXMiCmVjaG8gJ2V4cG9ydCBkZWVwX2RpdmVfZGlyPS9ob21lL3NoYXJlZC84VEJfSEREXzAxL3NhbS9naXRyZXBvcy9kZWVwLWRpdmUnCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX2Rpcj0iJHtkZWVwX2RpdmVfZGlyfS9FLVBldmUvb3V0cHV0LzA4LjItUGV2ZS1zUk5Bc2VxLVNob3J0U3RhY2stMzFicC1mYXN0cC1tZXJnZWQvU2hvcnRTdGFja19vdXQiJwplY2hvICdleHBvcnQgb3V0cHV0X2Rpcl90b3A9JHtkZWVwX2RpdmVfZGlyfS9FLVBldmUvb3V0cHV0LzA4LjIuMS1QZXZlLXNSTkFzZXEtU2hvcnRTdGFjay1GYXN0QS1leHRyYWN0aW9uJwplY2hvICIiCgplY2hvICIjIElucHV0L091dHB1dCBmaWxlcyIKZWNobyAnZXhwb3J0IG91dHB1dF9mYXN0YT0ibWF0dXJlLW1pUkJhc2UtbWF0Y2hlcy5mYXN0YSInCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX2Zhc3RhPSJtaXIuZmFzdGEiJwplY2hvICdleHBvcnQgc2hvcnRzdGFja19mYXN0YV9pbmRleD0ibWlyLmZhc3RhLmZhaSInCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX2ZpeGVkX2Zhc3RhPSJtaXItY29vcmRzLWZpeGVkLmZhc3RhIicKZWNobyAnZXhwb3J0IHNob3J0c3RhY2tfZml4ZWRfZmFzdGFfaW5kZXg9Im1pci1jb29yZHMtZml4ZWQuZmFzdGEuZmFpIicKCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX3Jlc3VsdHNfZmlsZT0iUmVzdWx0cy50eHQiJwplY2hvICdleHBvcnQgcmVnaW9ucz0ibWF0dXJlLW1pUkJhc2UtcmVnaW9ucy50eHQiJwoKZWNobyAiIgoKZWNobyAiIyBTZXQgbnVtYmVyIG9mIENQVXMgdG8gdXNlIgplY2hvICdleHBvcnQgdGhyZWFkcz00MCcKZWNobyAiIgoKZWNobyAiIyBQcm9ncmFtcyIKZWNobyAnZXhwb3J0IHNhbXRvb2xzPS9ob21lL3NoYXJlZC9zYW10b29scy0xLjEyL3NhbXRvb2xzJwoKCn0gPiAuYmFzaHZhcnMKCmNhdCAuYmFzaHZhcnMKYGBgCgojIEV4YW1pbmUgYFJlc3VsdHMudHh0YAoKIyMgSGVhZApgYGB7ciBoZWFkLXJlc3VsdHMudHh0LCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgpoZWFkICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfcmVzdWx0c19maWxlfSIgfCBjb2x1bW4gLXQKYGBgCgojIyBDb2x1bW5zIG9mIGludGVyZXN0CgpDb2x1bW4gMTogUmVnaW9uIG9mIG1pUk5BIG1hdGNoCgpDb2x1bW4gMjA6IFNob3J0U3RhY2sgbWlSTkE/IFkvTgoKQ29sdW1uIDIxOiBNYXRjaCB0byBtaVJCYXNlPyBOQSBvciBtaVJCYXNlIG1hdGNoCgpgYGB7ciBjb2xzLW9mLWludGVyZXN0LCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgphd2sgJ3twcmludCAkMSJcdCIkMjAiXHQiJDIxfScgIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19yZXN1bHRzX2ZpbGV9IiB8IGhlYWQgfCBjb2x1bW4gLXQKYGBgCgojIyBtaVJOQXMgb2YgaW50ZXJlc3QKYGBge3IgbWlSTkFzLW9mLWludGVyZXN0LCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgphd2sgJyQyMCA9PSAiWSIgJiYgJDIxICE9ICJOQSIge3ByaW50ICQxIlx0IiQyMCJcdCIkMjF9JyAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX3Jlc3VsdHNfZmlsZX0iIHwgaGVhZCB8IGNvbHVtbiAtdAoKZWNobyAiIgplY2hvICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iCmVjaG8gIiIKZWNobyAiTnVtYmVyIG9mIG1pUk5BcyBtYXRjaGluZyBtaVJCYXNlOiIKCmF3ayAnJDIwID09ICJZIiAmJiAkMjEgIT0gIk5BIiB7cHJpbnQgJDEiXHQiJDIwIlx0IiQyMX0nICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfcmVzdWx0c19maWxlfSIgfCB3YyAtbCAKYGBgCgojIEV4YW1pbmUgU2hvcnRTdGFjayBtaVJOQSBGYXN0QQoKIyMgSGVhZCBGYXN0QQoKYGBge3IgaGVhZC1GYXN0QSwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKZ3JlcCAiXj4iICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZmFzdGF9IiB8IGhlYWQKYGBgCgojIEZpeCBGYXN0QSBkZXNjcmlwdGlvbiBzdGFydGluZyBjb29yZGluYXRlcwoKTmVlZGVkLCBkdWUgdG8gW2J1ZyBpbiBjb2RlXShodHRwczovL2dpdGh1Yi5jb20vTWlrZUF4dGVsbC9TaG9ydFN0YWNrL2lzc3Vlcy8xNTMjaXNzdWVjb21tZW50LTIxMjI4OTc0ODYpIChHaXRIdWIgSXNzdWUpIHdoaWNoIGluY29ycmVjdGx5IGNhbGN1bGF0ZXMgdGhlIHN0YXJ0aW5nIGNvb3JkaW5hdGVzIGluIHRoZSBGYXN0QSBvdXRwdXQuIEFsbCBvdGhlciBmaWxlcyB3aGVyZSBzdGFydC9zdG9wIGNvb3JkaW5hdGVzIGFyZSBjb252ZXllZCBhcmUgY29ycmVjdC4KClRoZSBpbmNvcnJlY3Qgc3RhcnRpbmcgY29vcmRpbmF0ZXMgY2F1c2UgYW4gaXNzdWUgaW4gZG93bnN0cmVhbSBtYW5pcHVsYXRpb24sIGJlY2F1c2UgdGhlIEZhc3RBIGhlYWRlcnMgbmVlZCB0byBtYXRjaCB0aGUgU2hvcnRTdGFjayByZXN1bHRzIGZpbGUuCgpgYGB7ciBmaXgtRmFzdEEtY29vcmRpbmF0ZXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmF3ayAnCi9ePi8gewogICAgIyBTcGxpdCB0aGUgbGluZSBpbnRvIG1haW4gcGFydHMgYmFzZWQgb24gIjo6IiBkZWxpbWl0ZXIKICAgIHNwbGl0KCQwLCBtYWluX3BhcnRzLCAiOjoiKQogICAgCiAgICAjIEV4dHJhY3QgdGhlIGNvb3JkaW5hdGUgcGFydCBhbmQgc3RyYW5kIGluZm9ybWF0aW9uIHNlcGFyYXRlbHkKICAgIGNvb3JkaW5hdGVzX3N0cmFuZCA9IG1haW5fcGFydHNbMl0KICAgIHNwbGl0KGNvb3JkaW5hdGVzX3N0cmFuZCwgY29vcmRfcGFydHMsICJbOi1dIikKICAgIAogICAgIyBEZXRlcm1pbmUgaWYgdGhlIHN0cmFuZCBpbmZvcm1hdGlvbiBpcyBwcmVzZW50IGFuZCBleHRyYWN0IGl0CiAgICBzdHJhbmQgPSAiIgogICAgaWYgKHN1YnN0cihjb29yZGluYXRlc19zdHJhbmQsIGxlbmd0aChjb29yZGluYXRlc19zdHJhbmQpKSB+IC9bXChcKVwtXCtdLykgewogICAgICAgIHN0cmFuZCA9IHN1YnN0cihjb29yZGluYXRlc19zdHJhbmQsIGxlbmd0aChjb29yZGluYXRlc19zdHJhbmQpIC0gMSkKICAgICAgICBjb29yZGluYXRlc19zdHJhbmQgPSBzdWJzdHIoY29vcmRpbmF0ZXNfc3RyYW5kLCAxLCBsZW5ndGgoY29vcmRpbmF0ZXNfc3RyYW5kKSAtIDIpCiAgICAgICAgc3BsaXQoY29vcmRpbmF0ZXNfc3RyYW5kLCBjb29yZF9wYXJ0cywgIls6LV0iKQogICAgfQogICAgCiAgICAjIEluY3JlbWVudCB0aGUgc3RhcnRpbmcgY29vcmRpbmF0ZSBieSAxCiAgICBuZXdfc3RhcnQgPSBjb29yZF9wYXJ0c1syXSArIDEKICAgIAogICAgIyBSZWNvbnN0cnVjdCB0aGUgZGVzY3JpcHRpb24gbGluZSB3aXRoIHRoZSBuZXcgc3RhcnRpbmcgY29vcmRpbmF0ZQogICAgbmV3X2Rlc2NyaXB0aW9uID0gbWFpbl9wYXJ0c1sxXSAiOjoiIGNvb3JkX3BhcnRzWzFdICI6IiBuZXdfc3RhcnQgIi0iIGNvb3JkX3BhcnRzWzNdIHN0cmFuZAogICAgCiAgICAjIFByaW50IHRoZSBtb2RpZmllZCBkZXNjcmlwdGlvbiBsaW5lCiAgICBwcmludCBuZXdfZGVzY3JpcHRpb24KICAgIAogICAgIyBTa2lwIHRvIHRoZSBuZXh0IGxpbmUgdG8gcHJvY2VzcyB0aGUgc2VxdWVuY2UgbGluZQogICAgbmV4dAp9CgojIEZvciBzZXF1ZW5jZSBsaW5lcywgcHJpbnQgdGhlbSBhcy1pcwp7CiAgICBwcmludAp9CicgIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19mYXN0YX0iIFwKPiAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX2ZpeGVkX2Zhc3RhfSIKCmRpZmYgIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19mYXN0YX0iIFwKIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19maXhlZF9mYXN0YX0iIFwKfCBoZWFkCgoKYGBgCgojIENyZWF0ZSByZWdpb25zIGZpbGUgZm9yIHVzZSB3aXRoIGBzYW10b29sc2AKCiMjIE1ha2UgRmFzdEEgaW5kZXgKCmBgYHtyIEZhc3RBLWluZGV4LCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgoke3NhbXRvb2xzfSBmYWlkeCAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX2ZpeGVkX2Zhc3RhfSIKCgpoZWFkICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZml4ZWRfZmFzdGFfaW5kZXh9IgpgYGAKCiMjIENvbnN0cnVjdCByZWdpb25zIG9mIG1pUkJhc2UgbWF0Y2hlcyBmb3IgRmFzdEEgaW5kZXgKCgpgYGB7ciBjb250cnN1Y3QtcmVnaW9ucy1maWxlLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgojIE1ha2Ugb3V0cHV0IGRpcmVjdG9yeSwgaWYgaXQgZG9lc24ndCBleGlzdApta2RpciAtLXBhcmVudHMgIiR7b3V0cHV0X2Rpcl90b3B9IgoKewogICBhd2sgJyQyMCA9PSAiWSIgJiYgJDIxICE9ICJOQSIge3ByaW50ICQyfScgIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19yZXN1bHRzX2ZpbGV9IiBcCiAgIHwgZ3JlcCAtLWZpeGVkLXN0cmluZ3MgLS1maWxlIC0gIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19maXhlZF9mYXN0YV9pbmRleH0iIFwKICAgfCBhd2sgJ3twcmludCAkMX0nCn0gXAo+ICIke291dHB1dF9kaXJfdG9wfS8ke3JlZ2lvbnN9IgoKaGVhZCAiJHtvdXRwdXRfZGlyX3RvcH0vJHtyZWdpb25zfSIKCmBgYAoKCgojIEV4dHJhY3QgRmFzdEFzCgpgYGB7ciBleHRyYWN0LUZhc3RBcywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKJHtzYW10b29sc30gZmFpZHggIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19maXhlZF9mYXN0YX0iIFwKLS1yZWdpb24tZmlsZSAiJHtvdXRwdXRfZGlyX3RvcH0vJHtyZWdpb25zfSIgXAo+ICIke291dHB1dF9kaXJfdG9wfS8ke291dHB1dF9mYXN0YX0iCgpoZWFkICIke291dHB1dF9kaXJfdG9wfS8ke291dHB1dF9mYXN0YX0iCgplY2hvICIiCmVjaG8gIiIKZWNobyAiIgplY2hvICJOdW1iZXIgb2YgRmFzdEEgc2VxdWVuY2VzOiIKZ3JlcCAiXj4iIC0tY291bnQgIiR7b3V0cHV0X2Rpcl90b3B9LyR7b3V0cHV0X2Zhc3RhfSIKCmBgYA==