0.1 intersectBed

Examine our input files (intersectBed accepts .bed and .gff files)

head -5 ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/mirna_results_03_04_2024_t_13_00_39/novel_mature_03_04_2024_t_13_00_39_score-50_to_na.bed
echo ""
head -5 ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results.gff3
browser position 
browser hide all
track name="notTrackname.novel_miRNAs" description="novel miRNAs detected by miRDeep2 for notTrackname" visibility=2
itemRgb="On";
NC_058066.1_Acropora_millepora_isolate_JS-1_chromosome_1_Amil_v2.1_whole_genome_shotgun_sequence    20346247    20346271    NC_058066.1_Acropora_millepora_isolate_JS-1_chromosome_1_Amil_v2.1_whole_genome_shotgun_sequence_49320  127017.5    -   20346247    20346271    0,0,255

NC_058066.1 ShortStack  Unknown_sRNA_locus  152483  152910  140 -   .   ID=Cluster_1;DicerCall=N;MIRNA=N
NC_058066.1 ShortStack  Unknown_sRNA_locus  161064  161674  549 .   .   ID=Cluster_2;DicerCall=N;MIRNA=N
NC_058066.1 ShortStack  Unknown_sRNA_locus  172073  172496  105 -   .   ID=Cluster_3;DicerCall=N;MIRNA=N
NC_058066.1 ShortStack  Unknown_sRNA_locus  203242  203651  100 .   .   ID=Cluster_4;DicerCall=N;MIRNA=N
NC_058066.1 ShortStack  Unknown_sRNA_locus  204535  205150  313 .   .   ID=Cluster_5;DicerCall=N;MIRNA=N

We need to get two input files that contain only mature miRNAs and have the same sequence naming conventions for matching purposes. That means the miRdeep2 mature miRNAs file need to be reformatted, and the ShortStack full results file needs to be filtered.

# remove header lines, shorten chromosome ref names to match those used in ShortStack output, and ensure final file is tab-delimited instead of space-delimited
tail -n +5 ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/mirna_results_03_04_2024_t_13_00_39/novel_mature_03_04_2024_t_13_00_39_score-50_to_na.bed | \
awk 'BEGIN { FS = "\t" } { sub(/\.1.*/, ".1", $1); print }' | \
tr ' ' '\t' > ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/mirna_results_03_04_2024_t_13_00_39/novel_mature_03_04_2024_t_13_00_39_score-50_to_na_formatted.bed

# filter full results to obtain a gff file of only the mature miRNAs
awk -F'\t' '$3 == "mature_miRNA"' ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results.gff3 > ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results_mature.gff3

Check the files

head -5 ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/mirna_results_03_04_2024_t_13_00_39/novel_mature_03_04_2024_t_13_00_39_score-50_to_na_formatted.bed
echo ""
head -5 ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results_mature.gff3
NC_058066.1 20346247    20346271    NC_058066.1_Acropora_millepora_isolate_JS-1_chromosome_1_Amil_v2.1_whole_genome_shotgun_sequence_49320  127017.5    -   20346247    20346271    0,0,255
NC_058070.1 11598966    11598988    NC_058070.1_Acropora_millepora_isolate_JS-1_chromosome_5_Amil_v2.1_whole_genome_shotgun_sequence_208678 40616.1 +   11598966    11598988    255,0,0
NC_058068.1 597877  597899  NC_058068.1_Acropora_millepora_isolate_JS-1_chromosome_3_Amil_v2.1_whole_genome_shotgun_sequence_123927 40339.4 +   597877  597899  255,0,0
NC_058071.1 8840802 8840823 NC_058071.1_Acropora_millepora_isolate_JS-1_chromosome_6_Amil_v2.1_whole_genome_shotgun_sequence_256047 39769.6 +   8840802 8840823 255,0,0
NC_058068.1 598173  598195  NC_058068.1_Acropora_millepora_isolate_JS-1_chromosome_3_Amil_v2.1_whole_genome_shotgun_sequence_123929 38710.3 +   598173  598195  255,0,0

NC_058066.1 ShortStack  mature_miRNA    12757147    12757168    1413    -   .   ID=Cluster_316.mature;Parent=Cluster_316
NC_058066.1 ShortStack  mature_miRNA    20088679    20088700    102 +   .   ID=Cluster_514.mature;Parent=Cluster_514
NC_058066.1 ShortStack  mature_miRNA    20346249    20346271    27205   -   .   ID=Cluster_548.mature;Parent=Cluster_548
NC_058067.1 ShortStack  mature_miRNA    5656214 5656236 1338    -   .   ID=Cluster_1506.mature;Parent=Cluster_1506
NC_058067.1 ShortStack  mature_miRNA    16118270    16118291    7486    -   .   ID=Cluster_1900.mature;Parent=Cluster_1900

