Intro
This Workflow
This workflow takes an excerpt from the
microbiome_new_data
script with instructions for
constructing a representative phylogenetic tree from your 16S sequencing
results and expands on that to increase the flexibility of your
phylogenetic tree data for downstream processing.
Phylo Trees and ONT Data
Some of the standard microbiome profiling metrics rely on on an OTU
approach developed for the more traditional short-read sequences
produced by Illumina and other nextgen platforms. Constructing
representative sequences for each OTU enables phylogenetic analyses that
can be particularly useful in visualizations.
ONT Reads are generally still too messy and long to smoothly produce
consensus sequences for each taxon. I use a workaround to enable us to
still generate some phylogenetic estimates and graphics, though we will
really be visualizing the relationships between the reference sequences
for each taxon that our reads align to. The first step of this will use
Entrez Direct to source a reference fasta for each of the taxids from
our minimap2 results.
The Data Used Here
I am writing this script with a version of our lab’s pygmy loris
microbiome data. If you are working on one of our other microbiome
projects, it should be fairly simple to adapt the original .Rmd script
you are reading to a different dataset, especially if you make use of
the params settings in the yaml header at the top.
The Workflow
Fetch Reference FASTA Sequences
Taxonomy List
First, we will read in our raw alignment data gathered from the
wf-16s output.
alignments <- read_tsv("microeco/loris/alignments.tsv")
refseqs <- distinct(alignments, ref, taxid)
write_tsv(refseqs, "microeco/loris/fetch_references.txt")
Transfer the fetch_references.txt file from your local directory to
the proper directory on Swan and then run the script below.
Tip
I create a mirror of my repository/directory on Swan so that I can just
keep updating repositories as I move between swan and my local R consol.
Fetch New References Using Entrez Direct
Now you need to switch to the terminal and log into the HCC. We will
use the entrez-direct package to interface with NCBI’s databases adn
fetch our reference sequences. If you have not used the HCC before, then
refer to the readprocessing_multiplex_16s
script for more details.
Note: I recently discovered the R package taxreturn
which looks like an appealing alternative to do this straight from the R
console, so feel free to experiment with it if you are feeling
adventurous.
Batch Script
#!/bin/bash
#SBATCH --time=1:00:00
#SBATCH --job-name=fetch_refs
#SBATCH --error=/work/richlab/aliciarich/bioinformatics_stats/logs/fetch_refs_%A_%a.err
#SBATCH --output=/work/richlab/aliciarich/bioinformatics_stats/logs/fetch_refs_%A_%a.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --mem=100GB
#SBATCH --partition=guest
module purge
module load entrez-direct
module load seqkit
uid_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/fetch_references.txt"
accessions_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/accessions.txt"
fasta_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_unaligned.fasta"
> "$fasta_file"
cut -f1 "$uid_file" > "$accessions_file"
if efetch -db nuccore -input "$accessions_file" -format fasta -email "aliciarich@unomaha.edu" > "$fasta_file"; then
echo "Sequences fetched successfully."
else
echo "Error fetching sequences." >&2
exit 1
fi
Submit Batch Script
cd "/work/richlab/aliciarich/bioinformatics_stats/batch_scripts"
sbatch "fetch_refs.sh"
Once the script finishes running, transfer the
refs_unaligned.fasta
file from the directory on Swan to the
local matching directory to run the next step in R.
Relabel Sequences
refs_unaligned <- treeio::read.fasta("microeco/loris/refs_unaligned.fasta")
refs_labels <- enframe(labels(refs_unaligned), name = NULL, value = "label") %>%
mutate(accession = str_extract(label, "^\\w{2}_\\d+\\.\\d(?=\\s.+)")) %>%
left_join(select(alignments, superkingdom:taxid), by = join_by(accession == ref)) %>%
mutate(taxid = as.character(str_glue("txid{taxid}"))) %>%
arrange(superkingdom,
phylum,
class,
order,
family,
genus,
species,
accession) %>%
select(
superkingdom:species,
taxid,
accession,
label
)
write_tsv(refs_labels, "microeco/loris/reference_key.tsv")
refs_rename <- refs_labels %>%
select(label, taxid)
rename.fasta("microeco/loris/refs_unaligned.fasta", refs_rename, "microeco/loris/refs_renamed.fasta")
microeco/loris/refs_renamed.fasta has been saved to /Users/aliciamrich/GitRepos/richlab_main/bioinformatics_stats
Align Sequences and Build ML Tree
Batch Script
#!/bin/bash
#SBATCH --job-name=mafft_iqtree
#SBATCH --error=/work/richlab/aliciarich/bioinformatics_stats/logs/mafft_iqtree_%A.err
#SBATCH --output=/work/richlab/aliciarich/bioinformatics_stats/logs/mafft_iqtree_%A.out
#SBATCH --partition=guest
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=64G
#SBATCH --time=6:00:00
module purge
module load mafft/7.526
module load iqtree/2.3
input_fasta="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_renamed.fasta"
aligned_fasta="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_aligned_mafft.fasta"
out_prefix="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_tree"
mafft \
--thread 8 \
--retree 2 \
--maxiterate 1000 \
"$input_fasta" > "$aligned_fasta"
iqtree -s $aligned_fasta \
-m MFP+MERGE \
-B 1000 \
-T $SLURM_CPUS_PER_TASK \
-pre "$out_prefix" \
-redo
Submit Batch Script
cd "/work/richlab/aliciarich/bioinformatics_stats/batch_scripts"
sbatch "mafft_iqtree.sh"
Once the script finishes running, transfer the
refs_aligned_mafft.fasta
and
refs_tree.treefile
files from the directory on Swan to the
local matching directory to run the next step in R.
Note the Final Model Used
I also like to extract the bottom of the log file produced to keep
this note on the alignment model that the MAFFT algorithm selected. It
just makes it easier for copying and pasting into manuscripts later.
alg=A, model=DNA200 (2), 1.53 (4.59), -0.00 (-0.00), noshift, amax=0.0
8 thread(s)
Strategy:
FFT-NS-i (Accurate but slow)
Iterative refinement method (max. 16 iterations)
LS0tCnRpdGxlOiAiV29ya2luZyB3aXRoIDE2UyBEYXRhIGFuZCBSZWZlcmVuY2UgU2VxdWVuY2VzIgphdXRob3I6ICJBbGljaWEgTS4gUmljaCwgUGguRC4iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZToKICAgICAgYnNsaWI6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICBkZl9wcmludDogcGFnZWQKICAgIGNzczogam91cm5hbC5jc3MKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShjb25mbGljdGVkKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShic2xpYikKbGlicmFyeShodG1sdG9vbHMpCmxpYnJhcnkobWljcm9lY28pCmxpYnJhcnkoc2VxaW5yKQpsaWJyYXJ5KGFwZSkKbGlicmFyeShndEV4dHJhcykKbGlicmFyeShnZ3RyZWUpCmxpYnJhcnkodHJlZWRhdGF2ZXJzZSkKbGlicmFyeShwaHlsb3Rvb2xzKQpsaWJyYXJ5KFRyZWVUb29scykKCgpzb3VyY2UoInNldHVwL2tuaXRfZW5naW5lc19zaW1wbGUuUiIpCnNvdXJjZSgic2V0dXAvY29uZmxpY3RlZC5SIikKCmBgYAoKIyBJbnRybwoKIyMgVGhpcyBXb3JrZmxvdwoKVGhpcyB3b3JrZmxvdyB0YWtlcyBhbiBleGNlcnB0IGZyb20gdGhlIGBtaWNyb2Jpb21lX25ld19kYXRhYCBzY3JpcHQgd2l0aCBpbnN0cnVjdGlvbnMgZm9yIGNvbnN0cnVjdGluZyBhIHJlcHJlc2VudGF0aXZlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20geW91ciAxNlMgc2VxdWVuY2luZyByZXN1bHRzIGFuZCBleHBhbmRzIG9uIHRoYXQgdG8gaW5jcmVhc2UgdGhlIGZsZXhpYmlsaXR5IG9mIHlvdXIgcGh5bG9nZW5ldGljIHRyZWUgZGF0YSBmb3IgZG93bnN0cmVhbSBwcm9jZXNzaW5nLiAKCiMjIFBoeWxvIFRyZWVzIGFuZCBPTlQgRGF0YQoKU29tZSBvZiB0aGUgc3RhbmRhcmQgbWljcm9iaW9tZSBwcm9maWxpbmcgbWV0cmljcyByZWx5IG9uIG9uIGFuIE9UVSBhcHByb2FjaCBkZXZlbG9wZWQgZm9yIHRoZSBtb3JlIHRyYWRpdGlvbmFsIHNob3J0LXJlYWQgc2VxdWVuY2VzIHByb2R1Y2VkIGJ5IElsbHVtaW5hIGFuZCBvdGhlciBuZXh0Z2VuIHBsYXRmb3Jtcy4gQ29uc3RydWN0aW5nIHJlcHJlc2VudGF0aXZlIHNlcXVlbmNlcyBmb3IgZWFjaCBPVFUgZW5hYmxlcyBwaHlsb2dlbmV0aWMgYW5hbHlzZXMgdGhhdCBjYW4gYmUgcGFydGljdWxhcmx5IHVzZWZ1bCBpbiB2aXN1YWxpemF0aW9ucy4gIAogIApPTlQgUmVhZHMgYXJlIGdlbmVyYWxseSBzdGlsbCB0b28gbWVzc3kgYW5kIGxvbmcgdG8gc21vb3RobHkgcHJvZHVjZSBjb25zZW5zdXMgc2VxdWVuY2VzIGZvciBlYWNoIHRheG9uLiBJIHVzZSBhIHdvcmthcm91bmQgdG8gZW5hYmxlIHVzIHRvIHN0aWxsIGdlbmVyYXRlIHNvbWUgcGh5bG9nZW5ldGljIGVzdGltYXRlcyBhbmQgZ3JhcGhpY3MsIHRob3VnaCB3ZSB3aWxsIHJlYWxseSBiZSB2aXN1YWxpemluZyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSByZWZlcmVuY2Ugc2VxdWVuY2VzIGZvciBlYWNoIHRheG9uIHRoYXQgb3VyIHJlYWRzIGFsaWduIHRvLiBUaGUgZmlyc3Qgc3RlcCBvZiB0aGlzIHdpbGwgdXNlIEVudHJleiBEaXJlY3QgdG8gc291cmNlIGEgcmVmZXJlbmNlIGZhc3RhIGZvciBlYWNoIG9mIHRoZSB0YXhpZHMgZnJvbSBvdXIgbWluaW1hcDIgcmVzdWx0cy4gIAoKCiMjIFRoZSBEYXRhIFVzZWQgSGVyZQoKSSBhbSB3cml0aW5nIHRoaXMgc2NyaXB0IHdpdGggYSB2ZXJzaW9uIG9mIG91ciBsYWIncyBweWdteSBsb3JpcyBtaWNyb2Jpb21lIGRhdGEuIElmIHlvdSBhcmUgd29ya2luZyBvbiBvbmUgb2Ygb3VyIG90aGVyIG1pY3JvYmlvbWUgcHJvamVjdHMsIGl0IHNob3VsZCBiZSBmYWlybHkgc2ltcGxlIHRvIGFkYXB0IHRoZSBvcmlnaW5hbCAuUm1kIHNjcmlwdCB5b3UgYXJlIHJlYWRpbmcgdG8gYSBkaWZmZXJlbnQgZGF0YXNldCwgZXNwZWNpYWxseSBpZiB5b3UgbWFrZSB1c2Ugb2YgdGhlIHBhcmFtcyBzZXR0aW5ncyBpbiB0aGUgeWFtbCBoZWFkZXIgYXQgdGhlIHRvcC4KCiMjIFJlY29tbWVuZGVkIFJlYWRpbmcKCkZvciBhIGhlbHBmdWwgZ3VpZGUsIEkgcmVjb21tZW5kIHlvdSBsb29rIGF0IHRoaXMgb25saW5lIGJvb2s6IFtEYXRhIEludGVncmF0aW9uLCBNYW5pcHVsYXRpb24gYW5kIFZpc3VhbGl6YXRpb24gb2YgUGh5bG9nZW5ldGljIFRyZWVzXShodHRwczovL3l1bGFiLXNtdS50b3AvdHJlZWRhdGEtYm9vay9pbmRleC5odG1sKS4KCiMgVGhlIFdvcmtmbG93CgojIyBGZXRjaCBSZWZlcmVuY2UgRkFTVEEgU2VxdWVuY2VzCgojIyMgVGF4b25vbXkgTGlzdAoKRmlyc3QsIHdlIHdpbGwgcmVhZCBpbiBvdXIgcmF3IGFsaWdubWVudCBkYXRhIGdhdGhlcmVkIGZyb20gdGhlIHdmLTE2cyBvdXRwdXQuCgpgYGB7cn0KYWxpZ25tZW50cyA8LSByZWFkX3RzdigibWljcm9lY28vbG9yaXMvYWxpZ25tZW50cy50c3YiKQpyZWZzZXFzIDwtIGRpc3RpbmN0KGFsaWdubWVudHMsIHJlZiwgdGF4aWQpCndyaXRlX3RzdihyZWZzZXFzLCAibWljcm9lY28vbG9yaXMvZmV0Y2hfcmVmZXJlbmNlcy50eHQiKQpgYGAKCgpUcmFuc2ZlciB0aGUgZmV0Y2hfcmVmZXJlbmNlcy50eHQgZmlsZSBmcm9tIHlvdXIgbG9jYWwgZGlyZWN0b3J5IHRvIHRoZSBwcm9wZXIgZGlyZWN0b3J5IG9uIFN3YW4gYW5kIHRoZW4gcnVuIHRoZSBzY3JpcHQgYmVsb3cuICAKICAKPGRldGFpbHM+CjxzdW1tYXJ5PioqKlRpcCoqKjwvc3VtbWFyeT4KPHA+SSBjcmVhdGUgYSBtaXJyb3Igb2YgbXkgcmVwb3NpdG9yeS9kaXJlY3Rvcnkgb24gU3dhbiBzbyB0aGF0IEkgY2FuIGp1c3Qga2VlcCB1cGRhdGluZyByZXBvc2l0b3JpZXMgYXMgSSBtb3ZlIGJldHdlZW4gc3dhbiBhbmQgbXkgbG9jYWwgUiBjb25zb2wuPC9wPgo8L2RldGFpbHM+CgotLS0KCiMjIEZldGNoIE5ldyBSZWZlcmVuY2VzIFVzaW5nIEVudHJleiBEaXJlY3QKCk5vdyB5b3UgbmVlZCB0byBzd2l0Y2ggdG8gdGhlIHRlcm1pbmFsIGFuZCBsb2cgaW50byB0aGUgSENDLiBXZSB3aWxsIHVzZSB0aGUgZW50cmV6LWRpcmVjdCBwYWNrYWdlIHRvIGludGVyZmFjZSB3aXRoIE5DQkkncyBkYXRhYmFzZXMgYWRuIGZldGNoIG91ciByZWZlcmVuY2Ugc2VxdWVuY2VzLiBJZiB5b3UgaGF2ZSBub3QgdXNlZCB0aGUgSENDIGJlZm9yZSwgdGhlbiByZWZlciB0byB0aGUgW3JlYWRwcm9jZXNzaW5nX211bHRpcGxleF8xNnNdKGh0dHBzOi8vcmljaC1tb2xlY3VsYXItaGVhbHRoLWxhYi5naXRodWIuaW8vdHV0b3JpYWxzL3JlYWRwcm9jZXNzaW5nX211bHRpcGxleF8xNnMuaHRtbCkgc2NyaXB0IGZvciBtb3JlIGRldGFpbHMuCgo+Kk5vdGU6IEkgcmVjZW50bHkgZGlzY292ZXJlZCB0aGUgUiBwYWNrYWdlIFtgdGF4cmV0dXJuYF0oaHR0cHM6Ly9hbGV4cGlwZXIuZ2l0aHViLmlvL3RheHJldHVybi9pbmRleC5odG1sKSB3aGljaCBsb29rcyBsaWtlIGFuIGFwcGVhbGluZyBhbHRlcm5hdGl2ZSB0byBkbyB0aGlzIHN0cmFpZ2h0IGZyb20gdGhlIFIgY29uc29sZSwgc28gZmVlbCBmcmVlIHRvIGV4cGVyaW1lbnQgd2l0aCBpdCBpZiB5b3UgYXJlIGZlZWxpbmcgYWR2ZW50dXJvdXMuKgoKIyMjIEJhdGNoIFNjcmlwdAoKYGBge3Rlcm1pbmFsLCB3YXJuaW5nID0gRkFMU0UsIGVjaG8gPSBGQUxTRX0KIyEvYmluL2Jhc2gKI1NCQVRDSCAtLXRpbWU9MTowMDowMAojU0JBVENIIC0tam9iLW5hbWU9ZmV0Y2hfcmVmcwojU0JBVENIIC0tZXJyb3I9L3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL2xvZ3MvZmV0Y2hfcmVmc18lQV8lYS5lcnIKI1NCQVRDSCAtLW91dHB1dD0vd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvbG9ncy9mZXRjaF9yZWZzXyVBXyVhLm91dAojU0JBVENIIC0tbm9kZXM9MQojU0JBVENIIC0tbnRhc2tzLXBlci1ub2RlPTEKI1NCQVRDSCAtLW1lbT0xMDBHQgojU0JBVENIIC0tcGFydGl0aW9uPWd1ZXN0Cgptb2R1bGUgcHVyZ2UKbW9kdWxlIGxvYWQgZW50cmV6LWRpcmVjdAptb2R1bGUgbG9hZCBzZXFraXQgCgp1aWRfZmlsZT0iL3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL21pY3JvZWNvL2xvcmlzL2ZldGNoX3JlZmVyZW5jZXMudHh0IgphY2Nlc3Npb25zX2ZpbGU9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9hY2Nlc3Npb25zLnR4dCIKZmFzdGFfZmlsZT0iL3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL21pY3JvZWNvL2xvcmlzL3JlZnNfdW5hbGlnbmVkLmZhc3RhIgoKCj4gIiRmYXN0YV9maWxlIgoKY3V0IC1mMSAiJHVpZF9maWxlIiA+ICIkYWNjZXNzaW9uc19maWxlIgoKaWYgZWZldGNoIC1kYiBudWNjb3JlIC1pbnB1dCAiJGFjY2Vzc2lvbnNfZmlsZSIgLWZvcm1hdCBmYXN0YSAtZW1haWwgImFsaWNpYXJpY2hAdW5vbWFoYS5lZHUiID4gIiRmYXN0YV9maWxlIjsgdGhlbgogICAgZWNobyAiU2VxdWVuY2VzIGZldGNoZWQgc3VjY2Vzc2Z1bGx5LiIKZWxzZQogICAgZWNobyAiRXJyb3IgZmV0Y2hpbmcgc2VxdWVuY2VzLiIgPiYyCiAgICBleGl0IDEKZmkKCmBgYAoKIyMjIFN1Ym1pdCBCYXRjaCBTY3JpcHQKCmBgYHt0ZXJtaW5hbCwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CmNkICIvd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvYmF0Y2hfc2NyaXB0cyIKc2JhdGNoICJmZXRjaF9yZWZzLnNoIgpgYGAKCk9uY2UgdGhlIHNjcmlwdCBmaW5pc2hlcyBydW5uaW5nLCB0cmFuc2ZlciB0aGUgYHJlZnNfdW5hbGlnbmVkLmZhc3RhYCBmaWxlIGZyb20gdGhlIGRpcmVjdG9yeSBvbiBTd2FuIHRvIHRoZSBsb2NhbCBtYXRjaGluZyBkaXJlY3RvcnkgdG8gcnVuIHRoZSBuZXh0IHN0ZXAgaW4gUi4KCi0tLQoKIyMgUmVsYWJlbCBTZXF1ZW5jZXMKCmBgYHtyfQpyZWZzX3VuYWxpZ25lZCA8LSB0cmVlaW86OnJlYWQuZmFzdGEoIm1pY3JvZWNvL2xvcmlzL3JlZnNfdW5hbGlnbmVkLmZhc3RhIikKCnJlZnNfbGFiZWxzIDwtIGVuZnJhbWUobGFiZWxzKHJlZnNfdW5hbGlnbmVkKSwgbmFtZSA9IE5VTEwsIHZhbHVlID0gImxhYmVsIikgJT4lCiAgbXV0YXRlKGFjY2Vzc2lvbiA9IHN0cl9leHRyYWN0KGxhYmVsLCAiXlxcd3syfV9cXGQrXFwuXFxkKD89XFxzLispIikpICU+JQogIGxlZnRfam9pbihzZWxlY3QoYWxpZ25tZW50cywgc3VwZXJraW5nZG9tOnRheGlkKSwgYnkgPSBqb2luX2J5KGFjY2Vzc2lvbiA9PSByZWYpKSAlPiUKICBtdXRhdGUodGF4aWQgPSBhcy5jaGFyYWN0ZXIoc3RyX2dsdWUoInR4aWR7dGF4aWR9IikpKSAlPiUKICBhcnJhbmdlKHN1cGVya2luZ2RvbSwKICAgICAgICAgIHBoeWx1bSwKICAgICAgICAgIGNsYXNzLAogICAgICAgICAgb3JkZXIsCiAgICAgICAgICBmYW1pbHksCiAgICAgICAgICBnZW51cywKICAgICAgICAgIHNwZWNpZXMsCiAgICAgICAgICBhY2Nlc3Npb24pICU+JQogIHNlbGVjdCgKICAgIHN1cGVya2luZ2RvbTpzcGVjaWVzLAogICAgdGF4aWQsCiAgICBhY2Nlc3Npb24sCiAgICBsYWJlbAogICkKd3JpdGVfdHN2KHJlZnNfbGFiZWxzLCAibWljcm9lY28vbG9yaXMvcmVmZXJlbmNlX2tleS50c3YiKQpgYGAKCmBgYHtyfQpyZWZzX3JlbmFtZSA8LSByZWZzX2xhYmVscyAlPiUKICBzZWxlY3QobGFiZWwsIHRheGlkKQoKcmVuYW1lLmZhc3RhKCJtaWNyb2Vjby9sb3Jpcy9yZWZzX3VuYWxpZ25lZC5mYXN0YSIsIHJlZnNfcmVuYW1lLCAibWljcm9lY28vbG9yaXMvcmVmc19yZW5hbWVkLmZhc3RhIikKYGBgCgotLS0KCiMjIEFsaWduIFNlcXVlbmNlcyBhbmQgQnVpbGQgTUwgVHJlZQoKIyMjIEJhdGNoIFNjcmlwdAoKYGBge3Rlcm1pbmFsLCB3YXJuaW5nID0gRkFMU0UsIGVjaG8gPSBGQUxTRX0KIyEvYmluL2Jhc2gKI1NCQVRDSCAtLWpvYi1uYW1lPW1hZmZ0X2lxdHJlZQojU0JBVENIIC0tZXJyb3I9L3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL2xvZ3MvbWFmZnRfaXF0cmVlXyVBLmVycgojU0JBVENIIC0tb3V0cHV0PS93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9sb2dzL21hZmZ0X2lxdHJlZV8lQS5vdXQKI1NCQVRDSCAtLXBhcnRpdGlvbj1ndWVzdAojU0JBVENIIC0tbm9kZXM9MQojU0JBVENIIC0tbnRhc2tzPTEKI1NCQVRDSCAtLWNwdXMtcGVyLXRhc2s9OCAgICAgICAgIAojU0JBVENIIC0tbWVtPTY0RyAgICAgICAgICAgICAgICAgCiNTQkFUQ0ggLS10aW1lPTY6MDA6MDAgICAgICAgICAgICAKCm1vZHVsZSBwdXJnZQptb2R1bGUgbG9hZCBtYWZmdC83LjUyNgptb2R1bGUgbG9hZCBpcXRyZWUvMi4zCgoKaW5wdXRfZmFzdGE9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX3JlbmFtZWQuZmFzdGEiCmFsaWduZWRfZmFzdGE9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX2FsaWduZWRfbWFmZnQuZmFzdGEiCm91dF9wcmVmaXg9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX3RyZWUiCgptYWZmdCBcCiAgLS10aHJlYWQgOCBcCiAgLS1yZXRyZWUgMiBcCiAgLS1tYXhpdGVyYXRlIDEwMDAgXAogICIkaW5wdXRfZmFzdGEiID4gIiRhbGlnbmVkX2Zhc3RhIgogIAoKaXF0cmVlIC1zICRhbGlnbmVkX2Zhc3RhIFwKICAgICAgICAtbSBNRlArTUVSR0UgXAogICAgICAgIC1CIDEwMDAgXAogICAgICAgIC1UICRTTFVSTV9DUFVTX1BFUl9UQVNLIFwKICAgICAgICAtcHJlICIkb3V0X3ByZWZpeCIgXAogICAgICAgIC1yZWRvCiAgCmBgYAoKIyMjIFN1Ym1pdCBCYXRjaCBTY3JpcHQKCmBgYHt0ZXJtaW5hbCwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CmNkICIvd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvYmF0Y2hfc2NyaXB0cyIKc2JhdGNoICJtYWZmdF9pcXRyZWUuc2giCmBgYAoKT25jZSB0aGUgc2NyaXB0IGZpbmlzaGVzIHJ1bm5pbmcsIHRyYW5zZmVyIHRoZSBgcmVmc19hbGlnbmVkX21hZmZ0LmZhc3RhYCBhbmQgYHJlZnNfdHJlZS50cmVlZmlsZWAgZmlsZXMgZnJvbSB0aGUgZGlyZWN0b3J5IG9uIFN3YW4gdG8gdGhlIGxvY2FsIG1hdGNoaW5nIGRpcmVjdG9yeSB0byBydW4gdGhlIG5leHQgc3RlcCBpbiBSLgoKIyMjIyBOb3RlIHRoZSBGaW5hbCBNb2RlbCBVc2VkCgpJIGFsc28gbGlrZSB0byBleHRyYWN0IHRoZSBib3R0b20gb2YgdGhlIGxvZyBmaWxlIHByb2R1Y2VkIHRvIGtlZXAgdGhpcyBub3RlIG9uIHRoZSBhbGlnbm1lbnQgbW9kZWwgdGhhdCB0aGUgTUFGRlQgYWxnb3JpdGhtIHNlbGVjdGVkLiBJdCBqdXN0IG1ha2VzIGl0IGVhc2llciBmb3IgY29weWluZyBhbmQgcGFzdGluZyBpbnRvIG1hbnVzY3JpcHRzIGxhdGVyLgoKYGBgCmFsZz1BLCBtb2RlbD1ETkEyMDAgKDIpLCAxLjUzICg0LjU5KSwgLTAuMDAgKC0wLjAwKSwgbm9zaGlmdCwgYW1heD0wLjAKOCB0aHJlYWQocykKClN0cmF0ZWd5OgogRkZULU5TLWkgKEFjY3VyYXRlIGJ1dCBzbG93KQogSXRlcmF0aXZlIHJlZmluZW1lbnQgbWV0aG9kIChtYXguIDE2IGl0ZXJhdGlvbnMpCmBgYAoKLS0tCgojIE5leHQgU3RlcHMKClByb2NlZWQgdG8gdGhlIFtgbWljcm9iaW9tZV9wcmVwcm9jZXNzaW5nYCB0dXRvcmlhbF0oaHR0cHM6Ly9yaWNoLW1vbGVjdWxhci1oZWFsdGgtbGFiLmdpdGh1Yi5pby90dXRvcmlhbHMvbWljcm9iaW9tZV9wcmVwcm9jZXNzaW5nLmh0bWwpIHRvIG1lcmdlIHRoZXNlIHdpdGggeW91ciBvdGhlciBtaWNyb2Jpb21lIHJlc3VsdHMgYmVmb3JlIGNsZWFuaW5nIGFuZCBmaWx0ZXJpbmcgeW91ciBkYXRhc2V0Lgo=