Looks good! Now we can input into intersectBed.

# intersectBed to ID sequences in the miRdeep2 mature miRNA output that match mature miRNAs ID'd by ShortStack
# -wa and -wb ensure we recieve full annotations from both input files in the output
/home/shared/bedtools2/bin/intersectBed \
-wa \
-wb \
-a ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results_mature.gff3 \
-b ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/mirna_results_03_04_2024_t_13_00_39/novel_mature_03_04_2024_t_13_00_39_score-50_to_na_formatted.bed \
&> ../output/17-Apul-ShortStack-miRdeep2-comparison/ShortStack_miRdeep2_mature_intersect.bed

0.2 Results

echo "Number of ShortStack mature miRNAs:"
wc -l < ../output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out/Results_mature.gff3
echo ""
echo "Number of ShortStack mature miRNAs also identified by miRdeep2:"
wc -l < ../output/17-Apul-ShortStack-miRdeep2-comparison/ShortStack_miRdeep2_mature_intersect.bed
Number of ShortStack mature miRNAs:
38

Number of ShortStack mature miRNAs also identified by miRdeep2:
35

While looking through the output file I noticed that two of the intersects originate from the same cluster… not really sure what that’s about…

head -21 ../output/17-Apul-ShortStack-miRdeep2-comparison/ShortStack_miRdeep2_mature_intersect.bed | tail -2
NC_058072.1 ShortStack  mature_miRNA    19030618    19030639    21560   +   .   ID=Cluster_6376.mature;Parent=Cluster_6376  NC_058072.1 19030617    19030639    NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614 12623.6 +   19030617    19030639    255,0,0
NC_058072.1 ShortStack  mature_miRNA    19030618    19030639    21560   +   .   ID=Cluster_6376.mature;Parent=Cluster_6376  NC_058072.1 19030617    19030639    NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613 1.1 +   19030617    19030639    255,0,0

It looks like they have pretty much identical entries (cluster, coordinates, etc.), except the end of the miRdeep locus name (NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614 vs NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613) and the miRdeep2 “score” value assigned to them (this is the column following the miRdeep2 locus name, 12623.6 vs 1.1). We can also check these two loci in the full miRdeep2 output.


# View full mirdeep2 output for these two loci
awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv
echo""
awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv

echo""
echo""

echo "mature miRNA sequences for these two loci:"
awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv | awk '{print $13}'

awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv | awk '{print $13}'

echo ""
echo ""

echo "precursor miRNA sequences for these two loci:"
awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv | awk '{print $15}'

awk -F'\t' '$1 == "NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613"' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv | awk '{print $15}'
NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295614 12623.6     -   24755   24435   0   320 no  -   tca-miR-11646-3p_MIMAT0045620_Tribolium_castaneum_miR-11646-3p  -   -   ugggugucaucuauuauguuuu  aacauaaaagauggcacc  ugggugucaucuauuauguuuuugcuuguuaaaacauaaaagauggcacc  NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence:19030617..19030667:+

NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence_295613 1.1     -   24449   24435   14  0   no  -   tca-miR-11646-3p_MIMAT0045620_Tribolium_castaneum_miR-11646-3p  -   -   ugggugucaucuauuauguuuu  aauguaacaaaauugacggccaga    aauguaacaaaauugacggccagaagccguacguauguagaaaauguggggugagugccugggugucaucuauuauguuuu   NC_058072.1_Acropora_millepora_isolate_JS-1_chromosome_7_Amil_v2.1_whole_genome_shotgun_sequence:19030558..19030639:+


mature miRNA sequences for these two loci:
ugggugucaucuauuauguuuu
ugggugucaucuauuauguuuu


precursor miRNA sequences for these two loci:
ugggugucaucuauuauguuuuugcuuguuaaaacauaaaagauggcacc
aauguaacaaaauugacggccagaagccguacguauguagaaaauguggggugagugccugggugucaucuauuauguuuu

Interesting… The two loci have identical mature miRNAs, but different precursors!

Let’s set that aside for now and do some quick investigation of the miRdeep2 evaluation criteria for all of these ShortStack/miRdeep2 shared miRNAs. This could give us an idea of what thresholds may be appropriate for filtering the miRdeep2 output.

mirdeepIDs=$(awk '{print $13}' ../output/17-Apul-ShortStack-miRdeep2-comparison/ShortStack_miRdeep2_mature_intersect.bed)

head -1 ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv > ../output/17-Apul-ShortStack-miRdeep2-comparison/intersect_miRdeep2_stats.txt
while IFS= read -r id; do
  # Use awk to process fileA and match column 1 with the current ID
  awk -F'\t' -v id="$id" '$1 == id {print}' ../output/11.1-Apul-sRNAseq-miRdeep2-31bp-fastp-merged/parsable-result_03_04_2024_t_13_00_39.csv
done <<< "$mirdeepIDs" >> ../output/17-Apul-ShortStack-miRdeep2-comparison/intersect_miRdeep2_stats.txt
intersect_miRdeep2_stats <- read.csv("../output/17-Apul-ShortStack-miRdeep2-comparison/intersect_miRdeep2_stats.txt", sep="\t")

intersect_miRdeep2_stats %>% 
  select(miRDeep2.score, significant.randfold.p.value) %>% 
  arrange(desc(miRDeep2.score)) %>%
  kable()
miRDeep2.score significant.randfold.p.value
127017.5 no
40616.1 no
40339.4 no
39769.6 no
38710.3 no
14705.5 no
12860.5 no
12623.6 no
7816.8 no
6367.0 no
5869.1 no
5325.7 no
4346.5 no
4203.4 no
2769.9 no
2323.0 no
1422.1 no
957.0 no
928.6 no
637.6 no
494.9 no
296.0 no
214.5 no
202.9 no
178.3 no
171.5 no
117.8 no
97.5 no
97.3 no
78.4 no
23.2 no
23.1 no
3.7 no
3.4 no
1.1 no

The miRdeep2 score is “the log-odds score assigned to the hairpin” and is essentially a probability that the locus is a miRNA (presumably based on the hairpin structure) on, with higher values indicating higher probability. MiRdeep2’s default score threshold for miRNA classification is 0, but coral miRNA papers we’ve seen use myriad thresholds (e.g., 4, 10).

The randfold is also an evaluation of ncrna secondary structure, and we want a significant randfold value (this would indicate high likelihood of miRNA precursory structure)

For some reason there are no miRdeep2 miRNAs with significant randfold p-values for A. pulchra, even though the other species have a bunch of loci with significant p-values. The miRdeep2 score is interesting though! All but 3 of the shared miRNAs have scores >10 – maybe that could be a good cutoff?

LS0tCnRpdGxlOiAiMTctQXB1bC1TaG9ydFN0YWNrLW1pUmRlZXAyLWNvbXBhcmlzb24iCmF1dGhvcjogIkthdGhsZWVuIER1cmtpbiIKZGF0ZTogIjIwMjQtMDUtMTciCm91dHB1dDogCiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICBnaXRodWJfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZHBseXIpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgICAgICAgICAjIERpc3BsYXkgY29kZSBjaHVua3MKICBldmFsID0gRkFMU0UsICAgICAgICAjIEV2YWx1YXRlIGNvZGUgY2h1bmtzCiAgd2FybmluZyA9IEZBTFNFLCAgICAgIyBIaWRlIHdhcm5pbmdzCiAgbWVzc2FnZSA9IEZBTFNFLCAgICAgIyBIaWRlIG1lc3NhZ2VzCiAgY29tbWVudCA9ICIiICAgICAgICAgIyBQcmV2ZW50cyBhcHBlbmRpbmcgJyMjJyB0byBiZWdpbm5pbmcgb2YgbGluZXMgaW4gY29kZSBvdXRwdXQKKQpgYGAKCiMjIGludGVyc2VjdEJlZAoKRXhhbWluZSBvdXIgaW5wdXQgZmlsZXMgKGludGVyc2VjdEJlZCBhY2NlcHRzIC5iZWQgYW5kIC5nZmYgZmlsZXMpCgpgYGB7ciB2aWV3LU9HLWlucHV0LWZpbGVzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CmhlYWQgLTUgLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL21pcm5hX3Jlc3VsdHNfMDNfMDRfMjAyNF90XzEzXzAwXzM5L25vdmVsX21hdHVyZV8wM18wNF8yMDI0X3RfMTNfMDBfMzlfc2NvcmUtNTBfdG9fbmEuYmVkCmVjaG8gIiIKaGVhZCAtNSAuLi9vdXRwdXQvMTMuMi4xLUFwdWwtc1JOQXNlcS1TaG9ydFN0YWNrLTMxYnAtZmFzdHAtbWVyZ2VkLWNuaWRhcmlhbl9taVJCYXNlL1Nob3J0U3RhY2tfb3V0L1Jlc3VsdHMuZ2ZmMwpgYGAKCldlIG5lZWQgdG8gZ2V0IHR3byBpbnB1dCBmaWxlcyB0aGF0IGNvbnRhaW4gb25seSBtYXR1cmUgbWlSTkFzIGFuZCBoYXZlIHRoZSBzYW1lIHNlcXVlbmNlIG5hbWluZyBjb252ZW50aW9ucyBmb3IgbWF0Y2hpbmcgcHVycG9zZXMuIFRoYXQgbWVhbnMgdGhlIG1pUmRlZXAyIG1hdHVyZSBtaVJOQXMgZmlsZSBuZWVkIHRvIGJlIHJlZm9ybWF0dGVkLCBhbmQgdGhlIFNob3J0U3RhY2sgZnVsbCByZXN1bHRzIGZpbGUgbmVlZHMgdG8gYmUgZmlsdGVyZWQuCgpgYGB7ciBwcmVwLWlucHV0LWZpbGVzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgcmVtb3ZlIGhlYWRlciBsaW5lcywgc2hvcnRlbiBjaHJvbW9zb21lIHJlZiBuYW1lcyB0byBtYXRjaCB0aG9zZSB1c2VkIGluIFNob3J0U3RhY2sgb3V0cHV0LCBhbmQgZW5zdXJlIGZpbmFsIGZpbGUgaXMgdGFiLWRlbGltaXRlZCBpbnN0ZWFkIG9mIHNwYWNlLWRlbGltaXRlZAp0YWlsIC1uICs1IC4uL291dHB1dC8xMS4xLUFwdWwtc1JOQXNlcS1taVJkZWVwMi0zMWJwLWZhc3RwLW1lcmdlZC9taXJuYV9yZXN1bHRzXzAzXzA0XzIwMjRfdF8xM18wMF8zOS9ub3ZlbF9tYXR1cmVfMDNfMDRfMjAyNF90XzEzXzAwXzM5X3Njb3JlLTUwX3RvX25hLmJlZCB8IFwKYXdrICdCRUdJTiB7IEZTID0gIlx0IiB9IHsgc3ViKC9cLjEuKi8sICIuMSIsICQxKTsgcHJpbnQgfScgfCBcCnRyICcgJyAnXHQnID4gLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL21pcm5hX3Jlc3VsdHNfMDNfMDRfMjAyNF90XzEzXzAwXzM5L25vdmVsX21hdHVyZV8wM18wNF8yMDI0X3RfMTNfMDBfMzlfc2NvcmUtNTBfdG9fbmFfZm9ybWF0dGVkLmJlZAoKIyBmaWx0ZXIgZnVsbCByZXN1bHRzIHRvIG9idGFpbiBhIGdmZiBmaWxlIG9mIG9ubHkgdGhlIG1hdHVyZSBtaVJOQXMKYXdrIC1GJ1x0JyAnJDMgPT0gIm1hdHVyZV9taVJOQSInIC4uL291dHB1dC8xMy4yLjEtQXB1bC1zUk5Bc2VxLVNob3J0U3RhY2stMzFicC1mYXN0cC1tZXJnZWQtY25pZGFyaWFuX21pUkJhc2UvU2hvcnRTdGFja19vdXQvUmVzdWx0cy5nZmYzID4gLi4vb3V0cHV0LzEzLjIuMS1BcHVsLXNSTkFzZXEtU2hvcnRTdGFjay0zMWJwLWZhc3RwLW1lcmdlZC1jbmlkYXJpYW5fbWlSQmFzZS9TaG9ydFN0YWNrX291dC9SZXN1bHRzX21hdHVyZS5nZmYzCmBgYAoKQ2hlY2sgdGhlIGZpbGVzCgpgYGB7ciB2aWV3LXByZXBwZWQtaW5wdXQtZmlsZXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KaGVhZCAtNSAuLi9vdXRwdXQvMTEuMS1BcHVsLXNSTkFzZXEtbWlSZGVlcDItMzFicC1mYXN0cC1tZXJnZWQvbWlybmFfcmVzdWx0c18wM18wNF8yMDI0X3RfMTNfMDBfMzkvbm92ZWxfbWF0dXJlXzAzXzA0XzIwMjRfdF8xM18wMF8zOV9zY29yZS01MF90b19uYV9mb3JtYXR0ZWQuYmVkCmVjaG8gIiIKaGVhZCAtNSAuLi9vdXRwdXQvMTMuMi4xLUFwdWwtc1JOQXNlcS1TaG9ydFN0YWNrLTMxYnAtZmFzdHAtbWVyZ2VkLWNuaWRhcmlhbl9taVJCYXNlL1Nob3J0U3RhY2tfb3V0L1Jlc3VsdHNfbWF0dXJlLmdmZjMKYGBgCgpMb29rcyBnb29kISBOb3cgd2UgY2FuIGlucHV0IGludG8gaW50ZXJzZWN0QmVkLgoKYGBge3IgaW50ZXJzZWN0QmVkLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgaW50ZXJzZWN0QmVkIHRvIElEIHNlcXVlbmNlcyBpbiB0aGUgbWlSZGVlcDIgbWF0dXJlIG1pUk5BIG91dHB1dCB0aGF0IG1hdGNoIG1hdHVyZSBtaVJOQXMgSUQnZCBieSBTaG9ydFN0YWNrCiMgLXdhIGFuZCAtd2IgZW5zdXJlIHdlIHJlY2lldmUgZnVsbCBhbm5vdGF0aW9ucyBmcm9tIGJvdGggaW5wdXQgZmlsZXMgaW4gdGhlIG91dHB1dAovaG9tZS9zaGFyZWQvYmVkdG9vbHMyL2Jpbi9pbnRlcnNlY3RCZWQgXAotd2EgXAotd2IgXAotYSAuLi9vdXRwdXQvMTMuMi4xLUFwdWwtc1JOQXNlcS1TaG9ydFN0YWNrLTMxYnAtZmFzdHAtbWVyZ2VkLWNuaWRhcmlhbl9taVJCYXNlL1Nob3J0U3RhY2tfb3V0L1Jlc3VsdHNfbWF0dXJlLmdmZjMgXAotYiAuLi9vdXRwdXQvMTEuMS1BcHVsLXNSTkFzZXEtbWlSZGVlcDItMzFicC1mYXN0cC1tZXJnZWQvbWlybmFfcmVzdWx0c18wM18wNF8yMDI0X3RfMTNfMDBfMzkvbm92ZWxfbWF0dXJlXzAzXzA0XzIwMjRfdF8xM18wMF8zOV9zY29yZS01MF90b19uYV9mb3JtYXR0ZWQuYmVkIFwKJj4gLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL1Nob3J0U3RhY2tfbWlSZGVlcDJfbWF0dXJlX2ludGVyc2VjdC5iZWQKCmBgYAoKIyMgUmVzdWx0cwoKYGBge3IgY291bnQtaW50ZXJzZWN0cywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQplY2hvICJOdW1iZXIgb2YgU2hvcnRTdGFjayBtYXR1cmUgbWlSTkFzOiIKd2MgLWwgPCAuLi9vdXRwdXQvMTMuMi4xLUFwdWwtc1JOQXNlcS1TaG9ydFN0YWNrLTMxYnAtZmFzdHAtbWVyZ2VkLWNuaWRhcmlhbl9taVJCYXNlL1Nob3J0U3RhY2tfb3V0L1Jlc3VsdHNfbWF0dXJlLmdmZjMKZWNobyAiIgplY2hvICJOdW1iZXIgb2YgU2hvcnRTdGFjayBtYXR1cmUgbWlSTkFzIGFsc28gaWRlbnRpZmllZCBieSBtaVJkZWVwMjoiCndjIC1sIDwgLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL1Nob3J0U3RhY2tfbWlSZGVlcDJfbWF0dXJlX2ludGVyc2VjdC5iZWQKYGBgCgpXaGlsZSBsb29raW5nIHRocm91Z2ggdGhlIG91dHB1dCBmaWxlIEkgbm90aWNlZCB0aGF0IHR3byBvZiB0aGUgaW50ZXJzZWN0cyBvcmlnaW5hdGUgZnJvbSB0aGUgc2FtZSBjbHVzdGVyLi4uIG5vdCByZWFsbHkgc3VyZSB3aGF0IHRoYXQncyBhYm91dC4uLgoKYGBge3IsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KaGVhZCAtMjEgLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL1Nob3J0U3RhY2tfbWlSZGVlcDJfbWF0dXJlX2ludGVyc2VjdC5iZWQgfCB0YWlsIC0yCmBgYAoKSXQgbG9va3MgbGlrZSB0aGV5IGhhdmUgcHJldHR5IG11Y2ggaWRlbnRpY2FsIGVudHJpZXMgKGNsdXN0ZXIsIGNvb3JkaW5hdGVzLCBldGMuKSwgZXhjZXB0IHRoZSBlbmQgb2YgdGhlIG1pUmRlZXAgbG9jdXMgbmFtZSAoTkNfMDU4MDcyLjFfQWNyb3BvcmFfbWlsbGVwb3JhX2lzb2xhdGVfSlMtMV9jaHJvbW9zb21lXzdcX0FtaWxfdjIuMV93aG9sZV9nZW5vbWVfc2hvdGd1bl9zZXF1ZW5jZVxfKioqMjk1NjE0KioqIHZzIE5DXzA1ODA3Mi4xX0Fjcm9wb3JhX21pbGxlcG9yYV9pc29sYXRlX0pTLTFfY2hyb21vc29tZV83XF9BbWlsX3YyLjFfd2hvbGVfZ2Vub21lX3Nob3RndW5fc2VxdWVuY2VcXyoqKjI5NTYxMyoqKikgYW5kIHRoZSBtaVJkZWVwMiAic2NvcmUiIHZhbHVlIGFzc2lnbmVkIHRvIHRoZW0gKHRoaXMgaXMgdGhlIGNvbHVtbiBmb2xsb3dpbmcgdGhlIG1pUmRlZXAyIGxvY3VzIG5hbWUsIDEyNjIzLjYgdnMgMS4xKS4gV2UgY2FuIGFsc28gY2hlY2sgdGhlc2UgdHdvIGxvY2kgaW4gdGhlIGZ1bGwgbWlSZGVlcDIgb3V0cHV0LgpgYGB7ciBjaGVjay1taXJkZWVwLW91dHB1dC1kdXBlcywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQoKIyBWaWV3IGZ1bGwgbWlyZGVlcDIgb3V0cHV0IGZvciB0aGVzZSB0d28gbG9jaQphd2sgLUYnXHQnICckMSA9PSAiTkNfMDU4MDcyLjFfQWNyb3BvcmFfbWlsbGVwb3JhX2lzb2xhdGVfSlMtMV9jaHJvbW9zb21lXzdfQW1pbF92Mi4xX3dob2xlX2dlbm9tZV9zaG90Z3VuX3NlcXVlbmNlXzI5NTYxNCInIC4uL291dHB1dC8xMS4xLUFwdWwtc1JOQXNlcS1taVJkZWVwMi0zMWJwLWZhc3RwLW1lcmdlZC9wYXJzYWJsZS1yZXN1bHRfMDNfMDRfMjAyNF90XzEzXzAwXzM5LmNzdgplY2hvIiIKYXdrIC1GJ1x0JyAnJDEgPT0gIk5DXzA1ODA3Mi4xX0Fjcm9wb3JhX21pbGxlcG9yYV9pc29sYXRlX0pTLTFfY2hyb21vc29tZV83X0FtaWxfdjIuMV93aG9sZV9nZW5vbWVfc2hvdGd1bl9zZXF1ZW5jZV8yOTU2MTMiJyAuLi9vdXRwdXQvMTEuMS1BcHVsLXNSTkFzZXEtbWlSZGVlcDItMzFicC1mYXN0cC1tZXJnZWQvcGFyc2FibGUtcmVzdWx0XzAzXzA0XzIwMjRfdF8xM18wMF8zOS5jc3YKCmVjaG8iIgplY2hvIiIKCmVjaG8gIm1hdHVyZSBtaVJOQSBzZXF1ZW5jZXMgZm9yIHRoZXNlIHR3byBsb2NpOiIKYXdrIC1GJ1x0JyAnJDEgPT0gIk5DXzA1ODA3Mi4xX0Fjcm9wb3JhX21pbGxlcG9yYV9pc29sYXRlX0pTLTFfY2hyb21vc29tZV83X0FtaWxfdjIuMV93aG9sZV9nZW5vbWVfc2hvdGd1bl9zZXF1ZW5jZV8yOTU2MTQiJyAuLi9vdXRwdXQvMTEuMS1BcHVsLXNSTkFzZXEtbWlSZGVlcDItMzFicC1mYXN0cC1tZXJnZWQvcGFyc2FibGUtcmVzdWx0XzAzXzA0XzIwMjRfdF8xM18wMF8zOS5jc3YgfCBhd2sgJ3twcmludCAkMTN9JwoKYXdrIC1GJ1x0JyAnJDEgPT0gIk5DXzA1ODA3Mi4xX0Fjcm9wb3JhX21pbGxlcG9yYV9pc29sYXRlX0pTLTFfY2hyb21vc29tZV83X0FtaWxfdjIuMV93aG9sZV9nZW5vbWVfc2hvdGd1bl9zZXF1ZW5jZV8yOTU2MTMiJyAuLi9vdXRwdXQvMTEuMS1BcHVsLXNSTkFzZXEtbWlSZGVlcDItMzFicC1mYXN0cC1tZXJnZWQvcGFyc2FibGUtcmVzdWx0XzAzXzA0XzIwMjRfdF8xM18wMF8zOS5jc3YgfCBhd2sgJ3twcmludCAkMTN9JwoKZWNobyAiIgplY2hvICIiCgplY2hvICJwcmVjdXJzb3IgbWlSTkEgc2VxdWVuY2VzIGZvciB0aGVzZSB0d28gbG9jaToiCmF3ayAtRidcdCcgJyQxID09ICJOQ18wNTgwNzIuMV9BY3JvcG9yYV9taWxsZXBvcmFfaXNvbGF0ZV9KUy0xX2Nocm9tb3NvbWVfN19BbWlsX3YyLjFfd2hvbGVfZ2Vub21lX3Nob3RndW5fc2VxdWVuY2VfMjk1NjE0IicgLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL3BhcnNhYmxlLXJlc3VsdF8wM18wNF8yMDI0X3RfMTNfMDBfMzkuY3N2IHwgYXdrICd7cHJpbnQgJDE1fScKCmF3ayAtRidcdCcgJyQxID09ICJOQ18wNTgwNzIuMV9BY3JvcG9yYV9taWxsZXBvcmFfaXNvbGF0ZV9KUy0xX2Nocm9tb3NvbWVfN19BbWlsX3YyLjFfd2hvbGVfZ2Vub21lX3Nob3RndW5fc2VxdWVuY2VfMjk1NjEzIicgLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL3BhcnNhYmxlLXJlc3VsdF8wM18wNF8yMDI0X3RfMTNfMDBfMzkuY3N2IHwgYXdrICd7cHJpbnQgJDE1fScKYGBgCkludGVyZXN0aW5nLi4uIFRoZSB0d28gbG9jaSBoYXZlIGlkZW50aWNhbCBtYXR1cmUgbWlSTkFzLCBidXQgZGlmZmVyZW50IHByZWN1cnNvcnMhCgoKTGV0J3Mgc2V0IHRoYXQgYXNpZGUgZm9yIG5vdyBhbmQgZG8gc29tZSBxdWljayBpbnZlc3RpZ2F0aW9uIG9mIHRoZSBtaVJkZWVwMiBldmFsdWF0aW9uIGNyaXRlcmlhIGZvciBhbGwgb2YgdGhlc2UgU2hvcnRTdGFjay9taVJkZWVwMiBzaGFyZWQgbWlSTkFzLiBUaGlzIGNvdWxkIGdpdmUgdXMgYW4gaWRlYSBvZiB3aGF0IHRocmVzaG9sZHMgbWF5IGJlIGFwcHJvcHJpYXRlIGZvciBmaWx0ZXJpbmcgdGhlIG1pUmRlZXAyIG91dHB1dC4gCmBgYHtyIGNoZWNrLW1pcmRlZXAyLW91dHB1dC1hbGwtc2hhcmVkLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9Cm1pcmRlZXBJRHM9JChhd2sgJ3twcmludCAkMTN9JyAuLi9vdXRwdXQvMTctQXB1bC1TaG9ydFN0YWNrLW1pUmRlZXAyLWNvbXBhcmlzb24vU2hvcnRTdGFja19taVJkZWVwMl9tYXR1cmVfaW50ZXJzZWN0LmJlZCkKCmhlYWQgLTEgLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL3BhcnNhYmxlLXJlc3VsdF8wM18wNF8yMDI0X3RfMTNfMDBfMzkuY3N2ID4gLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL2ludGVyc2VjdF9taVJkZWVwMl9zdGF0cy50eHQKd2hpbGUgSUZTPSByZWFkIC1yIGlkOyBkbwogICMgVXNlIGF3ayB0byBwcm9jZXNzIGZpbGVBIGFuZCBtYXRjaCBjb2x1bW4gMSB3aXRoIHRoZSBjdXJyZW50IElECiAgYXdrIC1GJ1x0JyAtdiBpZD0iJGlkIiAnJDEgPT0gaWQge3ByaW50fScgLi4vb3V0cHV0LzExLjEtQXB1bC1zUk5Bc2VxLW1pUmRlZXAyLTMxYnAtZmFzdHAtbWVyZ2VkL3BhcnNhYmxlLXJlc3VsdF8wM18wNF8yMDI0X3RfMTNfMDBfMzkuY3N2CmRvbmUgPDw8ICIkbWlyZGVlcElEcyIgPj4gLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL2ludGVyc2VjdF9taVJkZWVwMl9zdGF0cy50eHQKYGBgCgpgYGB7ciB2aWV3LWNyaXRlcmlhLCBldmFsPVRSVUV9CmludGVyc2VjdF9taVJkZWVwMl9zdGF0cyA8LSByZWFkLmNzdigiLi4vb3V0cHV0LzE3LUFwdWwtU2hvcnRTdGFjay1taVJkZWVwMi1jb21wYXJpc29uL2ludGVyc2VjdF9taVJkZWVwMl9zdGF0cy50eHQiLCBzZXA9Ilx0IikKCmludGVyc2VjdF9taVJkZWVwMl9zdGF0cyAlPiUgCiAgc2VsZWN0KG1pUkRlZXAyLnNjb3JlLCBzaWduaWZpY2FudC5yYW5kZm9sZC5wLnZhbHVlKSAlPiUgCiAgYXJyYW5nZShkZXNjKG1pUkRlZXAyLnNjb3JlKSkgJT4lCiAga2FibGUoKQpgYGAKClRoZSBtaVJkZWVwMiBzY29yZSBpcyAidGhlIGxvZy1vZGRzIHNjb3JlIGFzc2lnbmVkIHRvIHRoZSBoYWlycGluIiBhbmQgaXMgZXNzZW50aWFsbHkgYSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBsb2N1cyBpcyBhIG1pUk5BIChwcmVzdW1hYmx5IGJhc2VkIG9uIHRoZSBoYWlycGluIHN0cnVjdHVyZSkgb24sIHdpdGggaGlnaGVyIHZhbHVlcyBpbmRpY2F0aW5nIGhpZ2hlciBwcm9iYWJpbGl0eS4gTWlSZGVlcDIncyBkZWZhdWx0IHNjb3JlIHRocmVzaG9sZCBmb3IgbWlSTkEgY2xhc3NpZmljYXRpb24gaXMgMCwgYnV0IGNvcmFsIG1pUk5BIHBhcGVycyB3ZSd2ZSBzZWVuIHVzZSBteXJpYWQgdGhyZXNob2xkcyAoZS5nLiwgNCwgMTApLgoKVGhlIHJhbmRmb2xkIGlzIGFsc28gYW4gZXZhbHVhdGlvbiBvZiBuY3JuYSBzZWNvbmRhcnkgc3RydWN0dXJlLCBhbmQgd2Ugd2FudCBhIHNpZ25pZmljYW50IHJhbmRmb2xkIHZhbHVlICh0aGlzIHdvdWxkIGluZGljYXRlIGhpZ2ggbGlrZWxpaG9vZCBvZiBtaVJOQSBwcmVjdXJzb3J5IHN0cnVjdHVyZSkKCkZvciBzb21lIHJlYXNvbiB0aGVyZSBhcmUgbm8gbWlSZGVlcDIgbWlSTkFzIHdpdGggc2lnbmlmaWNhbnQgcmFuZGZvbGQgcC12YWx1ZXMgZm9yIEEuIHB1bGNocmEsIGV2ZW4gdGhvdWdoIHRoZSBvdGhlciBzcGVjaWVzIGhhdmUgYSBidW5jaCBvZiBsb2NpIHdpdGggc2lnbmlmaWNhbnQgcC12YWx1ZXMuIFRoZSBtaVJkZWVwMiBzY29yZSBpcyBpbnRlcmVzdGluZyB0aG91Z2ghIEFsbCBidXQgMyBvZiB0aGUgc2hhcmVkIG1pUk5BcyBoYXZlIHNjb3JlcyA+MTAgLS0gbWF5YmUgdGhhdCBjb3VsZCBiZSBhIGdvb2QgY3V0b2ZmPwo=